Compare commits

...
Author SHA1 Message Date
Will Pazner d0611d256b Use static data member instead of static local variable in constructor 2024-11-14 07:47:35 -08:00
Will Pazner e561db6d0a MFEM_EXPORT for static kernel dispatch members
For compatibility with Windows/MSVC
2024-11-13 22:41:29 -08:00
Will Pazner 40dbb933e7 Attempt workaround for MSVC segfault
Potential compiler bug with delegated constructors in MSVC
2024-11-13 19:55:17 -08:00
Will Pazner 293b5f78e8 Change kernel specialization instantiation to use local static variable in constructor
This is in order to avoid issues with the static member variable being optimized
away by the compiler.
2024-11-12 12:55:08 -08:00
Will Pazner 2ebe3efde8 Add unit test for kernel specializations
Adds const reference accessor for the kernel dispatch table
2024-11-12 12:06:14 -08:00
Will Pazner 8007b5073f MFEM_EXPORT static member variables
Move QuadratureInterpolator::Kernels to static local variable
2024-11-09 07:31:08 -08:00
Will Pazner 780eaeda5a Don't inline Kernels::EnsureInitialized()
Prevent the compiler from optimizing out the calls
2024-11-08 14:15:48 -08:00
Will Pazner 8a4bb61a2a Ensure kernel dispatch tables are initialized
The kernel dispatch tables are initialized in the constructor of a static member
variable.

If this variable is not odr-used, then it may be optimized away, and the
initialization code is never called. This commit ensures the initialization occurs
by adding a no-op EnsureInitialized member function to the Kernels class that can
be called from the integrator constructor.
2024-11-08 12:05:33 -08:00
Will Pazner 6105a4e1fa Merge pull request #4560 from mfem/vector-identity-interpolator
Vector identity interpolator
2024-11-05 10:45:42 -08:00
Tzanio Kolev 759ca48add Merge pull request #4408 from mfem/device-ho-lor-H1
Device HO to LOR Transfer
2024-11-04 15:59:50 -08:00
Arturo Vargas c214533826 mention device LOR-HO transfer capability in changelog 2024-11-04 14:52:54 -08:00
Tzanio Kolev 8b8abfb611 Merge pull request #4436 from mfem/algoim_cut_integration_port
Algoim cut integration port
2024-11-03 10:21:57 -08:00
Tzanio Kolev 8989feda0d Merge pull request #4466 from mfem/col-der-kernel
Kernels to compute derivatives of gridfunctions with Lagrange interpolants on collocated points
2024-11-03 10:20:55 -08:00
Tzanio Kolev 784b74e1b3 Merge pull request #4523 from helloworld922/hip_uvm
Fixed support for HIP managed memory allocation/deallocation in the memory manager
2024-11-03 10:20:31 -08:00
Veselin Dobrev cea760b1e6 Fix a potential memory leak in class IdentityInterpolator
Reported-by: Will Pazner <pazner@users.noreply.github.com>
2024-11-01 19:11:43 -07:00
Veselin Dobrev 4b6e48e915 Merge branch 'master' into vector-identity-interpolator
Resolved conflicts and related edits:
   fem/bilininteg.hpp
2024-11-01 14:57:02 -07:00
Veselin Dobrev ba9de3252b In class IdentityInterpolator, add support for vector dimension
(number of components) greater than 1. The case of PA is not
supported yet.

Class VectorIdentityInterpolator simply inherits from
IdentityInterpolator while requiring the vector dimension to
be set at construction.
2024-11-01 14:35:55 -07:00
Veselin DobrevandWill Pazner c3ac1e2222 Apply reviewer suggestion
Co-authored-by: Will Pazner <11493037+pazner@users.noreply.github.com>
2024-10-30 18:05:22 -07:00
Arturo Vargas 031f8ad04a convert more multi-dim loops to 1d loops 2024-10-30 14:15:22 -07:00
Arturo Vargas 3a64973722 use 1D index instead of 3D to avoid thread block limits 2024-10-30 10:36:59 -07:00
Will Pazner bd6c2ab61a Change 3D thread block to 1D threading in EA LOR transfer
This kernel was requesting too many threads per block.

Since it doesn't use shared memory, there is no problem using a flat threading
strategy.
2024-10-29 21:30:12 -07:00
Will Pazner 1c90b1fd4f Ensure proper alias synchronization in EA LOR transfer 2024-10-29 21:16:37 -07:00
Will Pazner 41cc480ba8 Merge pull request #4555 from mfem/batched-mult-transpose
Batched mult transpose in LOR transfer
2024-10-29 15:10:21 -07:00
Will Pazner b1fc0a039f Use batched linear algebra in LOR transfer 2024-10-29 13:07:33 -07:00
Will Pazner a714c4e881 Fix signature of MixedMassEA 2024-10-29 12:55:48 -07:00
Will Pazner 8d189be921 Add DenseTensor::NewMemoryAndSize 2024-10-29 12:55:30 -07:00
Will Pazner 82b0035ba2 Add MultTranspose in batched linear algebra 2024-10-29 12:36:00 -07:00
Arturo Vargas a8db9de5a3 make memory type is now a method 2024-10-29 09:52:50 -07:00
Arturo Vargas c086d8362d removed unused var 2024-10-29 09:08:03 -07:00
Arturo Vargas cf78d5d9f5 clean up 2024-10-28 22:36:08 -07:00
Arturo Vargas 447d2ccd52 remove unused var 2024-10-28 22:27:59 -07:00
Arturo Vargas 323cd8a2ae clean up 2024-10-28 22:25:09 -07:00
Arturo Vargas cbb95d2a8e clean up pass and driver config 2024-10-28 22:08:51 -07:00
Arturo Vargas 1767d82a92 drivers 2024-10-28 21:54:05 -07:00
Arturo Vargas 4c33502069 remove error checking and introduce ea switch 2024-10-28 21:01:31 -07:00
blaz a74eed1083 Merge branch 'master' into algoim_cut_integration_port 2024-10-28 20:50:38 -07:00
Arturo Vargas 3de18c65ab ready to remove error checking routines 2024-10-28 20:12:35 -07:00
Arturo Vargas 8451125d53 remove dead code 2024-10-28 18:00:58 -07:00
Arturo Vargas d9c65990d2 Merge branch 'master' into device-ho-lor-H1 2024-10-28 17:54:20 -07:00
Arturo Vargas c1a796c60f decrease tol for testing 2024-10-28 17:54:06 -07:00
Arturo Vargas d7d0e802a0 remove coefficient usage 2024-10-28 17:41:40 -07:00
Vladimir Z Tomov dee95c1d72 improved the download / build / setup instructions. 2024-10-28 15:14:11 -07:00
Arturo Vargas 5099277778 increase solve tol 2024-10-28 14:28:06 -07:00
Arturo Vargas 3a9a131967 Merge branch 'device-ho-lor-H1' of github.com:mfem/mfem into device-ho-lor-H1 2024-10-28 14:26:46 -07:00
Arturo Vargas 4491140db5 reduce quad point calculation 2024-10-28 14:25:50 -07:00
Veselin Dobrev 17955e1140 Merge pull request #3480 from mfem/ab-am-refactor
New ode solver selection mechanism[ab-am-refactor]
2024-10-28 14:08:56 -07:00
Arturo VargasandAndrew Ho 89eb2213fc Update fem/transfer.cpp
Co-authored-by: Andrew Ho <ho37@llnl.gov>
2024-10-28 10:23:24 -07:00
Tzanio Kolev d703c8c7a4 Merge branch 'master' into hip_uvm 2024-10-27 14:45:23 -07:00
Veselin Dobrev e3c0420c09 In the CMake build system, skip the 'pmesh-fitting' test when
HYPRE is built with GPU support -- in that case the miniapp
returns MFEM_SKIP_RETURN_VALUE.
2024-10-25 16:07:17 -07:00
Arturo Vargas 235ab39d4a fix variable shadow issues 2024-10-24 12:56:06 -07:00
Arturo Vargas 55efebfa00 protected -> public when methods have kernels 2024-10-24 12:41:02 -07:00
Arturo Vargas fc13ff8f6c bug fixes 2024-10-23 16:22:31 -07:00
Arturo Vargas 08cf03fc7f need to to revisit batch linear alg usage 2024-10-23 14:58:33 -07:00
Arturo Vargas 3bb7ea788f use batch mult in more places 2024-10-23 13:57:22 -07:00
Arturo Vargas f1146c13b9 introduce make ref for dense tensor 2024-10-23 13:29:33 -07:00
Arturo Vargas 81fc677483 use CoefficientVector 2024-10-23 13:04:28 -07:00
Arturo Vargas 28f9bc4dd7 clean up 2024-10-22 15:54:37 -07:00
Arturo Vargas 1886e25382 clean up pass 2024-10-22 15:40:34 -07:00
Arturo Vargas e5cd8378dc clean up pass 2024-10-22 15:33:08 -07:00
Arturo Vargas be35149113 remove old function 2024-10-22 15:31:33 -07:00
Arturo Vargas 808560ba72 add documentation for UseDevice and VerifySolution 2024-10-22 12:57:04 -07:00
Arturo Vargas 30164b2db9 remove duplicate variables 2024-10-22 10:29:17 -07:00
Arturo Vargas feeebaacc1 clean up pass 2024-10-22 09:51:38 -07:00
Arturo Vargas ad46b5217f remove duplicate variables 2024-10-22 09:20:52 -07:00
Arturo Vargas 7c37e06cd5 set tol through methods 2024-10-21 15:57:27 -07:00
Arturo VargasandVeselin Dobrev 0cdfebca48 Update fem/transfer.cpp
Co-authored-by: Veselin Dobrev <v-dobrev@users.noreply.github.com>
2024-10-21 15:50:16 -07:00
Arturo Vargas 78ddcfee78 clean up 2024-10-21 15:48:45 -07:00
Arturo Vargas a92dc14745 revert public to protected 2024-10-21 15:19:25 -07:00
Arturo Vargas 718204a3c3 clean up pass 2024-10-21 15:16:01 -07:00
Arturo Vargas 569a756b11 clean up pass 2024-10-21 15:12:40 -07:00
Arturo Vargas 56381a3706 Merge branch 'device-ho-lor-H1' of github.com:mfem/mfem into device-ho-lor-H1 2024-10-21 15:01:18 -07:00
Arturo Vargas 645bf01441 clean up 2024-10-21 15:01:06 -07:00
Arturo VargasandWill Pazner 4eaa589c1f Update fem/transfer.hpp
Co-authored-by: Will Pazner <11493037+pazner@users.noreply.github.com>
2024-10-21 14:59:41 -07:00
Arturo Vargas 6205ec2b12 use Reciprocal 2024-10-21 14:43:14 -07:00
Arturo Vargas 027681ff54 clean up pass 2024-10-21 14:28:09 -07:00
Arturo VargasandWill Pazner 4acd812daa Update linalg/batched/native.cpp
Co-authored-by: Will Pazner <11493037+pazner@users.noreply.github.com>
2024-10-21 14:24:20 -07:00
Arturo VargasandWill Pazner a1024d3645 Update linalg/batched/native.cpp
Co-authored-by: Will Pazner <11493037+pazner@users.noreply.github.com>
2024-10-21 14:13:25 -07:00
Arturo VargasandAndrew Ho 6df6f1f199 Update miniapps/tools/lor-transfer-p.cpp
Co-authored-by: Andrew Ho <ho37@llnl.gov>
2024-10-21 14:12:22 -07:00
Arturo VargasandWill Pazner 29d97f356e Update linalg/batched/native.cpp
Co-authored-by: Will Pazner <11493037+pazner@users.noreply.github.com>
2024-10-21 14:09:30 -07:00
Arturo Vargas e91f98c2c1 Merge branch 'master' into device-ho-lor-H1 2024-10-21 14:08:38 -07:00
Arturo Vargas af9695d8f2 remove redundant namespace 2024-10-21 14:06:33 -07:00
Arturo Vargas f2f0b17d91 clean up pass 2024-10-21 13:58:57 -07:00
Veselin Dobrev 36f15e5784 Fix one more test failure when using HYPRE built with GPU + UVM
The fix uses a newly added constructor for HypreParVector that creates
an alias to existing Vector + offset.

Also, fix some doxygen comments.

This commit shouls also address issue #4351 (not tested yet).
2024-10-20 12:36:53 -07:00
Tzanio Kolev db1cb03562 Merge pull request #4510 from lindsayad/hypre-mixed-int
Compare PETSc 64bit int also with HYPRE_MIXEDINT
2024-10-19 15:52:00 -07:00
Tzanio Kolev b0cfba73ff Merge pull request #4461 from mfem/gslib-custom-interpolation-fix
bug-fix for custom interpolation utility with FindPointsGSLIB
2024-10-19 15:51:39 -07:00
Arturo Vargas 8ebcd5b6d3 fix precondioner 2024-10-18 17:12:36 -07:00
Veselin Dobrev 5c1d4f24a3 Fix test failures when using HYPRE built with GPU + UVM 2024-10-17 18:48:39 -07:00
Veselin Dobrev cf4e79b0e5 Bugfixes in MemoryManager::Copy* methods for the case of alias memory 2024-10-17 16:07:13 -07:00
Will Pazner d8a9621dd5 Fix sample runs with new ODE type integers
Also add type 6 for RK6
2024-10-16 21:59:22 -07:00
Arturo VargasandAndrew Ho 0c42c16022 Update miniapps/tools/lor-transfer-p.cpp
Co-authored-by: Andrew Ho <ho37@llnl.gov>
2024-10-16 17:00:20 -07:00
Arturo VargasandAndrew Ho 81f936aad5 Update miniapps/tools/lor-transfer-p.cpp
Co-authored-by: Andrew Ho <ho37@llnl.gov>
2024-10-15 16:39:08 -07:00
Arturo Vargas 5faf1e83bb Merge branch 'master' into device-ho-lor-H1 2024-10-15 09:11:57 -07:00
Tzanio Kolev 540c21c9e5 Merge pull request #4123 from mfem/najlkin/mixed-DG
D(P)G elements support in MixedBilinearForm
2024-10-14 18:03:19 -07:00
Tzanio Kolev 829af3b6d4 Merge branch 'master' into hip_uvm 2024-10-14 17:23:19 -07:00
Ketan Mittal bc13b805da Merge branch 'master' into gslib-custom-interpolation-fix 2024-10-11 10:42:59 -07:00
Will Pazner 7f962b0ee6 Remove need to call Opt<> when adding kernel specializations
If called without specifying optional template parameters (e.g. NBZ), they will
be default-constructed. This means kernels should handle the case of T_NBZ = 0
(and replace with NBZ = 1 or other suitable default value in that case).
2024-10-10 19:27:13 -07:00
Mittal, Ketan f0ca6327cc add kernel specialization to unit test 2024-10-10 17:20:40 -07:00
Will Pazner 82b0b3c9e5 Merge remote-tracking branch 'origin/master' into col-der-kernel
# Conflicts:
#	fem/qinterp/dispatch.hpp
#	fem/qinterp/grad_by_nodes.cpp
#	fem/qinterp/grad_by_vdim.cpp
#	fem/qinterp/grad_phys_by_nodes.cpp
#	fem/qinterp/grad_phys_by_vdim.cpp
2024-10-10 17:02:26 -07:00
Arturo Vargas a854669092 Merge branch 'master' into device-ho-lor-H1 2024-10-08 09:39:31 -07:00
Ido Akkerman 77f2bcb3af Also change the parallel case 2024-10-07 12:32:13 +02:00
Vladimir Z Tomov e58ec7d6e9 macro 2024-10-04 17:14:13 -07:00
Vladimir Z Tomov 7b5497868d minor 2024-10-04 16:51:47 -07:00
Vladimir Z Tomov f5e5f62194 style 2024-10-04 16:43:14 -07:00
Vladimir Z Tomov 8d6557fa59 minor 2024-10-04 16:23:33 -07:00
Vladimir Z Tomov 2c7f088dc7 surface Algoim integration in ex38. 2024-10-04 16:12:29 -07:00
Tzanio Kolev 11030265e2 Merge pull request #4480 from mfem/kinsol-options
Add Anderson acceleration and fixed point/Picard options
2024-10-04 15:52:48 -07:00
Vladimir Z Tomov 22a7948a1b volumetric Algoim in ex38. 2024-10-04 15:39:13 -07:00
Ido Akkerman 2aa283d3ec Correct default time integrator -- numbering changed 2024-10-04 18:19:25 +02:00
Ido Akkerman a6d067bc86 Try to fix ex10 bug 2024-10-04 17:20:20 +02:00
Ido Akkerman 9ddb323911 Make style 2024-10-04 16:27:36 +02:00
Ido Akkerman 3fba6c6c64 Add different mechanism for nuber of stages in ODE & Add a get function to statedata to accept blockvectors 2024-10-04 16:25:48 +02:00
Vladimir Z Tomov a42ef2644e Added algoim as option in ex38. 2024-10-02 12:23:21 -07:00
Vladimir Z Tomov 4f69b9bca4 Merge branch 'master' into algoim_cut_integration_port 2024-10-02 11:28:30 -07:00
Veselin Dobrev 0a00d9f69b Doxygen fix 2024-10-01 13:15:15 -07:00
Veselin Dobrev 87298ef8e4 Fix for SUNDIALS < v6 2024-10-01 13:10:28 -07:00
Arturo Vargas 5d6d96b5b1 merge with master and fix conflicts 2024-09-28 20:47:49 -07:00
Andrew Ho 676a94dcc5 Added support for HIP managed memory to the memory manager 2024-09-27 14:04:45 -07:00
Jan Nikl 635026fc5f Fixed override in TransposeIntegrator. 2024-09-26 08:35:55 -07:00
Jan Nikl 2a85a72d19 Merge branch 'master' into najlkin/mixed-DG 2024-09-26 08:30:20 -07:00
Tzanio Kolev 8ed11a5c9a Merge pull request #4356 from mfem/najlkin/mixed-form-elim-dofs
Elimination of essential DOFs/BCs in MixedBilinearForm
2024-09-25 18:43:03 -07:00
Tzanio Kolev 0739640110 Merge pull request #3138 from mfem/dispatch-map
Runtime dispatch for SMEM GPU kernels
2024-09-25 18:42:12 -07:00
Tzanio Kolev 96ac1d9444 Merge pull request #4500 from mfem/vector-move
Fix memory leak in Vector move assignment
2024-09-25 18:41:38 -07:00
Tzanio Kolev 1e29890736 Merge pull request #4399 from mfem/override
Override specifier in virtual functions
2024-09-21 16:57:22 -07:00
Tzanio Kolev 6c22a3a1ef Merge branch 'master' into override 2024-09-21 14:28:02 -07:00
Christopher vogl d6ae740c12 addressed style issues 2024-09-19 18:50:22 -07:00
cjvogl 8dc00bd3d0 added ex options check to avoid soft failures 2024-09-19 18:47:19 -07:00
cjvogl c9d87590fc refactored SUNDIALS examples to address bugs
- combined nls and nls-type for unified solver selection
- refactored HyperelasticOperator constructor with optional values for
  damping and AA
- avoiding setting JFNK for Picard iteration
- avoiding setting AA with 0 subspace
- avoiding setting damping unless user specified
2024-09-19 18:36:12 -07:00
cjvogl 04368ef95a propagated changed from SUNDIALS ex10p to ex10 2024-09-19 15:31:15 -07:00
Tzanio Kolev cfebb493c0 Merge pull request #4493 from mfem/stefanozampini/petsc-examples-init-device
Update petsc examples with missing device initializations
2024-09-19 07:41:53 -07:00
Tzanio Kolev af6cc43ad8 Merge pull request #4489 from mfem/print-mathematica-dev2
Adding PrintMathematica to dense linear algebra objects [print-mathematica-dev2]
2024-09-19 07:41:26 -07:00
Tzanio Kolev 3303e58921 Merge pull request #4448 from adam-sim-dev/remove-mesquitesmooth
Remove MesquiteSmooth which is not implemented
2024-09-19 07:41:03 -07:00
Alex Lindsay ea8fd50995 Compare PETSc 64bit int also with HYPRE_MIXEDINT 2024-09-16 21:37:22 -07:00
Arturo Vargas 24ed3a7fe2 Merge branch 'master' into device-ho-lor-H1 2024-09-16 09:14:48 -07:00
adam-sim-dev 192c4eeeea Merge branch 'master' into remove-mesquitesmooth 2024-09-16 20:25:31 +08:00
Arturo Vargas 3cedb47e7c fix style 2024-09-15 18:55:56 -07:00
Arturo Vargas c24baff0b9 use 2D for instead of 3D 2024-09-15 18:54:54 -07:00
Arturo Vargas 8bdd414658 true changes 2024-09-15 18:09:27 -07:00
Arturo Vargas d4b0014407 minor name change 2024-09-15 15:15:04 -07:00
Arturo Vargas e822520d5d revert back to master version 2024-09-15 15:11:23 -07:00
Arturo Vargas 4c952181c9 remove cout 2024-09-15 15:09:24 -07:00
Arturo Vargas 6d4f7570ad add timers to parallel driver 2024-09-15 15:07:46 -07:00
Tzanio Kolev 30bf4cae58 Merge pull request #4487 from mfem/cubit-reader-fix
Make reader comply with CUBIT output
2024-09-15 14:21:49 -07:00
Arturo Vargas 5d27d4c77f add timers to driver 2024-09-13 10:54:45 -07:00
Arturo Vargas e8a7f2136a build fixes and add helper methods 2024-09-13 10:01:44 -07:00
Arturo Vargas 167b591d01 remove old batch linear algebra header 2024-09-12 14:27:01 -07:00
Arturo Vargas 75452f6e30 remove intro example 2024-09-12 14:14:34 -07:00
Arturo Vargas 58bd809f87 integrate new batchlinear alg code 2024-09-12 14:12:46 -07:00
Will Pazner 542a72402c Fix memory leak in Vector move assignment 2024-09-11 20:32:16 -07:00
Arturo Vargas 96860ce2a6 Merge branch 'master' into device-ho-lor-H1 2024-09-11 10:25:56 -07:00
adam-sim-dev 344c72ad98 Merge branch 'master' into remove-mesquitesmooth 2024-09-11 15:17:27 +08:00
Will Pazner fb1a587206 Update CHANGELOG 2024-09-10 11:59:39 -07:00
Chris Vogl bd11106166 Revert changes to CVODESSolver::StepB 2024-09-10 11:55:49 -07:00
Will Pazner b2c53715e9 Runtime enable or disable fallback kernel reporting 2024-09-10 11:54:10 -07:00
Tzanio Kolev 957ca0d500 Merge pull request #4416 from mfem/build-bdr-dof-arr-dev
Add `FiniteElementSpace::BuildDofToBdrArrays()` and Minor Doc Clarification
2024-09-10 11:53:35 -07:00
dylan-copeland 20d8f980a5 Merge branch 'master' of github.com:mfem/mfem into override 2024-09-09 20:49:17 -07:00
dylan-copeland aeeddcb11e Fix a function in sundials. 2024-09-09 20:48:53 -07:00
Tzanio Kolev 596b76cee2 Merge branch 'master' into cubit-reader-fix 2024-09-09 11:55:15 -07:00
adam-sim-dev f8f04c9328 Merge branch 'master' into remove-mesquitesmooth 2024-09-09 08:22:01 +08:00
Tzanio Kolev 8555207d7b Merge pull request #4474 from tsokar/fix_tmop_fitting_bug
Fix uninitialized variables in pmesh-fitting
2024-09-08 15:36:09 -07:00
Stefano Zampini df87b22266 PETSc: Initialize device in examples
otherwise there will be mismatches in HYPRE and PETSc default devices for CUDA installs of MFEM
2024-09-08 14:19:48 +03:00
Stefano Zampini f57aa5a808 PETSc: fix Operator type conversion for device matrices
Add MATGENERIC to the supported operators for some operations
2024-09-08 09:56:58 +03:00
Stowell, Mark L ed256ff9a3 Removing special character from suggested Mathematica code 2024-09-05 18:03:27 -07:00
Stowell, Mark L dd127b07b5 Adding PrintMathematica to dense linear algebra objects 2024-09-05 18:02:15 -07:00
blaz df0c066e43 ALGOIM cut integration rules changes 2024-09-05 15:40:36 -07:00
Ketan Mittal 608ec13913 Merge branch 'master' into fix_tmop_fitting_bug 2024-09-05 12:29:00 -07:00
Ketan Mittal 8d01267e28 Merge branch 'master' into col-der-kernel 2024-09-05 12:26:44 -07:00
Julian Andrej b69059e79b fix sidesets too 2024-09-04 13:59:31 -07:00
Julian Andrej d6a4f0ae6c bug for bug implementation 2024-09-04 13:47:21 -07:00
Julian Andrej 0a9a48a9fc typo 2024-09-03 11:15:02 -07:00
Julian Andrej e0935aa66f remove rogue header include 2024-09-03 11:14:11 -07:00
Julian Andrej f56ef541cd remove comment 2024-09-03 11:09:51 -07:00
adam-sim-dev c5e02ba0cc Merge branch 'master' into remove-mesquitesmooth 2024-09-03 08:55:21 +08:00
Tzanio Kolev 3d43371e9d Merge pull request #4442 from mfem/bowen/miniapp-port
feature: make GLVis socket user-configurable in miniapps
2024-09-01 11:27:56 -07:00
Joseph SignorelliandJan Nikl 9c13b53522 Remove bdr attribute unnecessary setting
Co-authored-by: Jan Nikl <nikl1@llnl.gov>
2024-08-30 16:10:15 -05:00
Joseph Signorelli 83bd5a2f6c Correctly call base class function 2024-08-30 16:08:16 -05:00
Will Pazner 47de3415cf Internal namespace for Occa PA functions 2024-08-30 10:36:37 -07:00
Arturo Vargas 8130e46a06 merge with develop 2024-08-30 08:47:09 -07:00
Joseph Signorelli a80d35b387 Explicitly call FiniteElementSpace::GetEssentialVDofs 2024-08-29 11:33:50 -05:00
Joseph Signorelli b21b24b4cf Revert "debug commit"
This reverts commit 7a9ccc5dad.
2024-08-29 11:33:03 -05:00
Julian Andrej d13d2f0f7a add anderson acceleration and fixed point/picard options 2024-08-29 08:35:17 -07:00
Tzanio Kolev 5574298f29 Reverted commit_max_files_changed back to 50 2024-08-28 11:46:11 -07:00
Tzanio Kolev 8c09d9109c Adjusted CHANGELOG 2024-08-28 11:45:08 -07:00
john bowen 9cbb59b742 Formatting 2024-08-28 11:10:08 -07:00
Tzanio Kolev e5bbc170d3 Merge branch 'master' into dispatch-map 2024-08-28 10:51:40 -07:00
Joseph Signorelli 47ddbc4f67 Merge branch 'build-bdr-dof-arr-dev' of github.com:mfem/mfem into build-bdr-dof-arr-dev 2024-08-28 08:55:58 -05:00
Joseph Signorelli 4044514851 style 2024-08-28 08:55:52 -05:00
Joseph Signorelli 7a9ccc5dad debug commit 2024-08-28 08:55:34 -05:00
adam-sim-dev 60fc13dcaf Merge branch 'master' into remove-mesquitesmooth 2024-08-28 10:07:15 +08:00
Tzanio Kolev 20cb653eb3 Merge branch 'master' into build-bdr-dof-arr-dev 2024-08-27 17:04:18 -07:00
john bowen da8b01bcf1 Merge branch 'master' into bowen/miniapp-port 2024-08-27 14:44:04 -07:00
john bowen e4cfbc56d7 Add visport to declarations 2024-08-27 14:43:20 -07:00
Tzanio Kolev e50e54e090 Merge pull request #4283 from mfem/trigger-pymfem-ci
Add workflow for triggering pymfem CI
2024-08-27 13:00:45 -07:00
dylan-copeland db7072a5c4 Merge branch 'master' of github.com:mfem/mfem into override 2024-08-27 11:28:27 -07:00
Mittal, Ketan b82b7dc1a2 Merge branch 'master' of https://github.com/mfem/mfem into gslib-custom-interpolation-fix 2024-08-27 09:36:13 -07:00
Mittal, Ketan bb055a83c1 minor fix for L2 functions with points on faces 2024-08-27 09:35:52 -07:00
Tsokar 411ee5b1cf Update master 2024-08-27 17:29:16 +02:00
Tsokar fcc353b30c Initialize surf_fit_marker and surf_fit_mat_gf earlier 2024-08-27 17:25:44 +02:00
Tzanio Kolev b33a8d24ab Merge pull request #4453 from mfem/use-correct-bind
use ::bind instead of bind
2024-08-27 07:45:00 -07:00
Tsokar f1f98dd735 Fix uninitialized variables in pmesh-fitting 2024-08-27 08:46:37 +02:00
john bowen cc9885695b Merge branch 'master' into bowen/miniapp-port 2024-08-26 14:42:55 -07:00
john bowen d3a66a5887 Fix build issues 2024-08-26 14:39:23 -07:00
Tzanio Kolev e77d74aeef Merge branch 'master' into build-bdr-dof-arr-dev 2024-08-25 17:39:59 -07:00
Tzanio Kolev 723e8e656e Merge branch 'master' into remove-mesquitesmooth 2024-08-25 17:34:21 -07:00
Tzanio Kolev ac2a21516c Merge pull request #4447 from mfem/det-d1d-q1d-fix
Fix switched D1D and Q1D in determinant kernels
2024-08-25 15:22:05 -07:00
Tzanio Kolev 8ba104788f Merge pull request #4444 from mfem/small_doc_update
update the documentation of two methods in fespace
2024-08-25 15:21:49 -07:00
Tzanio Kolev a454a5407c Merge pull request #4464 from mfem/najlkin/fix-point-attr
Fixed Point default attribute.
2024-08-25 15:21:23 -07:00
Jan Nikl 689b46e3d6 Removed the workaround for 1D in the dof-to-arrays test. 2024-08-23 10:14:03 -07:00
Mittal, Ketan 95c7b8b692 Merge branch 'master' of https://github.com/mfem/mfem into col-der-kernel 2024-08-22 15:57:28 -07:00
Joseph Signorelli fb1d72e453 style 2024-08-22 17:24:46 -05:00
Joseph SignorelliandJan Nikl af1bc97a77 Fix forgotten reference
Co-authored-by: Jan Nikl <nikl1@llnl.gov>
2024-08-22 17:23:17 -05:00
Joseph Signorelli 4fac872989 style 2024-08-22 17:07:55 -05:00
Joseph Signorelli 76e7693235 Compare against boundary LDofs with associated BE on its own rank only 2024-08-22 17:06:50 -05:00
Joseph Signorelli 39fd1c5dee Loop over all the LDofs, not the TDofs! 2024-08-22 15:21:43 -05:00
Jan Nikl 85ccdf210a Fixed Point default attribute. 2024-08-22 12:53:33 -07:00
Joseph Signorelli fc802cbd6d Add continue to prevent segfaults. Separate element + bdr element checks. 2024-08-22 11:18:27 -05:00
Joseph Signorelli 61a49b8ca0 Fix MeshType::SEGMENT improperly setting bdr_attributes
Previous code used `Mesh::GenerateBoundaryElements()` followed by `Mesh::FinalizeTopology()`. This was preventing the ability to SetBdrAttributes for MeshType::SEGMENT
Fix is to instead just call `Mesh::FinalizeTopology(true)`.
2024-08-22 11:13:09 -05:00
Tzanio Kolev 0713dd34f0 Merge branch 'master' into build-bdr-dof-arr-dev 2024-08-21 08:28:51 -07:00
justinlaughlin 7d448fec3d undo change to bind on general/socketstream.cpp 2024-08-20 21:39:34 -07:00
justinlaughlin 88c0b0321c update isockstream.cpp to not use namespace std 2024-08-20 21:38:53 -07:00
Mittal, Ketan dddfd64c04 update unit test 2024-08-20 09:19:27 -07:00
Mittal, Ketan 3a03d25d8a fix for case when points_cnt = 0 2024-08-20 09:14:10 -07:00
Joseph Signorelli d303e35976 minor - fix failing test 2024-08-20 11:11:06 -05:00
Joseph Signorelli c34fc00644 style 2024-08-20 11:03:23 -05:00
Joseph Signorelli e71352e90e Implement parallel test 2024-08-20 11:03:01 -05:00
Joseph Signorelli 1d4f49acfb Include bdr dof check for serial. Renamed ldof variable to elemdof 2024-08-20 10:40:23 -05:00
john bowen ababf1aab3 Fix duplicated line 2024-08-19 10:53:41 -07:00
john bowen 0971513c89 Bump max number of files per branch 2024-08-19 10:45:28 -07:00
john bowen cef0828362 update changelog 2024-08-19 10:15:27 -07:00
john bowen 46cde14697 Merge branch 'master' into bowen/miniapp-port 2024-08-19 10:13:39 -07:00
justinlaughlin dd5963bd21 use ::bind instead of bind 2024-08-15 14:12:18 -07:00
Justin Laughlin e992d41a38 Merge branch 'master' into trigger-pymfem-ci 2024-08-14 15:27:22 -07:00
adam-sim-dev 2fad6d25b9 Remove MesquiteSmooth which is not implemented 2024-08-14 10:59:20 +08:00
dylan-copeland 898367b198 Merge branch 'master' of github.com:mfem/mfem into override 2024-08-13 19:24:59 -07:00
Will Pazner 0303669e9a Fix switched D1D and Q1D in determinant kernels 2024-08-13 16:03:36 -07:00
Joseph SignorelliandJan Nikl 104da453ed Update fem/fespace.hpp
Co-authored-by: Jan Nikl <nikl1@llnl.gov>
2024-08-13 13:22:52 -05:00
Mittal, Ketan 644e0540b1 Merge branch 'master' of https://github.com/mfem/mfem into col-der-kernel 2024-08-13 09:35:41 -07:00
Mittal, Ketan 4cbc97ae6b move permutation method to test 2024-08-13 09:35:13 -07:00
john bowen c82ce947d6 Reorder args 2024-08-12 16:14:48 -07:00
john bowen c8644c4b13 Reorder args 2024-08-12 15:56:29 -07:00
bslazarov fa10d89676 update the documentation of two methods in fesapce 2024-08-12 13:20:23 -07:00
john bowen e680558010 Add command line args for glvis 2024-08-12 13:04:12 -07:00
john bowen 0c12c9298b Make visport user configurable for miniapps 2024-08-12 13:01:37 -07:00
Mittal, Ketan 00cccf157f minor fix and update unit test 2024-08-11 14:39:42 -07:00
Mittal, Ketan da8efca267 derivative kernels for Lagrange polynomials on collocated nodes 2024-08-11 12:35:57 -07:00
Justin Laughlin 16fc316ee6 Update trigger-pymfem-ci.yml - remove pull-request from triggers 2024-08-08 15:44:23 -07:00
Justin Laughlin fd195a0e8a Merge branch 'master' into trigger-pymfem-ci 2024-08-08 15:23:54 -07:00
Justin Laughlin 45f5d4bd72 Update trigger-pymfem-ci.yml
update target for POST, change input, and add trigger on push to master
2024-08-08 15:23:21 -07:00
bslazarov 347d5f3861 final before changes :-) 2024-08-08 15:06:14 -07:00
Joseph SignorelliandWill Pazner 3c886d0c76 Update fem/fespace.hpp
Co-authored-by: Will Pazner <11493037+pazner@users.noreply.github.com>
2024-08-08 14:42:36 -05:00
Joseph Signorelli 4877bf12d1 Deprecate BuildDofToArrays, make build array fxns protected + automatic 2024-08-08 10:45:19 -05:00
Arturo Vargas 4a022b3393 Merge branch 'master' into device-ho-lor-H1 2024-08-07 11:44:30 -07:00
bslazarov db8304e311 algoim port 2024-08-06 16:21:24 -07:00
Joseph Signorelli 70941f93f0 Automatically build arrays on Get calls
- `Build` array fxns made const
- arrays declared as mutable
2024-08-06 17:04:19 -05:00
Joseph Signorelli f49ffcb99b Merge branch 'build-bdr-dof-arr-dev' of github.com:mfem/mfem into build-bdr-dof-arr-dev 2024-08-06 15:37:50 -05:00
Joseph Signorelli a076bd04cb Delete bdr dof arrays 2024-08-06 15:33:06 -05:00
Joseph Signorelli 095893d224 Merge branch 'master' into build-bdr-dof-arr-dev 2024-08-06 15:31:37 -05:00
blaz cf49036582 updated constructor 2024-08-05 23:03:15 -07:00
blaz 69b9e48cd6 port of Algoim Integration Rules 2024-08-05 22:51:05 -07:00
Will Pazner b023416c47 Use override specifier in more places
Identified using clang-tidy check 'modernize-use-override'
2024-08-05 09:45:46 -07:00
Arturo Vargas c786caef28 Merge branch 'master' into device-ho-lor-H1 2024-07-30 09:24:03 -07:00
Arturo Vargas 4abe31b237 clean up example 2024-07-29 17:00:31 -07:00
Arturo Vargas 2c723d8a21 fixup example 2024-07-29 16:56:40 -07:00
Arturo Vargas 9a742299b5 clean up code and fix error checking bug 2024-07-29 16:49:25 -07:00
Arturo Vargas 2b2b141281 remove dead code 2024-07-29 15:52:47 -07:00
Arturo Vargas e554d15416 delete old blas example 2024-07-29 15:46:41 -07:00
Arturo Vargas 1e19cc58d4 double -> real_t 2024-07-29 14:52:13 -07:00
Arturo Vargas 937390c63b clean up pass 2024-07-29 14:45:21 -07:00
Arturo Vargas 74f8617a9e remove variable shadowing 2024-07-29 14:42:14 -07:00
Arturo Vargas 77ee552475 remove shadow variable 2024-07-29 14:35:47 -07:00
Arturo Vargas efa4308b0c remove variable shadowing 2024-07-29 14:31:10 -07:00
Arturo Vargas 84caff9dd6 double -> real_t 2024-07-29 14:16:20 -07:00
Arturo Vargas 0d663eb13f remove variable shadowing 2024-07-29 14:12:20 -07:00
Arturo Vargas c1261461c5 double -> real_t 2024-07-29 14:03:49 -07:00
Arturo Vargas 256e513b02 double -> real_t 2024-07-29 14:01:03 -07:00
Arturo Vargas 9bf8f03d47 clean up pass 2024-07-29 13:52:22 -07:00
Arturo Vargas 45716da3e8 merge master and make style 2024-07-29 13:36:13 -07:00
Arturo Vargas 093be3733b make style 2024-07-29 13:16:43 -07:00
Arturo Vargas 7c6e4c48ae add missing header 2024-07-29 13:15:11 -07:00
Veselin Dobrev ac36c05f4b Fix typo 2024-07-26 16:10:45 -07:00
Veselin Dobrev 065c7dfd2b Add class VectorIdentityInterpolator 2024-07-26 15:08:46 -07:00
Arturo Vargas e8d76b6887 fix transfer fem spaces 2024-07-24 15:59:50 -07:00
Arturo Vargas f69981012a remove output 2024-07-24 15:55:20 -07:00
Arturo Vargas 2ebbe59aee revert cuda integration 2024-07-23 18:46:00 -07:00
Arturo Vargas bd7218a2e4 make style fixes 2024-07-23 15:14:43 -07:00
Arturo Vargas 8726340bc1 cuda cublas call not supported with 11.2 2024-07-23 13:09:35 -07:00
Arturo Vargas f0de5ade98 make function with lambda public 2024-07-23 12:47:35 -07:00
Arturo Vargas 77b88173b4 optimization pass for MPI version 2024-07-23 12:06:23 -07:00
Arturo Vargas bff6755a36 use mfem::out 2024-07-22 14:53:42 -07:00
Arturo Vargas b914196334 Merge branch 'master' into device-ho-lor-H1 2024-07-22 14:16:21 -07:00
dylan-copeland 661e2d3d2b Fixing some mistakes. 2024-07-19 17:14:46 -07:00
dylan-copeland 1c71292d7c Merge branch 'master' of github.com:mfem/mfem into override 2024-07-19 16:44:39 -07:00
dylan-copeland 0e7dc57fe5 A couple more files. 2024-07-19 16:43:50 -07:00
dylan-copeland 337ab968e1 Override for more header files, miniapps, and examples. 2024-07-19 16:38:03 -07:00
Joseph Signorelli 88f731cf32 Update docs 2024-07-19 15:02:16 -05:00
Joseph Signorelli f89885905c style 2024-07-19 14:49:58 -05:00
dylan-copeland 3bf5c6adad Override for files in linalg. 2024-07-19 12:19:56 -07:00
Joseph Signorelli def84fdd86 Add doftobdr arrays + minor documentation rephrase 2024-07-19 13:57:06 -05:00
dylan-copeland 565c2b800d Override for the remaining files in fem. 2024-07-19 11:10:00 -07:00
Christine Tseng 1b484707ab attempt of MassIntegrator replacement for lumped M_L and M_H build 2024-07-18 16:59:50 -07:00
Christine Tseng 72a520df8b clean up style, clean out unnecessary files 2024-07-18 13:57:17 -07:00
chrissytseng e44d7cdea7 Merge branch 'master' into device-ho-lor-H1 2024-07-18 13:12:26 -07:00
Christine Tseng 423edcc540 make style 2024-07-18 13:11:32 -07:00
Christine Tseng 9e71343031 commit backends.hpp 2024-07-17 15:32:36 -07:00
Christine Tseng 02194f6ecb made L2Projection public for mfem::forall; fixed dimension issue by initializing operator with scalar FES 2024-07-17 13:51:05 -07:00
Christine Tseng 09b0b3eacc edit coeff == nullptr case to set coeff = 1 2024-07-17 11:53:26 -07:00
Jan Nikl 0c91dba1bd Added verifies for SpMat(Elim)(). 2024-07-16 14:51:17 -07:00
Jan Nikl fce85e66a9 Removed virtual and added override in the whole DGTraceIntegrator. 2024-07-16 14:42:02 -07:00
Jan Nikl 6d5381cdd2 Removed virtualand added override to DGTraceIntegrator. 2024-07-16 14:33:46 -07:00
Christine Tseng 8bbf7a87c2 cleaned for intuitive naming; coeff set default to nullptr 2024-07-16 13:17:08 -07:00
Christine Tseng 432d290af5 fixed cases for building R in device H1Space; cleaned up 2024-07-15 16:50:51 -07:00
Christine Tseng a2ffe892c8 fixes for device H1Space parallel, including parallel driver 2024-07-15 16:03:43 -07:00
Christine Tseng ab8e18be26 added device H1Space parallel 2024-07-15 16:00:18 -07:00
dylan-copeland 5d6ca8b560 Fix for -Winconsistent-missing-override. 2024-07-12 21:10:43 -07:00
Dylan Copeland cc22712539 Override for some files in fem. 2024-07-12 19:49:00 -07:00
Dylan Copeland 6fbe2c2280 Override for remaining files in fem/fe. 2024-07-12 18:51:09 -07:00
Dylan Copeland 65b3cb157a Adding override specifier to virtual functions. 2024-07-12 12:05:29 -07:00
Christine Tseng 84b49f507a added compatibility for MFEM_USE_MPI for rank 1 2024-07-11 09:16:17 -07:00
Christine Tseng 7aa36f82d9 added H1Space device Restriction Operator class 2024-07-03 15:49:05 -07:00
Christine Tseng 5032ec9d7d cleaned up for less memory and computation 2024-07-02 15:33:20 -07:00
Christine Tseng 1c655cbdc5 Added preconditioner for H1Space Device prolongation operator - significant reductions to CGsolver iterations 2024-07-02 14:52:50 -07:00
Christine Tseng 170ebdc372 Added H1Space Device Prolong and Prolong Transpose 2024-07-01 16:45:46 -07:00
Christine Tseng b2c45912f7 added preliminary set up of P operator 2024-06-28 16:17:06 -07:00
Christine Tseng b758c68930 added H1 MultTranspose; cleaned up classes; R is ready for merge 2024-06-27 13:36:32 -07:00
Christine Tseng 5067891393 Added QuadCoeffFunc on inv(lumped M_L) and mixed mass element assembly for device 2024-06-27 12:15:28 -07:00
Will Pazner ffce41001e Suppress Doxygen warnings 2024-06-27 09:27:58 -07:00
Will Pazner 5724e4f274 Improve kernel dispatch mechanism and workaround MSVC issues
Introduce some workarounds for MSVC:

- Need to expand variadic macros explicitly
- Adjacent parameter packs in function templates not supported; use nested
  structs instead
- Can't use default parameters in template definition if not present in
  declaration

Some improvements to the kernel dispatch:

- Run is now a static member function (don't need to call Get)
- DIM is not treated differently from the other parameters
2024-06-27 09:27:58 -07:00
Will Pazner e189b0b0f0 Fix deprecated implicit cast warning 2024-06-26 16:12:42 -07:00
Will Pazner 11badb5d2f Workaround for gcc bug with variadic template parameter packs 2024-06-26 16:09:07 -07:00
Will Pazner 39e3854585 Remove extra semicolon, include <cstddef> 2024-06-26 15:57:55 -07:00
Will Pazner c271ac1eda Fix MFEM_REGISTER_KERNELS macro warnings
Fixes the warnings:

must specify at least one argument for '...' parameter of variadic macro
[-Werror,-Wgnu-zero-variadic-macro-arguments]

and

extra ';' inside a class [-Werror,-Wextra-semi]
2024-06-26 15:27:29 -07:00
Will Pazner ed8ce36e96 Use regular comments instead of Doxygen for MFEM_REGISTER_KERNELS macro 2024-06-26 15:26:46 -07:00
john bowen 66c71dd4f2 Merge branch 'dispatch-map-v2' into dispatch-map 2024-06-26 14:42:27 -07:00
Will Pazner 635c487665 Simplify kernel dispatch macro 2024-06-26 11:42:24 -07:00
Will Pazner 90c995f0e6 Add mechanism for reporting kernel fallbacks 2024-06-26 11:25:47 -07:00
Will Pazner 9d3ce2c394 Add headers to fem/CMakeLists.txt 2024-06-26 11:25:04 -07:00
Jan Nikl 6fd27950ed Revert "Added support of mixed elements to the non-linear form integrator."
This reverts commit 736f0aca8a.
2024-06-26 08:46:33 -07:00
Will Pazner 185b2bba58 Kernel dispatch for non-tensor eval kernels 2024-06-25 22:12:54 -07:00
Christine Tseng 297877bbef including transfer docs for Device Mult for H1 2024-06-25 16:35:07 -07:00
Christine Tseng f0e9b0b55f Added DeviceMult for H1 Space, missing QuadCoeffFunction ability on lumped(inv M_L) 2024-06-25 16:22:09 -07:00
Will Pazner 93e6be67d3 Doxygen documentation for dispatch map 2024-06-25 15:24:17 -07:00
Will Pazner 7a4ab004c2 Add Det kernel specializations 2024-06-25 15:11:11 -07:00
Will Pazner 467cc941f3 Fix to QuadratureInterpolator in H(div) linear solver 2024-06-25 15:06:22 -07:00
Will Pazner 5a5d9cfe77 Split QuadratureInterpolator kernel instantiations into multiple translation units 2024-06-25 15:05:48 -07:00
Will Pazner 998b531fe5 Rework NBZ kernel dispatch, add Det QuadratureInterpolator kernels 2024-06-25 14:39:00 -07:00
Will Pazner c33327f234 Bring back NBZ in QuadratureInterpolator 2024-06-25 13:29:56 -07:00
Will Pazner e60145110d QuadratureInterpolator kernel specializations 2024-06-25 13:03:04 -07:00
Will Pazner 5f04684f17 Bring back NBZ in mass and diffusion kernels 2024-06-25 12:48:48 -07:00
Will Pazner a3065a05dc Rename MFEM_DECLARE_KERNELS to MFEM_REGISTER_KERNELS 2024-06-25 11:06:21 -07:00
Will Pazner ede448d783 Unify kernel dispatch with and without fallback parameters 2024-06-25 11:05:36 -07:00
Will Pazner 2e0df87cd6 Use dispatch mechanism in QuadratureInterpolator 2024-06-24 21:57:07 -07:00
Will Pazner 5ec854e9e4 Rearrange parameters in kernel dispatch 2024-06-24 21:48:07 -07:00
Will Pazner 842c68b0b5 Proof of concept for dispatch with QuadratureInterpolator 2024-06-24 16:38:43 -07:00
Will Pazner c3806304d4 More simplifications 2024-06-24 15:50:12 -07:00
Will Pazner a092f9cad0 Small adjustments 2024-06-24 14:38:41 -07:00
Will Pazner 17eb65d619 Some suggestions for dispatch map 2024-06-24 13:47:01 -07:00
john bowen 75567ae1ef remove NBZ as a kernel parameter 2024-06-21 11:22:07 -07:00
john bowen c18e27aeac Merge branch 'master' into dispatch-map 2024-06-20 10:06:08 -07:00
john bowen 3d84777b69 Simplify kernel specialization class boilerplate using a macro. 2024-06-20 10:03:05 -07:00
Christine Tseng 69bfdf44c7 fix use_device if-statement under L2Space MultTranspose from DeviceMult to DeviceMultTranspose 2024-06-18 11:03:22 -07:00
Christine Tseng acd07bc6bd added QuadratureFunctionCoefficient; examples of coefficient implementation in lor-transfer.cpp driver 2024-06-18 10:32:35 -07:00
Christine Tseng 6a21cb7eba added QuadratureFunctionCoefficient for weighted integrals 2024-06-18 09:59:51 -07:00
john bowen cb6d48f499 Simplify Run method in kernel dispatch 2024-06-13 15:18:33 -07:00
Jan Nikl f135f662e7 Replaced depracated method MixedBilinearForm::EliminateTrialDofs(). 2024-06-13 11:40:41 -07:00
Jan Nikl 9ca87d3ecf Fixed shadowing in MixedBilinearForm. 2024-06-13 11:27:33 -07:00
Jan Nikl 10b9503528 Removed some extra spaces in MixedBilinearForm. 2024-06-13 11:03:10 -07:00
Jan Nikl 0572181086 Improved docstring in MixedBilinearForm. 2024-06-13 10:58:38 -07:00
Jan Nikl 8c58872ec8 Fixed math in bilinearform. 2024-06-13 10:39:28 -07:00
Jan Nikl df5b718f16 Added dof/bc elimination methods to MixedBilinearForm. 2024-06-13 10:39:15 -07:00
john bowen 01dfecd67e Fix unit test failures 2024-06-13 09:40:43 -07:00
john bowen f387244e57 Update kernel dispatch to support QuadratureInterpolator 2024-06-12 13:21:20 -07:00
Jan Nikl ce0d89397b Changed the allocation of empty matrices in BilinearForm::Compute*Matrix(). 2024-06-10 15:18:28 -07:00
Jan Nikl c2cc36e559 Changed the allocation of empty matrices in MixedBilinearForm::Compute*Matrix(). 2024-06-10 15:12:50 -07:00
Jan Nikl 305124eaaf Removed extra space in TransposeIntegrator. 2024-06-10 14:47:58 -07:00
Jan Nikl e30950f349 Fixed 'a' to 'an' in docstring of BilinearForm::AddInteriorFaceIntegrator(). 2024-06-10 14:22:49 -07:00
Jan Nikl 254ade218b Removed some extra spaces in bilinearform.cpp. 2024-06-10 14:17:41 -07:00
Christine Tseng 8d78dcaf9e vendor calls on batched mult in batchlinalg.cpp done; driver blas.cpp is for checks 2024-06-07 14:01:16 -07:00
IdoAkkerman a69e1c69ef Fix unittest 2024-05-31 17:31:18 +02:00
IdoAkkerman 4bafc17358 Rename out -> os 2024-05-31 16:54:30 +02:00
IdoAkkerman dfcb153e52 Remove unnecessary Get routine 2024-05-31 16:49:30 +02:00
IdoAkkerman eea4386fcf Merge branch 'master' into ab-am-refactor 2024-05-31 13:48:41 +02:00
john bowen 7b84f6ddc6 Merge branch 'master' into dispatch-map 2024-05-30 08:19:05 -07:00
Jan Nikl 22653aaf6e Revert "Fixed short circruiting."
This reverts commit 43dd9549f4.
2024-05-24 09:15:26 -07:00
Jan Nikl c6a3ccba0b Renamed Compute*FaceElementMatrix() methods to just Compute*FaceMatrix() to be more consistent. 2024-05-23 10:31:57 -07:00
Jan Nikl 755206a2d3 Added a note about ignored integrators. 2024-05-23 10:28:29 -07:00
Jan Nikl 43dd9549f4 Fixed short circruiting. 2024-05-23 10:19:40 -07:00
Ido Akkerman ebc27b9511 Merge branch 'master' into ab-am-refactor 2024-05-21 11:02:36 +02:00
Jan Nikl 1c17415be3 Changed double to real_t in DGTraceIntegrator::AssembleFaceMatrix(). 2024-05-20 09:38:33 -07:00
Jan Nikl eaed96dae0 Merge branch 'master' into najlkin/mixed-DG 2024-05-20 09:34:44 -07:00
Arturo Vargas da07b29b6d add missing cmake files 2024-05-14 16:38:50 -07:00
Arturo Vargas 0942a818ca Merge branch 'master' into artv3/device-ho-lor 2024-05-14 16:05:22 -07:00
Justin Laughlin badd444b9f add pull_request to triggers so it will show up 2024-05-07 17:55:33 -07:00
Justin Laughlin a3ce8974f6 add input to workflow_dispatch 2024-05-07 17:53:19 -07:00
Justin Laughlin f33a4ced53 Merge remote-tracking branch 'origin/master' into trigger-pymfem-ci 2024-05-07 17:48:16 -07:00
Arturo Vargas ddb518df90 clean up pass 2024-05-07 16:50:17 -07:00
Arturo Vargas 84575c6423 remove unused variables 2024-05-07 10:44:46 -07:00
Arturo Vargas 5e6727225b make style 2024-05-07 10:02:21 -07:00
Arturo Vargas 5c8dae8e8e fix constructor ordering 2024-05-07 10:00:01 -07:00
Arturo Vargas aa9886365f minor clean up 2024-05-06 13:25:23 -07:00
Arturo Vargas 38e48d89b1 fix name space issue 2024-05-06 13:14:30 -07:00
Arturo Vargas 64e2b26824 double -> real_t 2024-05-06 10:23:35 -07:00
Arturo Vargas 3137379e1d clean up pass 2024-05-06 10:16:13 -07:00
Arturo Vargas 901a85abf2 minor 2024-05-06 10:13:04 -07:00
Justin Laughlin 78fff76695 change ref to master, and remove inputs for now (until pymfem workflow is updated) 2024-05-03 21:06:26 -07:00
Justin Laughlin 947310138e refresh action 2024-05-03 21:02:54 -07:00
Justin Laughlin 1d939a207a change target repo to pymfem 2024-05-03 20:27:45 -07:00
Justin Laughlin 3a5d89a6fb need to add pull_request to triggers so it will show up as an action 2024-05-03 20:19:16 -07:00
Justin Laughlin c0cc3eb976 add workflow for triggering pymfem CI 2024-05-03 18:45:19 -07:00
Arturo Vargas aaf861460e transition by calling use device 2024-05-01 14:47:15 -07:00
Arturo Vargas 19500f3c0b Merge branch 'artv3/device-ho-lor' of github.com:mfem/mfem into artv3/device-ho-lor 2024-05-01 13:45:04 -07:00
Arturo Vargas 3f359156ed add temporary type 2024-05-01 13:44:53 -07:00
Arturo VargasandTom Stitt 67372245c4 Update linalg/batchlinalg.cpp
Co-authored-by: Tom Stitt <stitt4@llnl.gov>
2024-05-01 13:30:15 -07:00
Arturo Vargas 074f28ccba move macros to backends.hpp 2024-05-01 13:26:59 -07:00
Arturo Vargas 76cbcfd3be clean up pass 2024-04-30 11:40:03 -07:00
Arturo Vargas 48a170c57d NE -> len / general clean up 2024-04-30 11:37:01 -07:00
Arturo Vargas 782b0266f2 name change DeleteDevice_ ->ReleaseDeviceMemory 2024-04-04 15:59:26 -07:00
Arturo Vargas 7bd7f08fe9 LibBatchSolver -> BatchSolver 2024-04-04 14:59:51 -07:00
IdoAkkerman c2dc013de5 Fix merge error 2024-04-04 22:09:41 +02:00
Arturo VargasandTom Stitt 208f36f354 Update linalg/densemat.cpp
Co-authored-by: Tom Stitt <stitt4@llnl.gov>
2024-04-04 09:54:36 -07:00
Arturo VargasandTom Stitt 3a4fe0bfe7 Update linalg/batchlinalg.cpp
Co-authored-by: Tom Stitt <stitt4@llnl.gov>
2024-04-04 09:54:28 -07:00
IdoAkkerman 4230779792 Merge branch 'master' into ab-am-refactor 2024-04-04 14:05:24 +02:00
IdoAkkerman 7a4bd3fb51 Non-const Get and rename Append 2024-04-04 13:59:49 +02:00
IdoAkkerman 9e0f9cabc0 Merge branch 'master' into ab-am-refactor 2024-04-03 12:17:41 +02:00
IdoAkkerman b8a5c6e1a6 Fix 2 lines between class implementation 2024-04-03 12:06:08 +02:00
IdoAkkerman d168ea86ec Correct typo 2024-04-03 12:02:15 +02:00
IdoAkkerman 60b4414fd9 Added changes/additions to changelog 2024-04-03 11:54:56 +02:00
IdoAkkerman 59ec6ace17 Default Get implemented in ODEstate base class 2024-04-03 11:13:38 +02:00
IdoAkkerman 521b044d61 formatting ode2 message 2024-04-03 11:00:31 +02:00
IdoAkkerman 852da98c50 Changed ASSERT to range macro 2024-04-03 10:47:04 +02:00
IdoAkkerman 03904a8bb0 change argument name 2024-04-03 10:46:31 +02:00
IdoAkkerman 3cf792a66b Add dox to headerfile 2024-04-03 10:42:21 +02:00
IdoAkkerman 6bdaa12c88 Remove explicit function name from assert 2024-04-03 10:41:58 +02:00
IdoAkkerman 6787428ae8 Remove dox -- correct error messages 2024-04-03 10:40:52 +02:00
Ido AkkermanandVeselin Dobrev 68a9a070a5 Update linalg/ode.cpp
Co-authored-by: Veselin Dobrev <v-dobrev@users.noreply.github.com>
2024-04-03 10:34:24 +02:00
IdoAkkerman 12927b36f0 Make style 2024-04-02 17:00:45 +02:00
IdoAkkerman 43533b51d5 Merge branch 'master' into ab-am-refactor 2024-04-02 16:58:57 +02:00
john bowen 5f083cea48 Remove ubuntu cmake build error 2024-03-27 16:56:25 -07:00
john bowen 80e29c8950 Delete use of sizeof... due to msvc incompatability. 2024-03-27 16:34:34 -07:00
john bowen 7264091c6f Fix mac build 2024-03-27 16:12:12 -07:00
john bowen 33c0df349d fix makefile build 2024-03-27 14:59:13 -07:00
john bowen d3015edb40 Delete double usage 2024-03-27 14:18:55 -07:00
john bowen 927c7f82be Merge branch 'master' into dispatch-map 2024-03-27 14:13:17 -07:00
john bowen 008dda250b Fix unit tests 2024-03-27 14:08:54 -07:00
john bowen a6b00aacbf Merge branch 'master' into dispatch-map 2024-03-21 12:23:59 -07:00
john bowen 504ae95915 fix ld error 2024-03-21 12:23:26 -07:00
Arturo Vargas cfbedc494a fix formatting 2024-03-19 13:40:42 -07:00
john bowen 5d28b67295 copyright 2024-03-19 13:06:20 -07:00
john bowen b19800f1a7 Workaround for GCC limitation on class method non-type variadic pack deduction 2024-03-19 13:04:44 -07:00
Arturo Vargas 1b1d9ca272 clean up pass 2024-03-19 10:52:05 -07:00
john bowen e96dc7e4aa copyright 2024-03-07 10:59:20 -08:00
john bowen 3a113dcdd6 Merge branch 'master' into dispatch-map 2024-03-07 10:44:09 -08:00
john bowen 6a6d7eb83c Astyle 2024-03-07 10:43:50 -08:00
john bowen 8a0e295691 Delete occa merge artifact 2024-03-05 09:57:20 -08:00
john bowen 3386418737 Fixing build issues 2024-03-01 13:03:51 -08:00
john bowen 2f09777b17 tmp 2024-02-29 12:35:06 -08:00
john bowen 12842aa9e1 Tmp: Add non type parameter packs to generalize AddSpecialization API 2024-02-15 10:02:44 -08:00
Jan Nikl 3388132bc3 Added const qualifiers to the Compute(Bdr)FaceElementMatrix() methods of MixedBilinearForm. 2024-02-08 11:52:54 -08:00
Jan Nikl 1dedc55a42 Added MixedBilinearForm::Get(B)FBFI methods. 2024-02-08 11:43:16 -08:00
Jan Nikl fd6ac545fa Added MixedBilinearForm::Compute(Bdr)FaceElementMatrix(). 2024-02-08 11:42:06 -08:00
Jan Nikl 736f0aca8a Added support of mixed elements to the non-linear form integrator. 2024-02-08 11:38:24 -08:00
Jan Nikl cdc9127ed6 Added mixed boundary face integrators to MixedBilinearForm. 2024-02-08 11:37:26 -08:00
Jan Nikl cdbca8beb2 Added support of integral finite elements to DGTraceIntegrator for the mixed form. 2024-02-08 11:36:07 -08:00
Jan Nikl bffd75c0da Added mixed DG support to DGTraceIntegrator. 2024-02-08 11:35:34 -08:00
Jan Nikl 1b5ae7461b Added interior face integrators for mixed forms. 2024-02-08 11:33:42 -08:00
john bowen b07ff3f5db Merge branch 'master' into dispatch-map 2024-02-08 09:34:15 -08:00
john bowen b86fdfb46c Add clangd files to gitignore 2024-01-30 10:56:05 -08:00
john bowen 50905e0dcb Copyright 2024-01-30 10:55:15 -08:00
john bowen 9702811d72 Fix linker errors 2024-01-16 17:28:47 -08:00
john bowen 955fe9f9df Merge branch 'master' into dispatch-map 2024-01-16 14:44:06 -08:00
john bowen 97e4f45be3 astyle format 2024-01-16 14:43:30 -08:00
john bowen 60242d41bd Fix makefile build error 2024-01-16 14:33:40 -08:00
john bowen 1fb47dab6b Cleanup following rebase 2024-01-16 13:35:46 -08:00
john bowen cd671cae3e tmp 2024-01-03 13:58:12 -08:00
john bowen c2154f95fe Merge branch 'master' into dispatch-map 2024-01-02 13:14:48 -08:00
Ido Akkerman b48574391e Merge pull request #4041 from mfem/ab-am-refactor-unique-ptr
Use unique_ptr in PR #3480
2023-12-21 09:25:07 +01:00
Will Pazner cd6919ce29 Return unique_ptr from ODESolver::Select (and others) 2023-12-19 12:24:34 -08:00
Will Pazner 15f7f9dd1a Merge remote-tracking branch 'origin/master' into ab-am-refactor 2023-12-19 12:24:18 -08:00
Ido AkkermanandWill Pazner 2305d501db Apply suggestions from code review
Co-authored-by: Will Pazner <11493037+pazner@users.noreply.github.com>
2023-12-11 13:34:23 +01:00
IdoAkkerman e125207781 Merge branch 'master' into ab-am-refactor 2023-12-04 14:26:50 +01:00
IdoAkkerman 8701290a72 Small compile fix -- unusaed variable 2023-12-04 14:26:17 +01:00
IdoAkkerman 35e3930fd7 Refactor ode test -- split with and without restart 2023-12-04 13:15:25 +01:00
IdoAkkerman f5cf13076b Merge branch 'master' into ab-am-refactor 2023-11-29 11:33:55 +01:00
IdoAkkerman 2bb6c55d66 Move object and add comments 2023-11-29 11:33:22 +01:00
IdoAkkerman 08085843db Merge remote-tracking branch 'origin/ab-am-refactor-suggestion' into ab-am-refactor 2023-11-29 11:05:34 +01:00
IdoAkkerman 3123099784 Remove superfluous nullptr init 2023-11-29 10:35:08 +01:00
Christopher vogl 4e3df5a144 indentation adjustment for code style 2023-11-21 19:33:23 -08:00
Christopher vogl 6baa0e29db added missing 'override' discovered by clang 2023-11-21 19:31:29 -08:00
Christopher vogl 612b7aa4f7 added curly brackets to appease code style 2023-11-21 19:27:37 -08:00
Christopher vogl 80702006f2 updated test_ode to use new ODESolverWithStates class 2023-11-21 19:25:30 -08:00
Christopher vogl 6ac7f61224 introduced ODESolverWithStates interface and moved GetState from ODESolver 2023-11-21 19:24:49 -08:00
Christopher vogl 098063f588 introduced ODEStateData interface and renamed ODEStateData to ODEStateDataVector 2023-11-21 19:23:52 -08:00
IdoAkkerman c76b58fb12 Merge branch 'ab-am-refactor' of https://github.com/mfem/mfem into ab-am-refactor 2023-11-21 11:10:40 +01:00
IdoAkkerman 4849471dc2 Changed ABORT comment 2023-11-21 10:52:31 +01:00
Ido Akkerman 4c57ba72a6 Merge branch 'master' into ab-am-refactor 2023-11-21 10:01:56 +01:00
IdoAkkerman 0a44db4850 Add clang include 2023-11-20 17:15:07 +01:00
IdoAkkerman 04691f4c16 Add comments 2023-11-20 17:11:17 +01:00
IdoAkkerman 3e1aec8bf8 Rename data and members of ODEStateData, also different access from ODESolver 2023-11-20 16:51:58 +01:00
IdoAkkerman ab71be1272 Make style 2023-11-20 15:43:02 +01:00
IdoAkkerman d7352fbfd4 Merge branch 'ab-am-refactor' of https://github.com/mfem/mfem into ab-am-refactor 2023-11-20 15:41:08 +01:00
IdoAkkerman ab7028ed7e Use ABORT instead of error 2 2023-11-20 15:25:27 +01:00
IdoAkkerman 793dd5e4c2 Use ABORT instead of error 2023-11-20 15:24:41 +01:00
IdoAkkerman 3920872a08 Rename State, add const and use 2023-11-20 15:22:35 +01:00
IdoAkkerman 94fd002fab Rename StateData, add ODE 2023-11-20 14:53:08 +01:00
Ido Akkerman 282e5b1a3d Merge branch 'master' into ab-am-refactor 2023-11-06 09:36:14 +01:00
IdoAkkerman f49f007eda Small ubuntu fix 2023-11-03 10:13:39 +01:00
IdoAkkerman a2943f213f Make style 2023-11-03 09:59:04 +01:00
IdoAkkerman 9c35bfbfda Mem leak fix 2023-11-03 09:53:03 +01:00
IdoAkkerman e488fc158d Small macos fixes 2023-11-03 09:39:14 +01:00
IdoAkkerman 1d194da30d Merge branch 'master' into ab-am-refactor 2023-11-02 16:16:28 +01:00
Ido Akkerman 77d3c64a0d Add state to ODE2 2023-11-02 14:21:50 +01:00
Ido Akkerman cd0ef98f79 Fix potential sequence error 2023-11-02 13:55:03 +01:00
Ido Akkerman fcb853fd6c Add memtype statement 2023-11-02 13:50:10 +01:00
Ido Akkerman 5416209e9d Gen-Alpha also using statedata 2023-11-02 13:44:47 +01:00
Ido Akkerman 448a395e5b AB + AM works -- GA not 2023-11-02 13:36:42 +01:00
Ido Akkerman baacaa9726 State moved to ODESolver 2023-11-02 12:05:03 +01:00
Ido Akkerman 6fa0fb9efd Style + remove timecheck function 2023-11-02 10:17:49 +01:00
Ido Akkerman f5580dd673 Also let AM use the state class 2023-11-01 10:52:55 +01:00
Ido Akkerman 4d7c1c959f Add state class to ode 2023-11-01 10:29:43 +01:00
Ido Akkerman 3c4e2a65a6 Fix small typo 2023-11-01 10:29:16 +01:00
Ido Akkerman 3c53fbf767 Fixed ode solver index changes 2023-03-31 11:37:01 +02:00
Ido Akkerman 68b0c3c55f Resolved merge conflicts 2023-03-31 11:36:38 +02:00
Ido Akkerman 3fb8003f06 Fix static 2023-03-31 09:48:33 +02:00
Ido Akkerman 830eebd35e Remove tmp files 2023-03-30 15:06:35 +02:00
Ido Akkerman e36aaf91ed Mult or Step choice 2023-03-27 16:54:38 +02:00
Ido Akkerman 29e2b929f4 make style 2023-03-27 12:00:01 +02:00
Ido Akkerman 932b7dfa81 Change second order Type string 2023-03-27 11:59:22 +02:00
Ido Akkerman 36464a6ea5 Small fixes 2023-03-27 11:55:20 +02:00
Ido Akkerman 5c88b180e9 Avoid Mult to start second order integrators 2023-03-27 11:49:48 +02:00
Ido Akkerman b9e6521123 Fix windows error 2023-03-27 11:44:20 +02:00
Ido Akkerman 1f564b2674 Split implicit and explicit solvers in selection routine 2023-03-27 10:52:14 +02:00
Ido Akkerman 53e85b8bf4 Merge branch 'ab-am-refactor' of https://github.com/mfem/mfem into ab-am-refactor 2023-03-27 09:07:36 +02:00
Ido Akkerman 2a797169aa Fix include statement to be relative 2023-03-27 09:07:08 +02:00
Ido Akkerman 98f7556b21 Merge branch 'master' into ab-am-refactor 2023-03-24 09:20:23 +01:00
Ido Akkerman e185360c24 Merge master manually 2023-03-23 15:28:51 +01:00
Ido Akkerman 66cff6eeb4 Add comment regarding ownership 2023-03-23 12:15:19 +01:00
Ido AkkermanandChris Vogl a400c72ab6 Fix error message
Co-authored-by: Chris Vogl <vogl2@llnl.gov>
2023-03-23 10:02:18 +01:00
Ido AkkermanandChris Vogl 27b920d975 Fix error message
Co-authored-by: Chris Vogl <vogl2@llnl.gov>
2023-03-23 10:01:52 +01:00
Ido AkkermanandChris Vogl 058ad32dd9 Update linalg/ode.cpp
Fix error message

Co-authored-by: Chris Vogl <vogl2@llnl.gov>
2023-03-23 10:01:24 +01:00
Ido Akkerman c0476063a2 Merge branch 'master' into ab-am-refactor 2023-03-07 10:37:50 +01:00
Ido Akkerman 53f203ee79 fixing includes 2023-03-06 08:51:01 +01:00
Ido Akkerman 85f8b9b07f check if root every time 2023-03-06 08:27:43 +01:00
Ido Akkerman 336b82fafe Use order for RK selection 2023-02-23 12:48:15 +01:00
Ido Akkerman 222945b705 Modified stage handling for AM. Removed AM0, as it no longer works, and is redudant with BackwardEuler 2023-02-23 12:33:05 +01:00
Ido Akkerman 4d7e19e5e7 Add RK6 and RK8 unit tests. Routines and coefficients needed to change 2023-02-23 12:31:28 +01:00
Ido Akkerman 87d20a162c Fic conflicts 2023-02-23 10:54:55 +01:00
Ido Akkerman 8e1b422b61 Make compiler happy? 2023-02-22 09:05:02 +01:00
Ido Akkerman 965d8f7d4b Make compiler happy? 2023-02-21 17:56:32 +01:00
Ido Akkerman 470479f17a Make compiler happy? 2023-02-21 17:53:29 +01:00
Ido Akkerman fe8bd7c1bd Modify examples to use ODE selection machinery 2023-02-21 17:42:03 +01:00
Ido Akkerman 9314475e22 Adding LMS class and selector function 2023-02-21 17:41:12 +01:00
Ido Akkerman f5687330c7 Add timestep check. Flush history when step changes 2023-02-17 17:20:58 +01:00
Will Pazner f907191e58 Remove unneeded MassIntegrator member functions 2022-11-30 09:24:55 -08:00
Will Pazner 62a00562de Merge remote-tracking branch 'origin/master' into dispatch-map
# Conflicts:
#	fem/bilininteg_mass_pa.cpp
#	fem/bilininteg_mass_pa.hpp
2022-11-30 09:10:52 -08:00
Will Pazner 3316d89c63 Use 0 for default NBZ in kernel dispatch unless T::NBZ is defined 2022-11-30 09:00:28 -08:00
Will Pazner 6bf590c3ee Mass kernel dispatch 2022-11-29 21:05:43 -08:00
Will Pazner 78bf9951e3 Kernel dispatch WIP 2022-11-29 16:32:21 -08:00
Will Pazner 532060a646 Add generic dispatch table for PA kernels 2022-08-18 09:43:32 -07:00
Will Pazner 59f76ced6a Rename AddApplySpecialization to AddSpecialization 2022-08-10 21:40:56 -05:00
Will Pazner 0c2766ee76 Add dispatch table for DiffusionIntegrator::AssembleDiagonalPA 2022-08-10 16:40:19 -05:00
Will Pazner a90df38643 Calculate NBZ with constexpr pow 2022-08-10 14:15:50 -05:00
Will Pazner 407741b8e3 Add NBZ to DiffusionIntegrator kernel specialization 2022-08-10 12:32:32 -05:00
Will Pazner 3859678772 Runtime dispatch for specialized DiffusionIntegrator kernels 2022-08-10 12:10:04 -05:00
265 changed files with 9199 additions and 6293 deletions
+31
View File
@@ -0,0 +1,31 @@
# Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-806117.
#
# This file is part of the MFEM library. For more information and source code
# availability visit https://mfem.org.
#
# MFEM is free software; you can redistribute it and/or modify it under the
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.
name: "Trigger PyMFEM CI"
on:
push:
branches:
- master
jobs:
trigger-pymfem:
runs-on: ubuntu-latest
steps:
- name: Send POST request to trigger PyMFEM CI
run: |
curl -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.PYMFEM_CI_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/mfem/pymfem/actions/workflows/build-and-test-dispatch.yml/dispatches \
-d '{"ref":"master", "inputs":{"test_options":"fast"}}'
+3
View File
@@ -15,6 +15,9 @@
CMakeCache.txt
CMakeFiles/
# Clangd server cache
*.cache*
# Backup files
*~
+30
View File
@@ -10,6 +10,8 @@
Version 4.7.1 (development)
===========================
- Refactored ALGOIM cut integration rules. The interface is unified with
the interface for moment based cut integration rules.
Discretization improvements
---------------------------
@@ -30,11 +32,30 @@ New and updated examples and miniapps
- Added an MFEM example for the eikonal equation. This new solver is based on
the proximal Galerkin method introduced by Keith and Surowiec.
- Added a command line option to all miniapps (`-p` or `--send-port`) for
specifying the GLVis server socket port (19916 by default).
GPU computing
-------------
- Added support for GPU-accelerated batched linear algebra (using cuBLAS,
hipBLAS, MAGMA, or native MFEM functionality) through the BatchedLinAlg class.
- A new GPU kernel dispatch mechanism was introduced. Users can instantiate
specialized kernels for specific combinations of (for example) polynomial
degree and number of quadrature points using
`DiffusionIntegrator::AddSpecialization` and
`MassIntegrator::AddSpecialization` (this functionality may be added to more
integrators in the future).
- Calls to slower fallback kernels can be reported to `mfem::err` by setting
the environment variable `MFEM_REPORT_KERNELS` to any value other than `NO`
or by explicitly calling `KernelReporter::Enable`. Users can then add
specializations for these kernels to achieve higher performance.
- Element assembly kernels have been added for low-order refined to
high-order transfer operators. New kernels can be offloaded as device
kernels. Example usage may be found in lor-transfer.cpp under miniapps/tools.
Miscellaneous
-------------
- Refactored the `ARKStepSolver` class (ARKODE interface) to use
@@ -139,6 +160,15 @@ New and updated examples and miniapps
- Added two new example codes: 38 and 39/39p described above. Substantially
updated Example 18/18p.
- Added ODE solvers selection routines. This creates a uniformity across examples,
miniapps and other executables in regard to ODE(time-integrator) selection.
- Added new mechanism for retrieving and setting state vectors in ODE solvers.
This is relevant for AB/AM and gen-alpha solvers.
- Added ODEsolver/ODEsolver2 unit tests to verify order of convergence and
read/write functionality.
Miscellaneous
-------------
- Updated the Doxygen documentation style, which now requires Doxygen version
+7 -3
View File
@@ -502,10 +502,14 @@ MFEM_USE_CODIPACK = YES/NO
MFEM_USE_ALGOIM = YES/NO
Enable the usage of Algoim - a collection of high-order accurate numerical
methods and C++ algorithms for working with implicitly-defined geometry and
level set methods. The Algoim library requires the Blitz++ library. The MFEM
provides interface to Algoim v1. Thus, to check out the specific state use:
level set methods, see https://algoim.github.io. MFEM provides interface to
Algoim v1. To check out the specific Algoim state use:
https://github.com/algoim/algoim
git checkout 9c9ca0ef094d8ab0390ed36367a1151b459bbe0a
https://algoim.github.io
The Algoim library requires the Blitz++ library. To use the latest state of
Blitz++ that has been tested with MFEM, use:
https://github.com/blitzpp/blitz
git checkout f24a250a43dff88c31ad92916da828b7ea9a98b7
MFEM_USE_ADFORWARD = YES/NO
Enable forward mode for AD packages. This option is valid
+3 -1
View File
@@ -533,8 +533,10 @@ ifdef GOTCHA_DIR
endif
# BLITZ library configuration
BLITZ_DIR = @MFEM_DIR@/../blitz
# BLITZ_DIR must be the custom installation folder (-DCMAKE_INSTALL_PREFIX).
BLITZ_DIR = @MFEM_DIR@/../blitz/install
BLITZ_OPT = -I$(BLITZ_DIR)/include
# On intel machines, use /lib64 instead of /lib.
BLITZ_LIB = $(XLINKER)-rpath,$(BLITZ_DIR)/lib -L$(BLITZ_DIR)/lib -lblitz
# ALGOIM library configuration
+19 -45
View File
@@ -3,14 +3,14 @@
// Compile with: make ex10
//
// Sample runs:
// ex10 -m ../data/beam-quad.mesh -s 3 -r 2 -o 2 -dt 3
// ex10 -m ../data/beam-tri.mesh -s 3 -r 2 -o 2 -dt 3
// ex10 -m ../data/beam-hex.mesh -s 2 -r 1 -o 2 -dt 3
// ex10 -m ../data/beam-tet.mesh -s 2 -r 1 -o 2 -dt 3
// ex10 -m ../data/beam-wedge.mesh -s 2 -r 1 -o 2 -dt 3
// ex10 -m ../data/beam-quad.mesh -s 14 -r 2 -o 2 -dt 0.03 -vs 20
// ex10 -m ../data/beam-hex.mesh -s 14 -r 1 -o 2 -dt 0.05 -vs 20
// ex10 -m ../data/beam-quad-amr.mesh -s 3 -r 2 -o 2 -dt 3
// ex10 -m ../data/beam-quad.mesh -s 23 -r 2 -o 2 -dt 3
// ex10 -m ../data/beam-tri.mesh -s 23 -r 2 -o 2 -dt 3
// ex10 -m ../data/beam-hex.mesh -s 22 -r 1 -o 2 -dt 3
// ex10 -m ../data/beam-tet.mesh -s 22 -r 1 -o 2 -dt 3
// ex10 -m ../data/beam-wedge.mesh -s 22 -r 1 -o 2 -dt 3
// ex10 -m ../data/beam-quad.mesh -s 4 -r 2 -o 2 -dt 0.03 -vs 20
// ex10 -m ../data/beam-hex.mesh -s 4 -r 1 -o 2 -dt 0.05 -vs 20
// ex10 -m ../data/beam-quad-amr.mesh -s 23 -r 2 -o 2 -dt 3
//
// Description: This examples solves a time dependent nonlinear elasticity
// problem of the form dv/dt = H(x) + S v, dx/dt = v, where H is a
@@ -87,16 +87,16 @@ public:
real_t visc, real_t mu, real_t K);
/// Compute the right-hand side of the ODE system.
virtual void Mult(const Vector &vx, Vector &dvx_dt) const;
void Mult(const Vector &vx, Vector &dvx_dt) const override;
/** Solve the Backward-Euler equation: k = f(x + dt*k, t), for the unknown k.
This is the only requirement for high-order SDIRK implicit integration.*/
virtual void ImplicitSolve(const real_t dt, const Vector &x, Vector &k);
void ImplicitSolve(const real_t dt, const Vector &x, Vector &k) override;
real_t ElasticEnergy(const Vector &x) const;
real_t KineticEnergy(const Vector &v) const;
void GetElasticEnergyDensity(const GridFunction &x, GridFunction &w) const;
virtual ~HyperelasticOperator();
~HyperelasticOperator() override;
};
/** Nonlinear operator of the form:
@@ -120,12 +120,12 @@ public:
void SetParameters(real_t dt_, const Vector *v_, const Vector *x_);
/// Compute y = H(x + dt (v + dt k)) + M k + S (v + dt k).
virtual void Mult(const Vector &k, Vector &y) const;
void Mult(const Vector &k, Vector &y) const override;
/// Compute J = M + dt S + dt^2 grad_H(x + dt (v + dt k)).
virtual Operator &GetGradient(const Vector &k) const;
Operator &GetGradient(const Vector &k) const override;
virtual ~ReducedSystemOperator();
~ReducedSystemOperator() override;
};
@@ -141,8 +141,8 @@ private:
public:
ElasticEnergyCoefficient(HyperelasticModel &m, const GridFunction &x_)
: model(m), x(x_) { }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
virtual ~ElasticEnergyCoefficient() { }
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
~ElasticEnergyCoefficient() override { }
};
void InitialDeformation(const Vector &x, Vector &y);
@@ -160,7 +160,7 @@ int main(int argc, char *argv[])
const char *mesh_file = "../data/beam-quad.mesh";
int ref_levels = 2;
int order = 2;
int ode_solver_type = 3;
int ode_solver_type = 23;
real_t t_final = 300.0;
real_t dt = 3.0;
real_t visc = 1e-2;
@@ -177,11 +177,7 @@ int main(int argc, char *argv[])
args.AddOption(&order, "-o", "--order",
"Order (degree) of the finite elements.");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
"ODE solver: 1 - Backward Euler, 2 - SDIRK2, 3 - SDIRK3,\n\t"
" 11 - Forward Euler, 12 - RK2,\n\t"
" 13 - RK3 SSP, 14 - RK4."
" 22 - Implicit Midpoint Method,\n\t"
" 23 - SDIRK23 (A-stable), 24 - SDIRK34");
ODESolver::Types.c_str());
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
@@ -213,28 +209,7 @@ int main(int argc, char *argv[])
// 3. Define the ODE solver used for time integration. Several implicit
// singly diagonal implicit Runge-Kutta (SDIRK) methods, as well as
// explicit Runge-Kutta methods are available.
ODESolver *ode_solver;
switch (ode_solver_type)
{
// Implicit L-stable methods
case 1: ode_solver = new BackwardEulerSolver; break;
case 2: ode_solver = new SDIRK23Solver(2); break;
case 3: ode_solver = new SDIRK33Solver; break;
// Explicit methods
case 11: ode_solver = new ForwardEulerSolver; break;
case 12: ode_solver = new RK2Solver(0.5); break; // midpoint method
case 13: ode_solver = new RK3SSPSolver; break;
case 14: ode_solver = new RK4Solver; break;
case 15: ode_solver = new GeneralizedAlphaSolver(0.5); break;
// Implicit A-stable methods (not L-stable)
case 22: ode_solver = new ImplicitMidpointSolver; break;
case 23: ode_solver = new SDIRK23Solver; break;
case 24: ode_solver = new SDIRK34Solver; break;
default:
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
delete mesh;
return 3;
}
unique_ptr<ODESolver> ode_solver = ODESolver::Select(ode_solver_type);
// 4. Refine the mesh to increase the resolution. In this example we do
// 'ref_levels' of uniform refinement, where 'ref_levels' is a
@@ -371,7 +346,6 @@ int main(int argc, char *argv[])
}
// 10. Free the used memory.
delete ode_solver;
delete mesh;
return 0;
+19 -48
View File
@@ -3,14 +3,14 @@
// Compile with: make ex10p
//
// Sample runs:
// mpirun -np 4 ex10p -m ../data/beam-quad.mesh -s 3 -rs 2 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-tri.mesh -s 3 -rs 2 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-hex.mesh -s 2 -rs 1 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-tet.mesh -s 2 -rs 1 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-wedge.mesh -s 2 -rs 1 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-quad.mesh -s 14 -rs 2 -dt 0.03 -vs 20
// mpirun -np 4 ex10p -m ../data/beam-hex.mesh -s 14 -rs 1 -dt 0.05 -vs 20
// mpirun -np 4 ex10p -m ../data/beam-quad-amr.mesh -s 3 -rs 2 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-quad.mesh -s 23 -rs 2 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-tri.mesh -s 23 -rs 2 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-hex.mesh -s 22 -rs 1 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-tet.mesh -s 22 -rs 1 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-wedge.mesh -s 22 -rs 1 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-quad.mesh -s 4 -rs 2 -dt 0.03 -vs 20
// mpirun -np 4 ex10p -m ../data/beam-hex.mesh -s 4 -rs 1 -dt 0.05 -vs 20
// mpirun -np 4 ex10p -m ../data/beam-quad-amr.mesh -s 23 -rs 2 -dt 3
//
// Description: This examples solves a time dependent nonlinear elasticity
// problem of the form dv/dt = H(x) + S v, dx/dt = v, where H is a
@@ -89,17 +89,17 @@ public:
real_t visc, real_t mu, real_t K);
/// Compute the right-hand side of the ODE system.
virtual void Mult(const Vector &vx, Vector &dvx_dt) const;
void Mult(const Vector &vx, Vector &dvx_dt) const override;
/** Solve the Backward-Euler equation: k = f(x + dt*k, t), for the unknown k.
This is the only requirement for high-order SDIRK implicit integration.*/
virtual void ImplicitSolve(const real_t dt, const Vector &x, Vector &k);
void ImplicitSolve(const real_t dt, const Vector &x, Vector &k) override;
real_t ElasticEnergy(const ParGridFunction &x) const;
real_t KineticEnergy(const ParGridFunction &v) const;
void GetElasticEnergyDensity(const ParGridFunction &x,
ParGridFunction &w) const;
virtual ~HyperelasticOperator();
~HyperelasticOperator() override;
};
/** Nonlinear operator of the form:
@@ -125,12 +125,12 @@ public:
void SetParameters(real_t dt_, const Vector *v_, const Vector *x_);
/// Compute y = H(x + dt (v + dt k)) + M k + S (v + dt k).
virtual void Mult(const Vector &k, Vector &y) const;
void Mult(const Vector &k, Vector &y) const override;
/// Compute J = M + dt S + dt^2 grad_H(x + dt (v + dt k)).
virtual Operator &GetGradient(const Vector &k) const;
Operator &GetGradient(const Vector &k) const override;
virtual ~ReducedSystemOperator();
~ReducedSystemOperator() override;
};
@@ -146,8 +146,8 @@ private:
public:
ElasticEnergyCoefficient(HyperelasticModel &m, const ParGridFunction &x_)
: model(m), x(x_) { }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
virtual ~ElasticEnergyCoefficient() { }
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
~ElasticEnergyCoefficient() override { }
};
void InitialDeformation(const Vector &x, Vector &y);
@@ -172,7 +172,7 @@ int main(int argc, char *argv[])
int ser_ref_levels = 2;
int par_ref_levels = 0;
int order = 2;
int ode_solver_type = 3;
int ode_solver_type = 23;
real_t t_final = 300.0;
real_t dt = 3.0;
real_t visc = 1e-2;
@@ -192,11 +192,7 @@ int main(int argc, char *argv[])
args.AddOption(&order, "-o", "--order",
"Order (degree) of the finite elements.");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
"ODE solver: 1 - Backward Euler, 2 - SDIRK2, 3 - SDIRK3,\n\t"
" 11 - Forward Euler, 12 - RK2,\n\t"
" 13 - RK3 SSP, 14 - RK4."
" 22 - Implicit Midpoint Method,\n\t"
" 23 - SDIRK23 (A-stable), 24 - SDIRK34");
ODESolver::Types.c_str());
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
@@ -238,31 +234,7 @@ int main(int argc, char *argv[])
// 4. Define the ODE solver used for time integration. Several implicit
// singly diagonal implicit Runge-Kutta (SDIRK) methods, as well as
// explicit Runge-Kutta methods are available.
ODESolver *ode_solver;
switch (ode_solver_type)
{
// Implicit L-stable methods
case 1: ode_solver = new BackwardEulerSolver; break;
case 2: ode_solver = new SDIRK23Solver(2); break;
case 3: ode_solver = new SDIRK33Solver; break;
// Explicit methods
case 11: ode_solver = new ForwardEulerSolver; break;
case 12: ode_solver = new RK2Solver(0.5); break; // midpoint method
case 13: ode_solver = new RK3SSPSolver; break;
case 14: ode_solver = new RK4Solver; break;
case 15: ode_solver = new GeneralizedAlphaSolver(0.5); break;
// Implicit A-stable methods (not L-stable)
case 22: ode_solver = new ImplicitMidpointSolver; break;
case 23: ode_solver = new SDIRK23Solver; break;
case 24: ode_solver = new SDIRK34Solver; break;
default:
if (myid == 0)
{
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
}
delete mesh;
return 3;
}
unique_ptr<ODESolver> ode_solver = ODESolver::Select(ode_solver_type);
// 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
@@ -433,7 +405,6 @@ int main(int argc, char *argv[])
}
// 12. Free the used memory.
delete ode_solver;
delete pmesh;
return 0;
+1 -1
View File
@@ -53,7 +53,7 @@ public:
pmesh(pmesh_),
pgf(pgf_) {}
void MonitorSolution(int i, real_t norm, const Vector &x, bool final)
void MonitorSolution(int i, real_t norm, const Vector &x, bool final) override
{
char vishost[] = "localhost";
int visport = 19916;
+12 -33
View File
@@ -5,10 +5,10 @@
// Sample runs: ex16
// ex16 -m ../data/inline-tri.mesh
// ex16 -m ../data/disc-nurbs.mesh -tf 2
// ex16 -s 1 -a 0.0 -k 1.0
// ex16 -s 2 -a 1.0 -k 0.0
// ex16 -s 3 -a 0.5 -k 0.5 -o 4
// ex16 -s 14 -dt 1.0e-4 -tf 4.0e-2 -vs 40
// ex16 -s 21 -a 0.0 -k 1.0
// ex16 -s 22 -a 1.0 -k 0.0
// ex16 -s 23 -a 0.5 -k 0.5 -o 4
// ex16 -s 4 -dt 1.0e-4 -tf 4.0e-2 -vs 40
// ex16 -m ../data/fichera-q2.mesh
// ex16 -m ../data/fichera-mixed.mesh
// ex16 -m ../data/escher.mesh
@@ -76,15 +76,15 @@ public:
ConductionOperator(FiniteElementSpace &f, real_t alpha, real_t kappa,
const Vector &u);
virtual void Mult(const Vector &u, Vector &du_dt) const;
void Mult(const Vector &u, Vector &du_dt) const override;
/** Solve the Backward-Euler equation: k = f(u + dt*k, t), for the unknown k.
This is the only requirement for high-order SDIRK implicit integration.*/
virtual void ImplicitSolve(const real_t dt, const Vector &u, Vector &k);
void ImplicitSolve(const real_t dt, const Vector &u, Vector &k) override;
/// Update the diffusion BilinearForm K using the given true-dof vector `u`.
void SetParameters(const Vector &u);
virtual ~ConductionOperator();
~ConductionOperator() override;
};
real_t InitialTemperature(const Vector &x);
@@ -95,11 +95,13 @@ int main(int argc, char *argv[])
const char *mesh_file = "../data/star.mesh";
int ref_levels = 2;
int order = 2;
int ode_solver_type = 3;
int ode_solver_type = 23; // SDIRK33Solver
real_t t_final = 0.5;
real_t dt = 1.0e-2;
real_t alpha = 1.0e-2;
real_t kappa = 0.5;
bool visualization = true;
bool visit = false;
int vis_steps = 5;
@@ -115,8 +117,7 @@ int main(int argc, char *argv[])
args.AddOption(&order, "-o", "--order",
"Order (degree) of the finite elements.");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
"ODE solver: 1 - Backward Euler, 2 - SDIRK2, 3 - SDIRK3,\n\t"
"\t 11 - Forward Euler, 12 - RK2, 13 - RK3 SSP, 14 - RK4.");
ODESolver::Types.c_str());
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
@@ -149,28 +150,7 @@ int main(int argc, char *argv[])
// 3. Define the ODE solver used for time integration. Several implicit
// singly diagonal implicit Runge-Kutta (SDIRK) methods, as well as
// explicit Runge-Kutta methods are available.
ODESolver *ode_solver;
switch (ode_solver_type)
{
// Implicit L-stable methods
case 1: ode_solver = new BackwardEulerSolver; break;
case 2: ode_solver = new SDIRK23Solver(2); break;
case 3: ode_solver = new SDIRK33Solver; break;
// Explicit methods
case 11: ode_solver = new ForwardEulerSolver; break;
case 12: ode_solver = new RK2Solver(0.5); break; // midpoint method
case 13: ode_solver = new RK3SSPSolver; break;
case 14: ode_solver = new RK4Solver; break;
case 15: ode_solver = new GeneralizedAlphaSolver(0.5); break;
// Implicit A-stable methods (not L-stable)
case 22: ode_solver = new ImplicitMidpointSolver; break;
case 23: ode_solver = new SDIRK23Solver; break;
case 24: ode_solver = new SDIRK34Solver; break;
default:
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
delete mesh;
return 3;
}
unique_ptr<ODESolver> ode_solver = ODESolver::Select(ode_solver_type);
// 4. Refine the mesh to increase the resolution. In this example we do
// 'ref_levels' of uniform refinement, where 'ref_levels' is a
@@ -287,7 +267,6 @@ int main(int argc, char *argv[])
}
// 10. Free the used memory.
delete ode_solver;
delete mesh;
return 0;
+12 -33
View File
@@ -5,10 +5,10 @@
// Sample runs: mpirun -np 4 ex16p
// mpirun -np 4 ex16p -m ../data/inline-tri.mesh
// mpirun -np 4 ex16p -m ../data/disc-nurbs.mesh -tf 2
// mpirun -np 4 ex16p -s 1 -a 0.0 -k 1.0
// mpirun -np 4 ex16p -s 2 -a 1.0 -k 0.0
// mpirun -np 8 ex16p -s 3 -a 0.5 -k 0.5 -o 4
// mpirun -np 4 ex16p -s 14 -dt 1.0e-4 -tf 4.0e-2 -vs 40
// mpirun -np 4 ex16p -s 21 -a 0.0 -k 1.0
// mpirun -np 4 ex16p -s 22 -a 1.0 -k 0.0
// mpirun -np 8 ex16p -s 23 -a 0.5 -k 0.5 -o 4
// mpirun -np 4 ex16p -s 4 -dt 1.0e-4 -tf 4.0e-2 -vs 40
// mpirun -np 16 ex16p -m ../data/fichera-q2.mesh
// mpirun -np 16 ex16p -m ../data/fichera-mixed.mesh
// mpirun -np 16 ex16p -m ../data/escher-p2.mesh
@@ -78,15 +78,15 @@ public:
ConductionOperator(ParFiniteElementSpace &f, real_t alpha, real_t kappa,
const Vector &u);
virtual void Mult(const Vector &u, Vector &du_dt) const;
void Mult(const Vector &u, Vector &du_dt) const override;
/** Solve the Backward-Euler equation: k = f(u + dt*k, t), for the unknown k.
This is the only requirement for high-order SDIRK implicit integration.*/
virtual void ImplicitSolve(const real_t dt, const Vector &u, Vector &k);
void ImplicitSolve(const real_t dt, const Vector &u, Vector &k) override;
/// Update the diffusion BilinearForm K using the given true-dof vector `u`.
void SetParameters(const Vector &u);
virtual ~ConductionOperator();
~ConductionOperator() override;
};
real_t InitialTemperature(const Vector &x);
@@ -104,11 +104,13 @@ int main(int argc, char *argv[])
int ser_ref_levels = 2;
int par_ref_levels = 1;
int order = 2;
int ode_solver_type = 3;
int ode_solver_type = 23; // SDIRK33Solver
real_t t_final = 0.5;
real_t dt = 1.0e-2;
real_t alpha = 1.0e-2;
real_t kappa = 0.5;
bool visualization = true;
bool visit = false;
int vis_steps = 5;
@@ -127,8 +129,7 @@ int main(int argc, char *argv[])
args.AddOption(&order, "-o", "--order",
"Order (degree) of the finite elements.");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
"ODE solver: 1 - Backward Euler, 2 - SDIRK2, 3 - SDIRK3,\n\t"
"\t 11 - Forward Euler, 12 - RK2, 13 - RK3 SSP, 14 - RK4.");
ODESolver::Types.c_str());
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
@@ -169,28 +170,7 @@ int main(int argc, char *argv[])
// 4. Define the ODE solver used for time integration. Several implicit
// singly diagonal implicit Runge-Kutta (SDIRK) methods, as well as
// explicit Runge-Kutta methods are available.
ODESolver *ode_solver;
switch (ode_solver_type)
{
// Implicit L-stable methods
case 1: ode_solver = new BackwardEulerSolver; break;
case 2: ode_solver = new SDIRK23Solver(2); break;
case 3: ode_solver = new SDIRK33Solver; break;
// Explicit methods
case 11: ode_solver = new ForwardEulerSolver; break;
case 12: ode_solver = new RK2Solver(0.5); break; // midpoint method
case 13: ode_solver = new RK3SSPSolver; break;
case 14: ode_solver = new RK4Solver; break;
case 15: ode_solver = new GeneralizedAlphaSolver(0.5); break;
// Implicit A-stable methods (not L-stable)
case 22: ode_solver = new ImplicitMidpointSolver; break;
case 23: ode_solver = new SDIRK23Solver; break;
case 24: ode_solver = new SDIRK34Solver; break;
default:
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
delete mesh;
return 3;
}
unique_ptr<ODESolver> ode_solver = ODESolver::Select(ode_solver_type);
// 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
@@ -376,7 +356,6 @@ int main(int argc, char *argv[])
}
// 12. Free the used memory.
delete ode_solver;
delete pmesh;
return 0;
+2 -2
View File
@@ -69,7 +69,7 @@ public:
void SetDisplacement(GridFunction &u_) { u = &u_; }
void SetComponent(int i, int j) { si = i; sj = j; }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
};
// Simple GLVis visualization manager.
@@ -89,7 +89,7 @@ public:
void NewWindow();
void CloseConnection();
void PositionWindow();
virtual ~VisMan();
~VisMan() override;
};
// Manipulators for the GLVis visualization manager.
+2 -2
View File
@@ -69,7 +69,7 @@ public:
void SetDisplacement(GridFunction &u_) { u = &u_; }
void SetComponent(int i, int j) { si = i; sj = j; }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
};
// Simple GLVis visualization manager.
@@ -89,7 +89,7 @@ public:
void NewWindow();
void CloseConnection();
void PositionWindow();
virtual ~VisMan();
~VisMan() override;
};
// Manipulators for the GLVis visualization manager.
+2 -17
View File
@@ -90,8 +90,7 @@ int main(int argc, char *argv[])
args.AddOption(&order, "-o", "--order",
"Order (degree) of the finite elements.");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
"ODE solver: 1 - Forward Euler,\n\t"
" 2 - RK2 SSP, 3 - RK3 SSP, 4 - RK4, 6 - RK6.");
ODESolver::ExplicitTypes.c_str());
args.AddOption(&t_final, "-tf", "--t-final", "Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
"Time step. Positive number skips CFL timestep calculation.");
@@ -125,18 +124,7 @@ int main(int argc, char *argv[])
// 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;
}
unique_ptr<ODESolver> ode_solver = ODESolver::SelectExplicit(ode_solver_type);
// 4. Define the discontinuous DG finite element space of the given
// polynomial order on the refined mesh.
@@ -304,8 +292,5 @@ int main(int argc, char *argv[])
const real_t error = sol.ComputeLpError(2, u0);
cout << "Solution error: " << error << endl;
// Free the used memory.
delete ode_solver;
return 0;
}
+2 -17
View File
@@ -99,8 +99,7 @@ int main(int argc, char *argv[])
args.AddOption(&order, "-o", "--order",
"Order (degree) of the finite elements.");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
"ODE solver: 1 - Forward Euler,\n\t"
" 2 - RK2 SSP, 3 - RK3 SSP, 4 - RK4, 6 - RK6.");
ODESolver::ExplicitTypes.c_str());
args.AddOption(&t_final, "-tf", "--t-final", "Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
"Time step. Positive number skips CFL timestep calculation.");
@@ -148,18 +147,7 @@ int main(int argc, char *argv[])
// 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;
}
unique_ptr<ODESolver> ode_solver = ODESolver::SelectExplicit(ode_solver_type);
// 4. Define the discontinuous DG finite element space of the given
// polynomial order on the refined mesh.
@@ -360,8 +348,5 @@ int main(int argc, char *argv[])
cout << "Solution error: " << error << endl;
}
// Free the used memory.
delete ode_solver;
return 0;
}
+7 -7
View File
@@ -48,7 +48,7 @@ public:
print_level = print_lvl;
}
virtual void MonitorResidual(int it, real_t norm, const Vector &r, bool final);
void MonitorResidual(int it, real_t norm, const Vector &r, bool final) override;
private:
const std::string prefix;
@@ -116,10 +116,10 @@ public:
JacobianPreconditioner(Array<FiniteElementSpace *> &fes,
SparseMatrix &mass, Array<int> &offsets);
virtual void Mult(const Vector &k, Vector &y) const;
virtual void SetOperator(const Operator &op);
void Mult(const Vector &k, Vector &y) const override;
void SetOperator(const Operator &op) override;
virtual ~JacobianPreconditioner();
~JacobianPreconditioner() override;
};
// After spatial discretization, the rubber model can be written as:
@@ -161,13 +161,13 @@ public:
int iter, Coefficient &mu);
// Required to use the native newton solver
virtual Operator &GetGradient(const Vector &xp) const;
virtual void Mult(const Vector &k, Vector &y) const;
Operator &GetGradient(const Vector &xp) const override;
void Mult(const Vector &k, Vector &y) const override;
// Driver for the newton solver
void Solve(Vector &xp) const;
virtual ~RubberOperator();
~RubberOperator() override;
};
// Visualization driver
+7 -7
View File
@@ -62,7 +62,7 @@ public:
#endif
}
virtual void MonitorResidual(int it, real_t norm, const Vector &r, bool final);
void MonitorResidual(int it, real_t norm, const Vector &r, bool final) override;
private:
const std::string prefix;
@@ -130,10 +130,10 @@ public:
JacobianPreconditioner(Array<ParFiniteElementSpace *> &fes,
Operator &mass, Array<int> &offsets);
virtual void Mult(const Vector &k, Vector &y) const;
virtual void SetOperator(const Operator &op);
void Mult(const Vector &k, Vector &y) const override;
void SetOperator(const Operator &op) override;
virtual ~JacobianPreconditioner();
~JacobianPreconditioner() override;
};
// After spatial discretization, the rubber model can be written as:
@@ -175,13 +175,13 @@ public:
int iter, Coefficient &mu);
// Required to use the native newton solver
virtual Operator &GetGradient(const Vector &xp) const;
virtual void Mult(const Vector &k, Vector &y) const;
Operator &GetGradient(const Vector &xp) const override;
void Mult(const Vector &k, Vector &y) const override;
// Driver for the newton solver
void Solve(Vector &xp) const;
virtual ~RubberOperator();
~RubberOperator() override;
};
// Visualization driver
+2 -2
View File
@@ -79,14 +79,14 @@ class GradT : public Operator
{
public:
GradT() : Operator(1) {}
void Mult(const Vector &x, Vector &y) const { y.Set(1.0/m_, x); }
void Mult(const Vector &x, Vector &y) const override { y.Set(1.0/m_, x); }
};
class NegGradV : public TimeDependentOperator
{
public:
NegGradV() : TimeDependentOperator(1) {}
void Mult(const Vector &x, Vector &y) const;
void Mult(const Vector &x, Vector &y) const override;
};
int main(int argc, char *argv[])
+2 -2
View File
@@ -84,14 +84,14 @@ class GradT : public Operator
{
public:
GradT() : Operator(1) {}
void Mult(const Vector &x, Vector &y) const { y.Set(1.0/m_, x); }
void Mult(const Vector &x, Vector &y) const override { y.Set(1.0/m_, x); }
};
class NegGradV : public TimeDependentOperator
{
public:
NegGradV() : TimeDependentOperator(1) {}
void Mult(const Vector &x, Vector &y) const;
void Mult(const Vector &x, Vector &y) const override;
};
int main(int argc, char *argv[])
+7 -34
View File
@@ -61,20 +61,20 @@ public:
WaveOperator(FiniteElementSpace &f, Array<int> &ess_bdr, real_t speed);
using SecondOrderTimeDependentOperator::Mult;
virtual void Mult(const Vector &u, const Vector &du_dt,
Vector &d2udt2) const;
void Mult(const Vector &u, const Vector &du_dt,
Vector &d2udt2) const override;
/** Solve the Backward-Euler equation:
d2udt2 = f(u + fac0*d2udt2,dudt + fac1*d2udt2, t),
for the unknown d2udt2. */
using SecondOrderTimeDependentOperator::ImplicitSolve;
virtual void ImplicitSolve(const real_t fac0, const real_t fac1,
const Vector &u, const Vector &dudt, Vector &d2udt2);
void ImplicitSolve(const real_t fac0, const real_t fac1,
const Vector &u, const Vector &dudt, Vector &d2udt2) override;
///
void SetParameters(const Vector &u);
virtual ~WaveOperator();
~WaveOperator() override;
};
@@ -201,9 +201,7 @@ int main(int argc, char *argv[])
args.AddOption(&order, "-o", "--order",
"Order (degree) of the finite elements.");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
"ODE solver: [0--10] - GeneralizedAlpha(0.1 * s),\n\t"
"\t 11 - Average Acceleration, 12 - Linear Acceleration\n"
"\t 13 - CentralDifference, 14 - FoxGoodwin");
SecondOrderODESolver::Types.c_str());
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
@@ -238,32 +236,7 @@ int main(int argc, char *argv[])
// 3. Define the ODE solver used for time integration. Several second order
// time integrators are available.
SecondOrderODESolver *ode_solver;
switch (ode_solver_type)
{
// Implicit methods
case 0: ode_solver = new GeneralizedAlpha2Solver(0.0); break;
case 1: ode_solver = new GeneralizedAlpha2Solver(0.1); break;
case 2: ode_solver = new GeneralizedAlpha2Solver(0.2); break;
case 3: ode_solver = new GeneralizedAlpha2Solver(0.3); break;
case 4: ode_solver = new GeneralizedAlpha2Solver(0.4); break;
case 5: ode_solver = new GeneralizedAlpha2Solver(0.5); break;
case 6: ode_solver = new GeneralizedAlpha2Solver(0.6); break;
case 7: ode_solver = new GeneralizedAlpha2Solver(0.7); break;
case 8: ode_solver = new GeneralizedAlpha2Solver(0.8); break;
case 9: ode_solver = new GeneralizedAlpha2Solver(0.9); break;
case 10: ode_solver = new GeneralizedAlpha2Solver(1.0); break;
case 11: ode_solver = new AverageAccelerationSolver(); break;
case 12: ode_solver = new LinearAccelerationSolver(); break;
case 13: ode_solver = new CentralDifferenceSolver(); break;
case 14: ode_solver = new FoxGoodwinSolver(); break;
default:
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
delete mesh;
return 3;
}
SecondOrderODESolver *ode_solver= SecondOrderODESolver::Select(ode_solver_type);
// 4. Refine the mesh to increase the resolution. In this example we do
// 'ref_levels' of uniform refinement, where 'ref_levels' is a
+2 -2
View File
@@ -103,8 +103,8 @@ public:
using VectorCoefficient::Eval;
virtual void Eval(Vector &K, ElementTransformation &T,
const IntegrationPoint &ip)
void Eval(Vector &K, ElementTransformation &T,
const IntegrationPoint &ip) override
{
real_t x[3];
Vector transip(x, 3);
+2 -2
View File
@@ -102,8 +102,8 @@ public:
using VectorCoefficient::Eval;
virtual void Eval(Vector &K, ElementTransformation &T,
const IntegrationPoint &ip)
void Eval(Vector &K, ElementTransformation &T,
const IntegrationPoint &ip) override
{
real_t x[3];
Vector transip(x, 3);
+1 -1
View File
@@ -58,7 +58,7 @@ public:
}
}
virtual ~DiffusionMultigrid()
~DiffusionMultigrid() override
{
delete amg;
}
+3 -3
View File
@@ -53,7 +53,7 @@ public:
real_t min_val_=-36)
: u(&u_), obstacle(&obst_), min_val(min_val_) { }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
};
class ExponentialGridFunctionCoefficient : public Coefficient
@@ -69,7 +69,7 @@ public:
real_t min_val_=0.0, real_t max_val_=1e6)
: u(&u_), obstacle(&obst_), min_val(min_val_), max_val(max_val_) { }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
};
int main(int argc, char *argv[])
@@ -258,7 +258,7 @@ int main(int argc, char *argv[])
MixedBilinearForm a10(&H1fes,&L2fes);
a10.AddDomainIntegrator(new MixedScalarMassIntegrator());
a10.Assemble();
a10.EliminateTrialDofs(ess_bdr, x.GetBlock(0), rhs.GetBlock(1));
a10.EliminateTrialEssentialBC(ess_bdr, x.GetBlock(0), rhs.GetBlock(1));
a10.Finalize();
SparseMatrix &A10 = a10.SpMat();
+2 -2
View File
@@ -53,7 +53,7 @@ public:
real_t min_val_=-36)
: u(&u_), obstacle(&obst_), min_val(min_val_) { }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
};
class ExponentialGridFunctionCoefficient : public Coefficient
@@ -69,7 +69,7 @@ public:
real_t min_val_=0.0, real_t max_val_=1e6)
: u(&u_), obstacle(&obst_), min_val(min_val_), max_val(max_val_) { }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
};
int main(int argc, char *argv[])
+8 -8
View File
@@ -52,8 +52,8 @@ public:
fun(fun_) {}
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip)
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override
{
return fun(GridFunctionCoefficient::Eval(T, ip));
}
@@ -83,8 +83,8 @@ public:
OtherGridF_cf(OtherGridF),
fun(fun_) {}
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip)
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override
{
const real_t value1 = fun(GridFunctionCoefficient::Eval(T, ip));
const real_t value2 = fun(OtherGridF_cf.Eval(T, ip));
@@ -108,7 +108,7 @@ public:
: rho_filter(rho_filter_), min_val(min_val_), max_val(max_val_),
exponent(exponent_) { }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip)
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override
{
real_t val = rho_filter->GetValue(T, ip);
real_t coeff = min_val + pow(val,exponent)*(max_val-min_val);
@@ -142,7 +142,7 @@ public:
MFEM_ASSERT(rho_filter, "density field is not set");
}
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip)
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override
{
real_t L = lambda->Eval(T, ip);
real_t M = mu->Eval(T, ip);
@@ -176,8 +176,8 @@ public:
using VectorCoefficient::Eval;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip)
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override
{
Vector xx; xx.SetSize(T.GetDimension());
T.Transform(ip,xx);
+113 -83
View File
@@ -3,18 +3,18 @@
// Compile with: make ex38
//
// Sample runs:
// (since all sample runs require LAPACK, the * symbol is used to exclude them
// from the automatically generated internal MFEM tests).
// (since all sample runs require LAPACK or ALGOIM, the * symbol is used to
// exclude them from the automatically generated internal MFEM tests).
// * ex38
// * ex38 -i volumetric1d
// * ex38 -i surface2d
// * ex38 -i surface2d -o 4 -r 5
// * ex38 -i surface2d -o 4 -r 5 -m 1
// * ex38 -i volumetric2d
// * ex38 -i volumetric2d -o 4 -r 5
// * ex38 -i volumetric2d -o 4 -r 5 -m 1
// * ex38 -i surface3d
// * ex38 -i surface3d -o 4 -r 5
// * ex38 -i surface3d -o 3 -r 4 -m 1
// * ex38 -i volumetric3d
// * ex38 -i volumetric3d -o 4 -r 5
// * ex38 -i volumetric3d -o 3 -r 4 -m 1
//
// Description: This example code demonstrates the use of MFEM to integrate
// functions over implicit interfaces and subdomains bounded by
@@ -125,7 +125,6 @@ real_t Volume()
}
}
#ifdef MFEM_USE_LAPACK
/**
@brief Class for surface IntegrationRule
@@ -135,11 +134,14 @@ real_t Volume()
class SIntegrationRule : public IntegrationRule
{
protected:
/// @brief Space Dimension of the IntegrationRule
/// method 0 is moments-based, 1 is Algoim.
int method, ir_order, ls_order;
Coefficient &level_set;
/// Space Dimension of the IntegrationRule
int dim;
/// @brief Column-wise matrix of the quadtrature weights
/// Column-wise matrix of the quadtrature weights
DenseMatrix Weights;
/// @brief Column-wise matrix of the transformation weights of the normal
/// Column-wise matrix of the transformation weights of the normal
DenseMatrix SurfaceWeights;
public:
@@ -153,15 +155,21 @@ public:
@param [in] lsOrder Polynomial degree for approx of level-set function
@param [in] mesh Pointer to the mesh that is used
*/
SIntegrationRule(int Order, Coefficient& LvlSet, int lsOrder, Mesh* mesh)
SIntegrationRule(int method_, int Order,
Coefficient& LvlSet, int lsOrder, Mesh* mesh)
: method(method_), ir_order(Order), ls_order(lsOrder),
level_set(LvlSet), dim(mesh->Dimension())
{
dim = mesh->Dimension();
// Nothing gets pre-computed for Algoim.
if (method == 1) { return; }
#ifdef MFEM_USE_LAPACK
MomentFittingIntRules mf_ir(ir_order, level_set, ls_order);
IsoparametricTransformation Tr;
MomentFittingIntRules MFIRs(Order, LvlSet, lsOrder);
mesh->GetElementTransformation(0, &Tr);
IntegrationRule ir;
MFIRs.GetSurfaceIntegrationRule(Tr, ir);
mf_ir.GetSurfaceIntegrationRule(Tr, ir);
if (dim >1)
{
Weights.SetSize(ir.GetNPoints(), mesh->GetNE());
@@ -172,7 +180,7 @@ public:
}
SurfaceWeights.SetSize(ir.GetNPoints(), mesh->GetNE());
Vector w;
MFIRs.GetSurfaceWeights(Tr, ir, w);
mf_ir.GetSurfaceWeights(Tr, ir, w);
SurfaceWeights.SetCol(0, w);
SetSize(ir.GetNPoints());
@@ -198,8 +206,8 @@ public:
for (int elem = 1; elem < mesh->GetNE(); elem++)
{
mesh->GetElementTransformation(elem, &Tr);
MFIRs.GetSurfaceIntegrationRule(Tr, ir);
MFIRs.GetSurfaceWeights(Tr, ir, w);
mf_ir.GetSurfaceIntegrationRule(Tr, ir);
mf_ir.GetSurfaceWeights(Tr, ir, w);
SurfaceWeights.SetCol(elem, w);
for (int ip = 0; ip < GetNPoints(); ip++)
@@ -215,48 +223,48 @@ public:
}
}
}
#else
MFEM_ABORT("Moment-fitting requires MFEM to be built with LAPACK!");
#endif
}
/**
@brief Set the weights for the given element and multiply them with the
transformation of the interface
*/
void SetElementinclSurfaceWeight(int Element)
void SetElementAndSurfaceWeight(ElementTransformation &Tr)
{
if (dim == 1)
if (method == 1)
{
IntegrationPoint &intp = IntPoint(0);
intp.x = Weights(0, Element);
intp.weight = Weights(1, Element);
cout << intp.x << " " << Element << endl;
}
else
#ifdef MFEM_USE_ALGOIM
AlgoimIntegrationRules a_ir(ir_order, level_set, ls_order);
a_ir.GetSurfaceIntegrationRule(Tr, *this);
Vector w;
a_ir.GetSurfaceWeights(Tr, *this, w);
for (int ip = 0; ip < GetNPoints(); ip++)
{
IntegrationPoint &intp = IntPoint(ip);
intp.weight = Weights(ip, Element) * SurfaceWeights(ip, Element);
IntPoint(ip).weight *= w(ip);
}
}
return;
#else
MFEM_ABORT("MFEM is not built with Algoim support!");
#endif
}
/// @brief Set the weights for the given element
void SetElement(int Element)
{
if (dim == 1)
{
IntegrationPoint &intp = IntPoint(0);
intp.x = Weights(0, Element);
intp.weight = Weights(1, Element);
IntPoint(0).x = Weights(0, Tr.ElementNo);
IntPoint(0).weight = Weights(1, Tr.ElementNo);
}
else
{
for (int ip = 0; ip < GetNPoints(); ip++)
{
IntegrationPoint &intp = IntPoint(ip);
intp.weight = Weights(ip, Element);
IntPoint(ip).weight = Weights(ip, Tr.ElementNo) *
SurfaceWeights(ip, Tr.ElementNo);
}
}
}
/// @brief Destructor of SIntegrationRule
~SIntegrationRule() {}
};
/**
@@ -268,9 +276,12 @@ public:
class CIntegrationRule : public IntegrationRule
{
protected:
/// @brief Space Dimension of the IntegrationRule
/// method 0 is moments-based, 1 is Algoim.
int method, ir_order, ls_order;
Coefficient &level_set;
/// Space Dimension of the IntegrationRule
int dim;
/// @brief Column-wise matrix of the quadtrature weights
/// Column-wise matrix of the quadtrature positions and weights.
DenseMatrix Weights;
public:
@@ -284,15 +295,21 @@ public:
@param [in] lsOrder Polynomial degree for approx of level-set function
@param [in] mesh Pointer to the mesh that is used
*/
CIntegrationRule(int Order, Coefficient& LvlSet, int lsOrder, Mesh* mesh)
CIntegrationRule(int method_, int Order,
Coefficient &LvlSet, int lsOrder, Mesh *mesh)
: method(method_), ir_order(Order), ls_order(lsOrder),
level_set(LvlSet), dim(mesh->Dimension())
{
dim = mesh->Dimension();
// Nothing gets pre-computed for Algoim.
if (method == 1) { return; }
#ifdef MFEM_USE_LAPACK
MomentFittingIntRules mf_ir(ir_order, level_set, ls_order);
IsoparametricTransformation Tr;
MomentFittingIntRules MFIRs(Order, LvlSet, lsOrder);
mesh->GetElementTransformation(0, &Tr);
IntegrationRule ir;
MFIRs.GetVolumeIntegrationRule(Tr, ir);
mf_ir.GetVolumeIntegrationRule(Tr, ir);
if (dim > 1)
{
Weights.SetSize(ir.GetNPoints(), mesh->GetNE());
@@ -324,9 +341,9 @@ public:
for (int elem = 1; elem < mesh->GetNE(); elem++)
{
mesh->GetElementTransformation(elem, &Tr);
MFIRs.GetVolumeIntegrationRule(Tr, ir);
mf_ir.GetVolumeIntegrationRule(Tr, ir);
for (int ip = 0; ip < GetNPoints(); ip++)
for (int ip = 0; ip < ir.GetNPoints(); ip++)
{
if (dim > 1)
{
@@ -339,29 +356,39 @@ public:
}
}
}
#else
MFEM_ABORT("Moment-fitting requires MFEM to be built with LAPACK!");
#endif
}
/// @brief Set the weights for the given element
void SetElement(int Element)
void SetElement(ElementTransformation &Tr)
{
if (dim == 1)
for (int ip = 0; ip < GetNPoints(); ip++)
{
IntegrationPoint &intp = IntPoint(ip);
intp.x = Weights(2 * ip, Element);
intp.weight = Weights(2 * ip + 1, Element);
}
else
for (int ip = 0; ip < GetNPoints(); ip++)
{
IntegrationPoint &intp = IntPoint(ip);
intp.weight = Weights(ip, Element);
}
}
if (method == 1)
{
#ifdef MFEM_USE_ALGOIM
AlgoimIntegrationRules a_ir(ir_order, level_set, ls_order);
a_ir.GetVolumeIntegrationRule(Tr, *this);
return;
#else
MFEM_ABORT("MFEM is not built with Algoim support!");
#endif
}
/// @brief Destructor of CIntegrationRule
~CIntegrationRule() {}
for (int ip = 0; ip < GetNPoints(); ip++)
{
IntegrationPoint &intp = IntPoint(ip);
if (dim == 1)
{
intp.x = Weights(2 * ip, Tr.ElementNo);
intp.weight = Weights(2 * ip + 1, Tr.ElementNo);
}
else { intp.weight = Weights(ip, Tr.ElementNo); }
}
}
};
/**
@brief Class for surface linearform integrator
@@ -408,9 +435,9 @@ public:
@param [in] Tr transformation of finite element
@param [out] elvect vector containing the
*/
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override
{
int dof = el.GetDof();
shape.SetSize(dof);
@@ -418,7 +445,7 @@ public:
elvect = 0.;
// Update the surface integration rule for the current element
SIntRule->SetElementinclSurfaceWeight(Tr.ElementNo);
SIntRule->SetElementAndSurfaceWeight(Tr);
for (int ip = 0; ip < SIntRule->GetNPoints(); ip++)
{
@@ -476,9 +503,9 @@ public:
@param [in] Tr transformation of finite element
@param [out] elvect vector containing the
*/
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override
{
int dof = el.GetDof();
shape.SetSize(dof);
@@ -486,7 +513,7 @@ public:
elvect = 0.;
// Update the subdomain integration rule
CIntRule->SetElement(Tr.ElementNo);
CIntRule->SetElement(Tr);
for (int ip = 0; ip < CIntRule->GetNPoints(); ip++)
{
@@ -498,17 +525,14 @@ public:
}
}
};
#endif // MFEM_USE_LAPACK
int main(int argc, char *argv[])
{
#ifndef MFEM_USE_LAPACK
cout << "MFEM must be built with LAPACK for this example." << endl;
return MFEM_SKIP_RETURN_VALUE;
#else
#if defined(MFEM_USE_LAPACK) || defined(MFEM_USE_ALGOIM)
// 1. Parse he command-line options.
int ref_levels = 3;
int order = 2;
int method = 0;
const char *inttype = "surface2d";
bool visualization = true;
itype = IntegrationType::Surface2D;
@@ -516,6 +540,8 @@ int main(int argc, char *argv[])
OptionsParser args(argc, argv);
args.AddOption(&order, "-o", "--order", "Order of quadrature rule");
args.AddOption(&ref_levels, "-r", "--refine", "Number of meh refinements");
args.AddOption(&method, "-m", "--method",
"Cut integration method: 0 for moments-based, 1 for Algoim.");
args.AddOption(&inttype, "-i", "--integrationtype",
"IntegrationType to demonstrate");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
@@ -550,7 +576,7 @@ int main(int argc, char *argv[])
}
// 2. Construct and refine the mesh.
Mesh *mesh;
Mesh *mesh = nullptr;
if (itype == IntegrationType::Volumetric1D)
{
mesh = new Mesh("../data/inline-segment.mesh");
@@ -598,13 +624,14 @@ int main(int argc, char *argv[])
// 5. Define the necessary Integration rules on element 0.
IsoparametricTransformation Tr;
mesh->GetElementTransformation(0, &Tr);
SIntegrationRule* sir = new SIntegrationRule(order, levelset, 2, mesh);
SIntegrationRule* sir = new SIntegrationRule(method, order,
levelset, 2, mesh);
CIntegrationRule* cir = NULL;
if (itype == IntegrationType::Volumetric1D
|| itype == IntegrationType::Volumetric2D
|| itype == IntegrationType::Volumetric3D)
{
cir = new CIntegrationRule(order, levelset, 2, mesh);
cir = new CIntegrationRule(method, order, levelset, 2, mesh);
}
// 6. Define and assemble the linear forms on the finite element space.
@@ -651,7 +678,7 @@ int main(int argc, char *argv[])
cout << "============================================" << endl;
cout << "Computed value of surface integral: " << surface.Sum() << endl;
cout << "True value of surface integral: " << Surface() << endl;
cout << "Absolute Error (Surface): ";
cout << "Absolute Error (Surface): ";
cout << abs(surface.Sum() - Surface()) << endl;
cout << "Relative Error (Surface): ";
cout << abs(surface.Sum() - Surface()) / Surface() << endl;
@@ -662,7 +689,7 @@ int main(int argc, char *argv[])
cout << "--------------------------------------------" << endl;
cout << "Computed value of volume integral: " << volume.Sum() << endl;
cout << "True value of volume integral: " << Volume() << endl;
cout << "Absolute Error (Volume): ";
cout << "Absolute Error (Volume): ";
cout << abs(volume.Sum() - Volume()) << endl;
cout << "Relative Error (Volume): ";
cout << abs(volume.Sum() - Volume()) / Volume() << endl;
@@ -691,5 +718,8 @@ int main(int argc, char *argv[])
delete fespace;
delete mesh;
return EXIT_SUCCESS;
#endif //MFEM_USE_LAPACK
#else
cout << "MFEM must be built with LAPACK or ALGOIM for this example." << endl;
return MFEM_SKIP_RETURN_VALUE;
#endif // MFEM_USE_LAPACK
}
+4 -4
View File
@@ -69,8 +69,8 @@ public:
using VectorCoefficient::Eval;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
void SetAlpha(real_t alpha_) { alpha = alpha_; }
};
@@ -84,8 +84,8 @@ public:
DZCoefficient(int height, GridFunction &psi_, real_t alpha_ = 1.0)
: MatrixCoefficient(height), psi(&psi_), alpha(alpha_) { }
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip) override;
void SetAlpha(real_t alpha_) { alpha = alpha_; }
};
+4 -4
View File
@@ -69,8 +69,8 @@ public:
using VectorCoefficient::Eval;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
void SetAlpha(real_t alpha_) { alpha = alpha_; }
};
@@ -84,8 +84,8 @@ public:
DZCoefficient(int height, ParGridFunction &psi_, real_t alpha_ = 1.0)
: MatrixCoefficient(height), psi(&psi_), alpha(alpha_) { }
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip) override;
void SetAlpha(real_t alpha_) { alpha = alpha_; }
};
+1 -1
View File
@@ -157,7 +157,7 @@ int main(int argc, char *argv[])
MixedBilinearForm *B0 = new MixedBilinearForm(x0_space,test_space);
B0->AddDomainIntegrator(new DiffusionIntegrator(one));
B0->Assemble();
B0->EliminateTrialDofs(ess_bdr, x.GetBlock(x0_var), F);
B0->EliminateTrialEssentialBC(ess_bdr, x.GetBlock(x0_var), F);
B0->Finalize();
MixedBilinearForm *Bhat = new MixedBilinearForm(xhat_space,test_space);
+8 -35
View File
@@ -9,7 +9,7 @@
// ex9 -m ../data/periodic-square.mesh -p 1 -r 2 -dt 0.005 -tf 9
// ex9 -m ../data/periodic-hexagon.mesh -p 1 -r 2 -dt 0.005 -tf 9
// ex9 -m ../data/amr-quad.mesh -p 1 -r 2 -dt 0.002 -tf 9
// ex9 -m ../data/amr-quad.mesh -p 1 -r 2 -dt 0.02 -s 13 -tf 9
// ex9 -m ../data/amr-quad.mesh -p 1 -r 2 -dt 0.02 -s 23 -tf 9
// ex9 -m ../data/star-q3.mesh -p 1 -r 2 -dt 0.005 -tf 9
// ex9 -m ../data/star-mixed.mesh -p 1 -r 2 -dt 0.005 -tf 9
// ex9 -m ../data/disc-nurbs.mesh -p 1 -r 3 -dt 0.005 -tf 9
@@ -104,12 +104,12 @@ public:
}
}
void SetOperator(const Operator &op)
void SetOperator(const Operator &op) override
{
linear_solver.SetOperator(op);
}
virtual void Mult(const Vector &x, Vector &y) const
void Mult(const Vector &x, Vector &y) const override
{
linear_solver.Mult(x, y);
}
@@ -134,10 +134,10 @@ private:
public:
FE_Evolution(BilinearForm &M_, BilinearForm &K_, const Vector &b_);
virtual void Mult(const Vector &x, Vector &y) const;
virtual void ImplicitSolve(const real_t dt, const Vector &x, Vector &k);
void Mult(const Vector &x, Vector &y) const override;
void ImplicitSolve(const real_t dt, const Vector &x, Vector &k) override;
virtual ~FE_Evolution();
~FE_Evolution() override;
};
@@ -182,12 +182,7 @@ int main(int argc, char *argv[])
args.AddOption(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
"ODE solver: 1 - Forward Euler,\n\t"
" 2 - RK2 SSP, 3 - RK3 SSP, 4 - RK4, 6 - RK6,\n\t"
" 11 - Backward Euler,\n\t"
" 12 - SDIRK23 (L-stable), 13 - SDIRK33,\n\t"
" 22 - Implicit Midpoint Method,\n\t"
" 23 - SDIRK23 (A-stable), 24 - SDIRK34");
ODESolver::Types.c_str());
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
@@ -224,28 +219,7 @@ int main(int argc, char *argv[])
// 3. 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(1.0); break;
case 3: ode_solver = new RK3SSPSolver; break;
case 4: ode_solver = new RK4Solver; break;
case 6: ode_solver = new RK6Solver; break;
// Implicit (L-stable) methods
case 11: ode_solver = new BackwardEulerSolver; break;
case 12: ode_solver = new SDIRK23Solver(2); break;
case 13: ode_solver = new SDIRK33Solver; break;
// Implicit A-stable methods (not L-stable)
case 22: ode_solver = new ImplicitMidpointSolver; break;
case 23: ode_solver = new SDIRK23Solver; break;
case 24: ode_solver = new SDIRK34Solver; break;
default:
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
return 3;
}
unique_ptr<ODESolver> ode_solver = ODESolver::Select(ode_solver_type);
// 4. Refine the mesh to increase the resolution. In this example we do
// 'ref_levels' of uniform refinement, where 'ref_levels' is a
@@ -440,7 +414,6 @@ int main(int argc, char *argv[])
}
// 10. Free the used memory.
delete ode_solver;
delete pd;
delete dc;
+12 -42
View File
@@ -9,7 +9,7 @@
// mpirun -np 4 ex9p -m ../data/periodic-square.mesh -p 1 -dt 0.005 -tf 9
// mpirun -np 4 ex9p -m ../data/periodic-hexagon.mesh -p 1 -dt 0.005 -tf 9
// mpirun -np 4 ex9p -m ../data/amr-quad.mesh -p 1 -rp 1 -dt 0.002 -tf 9
// mpirun -np 4 ex9p -m ../data/amr-quad.mesh -p 1 -rp 1 -dt 0.02 -s 13 -tf 9
// mpirun -np 4 ex9p -m ../data/amr-quad.mesh -p 1 -rp 1 -dt 0.02 -s 23 -tf 9
// mpirun -np 4 ex9p -m ../data/star-q3.mesh -p 1 -rp 1 -dt 0.004 -tf 9
// mpirun -np 4 ex9p -m ../data/star-mixed.mesh -p 1 -rp 1 -dt 0.004 -tf 9
// mpirun -np 4 ex9p -m ../data/disc-nurbs.mesh -p 1 -rp 1 -dt 0.005 -tf 9
@@ -92,7 +92,7 @@ private:
public:
AIR_prec(int blocksize_) : AIR_solver(NULL), blocksize(blocksize_) { }
void SetOperator(const Operator &op)
void SetOperator(const Operator &op) override
{
width = op.Width();
height = op.Height();
@@ -110,7 +110,7 @@ public:
AIR_solver->SetMaxLevels(50);
}
virtual void Mult(const Vector &x, Vector &y) const
void Mult(const Vector &x, Vector &y) const override
{
// Scale the rhs by block inverse and solve system
HypreParVector z_s;
@@ -119,7 +119,7 @@ public:
AIR_solver->Mult(z_s, y);
}
~AIR_prec()
~AIR_prec() override
{
delete AIR_solver;
}
@@ -185,17 +185,17 @@ public:
}
}
void SetOperator(const Operator &op)
void SetOperator(const Operator &op) override
{
linear_solver.SetOperator(op);
}
virtual void Mult(const Vector &x, Vector &y) const
void Mult(const Vector &x, Vector &y) const override
{
linear_solver.Mult(x, y);
}
~DG_Solver()
~DG_Solver() override
{
delete prec;
delete A;
@@ -223,10 +223,10 @@ public:
FE_Evolution(ParBilinearForm &M_, ParBilinearForm &K_, const Vector &b_,
PrecType prec_type);
virtual void Mult(const Vector &x, Vector &y) const;
virtual void ImplicitSolve(const real_t dt, const Vector &x, Vector &k);
void Mult(const Vector &x, Vector &y) const override;
void ImplicitSolve(const real_t dt, const Vector &x, Vector &k) override;
virtual ~FE_Evolution();
~FE_Evolution() override;
};
@@ -285,12 +285,7 @@ int main(int argc, char *argv[])
args.AddOption(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
"ODE solver: 1 - Forward Euler,\n\t"
" 2 - RK2 SSP, 3 - RK3 SSP, 4 - RK4, 6 - RK6,\n\t"
" 11 - Backward Euler,\n\t"
" 12 - SDIRK23 (L-stable), 13 - SDIRK33,\n\t"
" 22 - Implicit Midpoint Method,\n\t"
" 23 - SDIRK23 (A-stable), 24 - SDIRK34");
ODESolver::Types.c_str());
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
@@ -338,31 +333,7 @@ int main(int argc, char *argv[])
// 4. 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(1.0); break;
case 3: ode_solver = new RK3SSPSolver; break;
case 4: ode_solver = new RK4Solver; break;
case 6: ode_solver = new RK6Solver; break;
// Implicit (L-stable) methods
case 11: ode_solver = new BackwardEulerSolver; break;
case 12: ode_solver = new SDIRK23Solver(2); break;
case 13: ode_solver = new SDIRK33Solver; break;
// Implicit A-stable methods (not L-stable)
case 22: ode_solver = new ImplicitMidpointSolver; break;
case 23: ode_solver = new SDIRK23Solver; break;
case 24: ode_solver = new SDIRK34Solver; break;
default:
if (Mpi::Root())
{
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
}
delete mesh;
return 3;
}
unique_ptr<ODESolver> ode_solver = ODESolver::Select(ode_solver_type);
// 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
@@ -642,7 +613,6 @@ int main(int argc, char *argv[])
delete m;
delete fes;
delete pmesh;
delete ode_solver;
delete pd;
#ifdef MFEM_USE_ADIOS2
if (adios2)
+9 -1
View File
@@ -206,6 +206,7 @@ int main(int argc, char *argv[])
bool use_petsc = true;
const char *petscrc_file = "";
bool petsc_use_jfnk = false;
const char *device_config = "cpu";
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
@@ -243,6 +244,8 @@ int main(int argc, char *argv[])
args.AddOption(&petsc_use_jfnk, "-jfnk", "--jfnk", "-no-jfnk",
"--no-jfnk",
"Use JFNK with user-defined preconditioner factory.");
args.AddOption(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.Parse();
if (!args.Good())
{
@@ -257,7 +260,12 @@ int main(int argc, char *argv[])
args.PrintOptions(cout);
}
// 2b. We initialize PETSc
// 2b. Enable hardware devices such as GPUs, and programming models such as
// CUDA, OCCA, RAJA and OpenMP based on command line options.
Device device(device_config);
if (myid == 0) { device.Print(); }
// 2c. We initialize PETSc
if (use_petsc)
{
MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL);
+9 -1
View File
@@ -67,6 +67,7 @@ int main(int argc, char *argv[])
bool use_petsc = true;
const char *petscrc_file = "";
bool use_nonoverlapping = false;
const char *device_config = "cpu";
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
@@ -95,6 +96,8 @@ int main(int argc, char *argv[])
"-no-nonoverlapping", "--no-nonoverlapping",
"Use or not the block diagonal PETSc's matrix format "
"for non-overlapping domain decomposition.");
args.AddOption(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.Parse();
if (!args.Good())
{
@@ -109,7 +112,12 @@ int main(int argc, char *argv[])
args.PrintOptions(cout);
}
// 2b. We initialize PETSc
// 2b. Enable hardware devices such as GPUs, and programming models such as
// CUDA, OCCA, RAJA and OpenMP based on command line options.
Device device(device_config);
if (myid == 0) { device.Print(); }
// 2c. We initialize PETSc
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
// 3. Read the (serial) mesh from the given mesh file on all processors. We
+11 -2
View File
@@ -61,6 +61,7 @@ int main(int argc, char *argv[])
bool use_petsc = true;
const char *petscrc_file = "";
bool use_nonoverlapping = false;
const char *device_config = "cpu";
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
@@ -87,6 +88,8 @@ int main(int argc, char *argv[])
"-no-nonoverlapping", "--no-nonoverlapping",
"Use or not the block diagonal PETSc's matrix format "
"for non-overlapping domain decomposition.");
args.AddOption(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.Parse();
if (!args.Good())
{
@@ -100,10 +103,16 @@ int main(int argc, char *argv[])
{
args.PrintOptions(cout);
}
// 2b. We initialize PETSc
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
kappa = freq * M_PI;
// 2b. Enable hardware devices such as GPUs, and programming models such as
// CUDA, OCCA, RAJA and OpenMP based on command line options.
Device device(device_config);
if (myid == 0) { device.Print(); }
// 2c. We initialize PETSc
if (use_petsc) { MFEMInitializePetsc(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
// and volume meshes with the same code.
+11 -2
View File
@@ -58,6 +58,7 @@ int main(int argc, char *argv[])
bool use_petsc = true;
const char *petscrc_file = "";
bool use_nonoverlapping = false;
const char *device_config = "cpu";
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
@@ -88,6 +89,8 @@ int main(int argc, char *argv[])
"-no-nonoverlapping", "--no-nonoverlapping",
"Use or not the block diagonal PETSc's matrix format "
"for non-overlapping domain decomposition.");
args.AddOption(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.Parse();
if (!args.Good())
{
@@ -101,10 +104,16 @@ int main(int argc, char *argv[])
{
args.PrintOptions(cout);
}
// 2b. We initialize PETSc
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
kappa = freq * M_PI;
// 2b. Enable hardware devices such as GPUs, and programming models such as
// CUDA, OCCA, RAJA and OpenMP based on command line options.
Device device(device_config);
if (myid == 0) { device.Print(); }
// 2c. We initialize PETSc
if (use_petsc) { MFEMInitializePetsc(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
// and volume, as well as periodic meshes with the same code.
+28 -7
View File
@@ -59,6 +59,8 @@ int main(int argc, char *argv[])
// 2. Parse command-line options.
const char *mesh_file = "../../data/star.mesh";
int ser_ref_levels = -1;
int par_ref_levels = 2;
int order = 1;
bool par_format = false;
bool visualization = 1;
@@ -66,15 +68,22 @@ int main(int argc, char *argv[])
bool use_nonoverlapping = false;
bool local_bdr_spec = false;
const char *petscrc_file = "";
const char *device_config = "cpu";
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
"Mesh file to use.");
args.AddOption(&ser_ref_levels, "-rs", "--refine-serial",
"Number of times to refine the mesh uniformly in serial.");
args.AddOption(&par_ref_levels, "-rp", "--refine-parallel",
"Number of times to refine the mesh uniformly in parallel.");
args.AddOption(&order, "-o", "--order",
"Finite element order (polynomial degree).");
args.AddOption(&par_format, "-pf", "--parallel-format", "-sf",
"--serial-format",
"Format to use when saving the results for VisIt.");
args.AddOption(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
@@ -103,7 +112,13 @@ int main(int argc, char *argv[])
{
args.PrintOptions(cout);
}
// 2b. We initialize PETSc
// 2b. Enable hardware devices such as GPUs, and programming models such as
// CUDA, OCCA, RAJA and OpenMP based on command line options.
Device device(device_config);
if (myid == 0) { device.Print(); }
// 2c. We initialize PETSc
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
// 3. Read the (serial) mesh from the given mesh file on all processors. We
@@ -117,9 +132,11 @@ int main(int argc, char *argv[])
// 'ref_levels' to be the largest number that gives a final mesh with no
// more than 10,000 elements.
{
int ref_levels =
(int)floor(log(10000./mesh->GetNE())/log(2.)/dim);
for (int l = 0; l < ref_levels; l++)
if (ser_ref_levels < 0)
{
ser_ref_levels = (int)floor(log(10000./mesh->GetNE())/log(2.)/dim);
}
for (int l = 0; l < ser_ref_levels; l++)
{
mesh->UniformRefinement();
}
@@ -131,7 +148,6 @@ int main(int argc, char *argv[])
ParMesh *pmesh = new ParMesh(MPI_COMM_WORLD, *mesh);
delete mesh;
{
int par_ref_levels = 2;
for (int l = 0; l < par_ref_levels; l++)
{
pmesh->UniformRefinement();
@@ -187,21 +203,26 @@ int main(int argc, char *argv[])
// 9. Define the parallel grid function and parallel linear forms, solution
// vector and rhs.
BlockVector x(block_offsets), rhs(block_offsets);
BlockVector trueX(block_trueOffsets), trueRhs(block_trueOffsets);
MemoryType mt = device.GetMemoryType();
BlockVector x(block_offsets, mt), rhs(block_offsets, mt);
BlockVector trueX(block_trueOffsets, mt), trueRhs(block_trueOffsets, mt);
ParLinearForm *fform(new ParLinearForm);
fform->Update(R_space, rhs.GetBlock(0), 0);
fform->AddDomainIntegrator(new VectorFEDomainLFIntegrator(fcoeff));
fform->AddBoundaryIntegrator(new VectorFEBoundaryFluxLFIntegrator(fnatcoeff));
fform->Assemble();
fform->SyncAliasMemory(rhs);
fform->ParallelAssemble(trueRhs.GetBlock(0));
trueRhs.GetBlock(0).SyncAliasMemory(trueRhs);
ParLinearForm *gform(new ParLinearForm);
gform->Update(W_space, rhs.GetBlock(1), 0);
gform->AddDomainIntegrator(new DomainLFIntegrator(gcoeff));
gform->Assemble();
gform->SyncAliasMemory(rhs);
gform->ParallelAssemble(trueRhs.GetBlock(1));
trueRhs.GetBlock(1).SyncAliasMemory(trueRhs);
// 10. Assemble the finite element matrices for the Darcy operator
//
+10 -1
View File
@@ -53,6 +53,7 @@ int main(int argc, char *argv[])
bool use_petsc = true;
const char *petscrc_file = "";
bool use_nonoverlapping = false;
const char *device_config = "cpu";
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
@@ -73,6 +74,8 @@ int main(int argc, char *argv[])
"-no-nonoverlapping", "--no-nonoverlapping",
"Use or not the block diagonal PETSc's matrix format "
"for non-overlapping domain decomposition.");
args.AddOption(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.Parse();
if (!args.Good())
{
@@ -86,7 +89,13 @@ int main(int argc, char *argv[])
{
args.PrintOptions(cout);
}
// 2b. We initialize PETSc
// 2b. Enable hardware devices such as GPUs, and programming models such as
// CUDA, OCCA, RAJA and OpenMP based on command line options.
Device device(device_config);
if (myid == 0) { device.Print(); }
// 2c. We initialize PETSc
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
// 3. Read the (serial) mesh from the given mesh file on all processors. We
+105 -49
View File
@@ -9,9 +9,9 @@
// ex10 -m ../../data/beam-quad.mesh -r 2 -o 2 -s 12 -dt 0.15 -vs 10
// ex10 -m ../../data/beam-tri.mesh -r 2 -o 2 -s 16 -dt 0.3 -vs 5
// ex10 -m ../../data/beam-hex.mesh -r 1 -o 2 -s 12 -dt 0.2 -vs 5
// ex10 -m ../../data/beam-tri.mesh -r 2 -o 2 -s 2 -dt 3 -nls kinsol
// ex10 -m ../../data/beam-quad.mesh -r 2 -o 2 -s 2 -dt 3 -nls kinsol
// ex10 -m ../../data/beam-hex.mesh -r 1 -o 2 -s 2 -dt 3 -nls kinsol
// ex10 -m ../../data/beam-tri.mesh -r 2 -o 2 -s 2 -dt 3 -nls 1
// ex10 -m ../../data/beam-quad.mesh -r 2 -o 2 -s 2 -dt 3 -nls 2
// ex10 -m ../../data/beam-hex.mesh -r 1 -o 2 -s 2 -dt 3 -nls 4
// ex10 -m ../../data/beam-quad.mesh -r 2 -o 2 -s 14 -dt 0.15 -vs 10
// ex10 -m ../../data/beam-tri.mesh -r 2 -o 2 -s 17 -dt 0.01 -vs 30
// ex10 -m ../../data/beam-hex.mesh -r 1 -o 2 -s 14 -dt 0.15 -vs 10
@@ -99,16 +99,11 @@ protected:
double saved_gamma; // saved gamma value from implicit setup
public:
/// Solver type to use in the ImplicitSolve() method, used by SDIRK methods.
enum NonlinearSolverType
{
NEWTON = 0, ///< Use MFEM's plain NewtonSolver
KINSOL = 1 ///< Use SUNDIALS' KINSOL (through MFEM's class KINSolver)
};
HyperelasticOperator(FiniteElementSpace &f, Array<int> &ess_bdr,
double visc, double mu, double K,
NonlinearSolverType nls_type);
int kinsol_nls_type = -1, double kinsol_damping = 0.0,
int kinsol_aa_n = 0);
/// Compute the right-hand side of the ODE system.
virtual void Mult(const Vector &vx, Vector &dvx_dt) const;
@@ -226,8 +221,10 @@ int main(int argc, char *argv[])
double mu = 0.25;
double K = 5.0;
bool visualization = true;
const char *nls = "newton";
int nonlinear_solver_type = 0;
int vis_steps = 1;
double kinsol_damping = 0.0;
int kinsol_aa_n = -1;
// Relative and absolute tolerances for CVODE and ARKODE.
const double reltol = 1e-1, abstol = 1e-1;
@@ -264,9 +261,18 @@ int main(int argc, char *argv[])
"15 - ARKODE implicit, approximate Jacobian,\n\t"
"16 - ARKODE implicit, specified Jacobian,\n\t"
"17 - ARKODE explicit, 4th order.");
args.AddOption(&nls, "-nls", "--nonlinear-solver",
"Nonlinear systems solver: "
"\"newton\" (plain Newton) or \"kinsol\" (KINSOL).");
args.AddOption(&nonlinear_solver_type, "-nls", "--nonlinear-solver",
"Nonlinear system solver:\n\t"
"0 - MFEM Newton method,\n\t"
"1 - KINSOL Newton method,\n\t"
"2 - KINSOL Newton method with globalization,\n\t"
"3 - KINSOL fixed-point method (with or without AA),\n\t"
"4 - KINSOL Picard method (with or without AA).");
args.AddOption(&kinsol_damping, "-damp", "--kinsol-damping",
"Picard or Fixed-Point damping parameter (only valid with KINSOL): "
"0 < d <= 1.0");
args.AddOption(&kinsol_aa_n, "-aan", "--anderson-subspace",
"Anderson Acceleration subspace size (only valid with KINSOL)");
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
@@ -297,22 +303,32 @@ int main(int argc, char *argv[])
return 1;
}
// check for valid nonlinear solver options
if (nonlinear_solver_type < 0 || nonlinear_solver_type > 4)
{
cout << "Unknown nonlinear solver type: " << nonlinear_solver_type << "\n";
return 1;
}
if (kinsol_damping > 0.0 &&
!(nonlinear_solver_type == 3 || nonlinear_solver_type == 4))
{
cout << "Only KINSOL fixed-point and Picard methods can use damping\n";
return 1;
}
if (kinsol_aa_n > 0 &&
!(nonlinear_solver_type == 3 || nonlinear_solver_type == 4))
{
cout << "Only KINSOL fixed-point and Picard methods can use AA\n";
return 1;
}
// 2. Read the mesh from the given mesh file. We can handle triangular,
// quadrilateral, tetrahedral and hexahedral meshes with the same code.
Mesh *mesh = new Mesh(mesh_file, 1, 1);
int dim = mesh->Dimension();
// 3. Setup the nonlinear solver
map<string,HyperelasticOperator::NonlinearSolverType> nls_map;
nls_map["newton"] = HyperelasticOperator::NEWTON;
nls_map["kinsol"] = HyperelasticOperator::KINSOL;
if (nls_map.find(nls) == nls_map.end())
{
cout << "Unknown type of nonlinear solver: " << nls << endl;
return 4;
}
// 4. Refine the mesh to increase the resolution. In this example we do
// 3. Refine the mesh to increase the resolution. In this example we do
// 'ref_levels' of uniform refinement, where 'ref_levels' is a
// command-line parameter.
for (int lev = 0; lev < ref_levels; lev++)
@@ -320,7 +336,7 @@ int main(int argc, char *argv[])
mesh->UniformRefinement();
}
// 5. Define the vector finite element spaces representing the mesh
// 4. Define the vector finite element spaces representing the mesh
// deformation x, the velocity v, and the initial configuration, x_ref.
// Define also the elastic energy density, w, which is in a discontinuous
// higher-order space. Since x and v are integrated in time as a system,
@@ -348,7 +364,7 @@ int main(int argc, char *argv[])
FiniteElementSpace w_fespace(mesh, &w_fec);
GridFunction w(&w_fespace);
// 6. Set the initial conditions for v and x, and the boundary conditions on
// 5. Set the initial conditions for v and x, and the boundary conditions on
// a beam-like mesh (see description above).
VectorFunctionCoefficient velo(dim, InitialVelocity);
v.ProjectCoefficient(velo);
@@ -361,9 +377,34 @@ int main(int argc, char *argv[])
ess_bdr = 0;
ess_bdr[0] = 1; // boundary attribute 1 (index 0) is fixed
// 7. Initialize the hyperelastic operator, the GLVis visualization and print
// 6. Initialize the hyperelastic operator, the GLVis visualization and print
// the initial energies.
HyperelasticOperator oper(fespace, ess_bdr, visc, mu, K, nls_map[nls]);
std::unique_ptr<HyperelasticOperator> oper;
if (nonlinear_solver_type == 0)
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr, visc, mu,
K);
else
{
switch (nonlinear_solver_type)
{
case 1:
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
visc, mu, K, KIN_NONE);
break;
case 2:
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
visc, mu, K, KIN_LINESEARCH);
break;
case 3:
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
visc, mu, K, KIN_FP, kinsol_damping, kinsol_aa_n);
break;
case 4:
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
visc, mu, K, KIN_PICARD, kinsol_damping, kinsol_aa_n);
break;
}
}
socketstream vis_v, vis_w;
if (visualization)
@@ -377,23 +418,23 @@ int main(int argc, char *argv[])
vis_w.open(vishost, visport);
if (vis_w)
{
oper.GetElasticEnergyDensity(x, w);
oper->GetElasticEnergyDensity(x, w);
vis_w.precision(8);
visualize(vis_w, mesh, &x, &w, "Elastic energy density", true);
}
}
double ee0 = oper.ElasticEnergy(x.GetTrueVector());
double ke0 = oper.KineticEnergy(v.GetTrueVector());
double ee0 = oper->ElasticEnergy(x.GetTrueVector());
double ke0 = oper->KineticEnergy(v.GetTrueVector());
cout << "initial elastic energy (EE) = " << ee0 << endl;
cout << "initial kinetic energy (KE) = " << ke0 << endl;
cout << "initial total energy (TE) = " << (ee0 + ke0) << endl;
// 8. Define the ODE solver used for time integration. Several implicit
// 7. Define the ODE solver used for time integration. Several implicit
// singly diagonal implicit Runge-Kutta (SDIRK) methods, as well as
// explicit Runge-Kutta methods are available.
double t = 0.0;
oper.SetTime(t);
oper->SetTime(t);
ODESolver *ode_solver = NULL;
CVODESolver *cvode = NULL;
@@ -417,7 +458,7 @@ int main(int argc, char *argv[])
case 11:
case 12:
cvode = new CVODESolver(CV_BDF);
cvode->Init(oper);
cvode->Init(*oper);
cvode->SetSStolerances(reltol, abstol);
CVodeSetEpsLin(cvode->GetMem(), cvode_eps_lin);
cvode->SetMaxStep(dt);
@@ -430,7 +471,7 @@ int main(int argc, char *argv[])
case 13:
case 14:
cvode = new CVODESolver(CV_ADAMS);
cvode->Init(oper);
cvode->Init(*oper);
cvode->SetSStolerances(reltol, abstol);
CVodeSetEpsLin(cvode->GetMem(), cvode_eps_lin);
cvode->SetMaxStep(dt);
@@ -443,7 +484,7 @@ int main(int argc, char *argv[])
case 15:
case 16:
arkode = new ARKStepSolver(ARKStepSolver::IMPLICIT);
arkode->Init(oper);
arkode->Init(*oper);
arkode->SetSStolerances(reltol, abstol);
ARKStepSetNonlinConvCoef(arkode->GetMem(), arkode_eps_nonlin);
arkode->SetMaxStep(dt);
@@ -455,16 +496,16 @@ int main(int argc, char *argv[])
// ARKStep Explicit methods
case 17:
arkode = new ARKStepSolver(ARKStepSolver::EXPLICIT);
arkode->Init(oper);
arkode->Init(*oper);
arkode->SetSStolerances(reltol, abstol);
arkode->SetMaxStep(dt);
ode_solver = arkode; break;
}
// Initialize MFEM integrators, SUNDIALS integrators are initialized above
if (ode_solver_type < 11) { ode_solver->Init(oper); }
if (ode_solver_type < 11) { ode_solver->Init(*oper); }
// 9. Perform time-integration (looping over the time iterations, ti, with a
// 8. Perform time-integration (looping over the time iterations, ti, with a
// time-step dt).
bool last_step = false;
for (int ti = 1; !last_step; ti++)
@@ -477,8 +518,8 @@ int main(int argc, char *argv[])
if (last_step || (ti % vis_steps) == 0)
{
double ee = oper.ElasticEnergy(x.GetTrueVector());
double ke = oper.KineticEnergy(v.GetTrueVector());
double ee = oper->ElasticEnergy(x.GetTrueVector());
double ke = oper->KineticEnergy(v.GetTrueVector());
cout << "step " << ti << ", t = " << t << ", EE = " << ee << ", KE = "
<< ke << ", ΔTE = " << (ee+ke)-(ee0+ke0) << endl;
@@ -492,14 +533,14 @@ int main(int argc, char *argv[])
visualize(vis_v, mesh, &x, &v);
if (vis_w)
{
oper.GetElasticEnergyDensity(x, w);
oper->GetElasticEnergyDensity(x, w);
visualize(vis_w, mesh, &x, &w);
}
}
}
}
// 10. Save the displaced mesh, the velocity and elastic energy.
// 9. Save the displaced mesh, the velocity and elastic energy.
{
v.SetFromTrueVector(); x.SetFromTrueVector();
GridFunction *nodes = &x;
@@ -514,11 +555,11 @@ int main(int argc, char *argv[])
v.Save(velo_ofs);
ofstream ee_ofs("elastic_energy.sol");
ee_ofs.precision(8);
oper.GetElasticEnergyDensity(x, w);
oper->GetElasticEnergyDensity(x, w);
w.Save(ee_ofs);
}
// 11. Free the used memory.
// 10. Free the used memory.
delete ode_solver;
delete mesh;
@@ -602,7 +643,9 @@ ReducedSystemOperator::~ReducedSystemOperator()
HyperelasticOperator::HyperelasticOperator(FiniteElementSpace &f,
Array<int> &ess_bdr, double visc,
double mu, double K,
NonlinearSolverType nls_type)
int kinsol_nls_type,
double kinsol_damping,
int kinsol_aa_n)
: TimeDependentOperator(2*f.GetTrueVSize(), 0.0), fespace(f),
M(&fespace), S(&fespace), H(&fespace),
viscosity(visc), z(height/2),
@@ -653,15 +696,28 @@ HyperelasticOperator::HyperelasticOperator(FiniteElementSpace &f,
J_prec = NULL;
#endif
if (nls_type == KINSOL)
if (kinsol_nls_type > 0)
{
KINSolver *kinsolver = new KINSolver(KIN_NONE, true);
KINSolver *kinsolver = new KINSolver(kinsol_nls_type, true);
if (kinsol_nls_type != KIN_PICARD)
{
kinsolver->SetJFNK(true);
kinsolver->SetLSMaxIter(100);
}
if (kinsol_aa_n > 0)
{
kinsolver->EnableAndersonAcc(kinsol_aa_n);
}
newton_solver = kinsolver;
newton_solver->SetOperator(*reduced_oper);
newton_solver->SetMaxIter(200);
newton_solver->SetRelTol(rel_tol);
newton_solver->SetPrintLevel(0);
kinsolver->SetMaxSetupCalls(4);
if (kinsol_damping > 0.0)
{
kinsolver->SetDamping(kinsol_damping);
}
}
else
{
+123 -59
View File
@@ -9,9 +9,9 @@
// mpirun -np 4 ex10p -m ../../data/beam-quad.mesh -rp 1 -o 2 -s 12 -dt 0.15 -vs 10
// mpirun -np 4 ex10p -m ../../data/beam-tri.mesh -rp 1 -o 2 -s 16 -dt 0.25 -vs 10
// mpirun -np 4 ex10p -m ../../data/beam-hex.mesh -rp 0 -o 2 -s 12 -dt 0.15 -vs 10
// mpirun -np 4 ex10p -m ../../data/beam-tri.mesh -rp 1 -o 2 -s 2 -dt 3 -nls kinsol
// mpirun -np 4 ex10p -m ../../data/beam-quad.mesh -rp 1 -o 2 -s 2 -dt 3 -nls kinsol
// mpirun -np 4 ex10p -m ../../data/beam-hex.mesh -rs 1 -o 2 -s 2 -dt 3 -nls kinsol
// mpirun -np 4 ex10p -m ../../data/beam-tri.mesh -rp 1 -o 2 -s 2 -dt 3 -nls 1
// mpirun -np 4 ex10p -m ../../data/beam-quad.mesh -rp 1 -o 2 -s 2 -dt 3 -nls 2
// mpirun -np 4 ex10p -m ../../data/beam-hex.mesh -rs 1 -o 2 -s 2 -dt 3 -nls 4
// mpirun -np 4 ex10p -m ../../data/beam-quad.mesh -rp 1 -o 2 -s 14 -dt 0.15 -vs 10
// mpirun -np 4 ex10p -m ../../data/beam-tri.mesh -rp 1 -o 2 -s 17 -dt 5e-3 -vs 60
// mpirun -np 4 ex10p -m ../../data/beam-hex.mesh -rp 0 -o 2 -s 14 -dt 0.15 -vs 10
@@ -101,16 +101,11 @@ protected:
double saved_gamma; // saved gamma value from implicit setup
public:
/// Solver type to use in the ImplicitSolve() method, used by SDIRK methods.
enum NonlinearSolverType
{
NEWTON = 0, ///< Use MFEM's plain NewtonSolver
KINSOL = 1 ///< Use SUNDIALS' KINSOL (through MFEM's class KINSolver)
};
HyperelasticOperator(ParFiniteElementSpace &f, Array<int> &ess_bdr,
double visc, double mu, double K,
NonlinearSolverType nls_type);
int kinsol_nls_type = -1, double kinsol_damping = 0.0,
int kinsol_aa_n = 0);
/// Compute the right-hand side of the ODE system.
virtual void Mult(const Vector &vx, Vector &dvx_dt) const;
@@ -235,8 +230,10 @@ int main(int argc, char *argv[])
double mu = 0.25;
double K = 5.0;
bool visualization = true;
const char *nls = "newton";
int nonlinear_solver_type = 0;
int vis_steps = 1;
double kinsol_damping = 0.0;
int kinsol_aa_n = -1;
// Relative and absolute tolerances for CVODE and ARKODE.
const double reltol = 1e-1, abstol = 1e-1;
@@ -275,9 +272,18 @@ int main(int argc, char *argv[])
"15 - ARKODE implicit, approximate Jacobian,\n\t"
"16 - ARKODE implicit, specified Jacobian,\n\t"
"17 - ARKODE explicit, 4th order.");
args.AddOption(&nls, "-nls", "--nonlinear-solver",
"Nonlinear systems solver: "
"\"newton\" (plain Newton) or \"kinsol\" (KINSOL).");
args.AddOption(&nonlinear_solver_type, "-nls", "--nonlinear-solver",
"Nonlinear system solver:\n\t"
"0 - MFEM Newton method,\n\t"
"1 - KINSOL Newton method,\n\t"
"2 - KINSOL Newton method with globalization,\n\t"
"3 - KINSOL fixed-point method (with or without AA),\n\t"
"4 - KINSOL Picard method (with or without AA).");
args.AddOption(&kinsol_damping, "-damp", "--kinsol-damping",
"Picard or Fixed-Point damping parameter (only valid with KINSOL): "
"0 < d <= 1.0");
args.AddOption(&kinsol_aa_n, "-aan", "--anderson-subspace",
"Anderson Acceleration subspace size (only valid with KINSOL)");
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
@@ -317,27 +323,42 @@ int main(int argc, char *argv[])
return 1;
}
// check for valid nonlinear solver options
if (nonlinear_solver_type < 0 || nonlinear_solver_type > 4)
{
if (myid == 0)
{
cout << "Unknown nonlinear solver type: " << nonlinear_solver_type
<< "\n";
}
return 1;
}
if (kinsol_damping > 0.0 &&
!(nonlinear_solver_type == 3 || nonlinear_solver_type == 4))
{
if (myid == 0)
{
cout << "Only KINSOL fixed-point and Picard methods can use damping\n";
}
return 1;
}
if (kinsol_aa_n > 0 &&
!(nonlinear_solver_type == 3 || nonlinear_solver_type == 4))
{
if (myid == 0)
{
cout << "Only KINSOL fixed-point and Picard methods can use AA\n";
}
return 1;
}
// 3. Read the serial mesh from the given mesh file on all processors. We can
// handle triangular, quadrilateral, tetrahedral and hexahedral meshes
// with the same code.
Mesh *mesh = new Mesh(mesh_file, 1, 1);
int dim = mesh->Dimension();
// 4. Nonlinear solver
map<string,HyperelasticOperator::NonlinearSolverType> nls_map;
nls_map["newton"] = HyperelasticOperator::NEWTON;
nls_map["kinsol"] = HyperelasticOperator::KINSOL;
if (nls_map.find(nls) == nls_map.end())
{
if (myid == 0)
{
cout << "Unknown type of nonlinear solver: " << nls << endl;
}
delete mesh;
return 4;
}
// 5. Refine the mesh in serial to increase the resolution. In this example
// 4. Refine the mesh in serial to increase the resolution. In this example
// we do 'ser_ref_levels' of uniform refinement, where 'ser_ref_levels' is
// a command-line parameter.
for (int lev = 0; lev < ser_ref_levels; lev++)
@@ -345,7 +366,7 @@ int main(int argc, char *argv[])
mesh->UniformRefinement();
}
// 6. Define a parallel mesh by a partitioning of the serial mesh. Refine
// 5. Define a parallel mesh by a partitioning of the serial mesh. Refine
// this mesh further in parallel to increase the resolution. Once the
// parallel mesh is defined, the serial mesh can be deleted.
ParMesh *pmesh = new ParMesh(MPI_COMM_WORLD, *mesh);
@@ -355,7 +376,7 @@ int main(int argc, char *argv[])
pmesh->UniformRefinement();
}
// 7. Define the parallel vector finite element spaces representing the mesh
// 6. Define the parallel vector finite element spaces representing the mesh
// deformation x_gf, the velocity v_gf, and the initial configuration,
// x_ref. Define also the elastic energy density, w_gf, which is in a
// discontinuous higher-order space. Since x and v are integrated in time
@@ -387,7 +408,7 @@ int main(int argc, char *argv[])
ParFiniteElementSpace w_fespace(pmesh, &w_fec);
ParGridFunction w_gf(&w_fespace);
// 8. Set the initial conditions for v_gf, x_gf and vx, and define the
// 7. Set the initial conditions for v_gf, x_gf and vx, and define the
// boundary conditions on a beam-like mesh (see description above).
VectorFunctionCoefficient velo(dim, InitialVelocity);
v_gf.ProjectCoefficient(velo);
@@ -402,9 +423,38 @@ int main(int argc, char *argv[])
ess_bdr = 0;
ess_bdr[0] = 1; // boundary attribute 1 (index 0) is fixed
// 9. Initialize the hyperelastic operator, the GLVis visualization and print
// 8. Initialize the hyperelastic operator, the GLVis visualization and print
// the initial energies.
HyperelasticOperator oper(fespace, ess_bdr, visc, mu, K, nls_map[nls]);
std::unique_ptr<HyperelasticOperator> oper;
if (nonlinear_solver_type == 0)
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr, visc, mu,
K);
else
{
switch (nonlinear_solver_type)
{
case 1:
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
visc, mu, K, KIN_NONE);
break;
case 2:
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
visc, mu, K, KIN_LINESEARCH);
break;
case 3:
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
visc, mu, K, KIN_FP, kinsol_damping, kinsol_aa_n);
break;
case 4:
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
visc, mu, K, KIN_PICARD, kinsol_damping, kinsol_aa_n);
break;
default:
cout << "Unknown type of nonlinear solver: "
<< nonlinear_solver_type << endl;
return 4;
}
}
socketstream vis_v, vis_w;
if (visualization)
@@ -420,14 +470,14 @@ int main(int argc, char *argv[])
vis_w.open(vishost, visport);
if (vis_w)
{
oper.GetElasticEnergyDensity(x_gf, w_gf);
oper->GetElasticEnergyDensity(x_gf, w_gf);
vis_w.precision(8);
visualize(vis_w, pmesh, &x_gf, &w_gf, "Elastic energy density", true);
}
}
double ee0 = oper.ElasticEnergy(x_gf);
double ke0 = oper.KineticEnergy(v_gf);
double ee0 = oper->ElasticEnergy(x_gf);
double ke0 = oper->KineticEnergy(v_gf);
if (myid == 0)
{
cout << "initial elastic energy (EE) = " << ee0 << endl;
@@ -435,11 +485,11 @@ int main(int argc, char *argv[])
cout << "initial total energy (TE) = " << (ee0 + ke0) << endl;
}
// 10. Define the ODE solver used for time integration. Several implicit
// singly diagonal implicit Runge-Kutta (SDIRK) methods, as well as
// explicit Runge-Kutta methods are available.
// 9. Define the ODE solver used for time integration. Several implicit
// singly diagonal implicit Runge-Kutta (SDIRK) methods, as well as
// explicit Runge-Kutta methods are available.
double t = 0.0;
oper.SetTime(t);
oper->SetTime(t);
ODESolver *ode_solver = NULL;
CVODESolver *cvode = NULL;
@@ -463,7 +513,7 @@ int main(int argc, char *argv[])
case 11:
case 12:
cvode = new CVODESolver(MPI_COMM_WORLD, CV_BDF);
cvode->Init(oper);
cvode->Init(*oper);
cvode->SetSStolerances(reltol, abstol);
CVodeSetEpsLin(cvode->GetMem(), cvode_eps_lin);
cvode->SetMaxStep(dt);
@@ -476,7 +526,7 @@ int main(int argc, char *argv[])
case 13:
case 14:
cvode = new CVODESolver(MPI_COMM_WORLD, CV_ADAMS);
cvode->Init(oper);
cvode->Init(*oper);
cvode->SetSStolerances(reltol, abstol);
CVodeSetEpsLin(cvode->GetMem(), cvode_eps_lin);
cvode->SetMaxStep(dt);
@@ -489,7 +539,7 @@ int main(int argc, char *argv[])
case 15:
case 16:
arkode = new ARKStepSolver(MPI_COMM_WORLD, ARKStepSolver::IMPLICIT);
arkode->Init(oper);
arkode->Init(*oper);
arkode->SetSStolerances(reltol, abstol);
ARKStepSetNonlinConvCoef(arkode->GetMem(), arkode_eps_nonlin);
arkode->SetMaxStep(dt);
@@ -501,16 +551,16 @@ int main(int argc, char *argv[])
// ARKStep Explicit methods
case 17:
arkode = new ARKStepSolver(MPI_COMM_WORLD, ARKStepSolver::EXPLICIT);
arkode->Init(oper);
arkode->Init(*oper);
arkode->SetSStolerances(reltol, abstol);
arkode->SetMaxStep(dt);
ode_solver = arkode; break;
}
// Initialize MFEM integrators, SUNDIALS integrators are initialized above
if (ode_solver_type < 11) { ode_solver->Init(oper); }
if (ode_solver_type < 11) { ode_solver->Init(*oper); }
// 11. Perform time-integration
// 10. Perform time-integration
// (looping over the time iterations, ti, with a time-step dt).
bool last_step = false;
for (int ti = 1; !last_step; ti++)
@@ -525,8 +575,8 @@ int main(int argc, char *argv[])
{
v_gf.SetFromTrueVector(); x_gf.SetFromTrueVector();
double ee = oper.ElasticEnergy(x_gf);
double ke = oper.KineticEnergy(v_gf);
double ee = oper->ElasticEnergy(x_gf);
double ke = oper->KineticEnergy(v_gf);
if (myid == 0)
{
@@ -542,14 +592,14 @@ int main(int argc, char *argv[])
visualize(vis_v, pmesh, &x_gf, &v_gf);
if (vis_w)
{
oper.GetElasticEnergyDensity(x_gf, w_gf);
oper->GetElasticEnergyDensity(x_gf, w_gf);
visualize(vis_w, pmesh, &x_gf, &w_gf);
}
}
}
}
// 12. Save the displaced mesh, the velocity and elastic energy.
// 11. Save the displaced mesh, the velocity and elastic energy.
{
v_gf.SetFromTrueVector(); x_gf.SetFromTrueVector();
GridFunction *nodes = &x_gf;
@@ -570,11 +620,11 @@ int main(int argc, char *argv[])
v_gf.Save(velo_ofs);
ofstream ee_ofs(ee_name.str().c_str());
ee_ofs.precision(8);
oper.GetElasticEnergyDensity(x_gf, w_gf);
oper->GetElasticEnergyDensity(x_gf, w_gf);
w_gf.Save(ee_ofs);
}
// 13. Free the used memory.
// 12. Free the used memory.
delete ode_solver;
delete pmesh;
@@ -664,7 +714,10 @@ ReducedSystemOperator::~ReducedSystemOperator()
HyperelasticOperator::HyperelasticOperator(ParFiniteElementSpace &f,
Array<int> &ess_bdr, double visc,
double mu, double K,
NonlinearSolverType nls_type)
int kinsol_nls_type,
double kinsol_damping,
int kinsol_aa_n)
: TimeDependentOperator(2*f.TrueVSize(), 0.0), fespace(f),
M(&fespace), S(&fespace), H(&fespace),
viscosity(visc), M_solver(f.GetComm()), z(height/2),
@@ -716,17 +769,28 @@ HyperelasticOperator::HyperelasticOperator(ParFiniteElementSpace &f,
J_minres->SetPreconditioner(*J_prec);
J_solver = J_minres;
if (nls_type == KINSOL)
if (kinsol_nls_type > 0)
{
KINSolver *kinsolver = new KINSolver(f.GetComm(), KIN_LINESEARCH, true);
kinsolver->SetJFNK(true);
kinsolver->SetLSMaxIter(100);
KINSolver *kinsolver = new KINSolver(f.GetComm(), kinsol_nls_type, true);
if (kinsol_nls_type != KIN_PICARD)
{
kinsolver->SetJFNK(true);
kinsolver->SetLSMaxIter(100);
}
if (kinsol_aa_n > 0)
{
kinsolver->EnableAndersonAcc(kinsol_aa_n);
}
newton_solver = kinsolver;
newton_solver->SetOperator(*reduced_oper);
newton_solver->SetMaxIter(200);
newton_solver->SetRelTol(rel_tol);
newton_solver->SetPrintLevel(1);
newton_solver->SetPrintLevel(0);
kinsolver->SetMaxSetupCalls(4);
if (kinsol_damping > 0.0)
{
kinsolver->SetDamping(kinsol_damping);
}
}
else
{
+3 -3
View File
@@ -112,8 +112,6 @@ set(SRCS
qinterp/eval_by_vdim.cpp
qinterp/grad_by_nodes.cpp
qinterp/grad_by_vdim.cpp
qinterp/grad_phys_by_nodes.cpp
qinterp/grad_phys_by_vdim.cpp
qspace.cpp
quadinterpolator.cpp
quadinterpolator_face.cpp
@@ -192,6 +190,9 @@ set(HDRS
hybridization.hpp
intrules.hpp
intrules_cut.hpp
kernel_dispatch.hpp
kernel_reporter.hpp
kernels.hpp
ceed/interface/basis.hpp
ceed/interface/integrator.hpp
ceed/interface/interface.hpp
@@ -223,7 +224,6 @@ set(HDRS
nonlinearform_ext.hpp
nonlininteg.hpp
qfunction.hpp
qinterp/dispatch.hpp
qinterp/eval.hpp
qinterp/grad.hpp
qspace.hpp
+305 -62
View File
@@ -289,9 +289,10 @@ void BilinearForm::ComputeElementMatrix(int i, DenseMatrix &elmat) const
return;
}
const FiniteElement &fe = *fes->GetFE(i);
if (domain_integs.Size())
{
const FiniteElement &fe = *fes->GetFE(i);
ElementTransformation *eltrans = fes->GetElementTransformation(i);
domain_integs[0]->AssembleElementMatrix(fe, *eltrans, elmat);
for (int k = 1; k < domain_integs.Size(); k++)
@@ -302,17 +303,18 @@ void BilinearForm::ComputeElementMatrix(int i, DenseMatrix &elmat) const
}
else
{
fes->GetElementVDofs(i, vdofs);
elmat.SetSize(vdofs.Size());
const int ndof = fe.GetDof() * fes->GetVDim();
elmat.SetSize(ndof);
elmat = 0.0;
}
}
void BilinearForm::ComputeBdrElementMatrix(int i, DenseMatrix &elmat) const
{
const FiniteElement &be = *fes->GetBE(i);
if (boundary_integs.Size())
{
const FiniteElement &be = *fes->GetBE(i);
ElementTransformation *eltrans = fes->GetBdrElementTransformation(i);
boundary_integs[0]->AssembleElementMatrix(be, *eltrans, elmat);
for (int k = 1; k < boundary_integs.Size(); k++)
@@ -323,8 +325,8 @@ void BilinearForm::ComputeBdrElementMatrix(int i, DenseMatrix &elmat) const
}
else
{
fes->GetBdrElementVDofs(i, vdofs);
elmat.SetSize(vdofs.Size());
const int ndof = be.GetDof() * fes->GetVDim();
elmat.SetSize(ndof);
elmat = 0.0;
}
}
@@ -1429,32 +1431,50 @@ void MixedBilinearForm::GetBlocks(Array2D<SparseMatrix *> &blocks) const
mat->GetBlocks(blocks);
}
void MixedBilinearForm::AddDomainIntegrator (BilinearFormIntegrator * bfi)
void MixedBilinearForm::AddDomainIntegrator(BilinearFormIntegrator *bfi)
{
domain_integs.Append (bfi);
domain_integs.Append(bfi);
domain_integs_marker.Append(NULL); // NULL marker means apply everywhere
}
void MixedBilinearForm::AddDomainIntegrator (BilinearFormIntegrator * bfi,
Array<int> &elem_marker)
void MixedBilinearForm::AddDomainIntegrator(BilinearFormIntegrator *bfi,
Array<int> &elem_marker)
{
domain_integs.Append (bfi);
domain_integs.Append(bfi);
domain_integs_marker.Append(&elem_marker);
}
void MixedBilinearForm::AddBoundaryIntegrator (BilinearFormIntegrator * bfi)
void MixedBilinearForm::AddBoundaryIntegrator(BilinearFormIntegrator *bfi)
{
boundary_integs.Append (bfi);
boundary_integs.Append(bfi);
boundary_integs_marker.Append(NULL); // NULL marker means apply everywhere
}
void MixedBilinearForm::AddBoundaryIntegrator (BilinearFormIntegrator * bfi,
Array<int> &bdr_marker)
void MixedBilinearForm::AddBoundaryIntegrator(BilinearFormIntegrator *bfi,
Array<int> &bdr_marker)
{
boundary_integs.Append (bfi);
boundary_integs.Append(bfi);
boundary_integs_marker.Append(&bdr_marker);
}
void MixedBilinearForm::AddInteriorFaceIntegrator(BilinearFormIntegrator *bfi)
{
interior_face_integs.Append(bfi);
}
void MixedBilinearForm::AddBdrFaceIntegrator(BilinearFormIntegrator *bfi)
{
boundary_face_integs.Append(bfi);
boundary_face_integs_marker.Append(NULL); // NULL marker means apply everywhere
}
void MixedBilinearForm::AddBdrFaceIntegrator(BilinearFormIntegrator *bfi,
Array<int> &bdr_marker)
{
boundary_face_integs.Append(bfi);
boundary_face_integs_marker.Append(&bdr_marker);
}
void MixedBilinearForm::AddTraceFaceIntegrator (BilinearFormIntegrator * bfi)
{
trace_face_integs.Append (bfi);
@@ -1587,6 +1607,108 @@ void MixedBilinearForm::Assemble(int skip_zeros)
}
}
if (interior_face_integs.Size())
{
FaceElementTransformations *ftr;
Array<int> trial_vdofs2, test_vdofs2;
const FiniteElement *trial_fe1, *trial_fe2, *test_fe1, *test_fe2;
int nfaces = mesh->GetNumFaces();
for (int i = 0; i < nfaces; i++)
{
ftr = mesh->GetInteriorFaceTransformations(i);
if (ftr != NULL)
{
trial_fes->GetElementVDofs(ftr->Elem1No, trial_vdofs);
test_fes->GetElementVDofs(ftr->Elem1No, test_vdofs);
trial_fe1 = trial_fes->GetFE(ftr->Elem1No);
test_fe1 = test_fes->GetFE(ftr->Elem1No);
if (ftr->Elem2No >= 0)
{
trial_fes->GetElementVDofs(ftr->Elem2No, trial_vdofs2);
test_fes->GetElementVDofs(ftr->Elem2No, test_vdofs2);
trial_vdofs.Append(trial_vdofs2);
test_vdofs.Append(test_vdofs2);
trial_fe2 = trial_fes->GetFE(ftr->Elem2No);
test_fe2 = test_fes->GetFE(ftr->Elem2No);
}
else
{
// The test_fe2 object is really a dummy and not used on the
// boundaries, but we can't dereference a NULL pointer, and we don't
// want to actually make a fake element.
trial_fe2 = trial_fe1;
test_fe2 = test_fe1;
}
for (int k = 0; k < interior_face_integs.Size(); k++)
{
interior_face_integs[k]->AssembleFaceMatrix(*trial_fe1, *test_fe1, *trial_fe2,
*test_fe2,
*ftr, elemmat);
mat->AddSubMatrix(test_vdofs, trial_vdofs, elemmat, skip_zeros);
}
}
}
}
if (boundary_face_integs.Size())
{
FaceElementTransformations *ftr;
Array<int> tr_vdofs2, te_vdofs2;
const FiniteElement *trial_fe1, *trial_fe2, *test_fe1, *test_fe2;
// Which boundary attributes need to be processed?
Array<int> bdr_attr_marker(mesh->bdr_attributes.Size() ?
mesh->bdr_attributes.Max() : 0);
bdr_attr_marker = 0;
for (int k = 0; k < boundary_face_integs.Size(); k++)
{
if (boundary_face_integs_marker[k] == NULL)
{
bdr_attr_marker = 1;
break;
}
Array<int> &bdr_marker = *boundary_face_integs_marker[k];
MFEM_ASSERT(bdr_marker.Size() == bdr_attr_marker.Size(),
"invalid boundary marker for boundary face integrator #"
<< k << ", counting from zero");
for (int i = 0; i < bdr_attr_marker.Size(); i++)
{
bdr_attr_marker[i] |= bdr_marker[i];
}
}
for (int i = 0; i < trial_fes -> GetNBE(); i++)
{
const int bdr_attr = mesh->GetBdrAttribute(i);
if (bdr_attr_marker[bdr_attr-1] == 0) { continue; }
ftr = mesh -> GetBdrFaceTransformations (i);
if (ftr != NULL)
{
trial_fes->GetElementVDofs(ftr->Elem1No, trial_vdofs);
test_fes->GetElementVDofs(ftr->Elem1No, test_vdofs);
trial_fe1 = trial_fes->GetFE(ftr->Elem1No);
test_fe1 = test_fes->GetFE(ftr->Elem1No);
// The test_fe2 object is really a dummy and not used on the
// boundaries, but we can't dereference a NULL pointer, and we don't
// want to actually make a fake element.
trial_fe2 = trial_fe1;
test_fe2 = test_fe1;
for (int k = 0; k < boundary_face_integs.Size(); k++)
{
if (boundary_face_integs_marker[k] &&
(*boundary_face_integs_marker[k])[bdr_attr-1] == 0) { continue; }
boundary_face_integs[k]->AssembleFaceMatrix(*trial_fe1, *test_fe1, *trial_fe2,
*test_fe2,
*ftr, elemmat);
mat->AddSubMatrix(test_vdofs, trial_vdofs, elemmat, skip_zeros);
}
}
}
}
if (trace_face_integs.Size())
{
FaceElementTransformations *ftr;
@@ -1767,10 +1889,11 @@ void MixedBilinearForm::ConformingAssemble()
void MixedBilinearForm::ComputeElementMatrix(int i, DenseMatrix &elmat) const
{
const FiniteElement &trial_fe = *trial_fes->GetFE(i);
const FiniteElement &test_fe = *test_fes->GetFE(i);
if (domain_integs.Size())
{
const FiniteElement &trial_fe = *trial_fes->GetFE(i);
const FiniteElement &test_fe = *test_fes->GetFE(i);
ElementTransformation *eltrans = test_fes->GetElementTransformation(i);
domain_integs[0]->AssembleElementMatrix2(trial_fe, test_fe, *eltrans,
elmat);
@@ -1783,19 +1906,21 @@ void MixedBilinearForm::ComputeElementMatrix(int i, DenseMatrix &elmat) const
}
else
{
trial_fes->GetElementVDofs(i, trial_vdofs);
test_fes->GetElementVDofs(i, test_vdofs);
elmat.SetSize(test_vdofs.Size(), trial_vdofs.Size());
const int tr_dofs = trial_fe.GetDof() * trial_fes->GetVDim();
const int te_dofs = test_fe.GetDof() * test_fes->GetVDim();
elmat.SetSize(te_dofs, tr_dofs);
elmat = 0.0;
}
}
void MixedBilinearForm::ComputeBdrElementMatrix(int i, DenseMatrix &elmat) const
{
const FiniteElement &trial_be = *trial_fes->GetBE(i);
const FiniteElement &test_be = *test_fes->GetBE(i);
if (boundary_integs.Size())
{
const FiniteElement &trial_be = *trial_fes->GetBE(i);
const FiniteElement &test_be = *test_fes->GetBE(i);
ElementTransformation *eltrans = test_fes->GetBdrElementTransformation(i);
boundary_integs[0]->AssembleElementMatrix2(trial_be, test_be, *eltrans,
elmat);
@@ -1808,9 +1933,103 @@ void MixedBilinearForm::ComputeBdrElementMatrix(int i, DenseMatrix &elmat) const
}
else
{
trial_fes->GetBdrElementVDofs(i, trial_vdofs);
test_fes->GetBdrElementVDofs(i, test_vdofs);
elmat.SetSize(test_vdofs.Size(), trial_vdofs.Size());
const int tr_dofs = trial_be.GetDof() * trial_fes->GetVDim();
const int te_dofs = test_be.GetDof() * test_fes->GetVDim();
elmat.SetSize(te_dofs, tr_dofs);
elmat = 0.0;
}
}
void MixedBilinearForm::ComputeFaceMatrix(int i, DenseMatrix &elmat) const
{
FaceElementTransformations *ftr;
Mesh *mesh = test_fes -> GetMesh();
ftr = mesh->GetFaceElementTransformations(i);
MFEM_ASSERT(ftr, "No associated face transformations.");
const FiniteElement *trial_fe1, *trial_fe2, *test_fe1, *test_fe2;
trial_fe1 = trial_fes->GetFE(ftr->Elem1No);
test_fe1 = test_fes->GetFE(ftr->Elem1No);
if (ftr->Elem2No >= 0)
{
trial_fe2 = trial_fes->GetFE(ftr->Elem2No);
test_fe2 = test_fes->GetFE(ftr->Elem2No);
}
else
{
// The test_fe2 object is really a dummy and not used on the
// boundaries, but we can't dereference a NULL pointer, and we don't
// want to actually make a fake element.
trial_fe2 = trial_fe1;
test_fe2 = test_fe1;
}
if (interior_face_integs.Size())
{
interior_face_integs[0]->AssembleFaceMatrix(*trial_fe1, *test_fe1, *trial_fe2,
*test_fe2,
*ftr, elmat);
for (int k = 1; k < interior_face_integs.Size(); k++)
{
interior_face_integs[k]->AssembleFaceMatrix(*trial_fe1, *test_fe1, *trial_fe2,
*test_fe2,
*ftr, elemmat);
elmat += elemmat;
}
}
else
{
int tr_dofs = trial_fe1->GetDof() * trial_fes->GetVDim();
int te_dofs = test_fe1->GetDof() * test_fes->GetVDim();
if (ftr->Elem2No >= 0)
{
tr_dofs += trial_fe2->GetDof() * trial_fes->GetVDim();
te_dofs += test_fe2->GetDof() * test_fes->GetVDim();
}
elmat.SetSize(te_dofs, tr_dofs);
elmat = 0.0;
}
}
void MixedBilinearForm::ComputeBdrFaceMatrix(int i, DenseMatrix &elmat) const
{
FaceElementTransformations *ftr;
Mesh *mesh = test_fes -> GetMesh();
ftr = mesh->GetBdrFaceTransformations(i);
MFEM_ASSERT(ftr, "No associated boundary face.");
const FiniteElement *trial_fe1, *trial_fe2, *test_fe1, *test_fe2;
trial_fe1 = trial_fes->GetFE(ftr->Elem1No);
test_fe1 = test_fes->GetFE(ftr->Elem1No);
// The test_fe2 object is really a dummy and not used on the
// boundaries, but we can't dereference a NULL pointer, and we don't
// want to actually make a fake element.
trial_fe2 = trial_fe1;
test_fe2 = test_fe1;
if (boundary_face_integs.Size())
{
boundary_face_integs[0]->AssembleFaceMatrix(*trial_fe1, *test_fe1, *trial_fe2,
*test_fe2,
*ftr, elmat);
for (int k = 1; k < boundary_face_integs.Size(); k++)
{
boundary_face_integs[k]->AssembleFaceMatrix(*trial_fe1, *test_fe1, *trial_fe2,
*test_fe2,
*ftr, elemmat);
elmat += elemmat;
}
}
else
{
const int tr_dofs = trial_fe1->GetDof() * trial_fes->GetVDim();
const int te_dofs = test_fe1->GetDof() * test_fes->GetVDim();
elmat.SetSize(te_dofs, tr_dofs);
elmat = 0.0;
}
}
@@ -1941,36 +2160,59 @@ void MixedBilinearForm::AssembleBdrElementMatrix(
mat->AddSubMatrix(test_vdofs_, trial_vdofs_, elmat, skip_zeros);
}
void MixedBilinearForm::EliminateTrialDofs (
void MixedBilinearForm::EliminateTrialEssentialBC(
const Array<int> &bdr_attr_is_ess, const Vector &sol, Vector &rhs )
{
int i, j, k;
Array<int> tr_vdofs, cols_marker (trial_fes -> GetVSize());
cols_marker = 0;
for (i = 0; i < trial_fes -> GetNBE(); i++)
if (bdr_attr_is_ess[trial_fes -> GetBdrAttribute (i)-1])
{
trial_fes -> GetBdrElementVDofs (i, tr_vdofs);
for (j = 0; j < tr_vdofs.Size(); j++)
{
if ( (k = tr_vdofs[j]) < 0 )
{
k = -1-k;
}
cols_marker[k] = 1;
}
}
mat -> EliminateCols (cols_marker, &sol, &rhs);
Array<int> trial_ess_dofs;
trial_fes->GetEssentialVDofs(bdr_attr_is_ess, trial_ess_dofs);
mat->EliminateCols(trial_ess_dofs, &sol, &rhs);
}
void MixedBilinearForm::EliminateEssentialBCFromTrialDofs (
void MixedBilinearForm::EliminateTrialEssentialBC(const Array<int>
&bdr_attr_is_ess)
{
Array<int> trial_ess_dofs;
trial_fes->GetEssentialVDofs(bdr_attr_is_ess, trial_ess_dofs);
mat->EliminateCols(trial_ess_dofs);
}
void MixedBilinearForm::EliminateTrialVDofs(const Array<int> &trial_vdofs_,
const Vector &sol, Vector &rhs)
{
Array<int> trial_vdofs_marker;
FiniteElementSpace::ListToMarker(trial_vdofs_, mat->Width(),
trial_vdofs_marker);
mat->EliminateCols(trial_vdofs_marker, &sol, &rhs);
}
void MixedBilinearForm::EliminateTrialVDofs(const Array<int> &trial_vdofs_)
{
if (mat_e == NULL)
{
mat_e = new SparseMatrix(mat->Height(), mat->Width());
}
Array<int> trial_vdofs_marker;
FiniteElementSpace::ListToMarker(trial_vdofs_, mat->Width(),
trial_vdofs_marker);
mat->EliminateCols(trial_vdofs_marker, *mat_e);
mat_e->Finalize();
}
void MixedBilinearForm::EliminateTrialVDofsInRHS(const Array<int> &trial_vdofs_,
const Vector &x, Vector &b)
{
mat_e->AddMult(x, b, -1.);
}
void MixedBilinearForm::EliminateEssentialBCFromTrialDofs(
const Array<int> &marked_vdofs, const Vector &sol, Vector &rhs)
{
mat -> EliminateCols (marked_vdofs, &sol, &rhs);
mat->EliminateCols(marked_vdofs, &sol, &rhs);
}
void MixedBilinearForm::EliminateTestDofs (const Array<int> &bdr_attr_is_ess)
void MixedBilinearForm::EliminateTestEssentialBC(const Array<int>
&bdr_attr_is_ess)
{
int i, j, k;
Array<int> te_vdofs;
@@ -1990,6 +2232,14 @@ void MixedBilinearForm::EliminateTestDofs (const Array<int> &bdr_attr_is_ess)
}
}
void MixedBilinearForm::EliminateTestVDofs(const Array<int> &test_vdofs_)
{
for (int i=0; i<test_vdofs_.Size(); ++i)
{
mat->EliminateRow(test_vdofs_[i]);
}
}
void MixedBilinearForm::FormRectangularSystemMatrix(
const Array<int> &trial_tdof_list,
const Array<int> &test_tdof_list,
@@ -2026,20 +2276,9 @@ void MixedBilinearForm::FormRectangularSystemMatrix(
mat = m;
}
Array<int> ess_trial_tdof_marker, ess_test_tdof_marker;
FiniteElementSpace::ListToMarker(trial_tdof_list, trial_fes->GetTrueVSize(),
ess_trial_tdof_marker);
FiniteElementSpace::ListToMarker(test_tdof_list, test_fes->GetTrueVSize(),
ess_test_tdof_marker);
EliminateTrialVDofs(trial_tdof_list);
EliminateTestVDofs(test_tdof_list);
mat_e = new SparseMatrix(mat->Height(), mat->Width());
mat->EliminateCols(ess_trial_tdof_marker, *mat_e);
for (int i=0; i<test_tdof_list.Size(); ++i)
{
mat->EliminateRow(test_tdof_list[i]);
}
mat_e->Finalize();
A.Reset(mat, false);
}
@@ -2068,7 +2307,7 @@ void MixedBilinearForm::FormRectangularLinearSystem(
A); // Set A = mat_e
}
// Eliminate essential BCs with B -= Ab xb
mat_e->AddMult(X, B, -1.0);
EliminateTrialVDofsInRHS(trial_tdof_list, X, B);
B.SetSubVector(test_tdof_list, 0.0);
}
@@ -2094,6 +2333,10 @@ MixedBilinearForm::~MixedBilinearForm()
for (i = 0; i < domain_integs.Size(); i++) { delete domain_integs[i]; }
for (i = 0; i < boundary_integs.Size(); i++)
{ delete boundary_integs[i]; }
for (i = 0; i < interior_face_integs.Size(); i++)
{ delete interior_face_integs[i]; }
for (i = 0; i < boundary_face_integs.Size(); i++)
{ delete boundary_face_integs[i]; }
for (i = 0; i < trace_face_integs.Size(); i++)
{ delete trace_face_integs[i]; }
for (i = 0; i < boundary_trace_face_integs.Size(); i++)
+140 -45
View File
@@ -294,13 +294,13 @@ public:
const real_t &operator()(int i, int j) { return (*mat)(i,j); }
/// Returns a reference to: $ M_{ij} $
virtual real_t &Elem(int i, int j);
real_t &Elem(int i, int j) override;
/// Returns constant reference to: $ M_{ij} $
virtual const real_t &Elem(int i, int j) const;
const real_t &Elem(int i, int j) const override;
/// Matrix vector multiplication: $ y = M x $
virtual void Mult(const Vector &x, Vector &y) const;
void Mult(const Vector &x, Vector &y) const override;
/** @brief Matrix vector multiplication with the original uneliminated
matrix. The original matrix is $ M + M_e $ so we have:
@@ -309,7 +309,7 @@ public:
{ mat->Mult(x, y); mat_e->AddMult(x, y); }
/// Add the matrix vector multiple to a vector: $ y += a M x $
virtual void AddMult(const Vector &x, Vector &y, const real_t a = 1.0) const
void AddMult(const Vector &x, Vector &y, const real_t a = 1.0) const override
{ mat -> AddMult (x, y, a); }
/** @brief Add the original uneliminated matrix vector multiple to a vector.
@@ -319,8 +319,8 @@ public:
{ mat->AddMult(x, y); mat_e->AddMult(x, y); }
/// Add the matrix transpose vector multiplication: $ y += a M^T x $
virtual void AddMultTranspose(const Vector & x, Vector & y,
const real_t a = 1.0) const
void AddMultTranspose(const Vector & x, Vector & y,
const real_t a = 1.0) const override
{ mat->AddMultTranspose(x, y, a); }
/** @brief Add the original uneliminated matrix transpose vector
@@ -330,7 +330,7 @@ public:
{ mat->AddMultTranspose(x, y); mat_e->AddMultTranspose(x, y); }
/// Matrix transpose vector multiplication: $ y = M^T x $
virtual void MultTranspose(const Vector & x, Vector & y) const;
void MultTranspose(const Vector & x, Vector & y) const override;
/// Compute $ y^T M x $
real_t InnerProduct(const Vector &x, const Vector &y) const
@@ -338,13 +338,13 @@ public:
/** @brief Returns a pointer to (approximation) of the matrix inverse:
$ M^{-1} $ (currently returns NULL) */
virtual MatrixInverse *Inverse() const;
MatrixInverse *Inverse() const override;
/** @brief Finalizes the matrix initialization if the ::AssemblyLevel is
AssemblyLevel::LEGACY.
The matrix that gets finalized is different if you are using static
condensation or hybridization.*/
virtual void Finalize(int skip_zeros = 1);
void Finalize(int skip_zeros = 1) override;
/** @brief Returns a const reference to the sparse matrix: $ M $
*
@@ -458,18 +458,18 @@ public:
conforming prolongation, and |.| denotes the entry-wise absolute value.
In general, this is just an approximation of the exact diagonal for this
case. */
virtual void AssembleDiagonal(Vector &diag) const;
void AssembleDiagonal(Vector &diag) const override;
/// Get the finite element space prolongation operator.
virtual const Operator *GetProlongation() const
const Operator *GetProlongation() const override
{ return fes->GetConformingProlongation(); }
/// Get the finite element space restriction operator
virtual const Operator *GetRestriction() const
const Operator *GetRestriction() const override
{ return fes->GetConformingRestriction(); }
/// Get the output finite element space prolongation matrix
virtual const Operator *GetOutputProlongation() const
const Operator *GetOutputProlongation() const override
{ return GetProlongation(); }
/** @brief Returns the output fe space restriction matrix, transposed
@@ -477,11 +477,11 @@ public:
Logically, this is the transpose of GetOutputRestriction, but in
practice it is convenient to have it in transposed form for
construction of RAP operators in matrix-free methods. */
virtual const Operator *GetOutputRestrictionTranspose() const
const Operator *GetOutputRestrictionTranspose() const override
{ return fes->GetRestrictionTransposeOperator(); }
/// Get the output finite element space restriction matrix
virtual const Operator *GetOutputRestriction() const
const Operator *GetOutputRestriction() const override
{ return GetRestriction(); }
/// Compute serial RAP operator and store it in @a A as a SparseMatrix.
@@ -566,7 +566,8 @@ public:
FormLinearSystem() method to recover the solution as a GridFunction-size
vector in @a x. Use the same arguments as in the FormLinearSystem() call.
*/
virtual void RecoverFEMSolution(const Vector &X, const Vector &b, Vector &x);
void RecoverFEMSolution(const Vector &X, const Vector &b,
Vector &x) override;
/// Compute and store internally all element matrices.
void ComputeElementMatrices();
@@ -771,6 +772,14 @@ protected:
/// Entries are not owned.
Array<Array<int>*> boundary_integs_marker;
/// Interior face integrators.
Array<BilinearFormIntegrator*> interior_face_integs;
/// Boundary face integrators.
Array<BilinearFormIntegrator*> boundary_face_integs;
/// Entries are not owned.
Array<Array<int>*> boundary_face_integs_marker;
/// Trace face (skeleton) integrators.
Array<BilinearFormIntegrator*> trace_face_integs;
@@ -811,32 +820,32 @@ public:
MixedBilinearForm *mbf);
/// Returns a reference to: $ M_{ij} $
virtual real_t &Elem(int i, int j);
real_t &Elem(int i, int j) override;
/// Returns a reference to: $ M_{ij} $
virtual const real_t &Elem(int i, int j) const;
const real_t &Elem(int i, int j) const override;
/// Matrix multiplication: $ y = M x $
virtual void Mult(const Vector & x, Vector & y) const;
void Mult(const Vector & x, Vector & y) const override;
/// Add the matrix vector multiple to a vector: $ y += a M x $
virtual void AddMult(const Vector & x, Vector & y,
const real_t a = 1.0) const;
void AddMult(const Vector & x, Vector & y,
const real_t a = 1.0) const override;
/// Matrix transpose vector multiplication: $ y = M^T x $
virtual void MultTranspose(const Vector & x, Vector & y) const;
void MultTranspose(const Vector & x, Vector & y) const override;
/// Add the matrix transpose vector multiplication: $ y += a M^T x $
virtual void AddMultTranspose(const Vector & x, Vector & y,
const real_t a = 1.0) const;
void AddMultTranspose(const Vector & x, Vector & y,
const real_t a = 1.0) const override;
/** @brief Returns a pointer to (approximation) of the matrix inverse:
$ M^{-1} $ (currently unimplemented and returns NULL)*/
virtual MatrixInverse *Inverse() const;
MatrixInverse *Inverse() const override;
/** @brief Finalizes the matrix initialization if the ::AssemblyLevel is
AssemblyLevel::LEGACY.*/
virtual void Finalize(int skip_zeros = 1);
void Finalize(int skip_zeros = 1) override;
/** @brief Extract the associated matrix as SparseMatrix blocks. The number
of block rows and columns is given by the vector dimensions (vdim) of the
@@ -847,15 +856,37 @@ public:
/** This will segfault if the usual sparse mat is not defined
like when static condensation is being used or AllocMat() has
not yet been called. */
const SparseMatrix &SpMat() const { return *mat; }
const SparseMatrix &SpMat() const
{
MFEM_VERIFY(mat, "mat is NULL and can't be dereferenced");
return *mat;
}
/// Returns a reference to the sparse matrix: $ M $
SparseMatrix &SpMat() { return *mat; }
SparseMatrix &SpMat()
{
MFEM_VERIFY(mat, "mat is NULL and can't be dereferenced");
return *mat;
}
/** @brief Nullifies the internal matrix $ M $ and returns a pointer
to it. Used for transferring ownership. */
SparseMatrix *LoseMat() { SparseMatrix *tmp = mat; mat = NULL; return tmp; }
/// Returns a const reference to the sparse matrix of eliminated b.c.: $ M_e $
const SparseMatrix &SpMatElim() const
{
MFEM_VERIFY(mat_e, "mat_e is NULL and can't be dereferenced");
return *mat_e;
}
/// Returns a reference to the sparse matrix of eliminated b.c.: $ M_e $
SparseMatrix &SpMatElim()
{
MFEM_VERIFY(mat_e, "mat_e is NULL and can't be dereferenced");
return *mat_e;
}
/// Adds a domain integrator. Assumes ownership of @a bfi.
void AddDomainIntegrator(BilinearFormIntegrator *bfi);
@@ -870,6 +901,16 @@ public:
void AddBoundaryIntegrator(BilinearFormIntegrator * bfi,
Array<int> &bdr_marker);
/// Adds an interior face integrator. Assumes ownership of @a bfi.
void AddInteriorFaceIntegrator(BilinearFormIntegrator *bfi);
/// Adds a boundary face integrator. Assumes ownership of @a bfi.
void AddBdrFaceIntegrator(BilinearFormIntegrator *bfi);
/// Adds a boundary face integrator. Assumes ownership of @a bfi.
void AddBdrFaceIntegrator(BilinearFormIntegrator *bfi,
Array<int> &bdr_marker);
/** @brief Add a trace face integrator. Assumes ownership of @a bfi.
This type of integrator assembles terms over all faces of the mesh using
@@ -900,6 +941,16 @@ public:
corresponding pointer (to Array<int>) will be NULL. */
Array<Array<int>*> *GetBBFI_Marker() { return &boundary_integs_marker; }
/// Access all integrators added with AddInteriorFaceIntegrator().
Array<BilinearFormIntegrator*> *GetFBFI() { return &interior_face_integs; }
/// Access all integrators added with AddBdrFaceIntegrator().
Array<BilinearFormIntegrator*> *GetBFBFI() { return &boundary_face_integs; }
/** @brief Access all boundary markers added with AddBdrFaceIntegrator().
If no marker was specified when the integrator was added, the
corresponding pointer (to Array<int>) will be NULL. */
Array<Array<int>*> *GetBFBFI_Marker() { return &boundary_face_integs_marker; }
/// Access all integrators added with AddTraceFaceIntegrator().
Array<BilinearFormIntegrator*> *GetTFBFI() { return &trace_face_integs; }
@@ -928,19 +979,19 @@ public:
void AssembleDiagonal_ADAt(const Vector &D, Vector &diag) const;
/// Get the input finite element space prolongation matrix
virtual const Operator *GetProlongation() const
const Operator *GetProlongation() const override
{ return trial_fes->GetProlongationMatrix(); }
/// Get the input finite element space restriction matrix
virtual const Operator *GetRestriction() const
const Operator *GetRestriction() const override
{ return trial_fes->GetRestrictionMatrix(); }
/// Get the test finite element space prolongation matrix
virtual const Operator *GetOutputProlongation() const
const Operator *GetOutputProlongation() const override
{ return test_fes->GetProlongationMatrix(); }
/// Get the test finite element space restriction matrix
virtual const Operator *GetOutputRestriction() const
const Operator *GetOutputRestriction() const override
{ return test_fes->GetRestrictionMatrix(); }
/** @brief For partially conforming trial and/or test FE spaces, complete the
@@ -965,6 +1016,13 @@ public:
/** @note The boundary attribute markers of the integrators are ignored. */
void ComputeBdrTraceFaceMatrix(int i, DenseMatrix &elmat) const;
/// Compute the face matrix of the given face element
void ComputeFaceMatrix(int i, DenseMatrix &elmat) const;
/// Compute the boundary face matrix of the given boundary element
/** @note The boundary attribute markers of the integrators are ignored. */
void ComputeBdrFaceMatrix(int i, DenseMatrix &elmat) const;
/// Assemble the given element matrix
/** The element matrix @a elmat is assembled for the element @a i, i.e.
added to the system matrix. The flag @a skip_zeros skips the zero
@@ -1005,24 +1063,61 @@ public:
Array<int> &test_vdofs,
int skip_zeros = 1);
/// Eliminate essential boundary DOFs from the columns of the system.
/// Eliminate essential boundary trial DOFs from the system.
/** The array @a bdr_attr_is_ess marks boundary attributes that constitute
the essential part of the boundary. All entries in the columns will be
set to 0.0 through elimination.*/
void EliminateTrialDofs(const Array<int> &bdr_attr_is_ess,
const Vector &sol, Vector &rhs);
the essential part of the boundary. */
void EliminateTrialEssentialBC(const Array<int> &bdr_attr_is_ess,
const Vector &sol, Vector &rhs);
/// Eliminate the list of DOFs from the columns of the system.
/** @a marked_vdofs is the of colunm numbers that will be eliminated. All
entries in the columns will be set to 0.0 through elimination.*/
/// Eliminate essential boundary trial DOFs from the system matrix.
/** The array @a bdr_attr_is_ess marks boundary attributes that constitute
the essential part of the boundary. */
void EliminateTrialEssentialBC(const Array<int> &bdr_attr_is_ess);
/// (DEPRECATED) Eliminate essential boundary trial DOFs from the system.
/** @see EliminateTrialEssentialBC() */
MFEM_DEPRECATED void EliminateTrialDofs(const Array<int> &bdr_attr_is_ess,
const Vector &sol, Vector &rhs)
{ EliminateTrialEssentialBC(bdr_attr_is_ess, sol, rhs); }
/// Eliminate the given trial @a vdofs. NOTE: here, @a vdofs is a list of DOFs.
/** In this case the eliminations are applied to the internal $ M $
and @a rhs without storing the elimination matrix $ M_e $. */
void EliminateTrialVDofs(const Array<int> &vdofs, const Vector &sol,
Vector &rhs);
/// Eliminate the given trial @a vdofs, storing the eliminated part internally in $ M_e $.
/** This method works in conjunction with EliminateTrialVDofsInRHS() and allows
elimination of boundary conditions in multiple right-hand sides. In this
method, @a vdofs is a list of DOFs. */
void EliminateTrialVDofs(const Array<int> &vdofs);
/** @brief Use the stored eliminated part of the matrix (see
EliminateTrialVDofs(const Array<int> &)) to modify the r.h.s.
@a b; @a vdofs is a list of DOFs (non-directional, i.e. >= 0). */
void EliminateTrialVDofsInRHS(const Array<int> &vdofs, const Vector &x,
Vector &b);
/** @brief Similar to
EliminateTrialVDofs(const Array<int> &, const Vector &, Vector &)
but here @a ess_dofs is a marker (boolean) array on all vector-dofs
(@a ess_dofs[i] < 0 is true). */
void EliminateEssentialBCFromTrialDofs(const Array<int> &marked_vdofs,
const Vector &sol, Vector &rhs);
/// Eliminate essential boundary DOFs from the rows of the system.
/// Eliminate essential boundary test DOFs from the system matrix.
/** The array @a bdr_attr_is_ess marks boundary attributes that constitute
the essential part of the boundary. All entries in the rows will be
set to 0.0 through elimination.*/
virtual void EliminateTestDofs(const Array<int> &bdr_attr_is_ess);
the essential part of the boundary. */
void EliminateTestEssentialBC(const Array<int> &bdr_attr_is_ess);
/// (DEPRECATED) Eliminate essential boundary test DOFs from the system.
/** @see EliminateTestEssentialBC() */
MFEM_DEPRECATED virtual void EliminateTestDofs(const Array<int>
&bdr_attr_is_ess)
{ EliminateTestEssentialBC(bdr_attr_is_ess); }
/// Eliminate the given test @a vdofs. NOTE: here, @a vdofs is a list of DOFs.
void EliminateTestVDofs(const Array<int> &vdofs);
/** @brief Return in @a A that is column-constrained.
@@ -1178,7 +1273,7 @@ public:
/** @brief Get the output finite element space restriction matrix in
transposed form. */
virtual const Operator *GetOutputRestrictionTranspose() const
const Operator *GetOutputRestrictionTranspose() const override
{ return test_fes->GetRestrictionTransposeOperator(); }
};
+50 -45
View File
@@ -37,19 +37,19 @@ protected:
public:
BilinearFormExtension(BilinearForm *form);
virtual MemoryClass GetMemoryClass() const
MemoryClass GetMemoryClass() const override
{ return Device::GetDeviceMemoryClass(); }
/// Get the finite element space prolongation matrix
virtual const Operator *GetProlongation() const;
const Operator *GetProlongation() const override;
/// Get the finite element space restriction matrix
virtual const Operator *GetRestriction() const;
const Operator *GetRestriction() const override;
/// Assemble at the level given for the BilinearFormExtension subclass
virtual void Assemble() = 0;
virtual void AssembleDiagonal(Vector &diag) const
void AssembleDiagonal(Vector &diag) const override
{
MFEM_ABORT("AssembleDiagonal not implemented for this assembly level!");
}
@@ -83,16 +83,17 @@ protected:
public:
PABilinearFormExtension(BilinearForm*);
void Assemble();
void AssembleDiagonal(Vector &diag) const;
void FormSystemMatrix(const Array<int> &ess_tdof_list, OperatorHandle &A);
void Assemble() override;
void AssembleDiagonal(Vector &diag) const override;
void FormSystemMatrix(const Array<int> &ess_tdof_list,
OperatorHandle &A) override;
void FormLinearSystem(const Array<int> &ess_tdof_list,
Vector &x, Vector &b,
OperatorHandle &A, Vector &X, Vector &B,
int copy_interior = 0);
void Mult(const Vector &x, Vector &y) const;
void MultTranspose(const Vector &x, Vector &y) const;
void Update();
int copy_interior = 0) override;
void Mult(const Vector &x, Vector &y) const override;
void MultTranspose(const Vector &x, Vector &y) const override;
void Update() override;
protected:
void SetupRestrictionOperators(const L2FaceValues m);
@@ -150,9 +151,9 @@ protected:
public:
EABilinearFormExtension(BilinearForm *form);
void Assemble();
void Mult(const Vector &x, Vector &y) const;
void MultTranspose(const Vector &x, Vector &y) const;
void Assemble() override;
void Mult(const Vector &x, Vector &y) const override;
void MultTranspose(const Vector &x, Vector &y) const override;
};
/// Data and methods for fully-assembled bilinear forms
@@ -165,18 +166,19 @@ private:
public:
FABilinearFormExtension(BilinearForm *form);
void Assemble();
void Assemble() override;
void RAP(OperatorHandle &A);
/** @note Always does `DIAG_ONE` policy to be consistent with
`Operator::FormConstrainedSystemOperator`. */
void EliminateBC(const Array<int> &ess_dofs, OperatorHandle &A);
void FormSystemMatrix(const Array<int> &ess_tdof_list, OperatorHandle &A);
void FormSystemMatrix(const Array<int> &ess_tdof_list,
OperatorHandle &A) override;
void FormLinearSystem(const Array<int> &ess_tdof_list,
Vector &x, Vector &b,
OperatorHandle &A, Vector &X, Vector &B,
int copy_interior = 0);
void Mult(const Vector &x, Vector &y) const;
void MultTranspose(const Vector &x, Vector &y) const;
int copy_interior = 0) override;
void Mult(const Vector &x, Vector &y) const override;
void MultTranspose(const Vector &x, Vector &y) const override;
/** DGMult and DGMultTranspose use the extended L-vector to perform the
computation. */
@@ -199,16 +201,17 @@ protected:
public:
MFBilinearFormExtension(BilinearForm *form);
void Assemble();
void AssembleDiagonal(Vector &diag) const;
void FormSystemMatrix(const Array<int> &ess_tdof_list, OperatorHandle &A);
void Assemble() override;
void AssembleDiagonal(Vector &diag) const override;
void FormSystemMatrix(const Array<int> &ess_tdof_list,
OperatorHandle &A) override;
void FormLinearSystem(const Array<int> &ess_tdof_list,
Vector &x, Vector &b,
OperatorHandle &A, Vector &X, Vector &B,
int copy_interior = 0);
void Mult(const Vector &x, Vector &y) const;
void MultTranspose(const Vector &x, Vector &y) const;
void Update();
int copy_interior = 0) override;
void Mult(const Vector &x, Vector &y) const override;
void MultTranspose(const Vector &x, Vector &y) const override;
void Update() override;
};
/// Class extending the MixedBilinearForm class to support different AssemblyLevels.
@@ -225,20 +228,20 @@ protected:
public:
MixedBilinearFormExtension(MixedBilinearForm *form);
virtual MemoryClass GetMemoryClass() const
MemoryClass GetMemoryClass() const override
{ return Device::GetMemoryClass(); }
/// Get the finite element space prolongation matrix
virtual const Operator *GetProlongation() const;
const Operator *GetProlongation() const override;
/// Get the finite element space restriction matrix
virtual const Operator *GetRestriction() const;
const Operator *GetRestriction() const override;
/// Get the output finite element space restriction matrix
virtual const Operator *GetOutputProlongation() const;
const Operator *GetOutputProlongation() const override;
/// Get the output finite element space restriction matrix
virtual const Operator *GetOutputRestriction() const;
const Operator *GetOutputRestriction() const override;
virtual void Assemble() = 0;
virtual void FormRectangularSystemOperator(const Array<int> &trial_tdof_list,
@@ -273,7 +276,7 @@ public:
PAMixedBilinearFormExtension(MixedBilinearForm *form);
/// Partial assembly of all internal integrators
void Assemble();
void Assemble() override;
/**
@brief Setup OperatorHandle A to contain constrained linear operator
@@ -283,7 +286,7 @@ public:
*/
void FormRectangularSystemOperator(const Array<int> &trial_tdof_list,
const Array<int> &test_tdof_list,
OperatorHandle &A);
OperatorHandle &A) override;
/**
Setup OperatorHandle A to contain constrained linear operator and
eliminate columns corresponding to essential dofs from system,
@@ -292,20 +295,21 @@ public:
void FormRectangularLinearSystem(const Array<int> &trial_tdof_list,
const Array<int> &test_tdof_list,
Vector &x, Vector &b,
OperatorHandle &A, Vector &X, Vector &B);
OperatorHandle &A, Vector &X, Vector &B) override;
/// y = A*x
void Mult(const Vector &x, Vector &y) const;
void Mult(const Vector &x, Vector &y) const override;
/// y += c*A*x
void AddMult(const Vector &x, Vector &y, const real_t c=1.0) const;
void AddMult(const Vector &x, Vector &y, const real_t c=1.0) const override;
/// y = A^T*x
void MultTranspose(const Vector &x, Vector &y) const;
void MultTranspose(const Vector &x, Vector &y) const override;
/// y += c*A^T*x
void AddMultTranspose(const Vector &x, Vector &y, const real_t c=1.0) const;
void AddMultTranspose(const Vector &x, Vector &y,
const real_t c=1.0) const override;
/// Assemble the diagonal of ADA^T for a diagonal vector D.
void AssembleDiagonal_ADAt(const Vector &D, Vector &diag) const;
void AssembleDiagonal_ADAt(const Vector &D, Vector &diag) const override;
/// Update internals for when a new MixedBilinearForm is given to this class
void Update();
void Update() override;
};
@@ -322,16 +326,17 @@ public:
PADiscreteLinearOperatorExtension(DiscreteLinearOperator *linop);
/// Partial assembly of all internal integrators
void Assemble();
void Assemble() override;
void AddMult(const Vector &x, Vector &y, const real_t c=1.0) const;
void AddMult(const Vector &x, Vector &y, const real_t c=1.0) const override;
void AddMultTranspose(const Vector &x, Vector &y, const real_t c=1.0) const;
void AddMultTranspose(const Vector &x, Vector &y,
const real_t c=1.0) const override;
void FormRectangularSystemOperator(const Array<int>&, const Array<int>&,
OperatorHandle& A);
OperatorHandle& A) override;
const Operator * GetOutputRestrictionTranspose() const;
const Operator * GetOutputRestrictionTranspose() const override;
private:
Vector test_multiplicity;
+182 -18
View File
@@ -170,6 +170,16 @@ void BilinearFormIntegrator::AssembleFaceMatrix(
" is not implemented for this class.");
}
void BilinearFormIntegrator::AssembleFaceMatrix(
const FiniteElement &trial_fe1, const FiniteElement &test_fe1,
const FiniteElement &trial_fe2, const FiniteElement &test_fe2,
FaceElementTransformations &Trans,
DenseMatrix &elmat)
{
MFEM_ABORT("AssembleFaceMatrix (mixed form) is not implemented for this"
" Integrator class.");
}
void BilinearFormIntegrator::AssembleFaceMatrix(
const FiniteElement &trial_face_fe, const FiniteElement &test_fe1,
const FiniteElement &test_fe2, FaceElementTransformations &Trans,
@@ -223,28 +233,38 @@ void TransposeIntegrator::SetIntRule(const IntegrationRule *ir)
bfi->SetIntRule(ir);
}
void TransposeIntegrator::AssembleElementMatrix (
void TransposeIntegrator::AssembleElementMatrix(
const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat)
{
bfi -> AssembleElementMatrix (el, Trans, bfi_elmat);
bfi->AssembleElementMatrix(el, Trans, bfi_elmat);
// elmat = bfi_elmat^t
elmat.Transpose (bfi_elmat);
}
void TransposeIntegrator::AssembleElementMatrix2 (
void TransposeIntegrator::AssembleElementMatrix2(
const FiniteElement &trial_fe, const FiniteElement &test_fe,
ElementTransformation &Trans, DenseMatrix &elmat)
{
bfi -> AssembleElementMatrix2 (test_fe, trial_fe, Trans, bfi_elmat);
bfi->AssembleElementMatrix2(test_fe, trial_fe, Trans, bfi_elmat);
// elmat = bfi_elmat^t
elmat.Transpose (bfi_elmat);
}
void TransposeIntegrator::AssembleFaceMatrix (
void TransposeIntegrator::AssembleFaceMatrix(
const FiniteElement &el1, const FiniteElement &el2,
FaceElementTransformations &Trans, DenseMatrix &elmat)
{
bfi -> AssembleFaceMatrix (el1, el2, Trans, bfi_elmat);
bfi->AssembleFaceMatrix(el1, el2, Trans, bfi_elmat);
// elmat = bfi_elmat^t
elmat.Transpose (bfi_elmat);
}
void TransposeIntegrator::AssembleFaceMatrix(
const FiniteElement &tr_el1, const FiniteElement &te_el1,
const FiniteElement &tr_el2, const FiniteElement &te_el2,
FaceElementTransformations &Trans, DenseMatrix &elmat)
{
bfi->AssembleFaceMatrix(te_el1, tr_el1, te_el2, tr_el2, Trans, bfi_elmat);
// elmat = bfi_elmat^t
elmat.Transpose (bfi_elmat);
}
@@ -3498,6 +3518,150 @@ void DGTraceIntegrator::AssembleFaceMatrix(const FiniteElement &el1,
}
}
void DGTraceIntegrator::AssembleFaceMatrix(const FiniteElement &trial_fe1,
const FiniteElement &test_fe1,
const FiniteElement &trial_fe2,
const FiniteElement &test_fe2,
FaceElementTransformations &Trans,
DenseMatrix &elmat)
{
int tr_ndof1, te_ndof1, tr_ndof2, te_ndof2;
real_t un, a, b, w;
dim = test_fe1.GetDim();
tr_ndof1 = trial_fe1.GetDof();
te_ndof1 = test_fe1.GetDof();
Vector vu(dim), nor(dim);
if (Trans.Elem2No >= 0)
{
tr_ndof2 = trial_fe2.GetDof();
te_ndof2 = test_fe2.GetDof();
}
else
{
tr_ndof2 = 0;
te_ndof2 = 0;
}
tr_shape1.SetSize(tr_ndof1);
te_shape1.SetSize(te_ndof1);
tr_shape2.SetSize(tr_ndof2);
te_shape2.SetSize(te_ndof2);
elmat.SetSize(te_ndof1 + te_ndof2, tr_ndof1 + tr_ndof2);
elmat = 0.0;
const IntegrationRule *ir = IntRule;
if (ir == NULL)
{
int order;
// Assuming order(u)==order(mesh)
if (Trans.Elem2No >= 0)
order = (min(Trans.Elem1->OrderW(), Trans.Elem2->OrderW()) +
max(trial_fe1.GetOrder(), trial_fe2.GetOrder()) +
max(test_fe1.GetOrder(), test_fe2.GetOrder()));
else
{
order = Trans.Elem1->OrderW() + trial_fe1.GetOrder() + test_fe1.GetOrder();
}
if (trial_fe1.Space() == FunctionSpace::Pk)
{
order++;
}
ir = &IntRules.Get(Trans.FaceGeom, order);
}
for (int p = 0; p < ir->GetNPoints(); p++)
{
const IntegrationPoint &ip = ir->IntPoint(p);
IntegrationPoint eip1, eip2;
Trans.Loc1.Transform(ip, eip1);
Trans.Elem1->SetIntPoint(&eip1);
if (tr_ndof2 && te_ndof2)
{
Trans.Loc2.Transform(ip, eip2);
Trans.Elem2->SetIntPoint(&eip2);
}
trial_fe1.CalcPhysShape(*Trans.Elem1, tr_shape1);
test_fe1.CalcPhysShape(*Trans.Elem1, te_shape1);
Trans.Face->SetIntPoint(&ip);
u->Eval(vu, *Trans.Elem1, eip1);
if (dim == 1)
{
nor(0) = 2*eip1.x - 1.0;
}
else
{
CalcOrtho(Trans.Face->Jacobian(), nor);
}
un = vu * nor;
a = 0.5 * alpha * un;
b = beta * fabs(un);
// note: if |alpha/2|==|beta| then |a|==|b|, i.e. (a==b) or (a==-b)
// and therefore two blocks in the element matrix contribution
// (from the current quadrature point) are 0
if (rho)
{
real_t rho_p;
if (un >= 0.0 && tr_ndof2 && te_ndof2)
{
Trans.Elem2->SetIntPoint(&eip2);
rho_p = rho->Eval(*Trans.Elem2, eip2);
}
else
{
rho_p = rho->Eval(*Trans.Elem1, eip1);
}
a *= rho_p;
b *= rho_p;
}
w = ip.weight * (a+b);
if (w != 0.0)
{
for (int i = 0; i < te_ndof1; i++)
for (int j = 0; j < tr_ndof1; j++)
{
elmat(i, j) += w * te_shape1(i) * tr_shape1(j);
}
}
if (tr_ndof2 && te_ndof2)
{
trial_fe2.CalcPhysShape(*Trans.Elem2, tr_shape2);
test_fe2.CalcPhysShape(*Trans.Elem2, te_shape2);
if (w != 0.0)
for (int i = 0; i < te_ndof2; i++)
for (int j = 0; j < tr_ndof1; j++)
{
elmat(te_ndof1+i, j) -= w * te_shape2(i) * tr_shape1(j);
}
w = ip.weight * (b-a);
if (w != 0.0)
{
for (int i = 0; i < te_ndof2; i++)
for (int j = 0; j < tr_ndof2; j++)
{
elmat(te_ndof1+i, tr_ndof1+j) += w * te_shape2(i) * tr_shape2(j);
}
for (int i = 0; i < te_ndof1; i++)
for (int j = 0; j < tr_ndof2; j++)
{
elmat(i, tr_ndof1+j) -= w * te_shape1(i) * tr_shape2(j);
}
}
}
}
}
const IntegrationRule &DGTraceIntegrator::GetRule(
Geometry::Type geom, int order, FaceElementTransformations &T)
@@ -4390,8 +4554,8 @@ struct ShapeCoefficient : public VectorCoefficient
: VectorCoefficient(fe_.GetDof()), Q(q), fe(fe_) { }
using VectorCoefficient::Eval;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip)
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override
{
V.SetSize(vdim);
fe.CalcPhysShape(T, V);
@@ -4433,8 +4597,8 @@ ScalarVectorProductInterpolator::AssembleElementMatrix2(
VShapeCoefficient(Coefficient &q, const FiniteElement &fe_, int sdim)
: MatrixCoefficient(fe_.GetDof(), sdim), Q(q), fe(fe_) { }
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip)
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override
{
M.SetSize(height, width);
fe.CalcPhysVShape(T, M);
@@ -4470,8 +4634,8 @@ VectorScalarProductInterpolator::AssembleElementMatrix2(
: MatrixCoefficient(fe_.GetDof(), vq.GetVDim()), VQ(vq), fe(fe_),
vc(width), shape(height) { }
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip)
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override
{
M.SetSize(height, width);
VQ.Eval(vc, T, ip);
@@ -4510,8 +4674,8 @@ ScalarCrossProductInterpolator::AssembleElementMatrix2(
vshape(vdim, vq.GetVDim()), vc(vq.GetVDim()) { }
using VectorCoefficient::Eval;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip)
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override
{
V.SetSize(vdim);
VQ.Eval(vc, T, ip);
@@ -4554,8 +4718,8 @@ VectorCrossProductInterpolator::AssembleElementMatrix2(
MFEM_ASSERT(width == 3, "");
}
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip)
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override
{
M.SetSize(height, width);
VQ.Eval(vc, T, ip);
@@ -4603,8 +4767,8 @@ struct VDotVShapeCoefficient : public VectorCoefficient
vshape(vdim, vq.GetVDim()), vc(vq.GetVDim()) { }
using VectorCoefficient::Eval;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip)
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override
{
V.SetSize(vdim);
VQ.Eval(vc, T, ip);
+585 -481
View File
File diff suppressed because it is too large Load Diff
+156 -156
View File
@@ -90,12 +90,12 @@ public:
explicit ConstantCoefficient(real_t c = 1.0) { constant=c; }
/// Evaluate the coefficient at @a ip.
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip)
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override
{ return (constant); }
/// Fill the QuadratureFunction @a qf with the constant value.
void Project(QuadratureFunction &qf);
void Project(QuadratureFunction &qf) override;
};
/** @brief A piecewise constant coefficient with the constants keyed
@@ -130,8 +130,8 @@ public:
int GetNConst() { return constants.Size(); }
/// Evaluate the coefficient.
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/** @brief A piecewise coefficient with the pieces keyed off the element
@@ -195,7 +195,7 @@ public:
{ InitMap(attr, coefs); }
/// Set the time for time dependent coefficients
virtual void SetTime(real_t t);
void SetTime(real_t t) override;
/// Replace a set of coefficients
void UpdateCoefficients(const Array<int> & attr,
@@ -211,8 +211,8 @@ public:
{ pieces.erase(attr); }
/// Evaluate the coefficient.
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/// A general function coefficient
@@ -254,8 +254,8 @@ public:
}
/// Evaluate the coefficient at @a ip.
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/// A common base class for returning individual components of the domain's
@@ -271,8 +271,8 @@ protected:
public:
/// Evaluate the coefficient at @a ip.
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/// Scalar coefficient which returns the x-component of the evaluation point
@@ -307,8 +307,8 @@ public:
CylindricalRadialCoefficient() : transip(3) {}
/// Evaluate the coefficient at @a ip.
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/// Scalar coefficient which returns the angular position or azimuth (often
@@ -323,8 +323,8 @@ public:
CylindricalAzimuthalCoefficient() : transip(3) {}
/// Evaluate the coefficient at @a ip.
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/// Scalar coefficient which returns the height or altitude of
@@ -342,8 +342,8 @@ public:
SphericalRadialCoefficient() : transip(3) {}
/// Evaluate the coefficient at @a ip.
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/// Scalar coefficient which returns the azimuthal angle (often denoted by phi)
@@ -357,8 +357,8 @@ public:
SphericalAzimuthalCoefficient() : transip(3) {}
/// Evaluate the coefficient at @a ip.
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/// Scalar coefficient which returns the polar angle (often denoted by theta)
@@ -372,8 +372,8 @@ public:
SphericalPolarCoefficient() : transip(3) {}
/// Evaluate the coefficient at @a ip.
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
};
class GridFunction;
@@ -399,15 +399,15 @@ public:
const GridFunction * GetGridFunction() const { return GridF; }
/// Evaluate the coefficient at @a ip.
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
/// @brief Fill the QuadratureFunction @a qf by evaluating the coefficient at
/// the quadrature points.
///
/// This function uses the efficient QuadratureFunction::ProjectGridFunction
/// to fill the QuadratureFunction.
virtual void Project(QuadratureFunction &qf);
void Project(QuadratureFunction &qf) override;
};
@@ -433,10 +433,10 @@ public:
: Q1(q1), Q2(q2), Transform2(std::move(F)) { Transform1 = 0; }
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Evaluate the coefficient at @a ip.
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
};
/** @brief Delta function coefficient optionally multiplied by a weight
@@ -488,7 +488,7 @@ public:
}
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Set the center location of the delta function.
void SetDeltaCenter(const Vector& center);
@@ -534,7 +534,7 @@ public:
virtual real_t EvalDelta(ElementTransformation &T, const IntegrationPoint &ip);
/** @brief A DeltaFunction cannot be evaluated. Calling this method will
cause an MFEM error, terminating the application. */
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip)
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override
{ mfem_error("DeltaCoefficient::Eval"); return 0.; }
virtual ~DeltaCoefficient() { delete weight; }
};
@@ -555,10 +555,10 @@ public:
{ c = &c_; attr.Copy(active_attr); }
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Evaluate the coefficient at @a ip.
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip)
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override
{ return active_attr[T.Attribute-1] ? c->Eval(T, ip, GetTime()) : 0.0; }
};
@@ -628,8 +628,8 @@ public:
using VectorCoefficient::Eval;
/// Evaluate the vector coefficient at @a ip.
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) { V = vec; }
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override { V = vec; }
/// Return a reference to the constant vector in this class.
const Vector& GetVec() const { return vec; }
@@ -698,7 +698,7 @@ public:
: VectorCoefficient(vd) { InitMap(attr, coefs); }
/// Set the time for time dependent coefficients
virtual void SetTime(real_t t);
void SetTime(real_t t) override;
/// Replace a set of coefficients
void UpdateCoefficients(const Array<int> & attr,
@@ -713,8 +713,8 @@ public:
{ pieces.erase(attr); }
/// Evaluate the coefficient.
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
using VectorCoefficient::Eval;
};
@@ -728,8 +728,8 @@ public:
using VectorCoefficient::Eval;
/// Evaluate the vector coefficient at @a ip.
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual ~PositionVectorCoefficient() { }
};
@@ -765,8 +765,8 @@ public:
using VectorCoefficient::Eval;
/// Evaluate the vector coefficient at @a ip.
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual ~VectorFunctionCoefficient() { }
};
@@ -787,7 +787,7 @@ public:
explicit VectorArrayCoefficient(int dim);
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Returns i'th coefficient.
Coefficient* GetCoeff(int i) { return Coeff[i]; }
@@ -806,8 +806,8 @@ public:
using VectorCoefficient::Eval;
/** @brief Evaluate the coefficient. Each element of vector V comes from the
associated array of scalar coefficients. */
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
/// Destroys vector coefficient.
virtual ~VectorArrayCoefficient();
@@ -836,21 +836,21 @@ public:
const GridFunction * GetGridFunction() const { return GridFunc; }
/// Evaluate the vector coefficient at @a ip.
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
/** @brief Evaluate the vector coefficients at all of the locations in the
integration rule and write the vectors into the columns of matrix @a
M. */
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationRule &ir);
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationRule &ir) override;
/// @brief Fill the QuadratureFunction @a qf by evaluating the coefficient at
/// the quadrature points.
///
/// This function uses the efficient QuadratureFunction::ProjectGridFunction
/// to fill the QuadratureFunction.
virtual void Project(QuadratureFunction &qf);
void Project(QuadratureFunction &qf) override;
virtual ~VectorGridFunctionCoefficient() { }
};
@@ -874,14 +874,14 @@ public:
const GridFunction * GetGridFunction() const { return GridFunc; }
/// Evaluate the gradient vector coefficient at @a ip.
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
/** @brief Evaluate the gradient vector coefficient at all of the locations
in the integration rule and write the vectors into columns of matrix @a
M. */
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationRule &ir);
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationRule &ir) override;
virtual ~GradientGridFunctionCoefficient() { }
};
@@ -905,8 +905,8 @@ public:
using VectorCoefficient::Eval;
/// Evaluate the vector curl coefficient at @a ip.
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual ~CurlGridFunctionCoefficient() { }
};
@@ -929,8 +929,8 @@ public:
const GridFunction * GetGridFunction() const { return GridFunc; }
/// Evaluate the scalar divergence coefficient at @a ip.
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual ~DivergenceGridFunctionCoefficient() { }
};
@@ -973,7 +973,7 @@ public:
: VectorCoefficient(dir_.Size()), dir(dir_), d(x,y,z,s) { }
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Replace the associated DeltaCoefficient with a new DeltaCoefficient.
/** The new DeltaCoefficient cannot have a specified weight Coefficient, i.e.
@@ -998,8 +998,8 @@ public:
using VectorCoefficient::Eval;
/** @brief A VectorDeltaFunction cannot be evaluated. Calling this method
will cause an MFEM error, terminating the application. */
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip)
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override
{ mfem_error("VectorDeltaCoefficient::Eval"); }
virtual ~VectorDeltaCoefficient() { }
};
@@ -1021,17 +1021,17 @@ public:
{ c = &vc; attr.Copy(active_attr); }
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Evaluate the vector coefficient at @a ip.
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
/** @brief Evaluate the vector coefficient at all of the locations in the
integration rule and write the vectors into the columns of matrix @a
M. */
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationRule &ir);
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationRule &ir) override;
};
typedef VectorCoefficient DiagonalMatrixCoefficient;
@@ -1113,8 +1113,8 @@ public:
: MatrixCoefficient(m.Height(), m.Width()), mat(m) { }
using MatrixCoefficient::Eval;
/// Evaluate the matrix coefficient at @a ip.
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) { M = mat; }
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override { M = mat; }
/// Return a reference to the constant matrix.
const DenseMatrix& GetMatrix() { return mat; }
};
@@ -1207,7 +1207,7 @@ public:
: MatrixCoefficient(h, w, symm) { InitMap(attr, coefs); }
/// Set the time for time dependent coefficients
virtual void SetTime(real_t t);
void SetTime(real_t t) override;
/// Replace a set of coefficients
void UpdateCoefficients(const Array<int> & attr,
@@ -1222,8 +1222,8 @@ public:
{ pieces.erase(attr); }
/// Evaluate the coefficient.
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/** @brief A matrix coefficient with an optional scalar coefficient multiplier
@@ -1280,16 +1280,16 @@ public:
{ }
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Evaluate the matrix coefficient at @a ip.
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip) override;
/// (DEPRECATED) Evaluate the symmetric matrix coefficient at @a ip.
/** @deprecated Use Eval() instead. */
virtual void EvalSymmetric(Vector &K, ElementTransformation &T,
const IntegrationPoint &ip);
void EvalSymmetric(Vector &K, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual ~MatrixFunctionCoefficient() { }
};
@@ -1310,7 +1310,7 @@ public:
explicit MatrixArrayCoefficient (int dim);
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Get the coefficient located at (i,j) in the matrix.
Coefficient* GetCoeff (int i, int j) { return Coeff[i*width+j]; }
@@ -1328,8 +1328,8 @@ public:
{ return Coeff[i*width+j] ? Coeff[i*width+j] -> Eval(T, ip, GetTime()) : 0.0; }
/// Evaluate the matrix coefficient @a ip.
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual ~MatrixArrayCoefficient();
};
@@ -1392,11 +1392,11 @@ public:
{ c = &mc; attr.Copy(active_attr); }
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Evaluate the matrix coefficient at @a ip.
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/// Coefficients based on sums, products, or other functions of coefficients.
@@ -1425,7 +1425,7 @@ public:
: aConst(0.0), a(&A), b(&B), alpha(alpha_), beta(beta_) { }
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Reset the first term in the linear combination as a constant
void SetAConst(real_t A) { a = NULL; aConst = A; }
@@ -1453,8 +1453,8 @@ public:
real_t GetBeta() const { return beta; }
/// Evaluate the coefficient at @a ip.
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip)
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override
{
return alpha * ((a == NULL ) ? aConst : a->Eval(T, ip) )
+ beta * b->Eval(T, ip);
@@ -1502,8 +1502,8 @@ public:
@note When this method is called, the caller must make sure that the
IntegrationPoint associated with @a T is the same as @a ip. This can be
achieved by calling T.SetIntPoint(&ip). */
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip) override;
/// @deprecated Return a reference to the internal matrix used when evaluating this coefficient as a DenseMatrix.
@@ -1525,8 +1525,8 @@ public:
: SymmetricMatrixCoefficient(m.Height()), mat(m) { }
using SymmetricMatrixCoefficient::Eval;
/// Evaluate the matrix coefficient at @a ip.
virtual void Eval(DenseSymmetricMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) { M = mat; }
void Eval(DenseSymmetricMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override { M = mat; }
/// Return a reference to the constant matrix.
const DenseSymmetricMatrix& GetMatrix() { return mat; }
@@ -1576,12 +1576,12 @@ public:
{ }
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
using SymmetricMatrixCoefficient::Eval;
/// Evaluate the matrix coefficient at @a ip.
virtual void Eval(DenseSymmetricMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(DenseSymmetricMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual ~SymmetricMatrixFunctionCoefficient() { }
};
@@ -1606,7 +1606,7 @@ public:
: aConst(0.0), a(&A), b(&B) { }
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Reset the first term in the product as a constant
void SetAConst(real_t A) { a = NULL; aConst = A; }
@@ -1624,8 +1624,8 @@ public:
Coefficient * GetBCoef() const { return b; }
/// Evaluate the coefficient at @a ip.
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip)
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override
{ return ((a == NULL ) ? aConst : a->Eval(T, ip) ) * b->Eval(T, ip); }
};
@@ -1654,7 +1654,7 @@ public:
: aConst(0.0), bConst(B), a(&A), b(NULL) { }
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Reset the numerator in the ratio as a constant
void SetAConst(real_t A) { a = NULL; aConst = A; }
@@ -1677,8 +1677,8 @@ public:
Coefficient * GetBCoef() const { return b; }
/// Evaluate the coefficient
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip)
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override
{
real_t den = (b == NULL ) ? bConst : b->Eval(T, ip);
MFEM_ASSERT(den != 0.0, "Division by zero in RatioCoefficient");
@@ -1700,7 +1700,7 @@ public:
: a(&A), p(p_) { }
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Reset the base coefficient
void SetACoef(Coefficient &A) { a = &A; }
@@ -1713,8 +1713,8 @@ public:
real_t GetExponent() const { return p; }
/// Evaluate the coefficient at @a ip.
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip)
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override
{ return pow(a->Eval(T, ip), p); }
};
@@ -1733,7 +1733,7 @@ public:
InnerProductCoefficient(VectorCoefficient &A, VectorCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Reset the first vector in the inner product
void SetACoef(VectorCoefficient &A) { a = &A; }
@@ -1746,8 +1746,8 @@ public:
VectorCoefficient * GetBCoef() const { return b; }
/// Evaluate the coefficient at @a ip.
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/// Scalar coefficient defined as a cross product of two vectors in the xy-plane.
@@ -1765,7 +1765,7 @@ public:
VectorRotProductCoefficient(VectorCoefficient &A, VectorCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Reset the first vector in the product
void SetACoef(VectorCoefficient &A) { a = &A; }
@@ -1778,8 +1778,8 @@ public:
VectorCoefficient * GetBCoef() const { return b; }
/// Evaluate the coefficient at @a ip.
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/// Scalar coefficient defined as the determinant of a matrix coefficient
@@ -1795,7 +1795,7 @@ public:
DeterminantCoefficient(MatrixCoefficient &A);
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Reset the matrix coefficient
void SetACoef(MatrixCoefficient &A) { a = &A; }
@@ -1803,8 +1803,8 @@ public:
MatrixCoefficient * GetACoef() const { return a; }
/// Evaluate the determinant coefficient at @a ip.
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/// Scalar coefficient defined as the trace of a matrix coefficient
@@ -1820,7 +1820,7 @@ public:
TraceCoefficient(MatrixCoefficient &A);
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Reset the matrix coefficient
void SetACoef(MatrixCoefficient &A) { a = &A; }
@@ -1828,8 +1828,8 @@ public:
MatrixCoefficient * GetACoef() const { return a; }
/// Evaluate the trace coefficient at @a ip.
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/// Vector coefficient defined as the linear combination of two vectors
@@ -1866,7 +1866,7 @@ public:
Coefficient &alpha_, Coefficient &beta_);
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Reset the first vector coefficient
void SetACoef(VectorCoefficient &A_) { ACoef = &A_; }
@@ -1909,8 +1909,8 @@ public:
real_t GetBeta() const { return beta; }
/// Evaluate the coefficient at @a ip.
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
using VectorCoefficient::Eval;
};
@@ -1930,7 +1930,7 @@ public:
ScalarVectorProductCoefficient(Coefficient &A, VectorCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Reset the scalar factor as a constant
void SetAConst(real_t A) { a = NULL; aConst = A; }
@@ -1948,8 +1948,8 @@ public:
VectorCoefficient * GetBCoef() const { return b; }
/// Evaluate the coefficient at @a ip.
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
using VectorCoefficient::Eval;
};
@@ -1971,7 +1971,7 @@ public:
NormalizedVectorCoefficient(VectorCoefficient &A, real_t tol = 1e-6);
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Reset the vector coefficient
void SetACoef(VectorCoefficient &A) { a = &A; }
@@ -1979,8 +1979,8 @@ public:
VectorCoefficient * GetACoef() const { return a; }
/// Evaluate the coefficient at @a ip.
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
using VectorCoefficient::Eval;
};
@@ -1999,7 +1999,7 @@ public:
VectorCrossProductCoefficient(VectorCoefficient &A, VectorCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Reset the first term in the product
void SetACoef(VectorCoefficient &A) { a = &A; }
@@ -2012,8 +2012,8 @@ public:
VectorCoefficient * GetBCoef() const { return b; }
/// Evaluate the coefficient at @a ip.
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
using VectorCoefficient::Eval;
};
@@ -2033,7 +2033,7 @@ public:
MatrixVectorProductCoefficient(MatrixCoefficient &A, VectorCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Reset the matrix coefficient
void SetACoef(MatrixCoefficient &A) { a = &A; }
@@ -2046,8 +2046,8 @@ public:
VectorCoefficient * GetBCoef() const { return b; }
/// Evaluate the vector coefficient at @a ip.
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
using VectorCoefficient::Eval;
};
@@ -2066,8 +2066,8 @@ public:
: MatrixCoefficient(d, d), dim(d) { }
/// Evaluate the matrix coefficient at @a ip.
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/// Matrix coefficient defined as the linear combination of two matrices
@@ -2088,7 +2088,7 @@ public:
real_t alpha_ = 1.0, real_t beta_ = 1.0);
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Reset the first matrix coefficient
void SetACoef(MatrixCoefficient &A) { a = &A; }
@@ -2111,8 +2111,8 @@ public:
real_t GetBeta() const { return beta; }
/// Evaluate the matrix coefficient at @a ip.
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/// Matrix coefficient defined as the product of two matrices
@@ -2140,8 +2140,8 @@ public:
MatrixCoefficient * GetBCoef() const { return b; }
/// Evaluate the matrix coefficient at @a ip.
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/** @brief Matrix coefficient defined as a product of a scalar coefficient and a
@@ -2161,7 +2161,7 @@ public:
ScalarMatrixProductCoefficient(Coefficient &A, MatrixCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Reset the scalar factor as a constant
void SetAConst(real_t A) { a = NULL; aConst = A; }
@@ -2179,8 +2179,8 @@ public:
MatrixCoefficient * GetBCoef() const { return b; }
/// Evaluate the matrix coefficient at @a ip.
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/// Matrix coefficient defined as the transpose of a matrix coefficient
@@ -2194,7 +2194,7 @@ public:
TransposeMatrixCoefficient(MatrixCoefficient &A);
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Reset the matrix coefficient
void SetACoef(MatrixCoefficient &A) { a = &A; }
@@ -2202,8 +2202,8 @@ public:
MatrixCoefficient * GetACoef() const { return a; }
/// Evaluate the matrix coefficient at @a ip.
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/// Matrix coefficient defined as the inverse of a matrix coefficient.
@@ -2217,7 +2217,7 @@ public:
InverseMatrixCoefficient(MatrixCoefficient &A);
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Reset the matrix coefficient
void SetACoef(MatrixCoefficient &A) { a = &A; }
@@ -2225,8 +2225,8 @@ public:
MatrixCoefficient * GetACoef() const { return a; }
/// Evaluate the matrix coefficient at @a ip.
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/// Matrix coefficient defined as the exponential of a matrix coefficient.
@@ -2240,7 +2240,7 @@ public:
ExponentialMatrixCoefficient(MatrixCoefficient &A);
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Reset the matrix coefficient
void SetACoef(MatrixCoefficient &A) { a = &A; }
@@ -2248,8 +2248,8 @@ public:
MatrixCoefficient * GetACoef() const { return a; }
/// Evaluate the matrix coefficient at @a ip.
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/// Matrix coefficient defined as the outer product of two vector coefficients.
@@ -2267,7 +2267,7 @@ public:
OuterProductCoefficient(VectorCoefficient &A, VectorCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Reset the first vector in the outer product
void SetACoef(VectorCoefficient &A) { a = &A; }
@@ -2280,8 +2280,8 @@ public:
VectorCoefficient * GetBCoef() const { return b; }
/// Evaluate the matrix coefficient at @a ip.
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/** @brief Matrix coefficient defined as -a k x k x, for a vector k and scalar a
@@ -2305,7 +2305,7 @@ public:
CrossCrossCoefficient(Coefficient &A, VectorCoefficient &K);
/// Set the time for internally stored coefficients
void SetTime(real_t t);
void SetTime(real_t t) override;
/// Reset the scalar factor as a constant
void SetAConst(real_t A) { a = NULL; aConst = A; }
@@ -2323,8 +2323,8 @@ public:
VectorCoefficient * GetKCoef() const { return k; }
/// Evaluate the matrix coefficient at @a ip.
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override;
};
///@}
@@ -2349,10 +2349,10 @@ public:
const QuadratureFunction& GetQuadFunction() const { return QuadF; }
using VectorCoefficient::Eval;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Project(QuadratureFunction &qf);
void Project(QuadratureFunction &qf) override;
virtual ~VectorQuadratureFunctionCoefficient() { }
};
@@ -2371,9 +2371,9 @@ public:
const QuadratureFunction& GetQuadFunction() const { return QuadF; }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
virtual void Project(QuadratureFunction &qf);
void Project(QuadratureFunction &qf) override;
virtual ~QuadratureFunctionCoefficient() { }
};
+1 -1
View File
@@ -1245,7 +1245,7 @@ ParSesquilinearForm::FormLinearSystem(const Array<int> &ess_tdof_list,
hypre_ParCSRMatrix *Aih = *Ah;
Ah->HypreReadWrite();
const int *d_ess_tdof_list =
ess_tdof_list.GetMemory().Read(GetHypreMemoryClass(), n);
ess_tdof_list.GetMemory().Read(GetHypreForallMemoryClass(), n);
HYPRE_Int *d_diag_i = Aih->diag->i;
real_t *d_diag_data = Aih->diag->data;
mfem::hypre_forall(n, [=] MFEM_HOST_DEVICE (int k)
+11 -11
View File
@@ -454,28 +454,28 @@ public:
#endif
/// Set/change the mesh associated with the collection
virtual void SetMesh(Mesh *new_mesh) override;
void SetMesh(Mesh *new_mesh) override;
#ifdef MFEM_USE_MPI
/// Set/change the mesh associated with the collection.
virtual void SetMesh(MPI_Comm comm, Mesh *new_mesh) override;
void SetMesh(MPI_Comm comm, Mesh *new_mesh) override;
#endif
/// Add a grid function to the collection and update the root file
virtual void RegisterField(const std::string& field_name,
GridFunction *gf) override;
void RegisterField(const std::string& field_name,
GridFunction *gf) override;
/// Add a quadrature function to the collection and update the root file.
/** Visualization of quadrature function is not supported in VisIt(3.12).
A patch has been sent to VisIt developers in June 2020. */
virtual void RegisterQField(const std::string& q_field_name,
QuadratureFunction *qf) override;
void RegisterQField(const std::string& q_field_name,
QuadratureFunction *qf) override;
/// Set the number of digits used for both the cycle and the MPI rank
/// @note VisIt seems to require 6 pad digits for the MPI rank. Therefore,
/// this function uses this default value. This behavior can be overridden
/// by calling SetPadDigitsCycle() and SetPadDigitsRank() instead.
virtual void SetPadDigits(int digits) override
void SetPadDigits(int digits) override
{ pad_digits_cycle=digits; pad_digits_rank=6; }
/// Set VisIt parameter: default levels of detail for the MultiresControl
@@ -489,13 +489,13 @@ public:
void DeleteAll();
/// Save the collection and a VisIt root file
virtual void Save() override;
void Save() override;
/// Save a VisIt root file for the collection
void SaveRootFile();
/// Load the collection based on its VisIt data (described in its root file)
virtual void Load(int cycle_ = 0) override;
void Load(int cycle_ = 0) override;
/// We will delete the mesh and fields if we own them
virtual ~VisItDataCollection() {}
@@ -546,7 +546,7 @@ public:
/// Save the collection - the directory name is constructed based on the
/// cycle value
virtual void Save() override;
void Save() override;
/// Set the data format for the ParaView output files. Possible options are
/// VTKFormat::ASCII, VTKFormat::BINARY, and VTKFormat::BINARY32.
@@ -590,7 +590,7 @@ public:
void UseRestartMode(bool restart_mode_);
/// Load the collection - not implemented in the ParaView writer
virtual void Load(int cycle_ = 0) override;
void Load(int cycle_ = 0) override;
};
}
+15 -15
View File
@@ -385,10 +385,10 @@ private:
/** @brief Evaluate the Jacobian of the transformation at the IntPoint and
store it in dFdx. */
virtual const DenseMatrix &EvalJacobian();
const DenseMatrix &EvalJacobian() override;
// Evaluate the Hessian of the transformation at the IntPoint and store it
// in d2Fdx2.
virtual const DenseMatrix &EvalHessian();
const DenseMatrix &EvalHessian() override;
public:
IsoparametricTransformation() : FElem(NULL) {}
@@ -430,32 +430,32 @@ public:
/** @brief Transform integration point from reference coordinates to
physical coordinates and store them in the vector. */
virtual void Transform(const IntegrationPoint &, Vector &);
void Transform(const IntegrationPoint &, Vector &) override;
/** @brief Transform all the integration points from the integration rule
from reference coordinates to physical
coordinates and store them as column vectors in the matrix. */
virtual void Transform(const IntegrationRule &, DenseMatrix &);
void Transform(const IntegrationRule &, DenseMatrix &) override;
/** @brief Transform all the integration points from the column vectors
of @a matrix from reference coordinates to physical
coordinates and store them as column vectors in @a result. */
virtual void Transform(const DenseMatrix &matrix, DenseMatrix &result);
void Transform(const DenseMatrix &matrix, DenseMatrix &result) override;
/// Return the order of the current element we are using for the transformation.
virtual int Order() const { return FElem->GetOrder(); }
int Order() const override { return FElem->GetOrder(); }
/// Return the order of the elements of the Jacobian of the transformation.
virtual int OrderJ() const;
int OrderJ() const override;
/** @brief Return the order of the determinant of the Jacobian (weight)
of the transformation. */
virtual int OrderW() const;
int OrderW() const override;
/// Return the order of $ adj(J)^T \nabla fi $
virtual int OrderGrad(const FiniteElement *fe) const;
int OrderGrad(const FiniteElement *fe) const override;
virtual int GetSpaceDim() const { return PointMat.Height(); }
int GetSpaceDim() const override { return PointMat.Height(); }
/** @brief Transform a point @a pt from physical space to a point @a ip in
reference space and optionally can set a solver tolerance using @a phys_tol. */
@@ -463,8 +463,8 @@ public:
point in physical space. If the inversion fails a non-zero value is
returned. This method is not 100 percent reliable for non-linear
transformations. */
virtual int TransformBack(const Vector & v, IntegrationPoint & ip,
const real_t phys_rel_tol = tol_0)
int TransformBack (const Vector & v, IntegrationPoint & ip,
const real_t phys_rel_tol = tol_0) override
{
InverseElementTransformation inv_tr(this);
inv_tr.SetPhysicalRelTol(phys_rel_tol);
@@ -604,9 +604,9 @@ public:
has been configured. */
const IntegrationPoint &GetElement2IntPoint() { return eip2; }
virtual void Transform(const IntegrationPoint &, Vector &);
virtual void Transform(const IntegrationRule &, DenseMatrix &);
virtual void Transform(const DenseMatrix &matrix, DenseMatrix &result);
void Transform(const IntegrationPoint &, Vector &) override;
void Transform(const IntegrationRule &, DenseMatrix &) override;
void Transform(const DenseMatrix &matrix, DenseMatrix &result) override;
ElementTransformation & GetElement1Transformation();
ElementTransformation & GetElement2Transformation();
+13 -13
View File
@@ -172,10 +172,10 @@ public:
void SetFluxAveraging(int fa) { flux_averaging = fa; }
/// Return the total error from the last error estimate.
virtual real_t GetTotalError() const override { return total_error; }
real_t GetTotalError() const override { return total_error; }
/// Get a Vector with all element errors.
virtual const Vector &GetLocalErrors() override
const Vector &GetLocalErrors() override
{
if (MeshIsModified()) { ComputeEstimates(); }
return error_estimates;
@@ -184,14 +184,14 @@ public:
/** @brief Get an Array<int> with anisotropic flags for all mesh elements.
Return an empty array when anisotropic estimates are not available or
enabled. */
virtual const Array<int> &GetAnisotropicFlags() override
const Array<int> &GetAnisotropicFlags() override
{
if (MeshIsModified()) { ComputeEstimates(); }
return aniso_flags;
}
/// Reset the error estimator.
virtual void Reset() override { current_sequence = -1; }
void Reset() override { current_sequence = -1; }
/** @brief Destroy a ZienkiewiczZhuEstimator object. Destroys, if owned, the
FiniteElementSpace, flux_space. */
@@ -298,17 +298,17 @@ public:
}
/// Return the total error from the last error estimate.
virtual real_t GetTotalError() const override { return total_error; }
real_t GetTotalError() const override { return total_error; }
/// Get a Vector with all element errors.
virtual const Vector &GetLocalErrors() override
const Vector &GetLocalErrors() override
{
if (MeshIsModified()) { ComputeEstimates(); }
return error_estimates;
}
/// Reset the error estimator.
virtual void Reset() override { current_sequence = -1; }
void Reset() override { current_sequence = -1; }
virtual ~LSZienkiewiczZhuEstimator() { }
};
@@ -411,17 +411,17 @@ public:
void SetLocalErrorNormP(int p) { local_norm_p = p; }
/// Return the total error from the last error estimate.
virtual real_t GetTotalError() const override { return total_error; }
real_t GetTotalError() const override { return total_error; }
/// Get a Vector with all element errors.
virtual const Vector &GetLocalErrors() override
const Vector &GetLocalErrors() override
{
if (MeshIsModified()) { ComputeEstimates(); }
return error_estimates;
}
/// Reset the error estimator.
virtual void Reset() override { current_sequence = -1; }
void Reset() override { current_sequence = -1; }
/** @brief Destroy a L2ZienkiewiczZhuEstimator object. Destroys, if owned,
the FiniteElementSpace, flux_space. */
@@ -505,10 +505,10 @@ public:
void SetCoef(VectorCoefficient &A) { vcoef = &A; }
/// Reset the error estimator.
virtual void Reset() override { current_sequence = -1; }
void Reset() override { current_sequence = -1; }
/// Get a Vector with all element errors.
virtual const Vector &GetLocalErrors() override
const Vector &GetLocalErrors() override
{
if (MeshIsModified()) { ComputeEstimates(); }
return error_estimates;
@@ -661,7 +661,7 @@ public:
/// Reset the error estimator.
void Reset() override { current_sequence = -1; };
virtual real_t GetTotalError() const override { return total_error; }
real_t GetTotalError() const override { return total_error; }
/** @brief Change the method to compute hₑ on a per-element basis.
@param compute_element_coefficient_
+324 -324
View File
File diff suppressed because it is too large Load Diff
+31 -31
View File
@@ -28,12 +28,12 @@ private:
public:
/// Construct the H1_SegmentElement of order @a p and BasisType @a btype
H1_SegmentElement(const int p, const int btype = BasisType::GaussLobatto);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &Hessian) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &Hessian) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
};
@@ -49,12 +49,12 @@ public:
/// Construct the H1_QuadrilateralElement of order @a p and BasisType @a btype
H1_QuadrilateralElement(const int p,
const int btype = BasisType::GaussLobatto);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &Hessian) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &Hessian) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
};
@@ -70,12 +70,12 @@ private:
public:
/// Construct the H1_HexahedronElement of order @a p and BasisType @a btype
H1_HexahedronElement(const int p, const int btype = BasisType::GaussLobatto);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &Hessian) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &Hessian) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
};
@@ -93,11 +93,11 @@ private:
public:
/// Construct the H1_TriangleElement of order @a p and BasisType @a btype
H1_TriangleElement(const int p, const int btype = BasisType::GaussLobatto);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &ddshape) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &ddshape) const override;
};
@@ -117,11 +117,11 @@ public:
/// Construct the H1_TetrahedronElement of order @a p and BasisType @a btype
H1_TetrahedronElement(const int p,
const int btype = BasisType::GaussLobatto);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &ddshape) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &ddshape) const override;
};
@@ -143,9 +143,9 @@ public:
/// Construct the H1_WedgeElement of order @a p and BasisType @a btype
H1_WedgeElement(const int p,
const int btype = BasisType::GaussLobatto);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
};
} // namespace mfem
+49 -49
View File
@@ -28,13 +28,13 @@ private:
public:
/// Construct the L2_SegmentElement of order @a p and BasisType @a btype
L2_SegmentElement(const int p, const int btype = BasisType::GaussLegendre);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
{ ScalarLocalL2Restriction(Trans, R, *this); }
};
@@ -52,25 +52,25 @@ public:
/// Construct the L2_QuadrilateralElement of order @a p and BasisType @a btype
L2_QuadrilateralElement(const int p,
const int btype = BasisType::GaussLegendre);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const override
{ ProjectCurl_2D(fe, Trans, curl); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
{ ScalarLocalL2Restriction(Trans, R, *this); }
using FiniteElement::Project;
virtual void ProjectDiv(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &div) const;
virtual void Project(Coefficient &coeff,
ElementTransformation &Trans, Vector &dofs) const;
void ProjectDiv(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &div) const override;
void Project(Coefficient &coeff,
ElementTransformation &Trans, Vector &dofs) const override;
};
@@ -86,21 +86,21 @@ public:
/// Construct the L2_HexahedronElement of order @a p and BasisType @a btype
L2_HexahedronElement(const int p,
const int btype = BasisType::GaussLegendre);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
{ ScalarLocalL2Restriction(Trans, R, *this); }
using FiniteElement::Project;
virtual void ProjectDiv(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &div) const;
virtual void Project(Coefficient &coeff,
ElementTransformation &Trans, Vector &dofs) const;
void ProjectDiv(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &div) const override;
void Project(Coefficient &coeff,
ElementTransformation &Trans, Vector &dofs) const override;
};
@@ -118,17 +118,17 @@ public:
/// Construct the L2_TriangleElement of order @a p and BasisType @a btype
L2_TriangleElement(const int p,
const int btype = BasisType::GaussLegendre);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const override
{ ProjectCurl_2D(fe, Trans, curl); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
{ ScalarLocalL2Restriction(Trans, R, *this); }
};
@@ -149,13 +149,13 @@ public:
/// Construct the L2_TetrahedronElement of order @a p and BasisType @a btype
L2_TetrahedronElement(const int p,
const int btype = BasisType::GaussLegendre);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
{ ScalarLocalL2Restriction(Trans, R, *this); }
};
@@ -178,9 +178,9 @@ public:
/// Construct the L2_WedgeElement of order @a p and BasisType @a btype
L2_WedgeElement(const int p,
const int btype = BasisType::GaussLegendre);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
};
} // namespace mfem
+242 -235
View File
@@ -36,62 +36,63 @@ public:
const int cb_type = BasisType::GaussLobatto,
const int ob_type = BasisType::GaussLegendre);
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override
{ CalcVShape_ND(Trans, shape); }
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const override;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override
{
if (obasis1d.IsIntegratedType()) { ProjectIntegrated(vc, Trans, dofs); }
else { Project_ND(tk, dof2tk, vc, Trans, dofs); }
}
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const override
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
ElementTransformation &T,
Vector &dofs) const override
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ Project_ND(tk, dof2tk, fe, Trans, I); }
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const override
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const override
{ ProjectCurl_ND(tk, dof2tk, fe, Trans, curl); }
virtual void GetFaceMap(const int face_id, Array<int> &face_map) const;
void GetFaceMap(const int face_id, Array<int> &face_map) const override;
protected:
void ProjectIntegrated(VectorCoefficient &vc,
@@ -118,46 +119,47 @@ public:
ND_QuadrilateralElement(const int p,
const int cb_type = BasisType::GaussLobatto,
const int ob_type = BasisType::GaussLegendre);
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override
{ CalcVShape_ND(Trans, shape); }
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const override;
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override
{
if (obasis1d.IsIntegratedType()) { ProjectIntegrated(vc, Trans, dofs); }
else { Project_ND(tk, dof2tk, vc, Trans, dofs); }
}
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const override
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
ElementTransformation &T,
Vector &dofs) const override
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ Project_ND(tk, dof2tk, fe, Trans, I); }
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const override
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
virtual void GetFaceMap(const int face_id, Array<int> &face_map) const;
void GetFaceMap(const int face_id, Array<int> &face_map) const override;
protected:
void ProjectIntegrated(VectorCoefficient &vc,
@@ -184,47 +186,48 @@ class ND_TetrahedronElement : public VectorFiniteElement
public:
/// Construct the ND_TetrahedronElement of order @a p
ND_TetrahedronElement(const int p);
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override
{ CalcVShape_ND(Trans, shape); }
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const override;
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
virtual const StatelessDofTransformation *GetDofTransformation() const
const StatelessDofTransformation *GetDofTransformation() const override
{ return &doftrans; }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const override
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
ElementTransformation &T,
Vector &dofs) const override
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ Project_ND(tk, dof2tk, fe, Trans, I); }
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const override
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const override
{ ProjectCurl_ND(tk, dof2tk, fe, Trans, curl); }
};
@@ -247,42 +250,43 @@ class ND_TriangleElement : public VectorFiniteElement
public:
/// Construct the ND_TriangleElement of order @a p
ND_TriangleElement(const int p);
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override
{ CalcVShape_ND(Trans, shape); }
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const override;
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
virtual const StatelessDofTransformation *GetDofTransformation() const
const StatelessDofTransformation *GetDofTransformation() const override
{ return &doftrans; }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const override
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
ElementTransformation &T,
Vector &dofs) const override
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ Project_ND(tk, dof2tk, fe, Trans, I); }
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const override
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
};
@@ -298,39 +302,40 @@ public:
/** @brief Construct the ND_SegmentElement of order @a p and open
BasisType @a ob_type */
ND_SegmentElement(const int p, const int ob_type = BasisType::GaussLegendre);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override
{ obasis1d.Eval(ip.x, shape); }
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override
{ CalcVShape_ND(Trans, shape); }
// virtual void CalcCurlShape(const IntegrationPoint &ip,
// void CalcCurlShape(const IntegrationPoint &ip,
// DenseMatrix &curl_shape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
ElementTransformation &T,
Vector &dofs) const override
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ Project_ND(tk, dof2tk, fe, Trans, I); }
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const override
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
};
@@ -358,53 +363,54 @@ public:
const int cb_type = BasisType::GaussLobatto,
const int ob_type = BasisType::GaussLegendre);
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override
{ CalcVShape_ND(Trans, shape); }
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const override;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
virtual const StatelessDofTransformation *GetDofTransformation() const
const StatelessDofTransformation *GetDofTransformation() const override
{ return &doftrans; }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
ElementTransformation &T,
Vector &dofs) const override
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ Project_ND(tk, dof2tk, fe, Trans, I); }
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const override
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const override
{ ProjectCurl_ND(tk, dof2tk, fe, Trans, curl); }
};
@@ -423,11 +429,11 @@ public:
using FiniteElement::CalcVShape;
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override;
};
/// Arbitrary order, three component, Nedelec elements in 1D on a segment
@@ -455,56 +461,57 @@ public:
using FiniteElement::CalcVShape;
using FiniteElement::CalcPhysCurlShape;
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override;
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const override;
virtual void CalcPhysCurlShape(ElementTransformation &Trans,
DenseMatrix &curl_shape) const;
void CalcPhysCurlShape(ElementTransformation &Trans,
DenseMatrix &curl_shape) const override;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const;
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override;
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const override
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
ElementTransformation &T,
Vector &dofs) const override
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const;
void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override;
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const override
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const override
{ ProjectCurl_ND(tk, dof2tk, fe, Trans, curl); }
};
@@ -535,32 +542,32 @@ public:
const int cb_type = BasisType::GaussLobatto,
const int ob_type = BasisType::GaussLegendre);
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override;
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const override;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation(*this, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
{ MFEM_ABORT("method is not overloaded"); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation(CheckVectorFE(fe), Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const;
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override;
};
class ND_R2D_FiniteElement : public VectorFiniteElement
@@ -580,35 +587,35 @@ public:
using FiniteElement::CalcVShape;
using FiniteElement::CalcPhysCurlShape;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override;
virtual void CalcPhysCurlShape(ElementTransformation &Trans,
DenseMatrix &curl_shape) const;
void CalcPhysCurlShape(ElementTransformation &Trans,
DenseMatrix &curl_shape) const override;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation(*this, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const;
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override;
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation(CheckVectorFE(fe), Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const;
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override;
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const;
void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const override;
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const;
void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const override;
};
/// Arbitrary order Nedelec 3D elements in 2D on a triangle
@@ -635,10 +642,10 @@ public:
using ND_R2D_FiniteElement::CalcVShape;
using ND_R2D_FiniteElement::CalcPhysCurlShape;
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const override;
};
@@ -664,10 +671,10 @@ public:
using ND_R2D_FiniteElement::CalcVShape;
using ND_R2D_FiniteElement::CalcPhysCurlShape;
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const override;
};
+46 -46
View File
@@ -80,12 +80,12 @@ public:
NURBSFiniteElement(1),
shape_x(p + 1) { }
virtual void SetOrder() const;
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void CalcHessian (const IntegrationPoint &ip,
DenseMatrix &hessian) const;
void SetOrder() const override;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void CalcHessian (const IntegrationPoint &ip,
DenseMatrix &hessian) const override;
};
/// An arbitrary order 2D NURBS element on a square
@@ -115,12 +115,12 @@ public:
dshape_y(py + 1), d2shape_x(px + 1), d2shape_y(py + 1), du(dof,2)
{ orders[0] = px; orders[1] = py; }
virtual void SetOrder() const;
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void CalcHessian (const IntegrationPoint &ip,
DenseMatrix &hessian) const;
void SetOrder() const override;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void CalcHessian (const IntegrationPoint &ip,
DenseMatrix &hessian) const override;
};
/// An arbitrary order 3D NURBS element on a cube
@@ -155,12 +155,12 @@ public:
d2shape_x(px + 1), d2shape_y(py + 1), d2shape_z(pz + 1), du(dof,3)
{ orders[0] = px; orders[1] = py; orders[2] = pz; }
virtual void SetOrder() const;
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void CalcHessian (const IntegrationPoint &ip,
DenseMatrix &hessian) const;
void SetOrder() const override;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void CalcHessian (const IntegrationPoint &ip,
DenseMatrix &hessian) const override;
};
@@ -221,10 +221,10 @@ public:
kv1[1] = nullptr;
}
virtual void SetOrder() const;
void SetOrder() const override;
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
/** @brief Evaluate the values of all shape functions of a *vector* finite
element in physical space at the point described by @a Trans. */
@@ -232,15 +232,15 @@ public:
one vector shape function. The size (#dof x SDim) of @a shape must be set
in advance, where SDim >= #dim is the physical space dimension as
described by @a Trans. */
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override;
/** @brief Evaluate the divergence of all shape functions of a *vector*
finite element in reference space at the given point @a ip. */
/** The size (#dof) of the result Vector @a divshape must be set in advance.
*/
virtual void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const;
void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const override;
~NURBS_HDiv2DFiniteElement();
};
@@ -315,10 +315,10 @@ public:
kv1[2] = nullptr;
}
virtual void SetOrder() const;
void SetOrder() const override;
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
/** @brief Evaluate the values of all shape functions of a *vector* finite
element in physical space at the point described by @a Trans. */
@@ -326,15 +326,15 @@ public:
one vector shape function. The size (#dof x SDim) of @a shape must be set
in advance, where SDim >= #dim is the physical space dimension as
described by @a Trans. */
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override;
/** @brief Evaluate the divergence of all shape functions of a *vector*
finite element in reference space at the given point @a ip. */
/** The size (#dof) of the result Vector @a divshape must be set in advance.
*/
virtual void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const;
void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const override;
~NURBS_HDiv3DFiniteElement();
};
@@ -392,10 +392,10 @@ public:
kv1[1] = nullptr;
}
virtual void SetOrder() const;
void SetOrder() const override;
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
/** @brief Evaluate the values of all shape functions of a *vector* finite
element in physical space at the point described by @a Trans. */
@@ -403,8 +403,8 @@ public:
one vector shape function. The size (#dof x SDim) of @a shape must be set
in advance, where SDim >= #dim is the physical space dimension as
described by @a Trans. */
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override;
/** @brief Evaluate the curl of all shape functions of a *vector* finite
element in reference space at the given point @a ip. */
@@ -412,8 +412,8 @@ public:
of the curl of one vector shape function. The size (#dof x CDim) of
@a curl_shape must be set in advance, where CDim = 3 for #dim = 3 and
CDim = 1 for #dim = 2. */
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const override;
~NURBS_HCurl2DFiniteElement();
};
@@ -483,10 +483,10 @@ public:
kv1[2] = nullptr;
}
virtual void SetOrder() const;
void SetOrder() const override;
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
/** @brief Evaluate the values of all shape functions of a *vector* finite
element in physical space at the point described by @a Trans. */
@@ -494,8 +494,8 @@ public:
one vector shape function. The size (#dof x SDim) of @a shape must be set
in advance, where SDim >= #dim is the physical space dimension as
described by @a Trans. */
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override;
/** @brief Evaluate the curl of all shape functions of a *vector* finite
element in reference space at the given point @a ip. */
@@ -503,8 +503,8 @@ public:
of the curl of one vector shape function. The size (#dof x CDim) of
@a curl_shape must be set in advance, where CDim = 3 for #dim = 3 and
CDim = 1 for #dim = 2. */
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const override;
~NURBS_HCurl3DFiniteElement();
};
+70 -70
View File
@@ -34,31 +34,31 @@ public:
ScalarFiniteElement(D, G, Do, O, F)
{ }
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
{ ScalarLocalInterpolation(Trans, I, *this); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
{ ScalarLocalL2Restriction(Trans, R, *this); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ CheckScalarFE(fe).ScalarLocalInterpolation(Trans, I, *this); }
using FiniteElement::Project;
// Low-order monotone "projection" (actually it is not a projection): the
// dofs are set to be the Coefficient values at the nodes.
virtual void Project(Coefficient &coeff,
ElementTransformation &Trans, Vector &dofs) const;
void Project(Coefficient &coeff,
ElementTransformation &Trans, Vector &dofs) const override;
virtual void Project (VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const;
void Project (VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override;
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const;
void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const override;
};
@@ -88,17 +88,17 @@ class BiQuadPos2DFiniteElement : public PositiveFiniteElement
public:
/// Construct the BiQuadPos2DFiniteElement
BiQuadPos2DFiniteElement();
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override;
using FiniteElement::Project;
virtual void Project(Coefficient &coeff, ElementTransformation &Trans,
Vector &dofs) const;
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans,
Vector &dofs) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const
void Project(Coefficient &coeff, ElementTransformation &Trans,
Vector &dofs) const override;
void Project(VectorCoefficient &vc, ElementTransformation &Trans,
Vector &dofs) const override;
void ProjectDelta(int vertex, Vector &dofs) const override
{ dofs = 0.; dofs(vertex) = 1.; }
};
@@ -109,9 +109,9 @@ class QuadPos1DFiniteElement : public PositiveFiniteElement
public:
/// Construct the QuadPos1DFiniteElement
QuadPos1DFiniteElement();
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
};
@@ -131,10 +131,10 @@ private:
public:
/// Construct the H1Pos_SegmentElement of order @a p
H1Pos_SegmentElement(const int p);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
};
@@ -150,10 +150,10 @@ private:
public:
/// Construct the H1Pos_QuadrilateralElement of order @a p
H1Pos_QuadrilateralElement(const int p);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
};
@@ -169,10 +169,10 @@ private:
public:
/// Construct the H1Pos_HexahedronElement of order @a p
H1Pos_HexahedronElement(const int p);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
};
@@ -198,9 +198,9 @@ public:
static void CalcDShape(const int p, const real_t x, const real_t y,
real_t *dshape_1d, real_t *dshape);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
};
@@ -227,9 +227,9 @@ public:
static void CalcDShape(const int p, const real_t x, const real_t y,
const real_t z, real_t *dshape_1d, real_t *dshape);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
};
@@ -250,9 +250,9 @@ public:
/// Construct the H1Pos_WedgeElement of order @a p
H1Pos_WedgeElement(const int p);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
};
@@ -267,10 +267,10 @@ private:
public:
/// Construct the L2Pos_SegmentElement of order @a p
L2Pos_SegmentElement(const int p);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
};
@@ -285,10 +285,10 @@ private:
public:
/// Construct the L2Pos_QuadrilateralElement of order @a p
L2Pos_QuadrilateralElement(const int p);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
};
@@ -303,10 +303,10 @@ private:
public:
/// Construct the L2Pos_HexahedronElement of order @a p
L2Pos_HexahedronElement(const int p);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
};
@@ -321,10 +321,10 @@ private:
public:
/// Construct the L2Pos_TriangleElement of order @a p
L2Pos_TriangleElement(const int p);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
};
@@ -340,10 +340,10 @@ private:
public:
/// Construct the L2Pos_TetrahedronElement of order @a p
L2Pos_TetrahedronElement(const int p);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
};
@@ -364,9 +364,9 @@ public:
/// Construct the L2Pos_WedgeElement of order @a p
L2Pos_WedgeElement(const int p);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
};
} // namespace mfem
+182 -177
View File
@@ -38,51 +38,52 @@ public:
RT_QuadrilateralElement(const int p,
const int cb_type = BasisType::GaussLobatto,
const int ob_type = BasisType::GaussLegendre);
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override
{ CalcVShape_RT(Trans, shape); }
virtual void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const override;
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_RT(*this, nk, dof2nk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
{ LocalRestriction_RT(nk, dof2nk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_RT(CheckVectorFE(fe), nk, dof2nk, Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override
{
if (obasis1d.IsIntegratedType()) { ProjectIntegrated(vc, Trans, dofs); }
else { Project_RT(nk, dof2nk, vc, Trans, dofs); }
}
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const override
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
ElementTransformation &T,
Vector &dofs) const override
{ ProjectMatrixCoefficient_RT(nk, dof2nk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const
void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const override
{ Project_RT(nk, dof2nk, fe, Trans, I); }
// Gradient + rotation = Curl: H1 -> H(div)
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const override
{ ProjectGrad_RT(nk, dof2nk, fe, Trans, grad); }
// Curl = Gradient + rotation: H1 -> H(div)
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const override
{ ProjectGrad_RT(nk, dof2nk, fe, Trans, curl); }
virtual void GetFaceMap(const int face_id, Array<int> &face_map) const;
void GetFaceMap(const int face_id, Array<int> &face_map) const override;
protected:
void ProjectIntegrated(VectorCoefficient &vc, ElementTransformation &Trans,
@@ -109,48 +110,49 @@ public:
const int cb_type = BasisType::GaussLobatto,
const int ob_type = BasisType::GaussLegendre);
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override
{ CalcVShape_RT(Trans, shape); }
virtual void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const override;
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_RT(*this, nk, dof2nk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
{ LocalRestriction_RT(nk, dof2nk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_RT(CheckVectorFE(fe), nk, dof2nk, Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override
{
if (obasis1d.IsIntegratedType()) { ProjectIntegrated(vc, Trans, dofs); }
else { Project_RT(nk, dof2nk, vc, Trans, dofs); }
}
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const override
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
ElementTransformation &T,
Vector &dofs) const override
{ ProjectMatrixCoefficient_RT(nk, dof2nk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const
void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const override
{ Project_RT(nk, dof2nk, fe, Trans, I); }
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const override
{ ProjectCurl_RT(nk, dof2nk, fe, Trans, curl); }
/// @brief Return the mapping from lexicographically ordered face DOFs to
/// lexicographically ordered element DOFs corresponding to local face
/// @a face_id.
virtual void GetFaceMap(const int face_id, Array<int> &face_map) const;
void GetFaceMap(const int face_id, Array<int> &face_map) const override;
protected:
void ProjectIntegrated(VectorCoefficient &vc,
@@ -176,45 +178,46 @@ class RT_TriangleElement : public VectorFiniteElement
public:
/// Construct the RT_TriangleElement of order @a p
RT_TriangleElement(const int p);
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override
{ CalcVShape_RT(Trans, shape); }
virtual void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const override;
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_RT(*this, nk, dof2nk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
{ LocalRestriction_RT(nk, dof2nk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_RT(CheckVectorFE(fe), nk, dof2nk, Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const override
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
ElementTransformation &T,
Vector &dofs) const override
{ ProjectMatrixCoefficient_RT(nk, dof2nk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const
void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const override
{ Project_RT(nk, dof2nk, fe, Trans, I); }
// Gradient + rotation = Curl: H1 -> H(div)
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const override
{ ProjectGrad_RT(nk, dof2nk, fe, Trans, grad); }
// Curl = Gradient + rotation: H1 -> H(div)
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const override
{ ProjectGrad_RT(nk, dof2nk, fe, Trans, curl); }
};
@@ -236,39 +239,40 @@ class RT_TetrahedronElement : public VectorFiniteElement
public:
/// Construct the RT_TetrahedronElement of order @a p
RT_TetrahedronElement(const int p);
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override
{ CalcVShape_RT(Trans, shape); }
virtual void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const override;
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_RT(*this, nk, dof2nk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
{ LocalRestriction_RT(nk, dof2nk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_RT(CheckVectorFE(fe), nk, dof2nk, Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const override
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
ElementTransformation &T,
Vector &dofs) const override
{ ProjectMatrixCoefficient_RT(nk, dof2nk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const
void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const override
{ Project_RT(nk, dof2nk, fe, Trans, I); }
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const override
{ ProjectCurl_RT(nk, dof2nk, fe, Trans, curl); }
};
@@ -296,36 +300,37 @@ class RT_WedgeElement : public VectorFiniteElement
public:
RT_WedgeElement(const int p);
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override
{ CalcVShape_RT(Trans, shape); }
virtual void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const override;
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_RT(*this, nk, dof2nk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
{ LocalRestriction_RT(nk, dof2nk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation_RT(CheckVectorFE(fe), nk, dof2nk, Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
ElementTransformation &T,
Vector &dofs) const override
{ ProjectMatrixCoefficient_RT(nk, dof2nk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const
void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const override
{ Project_RT(nk, dof2nk, fe, Trans, I); }
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const override
{ ProjectCurl_RT(nk, dof2nk, fe, Trans, curl); }
};
@@ -353,27 +358,27 @@ public:
const int cb_type = BasisType::GaussLobatto,
const int ob_type = BasisType::GaussLegendre);
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override;
virtual void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const;
void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const override;
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const;
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override;
virtual void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const;
void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override;
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const;
void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const override;
};
@@ -401,26 +406,26 @@ public:
RT_R2D_SegmentElement(const int p,
const int ob_type = BasisType::GaussLegendre);
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override;
virtual void CalcDivShape(const IntegrationPoint &ip,
Vector &div_shape) const;
void CalcDivShape(const IntegrationPoint &ip,
Vector &div_shape) const override;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation(*this, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
{ MFEM_ABORT("method is not overloaded"); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation(CheckVectorFE(fe), Trans, I); }
};
@@ -440,32 +445,32 @@ private:
public:
using FiniteElement::CalcVShape;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation(*this, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const;
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override;
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
{ LocalInterpolation(CheckVectorFE(fe), Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const;
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override;
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const;
void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const override;
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const;
void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const override;
};
/// Arbitrary order Raviart-Thomas 3D elements in 2D on a triangle
@@ -489,11 +494,11 @@ public:
using RT_R2D_FiniteElement::CalcVShape;
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
virtual void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const;
void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const override;
};
/// Arbitrary order Raviart-Thomas 3D elements in 2D on a square
@@ -518,10 +523,10 @@ public:
using RT_R2D_FiniteElement::CalcVShape;
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
virtual void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const;
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const override;
};
+5 -5
View File
@@ -23,11 +23,11 @@ class H1Ser_QuadrilateralElement : public ScalarFiniteElement
public:
/// Construct the H1Ser_QuadrilateralElement of order @a p
H1Ser_QuadrilateralElement(const int p);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const;
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override;
using FiniteElement::Project;
};
+6 -6
View File
@@ -757,7 +757,7 @@ public:
order, or VariableOrder (default). */
explicit NURBS_HDivFECollection(int Order = VariableOrder, const int vdim = -1);
virtual void Reset() const override
void Reset() const override
{
SegmentFE->Reset();
QuadrilateralFE->Reset();
@@ -765,11 +765,11 @@ public:
ParallelepipedVFE->Reset();
}
virtual void SetDim(const int dim) override;
void SetDim(const int dim) override;
/** @brief Set the order and the name, based on the given @a Order: either a
positive number for fixed order, or VariableOrder. */
virtual void SetOrder(int Order) const override;
void SetOrder(int Order) const override;
const FiniteElement *
FiniteElementForGeometry(Geometry::Type GeomType) const override;
@@ -808,7 +808,7 @@ public:
explicit NURBS_HCurlFECollection(int Order = VariableOrder,
const int vdim = -1);
virtual void Reset() const override
void Reset() const override
{
SegmentFE->Reset();
QuadrilateralFE->Reset();
@@ -816,11 +816,11 @@ public:
ParallelepipedVFE->Reset();
}
virtual void SetDim(const int dim) override;
void SetDim(const int dim) override;
/** @brief Set the order and the name, based on the given @a Order: either a
positive number for fixed order, or VariableOrder. */
virtual void SetOrder(int Order) const override;
void SetOrder(int Order) const override;
const FiniteElement *
FiniteElementForGeometry(Geometry::Type GeomType) const override;
+28 -1
View File
@@ -478,7 +478,7 @@ void FiniteElementSpace::ReorderElementToDofTable()
}
}
void FiniteElementSpace::BuildDofToArrays()
void FiniteElementSpace::BuildDofToArrays_() const
{
if (dof_elem_array.Size()) { return; }
@@ -503,6 +503,31 @@ void FiniteElementSpace::BuildDofToArrays()
}
}
void FiniteElementSpace::BuildDofToBdrArrays() const
{
if (dof_bdr_elem_array.Size()) { return; }
BuildBdrElementToDofTable();
dof_bdr_elem_array.SetSize (ndofs);
dof_bdr_ldof_array.SetSize (ndofs);
dof_bdr_elem_array = -1;
for (int i = 0; i < mesh -> GetNBE(); i++)
{
const int *dofs = bdr_elem_dof -> GetRow(i);
const int n = bdr_elem_dof -> RowSize(i);
for (int j = 0; j < n; j++)
{
int dof = DecodeDof(dofs[j]);
if (dof_bdr_elem_array[dof] < 0)
{
dof_bdr_elem_array[dof] = i;
dof_bdr_ldof_array[dof] = j;
}
}
}
}
void MarkDofs(const Array<int> &dofs, Array<int> &mark_array)
{
for (auto d : dofs)
@@ -3496,6 +3521,8 @@ void FiniteElementSpace::Destroy()
dof_elem_array.DeleteAll();
dof_ldof_array.DeleteAll();
dof_bdr_elem_array.DeleteAll();
dof_bdr_ldof_array.DeleteAll();
for (int i = 0; i < VNURBSext.Size(); i++)
{
+31 -15
View File
@@ -265,7 +265,10 @@ protected:
mutable Table *bdr_elem_fos; // bdr face orientations by bdr element index
mutable Table *face_dof; // owned; in var-order space contains variant 0 DOFs
Array<int> dof_elem_array, dof_ldof_array;
mutable Array<int> dof_elem_array;
mutable Array<int> dof_ldof_array;
mutable Array<int> dof_bdr_elem_array;
mutable Array<int> dof_bdr_ldof_array;
NURBSExtension *NURBSext;
/** array of NURBS extension for H(div) and H(curl) vector elements.
@@ -339,6 +342,14 @@ protected:
void BuildBdrElementToDofTable() const;
void BuildFaceToDofTable() const;
/** @brief Initialize internal data that enables the use of the methods
GetElementForDof() and GetLocalDofForDof(). */
void BuildDofToArrays_() const;
/** @brief Initialize internal data that enables the use of the methods
GetBdrElementForDof() and GetBdrLocalDofForDof(). */
void BuildDofToBdrArrays() const;
/** @brief Generates partial face_dof table for a NURBS space.
The table is only defined for exterior faces that coincide with a
@@ -458,7 +469,7 @@ protected:
DerefinementOperator(const FiniteElementSpace *f_fes,
const FiniteElementSpace *c_fes,
BilinearFormIntegrator *mass_integ);
virtual void Mult(const Vector &x, Vector &y) const;
void Mult(const Vector &x, Vector &y) const override;
virtual ~DerefinementOperator();
};
@@ -591,7 +602,8 @@ public:
/// Returns true if the space contains elements of varying polynomial orders.
bool IsVariableOrder() const { return elem_order.Size(); }
/// The returned SparseMatrix is owned by the FiniteElementSpace.
/// The returned SparseMatrix is owned by the FiniteElementSpace. The method
/// returns nullptr if the matrix is identity.
const SparseMatrix *GetConformingProlongation() const;
/// The returned SparseMatrix is owned by the FiniteElementSpace.
@@ -604,7 +616,8 @@ public:
/// The returned SparseMatrix is owned by the FiniteElementSpace.
const SparseMatrix *GetHpConformingRestriction() const;
/// The returned Operator is owned by the FiniteElementSpace.
/// The returned Operator is owned by the FiniteElementSpace. The method
/// returns nullptr if the prolongation matrix is identity.
virtual const Operator *GetProlongationMatrix() const
{ return GetConformingProlongation(); }
@@ -1163,18 +1176,21 @@ public:
const Table &GetFaceToDofTable() const
{ if (!face_dof) { BuildFaceToDofTable(); } return *face_dof; }
/** @brief Initialize internal data that enables the use of the methods
GetElementForDof() and GetLocalDofForDof(). */
void BuildDofToArrays();
/// Deprecated. This function is not required to be called by the user.
MFEM_DEPRECATED void BuildDofToArrays() const { BuildDofToArrays_(); }
/// Return the index of the first element that contains ldof index @a i.
int GetElementForDof(int i) const { BuildDofToArrays_(); return dof_elem_array[i]; }
/// Return the dof index within the element from GetElementForDof() for ldof index @a i.
int GetLocalDofForDof(int i) const { BuildDofToArrays_(); return dof_ldof_array[i]; }
/// Return the index of the first boundary element that contains ldof index @a i.
int GetBdrElementForDof(int i) const { BuildDofToBdrArrays(); return dof_bdr_elem_array[i]; }
/// Return the dof index within the boundary element from GetBdrElementForDof() for ldof index @a i.
int GetBdrLocalDofForDof(int i) const { BuildDofToBdrArrays(); return dof_bdr_ldof_array[i]; }
/// Return the index of the first element that contains dof @a i.
/** This method can be called only after setup is performed using the method
BuildDofToArrays(). */
int GetElementForDof(int i) const { return dof_elem_array[i]; }
/// Return the local dof index in the first element that contains dof @a i.
/** This method can be called only after setup is performed using the method
BuildDofToArrays(). */
int GetLocalDofForDof(int i) const { return dof_ldof_array[i]; }
/** @brief Returns pointer to the FiniteElement in the FiniteElementCollection
associated with i'th element in the mesh object.
+2 -2
View File
@@ -61,10 +61,10 @@ public:
void SetProtocol(const std::string &protocol);
/// Save the collection and a FMS blueprint root file
virtual void Save();
void Save() override;
/// Load the collection based blueprint data
virtual void Load(int cycle = 0);
void Load(int cycle = 0) override;
};
} // namespace mfem
-4
View File
@@ -2435,8 +2435,6 @@ void GridFunction::ProjectCoefficient(
ElementTransformation *T = NULL;
const FiniteElement *fe = NULL;
fes->BuildDofToArrays(); // ensures GetElementForDof(), GetLocalDofForDof() initialized.
for (int i = 0; i < dofs.Size(); i++)
{
int dof = dofs[i], j = fes->GetElementForDof(dof);
@@ -2516,8 +2514,6 @@ void GridFunction::ProjectCoefficient(
Vector val;
fes->BuildDofToArrays(); // ensures GetElementForDof(), GetLocalDofForDof() initialized.
for (int i = 0; i < dofs.Size(); i++)
{
int dof = dofs[i], j = fes->GetElementForDof(dof);
+1 -1
View File
@@ -876,7 +876,7 @@ private:
public:
ExtrudeCoefficient(Mesh *m, Coefficient &s, int n_)
: n(n_), mesh_in(m), sol_in(s) { }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
virtual ~ExtrudeCoefficient() { }
};
+7 -5
View File
@@ -37,7 +37,7 @@ FindPointsGSLIB::FindPointsGSLIB()
: mesh(NULL),
fec_map_lin(NULL),
fdata2D(NULL), fdata3D(NULL), cr(NULL), gsl_comm(NULL),
dim(-1), points_cnt(0), setupflag(false), default_interp_value(0),
dim(-1), points_cnt(-1), setupflag(false), default_interp_value(0),
avgtype(AvgType::ARITHMETIC), bdr_tol(1e-8)
{
mesh_split.SetSize(4);
@@ -85,7 +85,7 @@ FindPointsGSLIB::FindPointsGSLIB(MPI_Comm comm_)
: mesh(NULL),
fec_map_lin(NULL),
fdata2D(NULL), fdata3D(NULL), cr(NULL), gsl_comm(NULL),
dim(-1), points_cnt(0), setupflag(false), default_interp_value(0),
dim(-1), points_cnt(-1), setupflag(false), default_interp_value(0),
avgtype(AvgType::ARITHMETIC), bdr_tol(1e-8)
{
mesh_split.SetSize(4);
@@ -307,6 +307,7 @@ void FindPointsGSLIB::FreeData()
}
if (fec_map_lin) { delete fec_map_lin; fec_map_lin = NULL; }
setupflag = false;
points_cnt = -1;
}
void FindPointsGSLIB::SetupSplitMeshes()
@@ -897,7 +898,8 @@ void FindPointsGSLIB::Interpolate(const GridFunction &field_in,
int gf_order_h1 = std::max(gf_order, 1); // H1 should be at least order 1
H1_FECollection fec(gf_order_h1, dim);
const int ncomp = field_in.FESpace()->GetVDim();
FiniteElementSpace fes(mesh, &fec, ncomp);
FiniteElementSpace fes(mesh, &fec, ncomp,
field_in.FESpace()->GetOrdering());
GridFunction field_in_h1(&fes);
if (avgtype == AvgType::ARITHMETIC)
@@ -927,7 +929,7 @@ void FindPointsGSLIB::Interpolate(const GridFunction &field_in,
{
for (int i = 0; i < indl2.Size(); i++)
{
int idx = field_in.FESpace()->GetOrdering() == Ordering::byNODES ?
int idx = field_in_h1.FESpace()->GetOrdering() == Ordering::byNODES?
indl2[i] + j*points_cnt:
indl2[i]*ncomp + j;
field_out(idx) = field_out_l2(idx);
@@ -1172,7 +1174,7 @@ void FindPointsGSLIB::DistributePointInfoToOwningMPIRanks(
Array<unsigned int> &recv_elem, Vector &recv_ref,
Array<unsigned int> &recv_code)
{
MFEM_VERIFY(points_cnt,
MFEM_VERIFY(points_cnt >= 0,
"Invalid size. Please make sure to call FindPoints method "
"before calling this function.");
+29 -114
View File
@@ -14,6 +14,35 @@
namespace mfem
{
// PA Diffusion Integrator
DiffusionIntegrator::Kernels DiffusionIntegrator::kernels;
DiffusionIntegrator::Kernels::Kernels()
{
// 2D
DiffusionIntegrator::AddSpecialization<2,2,2>();
DiffusionIntegrator::AddSpecialization<2,3,3>();
DiffusionIntegrator::AddSpecialization<2,4,4>();
DiffusionIntegrator::AddSpecialization<2,5,5>();
DiffusionIntegrator::AddSpecialization<2,6,6>();
DiffusionIntegrator::AddSpecialization<2,7,7>();
DiffusionIntegrator::AddSpecialization<2,8,8>();
DiffusionIntegrator::AddSpecialization<2,9,9>();
// 3D
DiffusionIntegrator::AddSpecialization<3,2,2>();
DiffusionIntegrator::AddSpecialization<3,2,3>();
DiffusionIntegrator::AddSpecialization<3,3,4>();
DiffusionIntegrator::AddSpecialization<3,4,5>();
DiffusionIntegrator::AddSpecialization<3,4,6>();
DiffusionIntegrator::AddSpecialization<3,5,6>();
DiffusionIntegrator::AddSpecialization<3,5,8>();
DiffusionIntegrator::AddSpecialization<3,6,7>();
DiffusionIntegrator::AddSpecialization<3,7,8>();
DiffusionIntegrator::AddSpecialization<3,8,9>();
}
void DiffusionIntegrator::Kernels::EnsureInitialized() { }
namespace internal
{
@@ -361,121 +390,7 @@ void OccaPADiffusionSetup3D(const int D1D,
}
OccaDiffSetup3D_ker.at(id)(NE, o_W, o_J, o_C, o_op, const_c);
}
#endif // MFEM_USE_OCCA
void PADiffusionAssembleDiagonal(const int dim,
const int D1D,
const int Q1D,
const int NE,
const bool symm,
const Array<real_t> &B,
const Array<real_t> &G,
const Vector &D,
Vector &Y)
{
if (dim == 2)
{
switch ((D1D << 4 ) | Q1D)
{
case 0x22: return SmemPADiffusionDiagonal2D<2,2,8>(NE,symm,B,G,D,Y);
case 0x33: return SmemPADiffusionDiagonal2D<3,3,8>(NE,symm,B,G,D,Y);
case 0x44: return SmemPADiffusionDiagonal2D<4,4,4>(NE,symm,B,G,D,Y);
case 0x55: return SmemPADiffusionDiagonal2D<5,5,4>(NE,symm,B,G,D,Y);
case 0x66: return SmemPADiffusionDiagonal2D<6,6,2>(NE,symm,B,G,D,Y);
case 0x77: return SmemPADiffusionDiagonal2D<7,7,2>(NE,symm,B,G,D,Y);
case 0x88: return SmemPADiffusionDiagonal2D<8,8,1>(NE,symm,B,G,D,Y);
case 0x99: return SmemPADiffusionDiagonal2D<9,9,1>(NE,symm,B,G,D,Y);
default: return PADiffusionDiagonal2D(NE,symm,B,G,D,Y,D1D,Q1D);
}
}
else if (dim == 3)
{
switch ((D1D << 4 ) | Q1D)
{
case 0x22: return SmemPADiffusionDiagonal3D<2,2>(NE,symm,B,G,D,Y);
case 0x23: return SmemPADiffusionDiagonal3D<2,3>(NE,symm,B,G,D,Y);
case 0x34: return SmemPADiffusionDiagonal3D<3,4>(NE,symm,B,G,D,Y);
case 0x45: return SmemPADiffusionDiagonal3D<4,5>(NE,symm,B,G,D,Y);
case 0x46: return SmemPADiffusionDiagonal3D<4,6>(NE,symm,B,G,D,Y);
case 0x56: return SmemPADiffusionDiagonal3D<5,6>(NE,symm,B,G,D,Y);
case 0x67: return SmemPADiffusionDiagonal3D<6,7>(NE,symm,B,G,D,Y);
case 0x78: return SmemPADiffusionDiagonal3D<7,8>(NE,symm,B,G,D,Y);
case 0x89: return SmemPADiffusionDiagonal3D<8,9>(NE,symm,B,G,D,Y);
case 0x9A: return SmemPADiffusionDiagonal3D<9,10>(NE,symm,B,G,D,Y);
default: return PADiffusionDiagonal3D(NE,symm,B,G,D,Y,D1D,Q1D);
}
}
MFEM_ABORT("Unknown kernel.");
}
void PADiffusionApply(const int dim,
const int D1D,
const int Q1D,
const int NE,
const bool symm,
const Array<real_t> &B,
const Array<real_t> &G,
const Array<real_t> &Bt,
const Array<real_t> &Gt,
const Vector &D,
const Vector &X,
Vector &Y)
{
#ifdef MFEM_USE_OCCA
if (DeviceCanUseOcca())
{
if (dim == 2)
{
OccaPADiffusionApply2D(D1D,Q1D,NE,B,G,Bt,Gt,D,X,Y);
return;
}
if (dim == 3)
{
OccaPADiffusionApply3D(D1D,Q1D,NE,B,G,Bt,Gt,D,X,Y);
return;
}
MFEM_ABORT("OCCA PADiffusionApply unknown kernel!");
}
#endif // MFEM_USE_OCCA
const int id = (D1D << 4) | Q1D;
if (dim == 2)
{
switch (id)
{
case 0x22: return SmemPADiffusionApply2D<2,2,16>(NE,symm,B,G,D,X,Y);
case 0x33: return SmemPADiffusionApply2D<3,3,16>(NE,symm,B,G,D,X,Y);
case 0x44: return SmemPADiffusionApply2D<4,4,8>(NE,symm,B,G,D,X,Y);
case 0x55: return SmemPADiffusionApply2D<5,5,8>(NE,symm,B,G,D,X,Y);
case 0x66: return SmemPADiffusionApply2D<6,6,4>(NE,symm,B,G,D,X,Y);
case 0x77: return SmemPADiffusionApply2D<7,7,4>(NE,symm,B,G,D,X,Y);
case 0x88: return SmemPADiffusionApply2D<8,8,2>(NE,symm,B,G,D,X,Y);
case 0x99: return SmemPADiffusionApply2D<9,9,2>(NE,symm,B,G,D,X,Y);
default: return PADiffusionApply2D(NE,symm,B,G,Bt,Gt,D,X,Y,D1D,Q1D);
}
}
if (dim == 3)
{
switch (id)
{
case 0x22: return SmemPADiffusionApply3D<2,2>(NE,symm,B,G,D,X,Y);
case 0x23: return SmemPADiffusionApply3D<2,3>(NE,symm,B,G,D,X,Y);
case 0x34: return SmemPADiffusionApply3D<3,4>(NE,symm,B,G,D,X,Y);
case 0x45: return SmemPADiffusionApply3D<4,5>(NE,symm,B,G,D,X,Y);
case 0x46: return SmemPADiffusionApply3D<4,6>(NE,symm,B,G,D,X,Y);
case 0x56: return SmemPADiffusionApply3D<5,6>(NE,symm,B,G,D,X,Y);
case 0x58: return SmemPADiffusionApply3D<5,8>(NE,symm,B,G,D,X,Y);
case 0x67: return SmemPADiffusionApply3D<6,7>(NE,symm,B,G,D,X,Y);
case 0x78: return SmemPADiffusionApply3D<7,8>(NE,symm,B,G,D,X,Y);
case 0x89: return SmemPADiffusionApply3D<8,9>(NE,symm,B,G,D,X,Y);
default: return PADiffusionApply3D(NE,symm,B,G,Bt,Gt,D,X,Y,D1D,Q1D);
}
}
MFEM_ABORT("Unknown kernel: 0x"<<std::hex << id << std::dec);
}
#ifdef MFEM_USE_OCCA
void OccaPADiffusionApply2D(const int D1D,
const int Q1D,
const int NE,
+65 -7
View File
@@ -12,6 +12,7 @@
#ifndef MFEM_BILININTEG_DIFFUSION_KERNELS_HPP
#define MFEM_BILININTEG_DIFFUSION_KERNELS_HPP
#include "../kernel_dispatch.hpp"
#include "../../config/config.hpp"
#include "../../general/array.hpp"
#include "../../general/forall.hpp"
@@ -36,7 +37,7 @@ void PADiffusionSetup(const int dim,
const Vector &C,
Vector &D);
// PA Diffusion Assemble 2D kernel
// PA Diffusion Assemble 2D f
template<int T_SDIM>
void PADiffusionSetup2D(const int Q1D,
const int coeffDim,
@@ -151,8 +152,23 @@ inline void PADiffusionDiagonal2D(const int NE,
});
}
namespace diffusion
{
constexpr int ipow(int x, int p) { return p == 0 ? 1 : x*ipow(x, p-1); }
constexpr int D11(int x) { return (11 - x)/2; }
constexpr int D10(int x) { return (10 - x)/2; }
constexpr int NBZApply(int D1D)
{
return ipow(2, D11(D1D) >= 0 ? D11(D1D) : 0);
}
constexpr int NBZDiagonal(int D1D)
{
return ipow(2, D10(D1D) >= 0 ? D10(D1D) : 0);
}
}
// Shared memory PA Diffusion Diagonal 2D kernel
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0>
template<int T_D1D = 0, int T_Q1D = 0>
inline void SmemPADiffusionDiagonal2D(const int NE,
const bool symmetric,
const Array<real_t> &b_,
@@ -162,9 +178,10 @@ inline void SmemPADiffusionDiagonal2D(const int NE,
const int d1d = 0,
const int q1d = 0)
{
static constexpr int T_NBZ = diffusion::NBZDiagonal(T_D1D);
static constexpr int NBZ = T_NBZ ? T_NBZ : 1;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
const int max_q1d = T_Q1D ? T_Q1D : DeviceDofQuadLimits::Get().MAX_Q1D;
const int max_d1d = T_D1D ? T_D1D : DeviceDofQuadLimits::Get().MAX_D1D;
MFEM_VERIFY(D1D <= max_d1d, "");
@@ -178,7 +195,6 @@ inline void SmemPADiffusionDiagonal2D(const int NE,
const int tidz = MFEM_THREAD_ID(z);
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
MFEM_SHARED real_t BG[2][MQ1*MD1];
@@ -628,20 +644,23 @@ inline void PADiffusionApply2D(const int NE,
}
// Shared memory PA Diffusion Apply 2D kernel
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0>
template<int T_D1D = 0, int T_Q1D = 0>
inline void SmemPADiffusionApply2D(const int NE,
const bool symmetric,
const Array<real_t> &b_,
const Array<real_t> &g_,
const Array<real_t> &bt_,
const Array<real_t> &gt_,
const Vector &d_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
{
static constexpr int T_NBZ = diffusion::NBZApply(T_D1D);
static constexpr int NBZ = T_NBZ ? T_NBZ : 1;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
const int max_q1d = T_Q1D ? T_Q1D : DeviceDofQuadLimits::Get().MAX_Q1D;
const int max_d1d = T_D1D ? T_D1D : DeviceDofQuadLimits::Get().MAX_D1D;
MFEM_VERIFY(D1D <= max_d1d, "");
@@ -656,7 +675,6 @@ inline void SmemPADiffusionApply2D(const int NE,
const int tidz = MFEM_THREAD_ID(z);
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
MFEM_SHARED real_t sBG[2][MQ1*MD1];
@@ -984,6 +1002,8 @@ inline void SmemPADiffusionApply3D(const int NE,
const bool symmetric,
const Array<real_t> &b_,
const Array<real_t> &g_,
const Array<real_t> &,
const Array<real_t> &,
const Vector &d_,
const Vector &x_,
Vector &y_,
@@ -1203,6 +1223,44 @@ inline void SmemPADiffusionApply3D(const int NE,
} // namespace internal
namespace
{
using ApplyKernelType = DiffusionIntegrator::ApplyKernelType;
using DiagonalKernelType = DiffusionIntegrator::DiagonalKernelType;
}
template<int DIM, int T_D1D, int T_Q1D>
ApplyKernelType DiffusionIntegrator::ApplyPAKernels::Kernel()
{
if (DIM == 2) { return internal::SmemPADiffusionApply2D<T_D1D,T_Q1D>; }
else if (DIM == 3) { return internal::SmemPADiffusionApply3D<T_D1D, T_Q1D>; }
else { MFEM_ABORT(""); }
}
inline
ApplyKernelType DiffusionIntegrator::ApplyPAKernels::Fallback(int DIM, int, int)
{
if (DIM == 2) { return internal::PADiffusionApply2D; }
else if (DIM == 3) { return internal::PADiffusionApply3D; }
else { MFEM_ABORT(""); }
}
template<int DIM, int D1D, int Q1D>
DiagonalKernelType DiffusionIntegrator::DiagonalPAKernels::Kernel()
{
if (DIM == 2) { return internal::SmemPADiffusionDiagonal2D<D1D,Q1D>; }
else if (DIM == 3) { return internal::SmemPADiffusionDiagonal3D<D1D, Q1D>; }
else { MFEM_ABORT(""); }
}
inline DiagonalKernelType
DiffusionIntegrator::DiagonalPAKernels::Fallback(int DIM, int, int)
{
if (DIM == 2) { return internal::PADiffusionDiagonal2D; }
else if (DIM == 3) { return internal::PADiffusionDiagonal3D; }
else { MFEM_ABORT(""); }
}
} // namespace mfem
#endif
+67 -41
View File
@@ -19,6 +19,73 @@
namespace mfem
{
void DiffusionIntegrator::AssembleDiagonalPA(Vector &diag)
{
if (DeviceCanUseCeed())
{
ceedOp->GetDiagonal(diag);
}
else
{
if (pa_data.Size() == 0) { AssemblePA(*fespace); }
const Array<real_t> &B = maps->B;
const Array<real_t> &G = maps->G;
const Vector &Dv = pa_data;
DiagonalPAKernels::Run(dim, dofs1D, quad1D, ne, symmetric, B, G, Dv,
diag, dofs1D, quad1D);
}
}
// PA Diffusion Apply kernel
void DiffusionIntegrator::AddMultPA(const Vector &x, Vector &y) const
{
if (DeviceCanUseCeed())
{
ceedOp->AddMult(x, y);
}
else
{
const Array<real_t> &B = maps->B;
const Array<real_t> &G = maps->G;
const Array<real_t> &Bt = maps->Bt;
const Array<real_t> &Gt = maps->Gt;
const Vector &Dv = pa_data;
#ifdef MFEM_USE_OCCA
if (DeviceCanUseOcca())
{
if (dim == 2)
{
internal::OccaPADiffusionApply2D(dofs1D,quad1D,ne,B,G,Bt,Gt,Dv,x,y);
return;
}
if (dim == 3)
{
internal::OccaPADiffusionApply3D(dofs1D,quad1D,ne,B,G,Bt,Gt,Dv,x,y);
return;
}
MFEM_ABORT("OCCA PADiffusionApply unknown kernel!");
}
#endif // MFEM_USE_OCCA
ApplyPAKernels::Run(dim, dofs1D, quad1D, ne, symmetric, B, G, Bt,
Gt, Dv, x, y, dofs1D, quad1D);
}
}
void DiffusionIntegrator::AddMultTransposePA(const Vector &x, Vector &y) const
{
if (symmetric)
{
AddMultPA(x, y);
}
else
{
MFEM_ABORT("DiffusionIntegrator::AddMultTransposePA only implemented in "
"the symmetric case.")
}
}
void DiffusionIntegrator::AssemblePA(const FiniteElementSpace &fes)
{
const MemoryType mt = (pa_mt == MemoryType::DEFAULT) ?
@@ -98,47 +165,6 @@ void DiffusionIntegrator::AssemblePatchPA(const int patch,
SetupPatchPA(patch, mesh); // For full quadrature, unitWeights = false
}
void DiffusionIntegrator::AssembleDiagonalPA(Vector &diag)
{
if (DeviceCanUseCeed())
{
ceedOp->GetDiagonal(diag);
}
else
{
if (pa_data.Size()==0) { AssemblePA(*fespace); }
internal::PADiffusionAssembleDiagonal(dim, dofs1D, quad1D, ne, symmetric,
maps->B, maps->G, pa_data, diag);
}
}
void DiffusionIntegrator::AddMultPA(const Vector &x, Vector &y) const
{
if (DeviceCanUseCeed())
{
ceedOp->AddMult(x, y);
}
else
{
internal::PADiffusionApply(dim, dofs1D, quad1D, ne, symmetric,
maps->B, maps->G, maps->Bt, maps->Gt,
pa_data, x, y);
}
}
void DiffusionIntegrator::AddMultTransposePA(const Vector &x, Vector &y) const
{
if (symmetric)
{
AddMultPA(x, y);
}
else
{
MFEM_ABORT("DiffusionIntegrator::AddMultTransposePA only implemented in "
"the symmetric case.")
}
}
// This version uses full 1D quadrature rules, taking into account the
// minimum interaction between basis functions and integration points.
void DiffusionIntegrator::AddMultPatchPA(const int patch, const Vector &x,
+3 -1
View File
@@ -1819,10 +1819,12 @@ void IdentityInterpolator::AssemblePA(const FiniteElementSpace &trial_fes,
MFEM_VERIFY(trial_el->GetOrder() == test_el->GetOrder(), "");
MFEM_VERIFY(vdim == 1, "vdim != 1 with PA is not supported yet!");
ne = trial_fes.GetNE();
const int order = trial_el->GetOrder();
dofquad_fe = new H1_SegmentElement(order);
dofquad_fe.reset(new H1_SegmentElement(order));
mfem::QuadratureFunctions1D qf1d;
mfem::IntegrationRule closed_ir;
closed_ir.SetSize(order + 1);
+27 -217
View File
@@ -14,78 +14,36 @@
namespace mfem
{
MassIntegrator::Kernels MassIntegrator::kernels;
MassIntegrator::Kernels::Kernels()
{
// 2D
MassIntegrator::AddSpecialization<2,2,2>();
MassIntegrator::AddSpecialization<2,3,3>();
MassIntegrator::AddSpecialization<2,4,4>();
MassIntegrator::AddSpecialization<2,5,5>();
MassIntegrator::AddSpecialization<2,6,6>();
MassIntegrator::AddSpecialization<2,7,7>();
MassIntegrator::AddSpecialization<2,8,8>();
MassIntegrator::AddSpecialization<2,9,9>();
// 3D
MassIntegrator::AddSpecialization<3,2,2>();
MassIntegrator::AddSpecialization<3,2,3>();
MassIntegrator::AddSpecialization<3,3,4>();
MassIntegrator::AddSpecialization<3,4,5>();
MassIntegrator::AddSpecialization<3,4,6>();
MassIntegrator::AddSpecialization<3,5,6>();
MassIntegrator::AddSpecialization<3,5,8>();
MassIntegrator::AddSpecialization<3,6,7>();
MassIntegrator::AddSpecialization<3,7,8>();
MassIntegrator::AddSpecialization<3,8,9>();
}
void MassIntegrator::Kernels::EnsureInitialized() { }
namespace internal
{
// PA Mass Diagonal 1D kernel
static void PAMassAssembleDiagonal1D(const int NE,
const Array<real_t> &b,
const Vector &d,
Vector &y,
const int D1D,
const int Q1D)
{
auto B = Reshape(b.Read(), Q1D, D1D);
auto D = Reshape(d.Read(), Q1D, NE);
auto Y = Reshape(y.ReadWrite(), D1D, NE);
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
for (int dx = 0; dx < D1D; ++dx)
{
for (int qx = 0; qx < Q1D; ++qx)
{
Y(dx, e) += B(qx, dx) * B(qx, dx) * D(qx, e);
}
}
});
}
void PAMassAssembleDiagonal(const int dim, const int D1D,
const int Q1D, const int NE,
const Array<real_t> &B,
const Vector &D,
Vector &Y)
{
if (dim == 1)
{
return PAMassAssembleDiagonal1D(NE,B,D,Y,D1D,Q1D);
}
else if (dim == 2)
{
switch ((D1D << 4 ) | Q1D)
{
case 0x22: return SmemPAMassAssembleDiagonal2D<2,2,16>(NE,B,D,Y);
case 0x33: return SmemPAMassAssembleDiagonal2D<3,3,16>(NE,B,D,Y);
case 0x44: return SmemPAMassAssembleDiagonal2D<4,4,8>(NE,B,D,Y);
case 0x55: return SmemPAMassAssembleDiagonal2D<5,5,8>(NE,B,D,Y);
case 0x66: return SmemPAMassAssembleDiagonal2D<6,6,4>(NE,B,D,Y);
case 0x77: return SmemPAMassAssembleDiagonal2D<7,7,4>(NE,B,D,Y);
case 0x88: return SmemPAMassAssembleDiagonal2D<8,8,2>(NE,B,D,Y);
case 0x99: return SmemPAMassAssembleDiagonal2D<9,9,2>(NE,B,D,Y);
default: return PAMassAssembleDiagonal2D(NE,B,D,Y,D1D,Q1D);
}
}
else if (dim == 3)
{
switch ((D1D << 4 ) | Q1D)
{
case 0x23: return SmemPAMassAssembleDiagonal3D<2,3>(NE,B,D,Y);
case 0x24: return SmemPAMassAssembleDiagonal3D<2,4>(NE,B,D,Y);
case 0x26: return SmemPAMassAssembleDiagonal3D<2,6>(NE,B,D,Y);
case 0x34: return SmemPAMassAssembleDiagonal3D<3,4>(NE,B,D,Y);
case 0x35: return SmemPAMassAssembleDiagonal3D<3,5>(NE,B,D,Y);
case 0x45: return SmemPAMassAssembleDiagonal3D<4,5>(NE,B,D,Y);
case 0x48: return SmemPAMassAssembleDiagonal3D<4,8>(NE,B,D,Y);
case 0x56: return SmemPAMassAssembleDiagonal3D<5,6>(NE,B,D,Y);
case 0x67: return SmemPAMassAssembleDiagonal3D<6,7>(NE,B,D,Y);
case 0x78: return SmemPAMassAssembleDiagonal3D<7,8>(NE,B,D,Y);
case 0x89: return SmemPAMassAssembleDiagonal3D<8,9>(NE,B,D,Y);
default: return PAMassAssembleDiagonal3D(NE,B,D,Y,D1D,Q1D);
}
}
MFEM_ABORT("Unknown kernel.");
}
#ifdef MFEM_USE_OCCA
void OccaPAMassApply2D(const int D1D,
const int Q1D,
@@ -176,154 +134,6 @@ void OccaPAMassApply3D(const int D1D,
}
#endif // MFEM_USE_OCCA
MFEM_HOST_DEVICE inline
void PAMassApply1D_Element(const int e,
const int NE,
const real_t *b_,
const real_t *bt_,
const real_t *d_,
const real_t *x_,
real_t *y_,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = d1d;
const int Q1D = q1d;
auto B = ConstDeviceMatrix(b_, Q1D, D1D);
auto Bt = ConstDeviceMatrix(bt_, D1D, Q1D);
auto D = ConstDeviceMatrix(d_, Q1D, NE);
auto X = ConstDeviceMatrix(x_, D1D, NE);
auto Y = DeviceMatrix(y_, D1D, NE);
real_t XQ[DofQuadLimits::MAX_Q1D];
for (int qx = 0; qx < Q1D; ++qx)
{
XQ[qx] = 0.0;
}
for (int dx = 0; dx < D1D; ++dx)
{
const real_t s = X(dx,e);
for (int qx = 0; qx < Q1D; ++qx)
{
XQ[qx] += B(qx,dx)*s;
}
}
for (int qx = 0; qx < Q1D; ++qx)
{
const real_t q = XQ[qx]*D(qx,e);
for (int dx = 0; dx < D1D; ++dx)
{
Y(dx,e) += Bt(dx,qx) * q;
}
}
}
// PA Mass Apply 1D kernel
static void PAMassApply1D(const int NE,
const Array<real_t> &b_,
const Array<real_t> &bt_,
const Vector &d_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
{
MFEM_VERIFY(d1d <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(q1d <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
const auto B = b_.Read();
const auto Bt = bt_.Read();
const auto D = d_.Read();
const auto X = x_.Read();
auto Y = y_.ReadWrite();
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
internal::PAMassApply1D_Element(e, NE, B, Bt, D, X, Y, d1d, q1d);
});
}
void PAMassApply(const int dim,
const int D1D,
const int Q1D,
const int NE,
const Array<real_t> &B,
const Array<real_t> &Bt,
const Vector &D,
const Vector &X,
Vector &Y)
{
#ifdef MFEM_USE_OCCA
if (DeviceCanUseOcca())
{
if (dim == 2)
{
return OccaPAMassApply2D(D1D,Q1D,NE,B,Bt,D,X,Y);
}
if (dim == 3)
{
return OccaPAMassApply3D(D1D,Q1D,NE,B,Bt,D,X,Y);
}
MFEM_ABORT("OCCA PA Mass Apply unknown kernel!");
}
#endif // MFEM_USE_OCCA
const int id = (D1D << 4) | Q1D;
if (dim == 1)
{
return PAMassApply1D(NE,B,Bt,D,X,Y,D1D,Q1D);
}
else if (dim == 2)
{
switch (id)
{
case 0x22: return SmemPAMassApply2D<2,2,16>(NE,B,Bt,D,X,Y);
case 0x24: return SmemPAMassApply2D<2,4,16>(NE,B,Bt,D,X,Y);
case 0x33: return SmemPAMassApply2D<3,3,16>(NE,B,Bt,D,X,Y);
case 0x34: return SmemPAMassApply2D<3,4,16>(NE,B,Bt,D,X,Y);
case 0x35: return SmemPAMassApply2D<3,5,16>(NE,B,Bt,D,X,Y);
case 0x36: return SmemPAMassApply2D<3,6,16>(NE,B,Bt,D,X,Y);
case 0x44: return SmemPAMassApply2D<4,4,8>(NE,B,Bt,D,X,Y);
case 0x46: return SmemPAMassApply2D<4,6,8>(NE,B,Bt,D,X,Y);
case 0x48: return SmemPAMassApply2D<4,8,4>(NE,B,Bt,D,X,Y);
case 0x55: return SmemPAMassApply2D<5,5,8>(NE,B,Bt,D,X,Y);
case 0x57: return SmemPAMassApply2D<5,7,8>(NE,B,Bt,D,X,Y);
case 0x58: return SmemPAMassApply2D<5,8,2>(NE,B,Bt,D,X,Y);
case 0x66: return SmemPAMassApply2D<6,6,4>(NE,B,Bt,D,X,Y);
case 0x77: return SmemPAMassApply2D<7,7,4>(NE,B,Bt,D,X,Y);
case 0x88: return SmemPAMassApply2D<8,8,2>(NE,B,Bt,D,X,Y);
case 0x99: return SmemPAMassApply2D<9,9,2>(NE,B,Bt,D,X,Y);
default: return PAMassApply2D(NE,B,Bt,D,X,Y,D1D,Q1D);
}
}
else if (dim == 3)
{
switch (id)
{
case 0x22: return SmemPAMassApply3D<2,2>(NE,B,Bt,D,X,Y);
case 0x23: return SmemPAMassApply3D<2,3>(NE,B,Bt,D,X,Y);
case 0x24: return SmemPAMassApply3D<2,4>(NE,B,Bt,D,X,Y);
case 0x26: return SmemPAMassApply3D<2,6>(NE,B,Bt,D,X,Y);
case 0x34: return SmemPAMassApply3D<3,4>(NE,B,Bt,D,X,Y);
case 0x35: return SmemPAMassApply3D<3,5>(NE,B,Bt,D,X,Y);
case 0x36: return SmemPAMassApply3D<3,6>(NE,B,Bt,D,X,Y);
case 0x37: return SmemPAMassApply3D<3,7>(NE,B,Bt,D,X,Y);
case 0x45: return SmemPAMassApply3D<4,5>(NE,B,Bt,D,X,Y);
case 0x46: return SmemPAMassApply3D<4,6>(NE,B,Bt,D,X,Y);
case 0x48: return SmemPAMassApply3D<4,8>(NE,B,Bt,D,X,Y);
case 0x56: return SmemPAMassApply3D<5,6>(NE,B,Bt,D,X,Y);
case 0x58: return SmemPAMassApply3D<5,8>(NE,B,Bt,D,X,Y);
case 0x67: return SmemPAMassApply3D<6,7>(NE,B,Bt,D,X,Y);
case 0x78: return SmemPAMassApply3D<7,8>(NE,B,Bt,D,X,Y);
case 0x89: return SmemPAMassApply3D<8,9>(NE,B,Bt,D,X,Y);
case 0x9A: return SmemPAMassApply3D<9,10>(NE,B,Bt,D,X,Y);
default: return PAMassApply3D(NE,B,Bt,D,X,Y,D1D,Q1D);
}
}
mfem::out << "Unknown kernel 0x" << std::hex << id << std::endl;
MFEM_ABORT("Unknown kernel.");
}
} // namespace internal
} // namespace mfem
+149 -22
View File
@@ -25,11 +25,95 @@ namespace mfem
namespace internal
{
void PAMassAssembleDiagonal(const int dim, const int D1D,
const int Q1D, const int NE,
const Array<real_t> &B,
const Vector &D,
Vector &Y);
// PA Mass Diagonal 1D kernel
static void PAMassAssembleDiagonal1D(const int NE,
const Array<real_t> &b,
const Vector &d,
Vector &y,
const int D1D,
const int Q1D)
{
auto B = Reshape(b.Read(), Q1D, D1D);
auto D = Reshape(d.Read(), Q1D, NE);
auto Y = Reshape(y.ReadWrite(), D1D, NE);
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
for (int dx = 0; dx < D1D; ++dx)
{
for (int qx = 0; qx < Q1D; ++qx)
{
Y(dx, e) += B(qx, dx) * B(qx, dx) * D(qx, e);
}
}
});
}
MFEM_HOST_DEVICE inline
void PAMassApply1D_Element(const int e,
const int NE,
const real_t *b_,
const real_t *bt_,
const real_t *d_,
const real_t *x_,
real_t *y_,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = d1d;
const int Q1D = q1d;
auto B = ConstDeviceMatrix(b_, Q1D, D1D);
auto Bt = ConstDeviceMatrix(bt_, D1D, Q1D);
auto D = ConstDeviceMatrix(d_, Q1D, NE);
auto X = ConstDeviceMatrix(x_, D1D, NE);
auto Y = DeviceMatrix(y_, D1D, NE);
real_t XQ[DofQuadLimits::MAX_Q1D];
for (int qx = 0; qx < Q1D; ++qx)
{
XQ[qx] = 0.0;
}
for (int dx = 0; dx < D1D; ++dx)
{
const real_t s = X(dx,e);
for (int qx = 0; qx < Q1D; ++qx)
{
XQ[qx] += B(qx,dx)*s;
}
}
for (int qx = 0; qx < Q1D; ++qx)
{
const double q = XQ[qx]*D(qx,e);
for (int dx = 0; dx < D1D; ++dx)
{
Y(dx,e) += Bt(dx,qx) * q;
}
}
}
// PA Mass Apply 1D kernel
static void PAMassApply1D(const int NE,
const Array<real_t> &b_,
const Array<real_t> &bt_,
const Vector &d_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
{
MFEM_VERIFY(d1d <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(q1d <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
const auto B = b_.Read();
const auto Bt = bt_.Read();
const auto D = d_.Read();
const auto X = x_.Read();
auto Y = y_.ReadWrite();
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
internal::PAMassApply1D_Element(e, NE, B, Bt, D, X, Y, d1d, q1d);
});
}
// PA Mass Diagonal 2D kernel
template<int T_D1D = 0, int T_Q1D = 0>
@@ -78,8 +162,18 @@ inline void PAMassAssembleDiagonal2D(const int NE,
});
}
namespace mass
{
constexpr int ipow(int x, int p) { return p == 0 ? 1 : x*ipow(x, p-1); }
constexpr int D(int D1D) { return (11 - D1D) / 2; }
constexpr int NBZ(int D1D)
{
return ipow(2, D(D1D) >= 0 ? D(D1D) : 0);
}
}
// Shared memory PA Mass Diagonal 2D kernel
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0>
template<int T_D1D = 0, int T_Q1D = 0>
inline void SmemPAMassAssembleDiagonal2D(const int NE,
const Array<real_t> &b_,
const Vector &d_,
@@ -87,9 +181,10 @@ inline void SmemPAMassAssembleDiagonal2D(const int NE,
const int d1d = 0,
const int q1d = 0)
{
static constexpr int T_NBZ = mass::NBZ(T_D1D);
static constexpr int NBZ = T_NBZ ? T_NBZ : 1;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
const int max_q1d = T_Q1D ? T_Q1D : DeviceDofQuadLimits::Get().MAX_Q1D;
const int max_d1d = T_D1D ? T_D1D : DeviceDofQuadLimits::Get().MAX_D1D;
MFEM_VERIFY(D1D <= max_d1d, "");
@@ -102,7 +197,6 @@ inline void SmemPAMassAssembleDiagonal2D(const int NE,
const int tidz = MFEM_THREAD_ID(z);
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
MFEM_SHARED real_t B[MQ1][MD1];
@@ -302,16 +396,6 @@ inline void SmemPAMassAssembleDiagonal3D(const int NE,
});
}
void PAMassApply(const int dim,
const int D1D,
const int Q1D,
const int NE,
const Array<real_t> &B,
const Array<real_t> &Bt,
const Vector &D,
const Vector &X,
Vector &Y);
#ifdef MFEM_USE_OCCA
// OCCA PA Mass Apply 2D kernel
void OccaPAMassApply2D(const int D1D,
@@ -964,7 +1048,7 @@ inline void PAMassApply2D(const int NE,
}
// Shared memory PA Mass Apply 2D kernel
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0>
template<int T_D1D = 0, int T_Q1D = 0>
inline void SmemPAMassApply2D(const int NE,
const Array<real_t> &b_,
const Array<real_t> &bt_,
@@ -975,9 +1059,10 @@ inline void SmemPAMassApply2D(const int NE,
const int q1d = 0)
{
MFEM_CONTRACT_VAR(bt_);
static constexpr int T_NBZ = mass::NBZ(T_D1D);
static constexpr int NBZ = T_NBZ ? T_NBZ : 1;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
const int max_q1d = T_Q1D ? T_Q1D : DeviceDofQuadLimits::Get().MAX_Q1D;
const int max_d1d = T_D1D ? T_D1D : DeviceDofQuadLimits::Get().MAX_D1D;
MFEM_VERIFY(D1D <= max_d1d, "");
@@ -988,8 +1073,8 @@ inline void SmemPAMassApply2D(const int NE,
auto Y = y_.ReadWrite();
mfem::forall_2D_batch(NE, Q1D, Q1D, NBZ, [=] MFEM_HOST_DEVICE (int e)
{
internal::SmemPAMassApply2D_Element<T_D1D,T_Q1D,T_NBZ>(e, NE, b, D, x, Y, d1d,
q1d);
internal::SmemPAMassApply2D_Element<T_D1D,T_Q1D,T_NBZ>(
e, NE, b, D, x, Y, d1d, q1d);
});
}
@@ -1049,6 +1134,48 @@ inline void SmemPAMassApply3D(const int NE,
} // namespace internal
namespace
{
using ApplyKernelType = MassIntegrator::ApplyKernelType;
using DiagonalKernelType = MassIntegrator::DiagonalKernelType;
}
template<int DIM, int T_D1D, int T_Q1D>
ApplyKernelType MassIntegrator::ApplyPAKernels::Kernel()
{
if (DIM == 1) { return internal::PAMassApply1D; }
else if (DIM == 2) { return internal::SmemPAMassApply2D<T_D1D,T_Q1D>; }
else if (DIM == 3) { return internal::SmemPAMassApply3D<T_D1D, T_Q1D>; }
else { MFEM_ABORT(""); }
}
inline ApplyKernelType MassIntegrator::ApplyPAKernels::Fallback(
int DIM, int, int)
{
if (DIM == 1) { return internal::PAMassApply1D; }
else if (DIM == 2) { return internal::PAMassApply2D; }
else if (DIM == 3) { return internal::PAMassApply3D; }
else { MFEM_ABORT(""); }
}
template<int DIM, int T_D1D, int T_Q1D>
DiagonalKernelType MassIntegrator::DiagonalPAKernels::Kernel()
{
if (DIM == 1) { return internal::PAMassAssembleDiagonal1D; }
else if (DIM == 2) { return internal::SmemPAMassAssembleDiagonal2D<T_D1D,T_Q1D>; }
else if (DIM == 3) { return internal::SmemPAMassAssembleDiagonal3D<T_D1D, T_Q1D>; }
else { MFEM_ABORT(""); }
}
inline DiagonalKernelType MassIntegrator::DiagonalPAKernels::Fallback(
int DIM, int, int)
{
if (DIM == 1) { return internal::PAMassAssembleDiagonal1D; }
else if (DIM == 2) { return internal::PAMassAssembleDiagonal2D; }
else if (DIM == 3) { return internal::PAMassAssembleDiagonal3D; }
else { MFEM_ABORT(""); }
}
} // namespace mfem
#endif
+24 -4
View File
@@ -19,6 +19,8 @@
namespace mfem
{
// PA Mass Integrator
void MassIntegrator::AssemblePA(const FiniteElementSpace &fes)
{
const MemoryType mt = (pa_mt == MemoryType::DEFAULT) ?
@@ -195,8 +197,8 @@ void MassIntegrator::AssembleDiagonalPA(Vector &diag)
}
else
{
internal::PAMassAssembleDiagonal(dim, dofs1D, quad1D, ne, maps->B, pa_data,
diag);
DiagonalPAKernels::Run(dim, dofs1D, quad1D, ne, maps->B, pa_data,
diag, dofs1D, quad1D);
}
}
@@ -208,8 +210,26 @@ void MassIntegrator::AddMultPA(const Vector &x, Vector &y) const
}
else
{
internal::PAMassApply(dim, dofs1D, quad1D, ne, maps->B, maps->Bt, pa_data, x,
y);
const int D1D = dofs1D;
const int Q1D = quad1D;
const Array<real_t> &B = maps->B;
const Array<real_t> &Bt = maps->Bt;
const Vector &D = pa_data;
#ifdef MFEM_USE_OCCA
if (DeviceCanUseOcca())
{
if (dim == 2)
{
return internal::OccaPAMassApply2D(D1D,Q1D,ne,B,Bt,D,x,y);
}
if (dim == 3)
{
return internal::OccaPAMassApply3D(D1D,Q1D,ne,B,Bt,D,x,y);
}
MFEM_ABORT("OCCA PA Mass Apply unknown kernel!");
}
#endif // MFEM_USE_OCCA
ApplyPAKernels::Run(dim, D1D, Q1D, ne, B, Bt, D, x, y, D1D, Q1D);
}
}
+166
View File
@@ -31,6 +31,172 @@ void CutIntegrationRules::SetLevelSetProjectionOrder(int order)
lsOrder = order;
}
#ifdef MFEM_USE_ALGOIM
void AlgoimIntegrationRules::GetSurfaceIntegrationRule(ElementTransformation
&Tr,
IntegrationRule &result)
{
GenerateLSVector(Tr,LvlSet);
const int dim=pe->GetDim();
int np1d=CutIntegrationRules::Order/2+1;
if (dim==2)
{
LevelSet2D ls(pe,lsvec);
auto q = Algoim::quadGen<2>(ls,Algoim::BoundingBox<real_t,2>(0.0,1.0),
2, -1, np1d);
result.SetSize(q.nodes.size());
result.SetOrder(CutIntegrationRules::Order);
for (size_t i=0; i<q.nodes.size(); i++)
{
IntegrationPoint& ip=result.IntPoint(i);
ip.Set2w(q.nodes[i].x(0),q.nodes[i].x(1),q.nodes[i].w);
}
}
else
{
LevelSet3D ls(pe,lsvec);
auto q = Algoim::quadGen<3>(ls,Algoim::BoundingBox<real_t,3>(0.0,1.0),
3, -1, np1d);
result.SetSize(q.nodes.size());
result.SetOrder(CutIntegrationRules::Order);
for (size_t i=0; i<q.nodes.size(); i++)
{
IntegrationPoint& ip=result.IntPoint(i);
ip.Set(q.nodes[i].x(0),q.nodes[i].x(1),q.nodes[i].x(2),q.nodes[i].w);
}
}
}
void AlgoimIntegrationRules::GetVolumeIntegrationRule(ElementTransformation &Tr,
IntegrationRule &result,
const IntegrationRule *sir)
{
GenerateLSVector(Tr,LvlSet);
const int dim=pe->GetDim();
int np1d=CutIntegrationRules::Order/2+1;
if (dim==2)
{
LevelSet2D ls(pe,lsvec);
auto q = Algoim::quadGen<2>(ls,Algoim::BoundingBox<real_t,2>(0.0,1.0),
-1, -1, np1d);
result.SetSize(q.nodes.size());
result.SetOrder(CutIntegrationRules::Order);
for (size_t i=0; i<q.nodes.size(); i++)
{
IntegrationPoint& ip=result.IntPoint(i);
ip.Set2w(q.nodes[i].x(0),q.nodes[i].x(1),q.nodes[i].w);
}
}
else
{
LevelSet3D ls(pe,lsvec);
auto q = Algoim::quadGen<3>(ls,Algoim::BoundingBox<real_t,3>(0.0,1.0),
-1, -1, np1d);
result.SetSize(q.nodes.size());
result.SetOrder(CutIntegrationRules::Order);
for (size_t i=0; i<q.nodes.size(); i++)
{
IntegrationPoint& ip=result.IntPoint(i);
ip.Set(q.nodes[i].x(0),q.nodes[i].x(1),q.nodes[i].x(2),q.nodes[i].w);
}
}
}
void AlgoimIntegrationRules::GetSurfaceWeights(ElementTransformation &Tr,
const IntegrationRule &sir,
Vector &weights)
{
GenerateLSVector(Tr,LvlSet);
DenseMatrix bmat; // gradients of the shape functions in isoparametric space
DenseMatrix pmat; // gradients of the shape functions in physical space
Vector inormal; // normal to the level set in isoparametric space
Vector tnormal; // normal to the level set in physical space
bmat.SetSize(pe->GetDof(),pe->GetDim());
pmat.SetSize(pe->GetDof(),pe->GetDim());
inormal.SetSize(pe->GetDim());
tnormal.SetSize(pe->GetDim());
weights.SetSize(sir.GetNPoints());
for (int j = 0; j < sir.GetNPoints(); j++)
{
const IntegrationPoint &ip = sir.IntPoint(j);
Tr.SetIntPoint(&ip);
pe->CalcDShape(ip,bmat);
Mult(bmat, Tr.InverseJacobian(), pmat);
// compute the normal to the LS in isoparametric space
bmat.MultTranspose(lsvec,inormal);
// compute the normal to the LS in physical space
pmat.MultTranspose(lsvec,tnormal);
weights[j]= tnormal.Norml2() / inormal.Norml2();
}
}
void AlgoimIntegrationRules::GenerateLSVector(ElementTransformation &Tr,
Coefficient* lvlset)
{
//check if the coefficient is already projected
if (currentElementNo==Tr.ElementNo)
{
if (currentLvlSet==lvlset)
{
if (currentGeometry==Tr.GetGeometryType())
{
return;
}
}
}
currentElementNo=Tr.ElementNo;
if (currentGeometry!=Tr.GetGeometryType())
{
delete le;
delete pe;
currentGeometry=Tr.GetGeometryType();
if (Tr.GetGeometryType()==Geometry::Type::SQUARE)
{
pe=new H1Pos_QuadrilateralElement(lsOrder);
le=new H1_QuadrilateralElement(lsOrder);
}
else if (Tr.GetGeometryType()==Geometry::Type::CUBE)
{
pe=new H1Pos_HexahedronElement(lsOrder);
le=new H1_HexahedronElement(lsOrder);
}
else
{
MFEM_ABORT("Currently MFEM + Algoim supports only quads and hexes.");
}
T.SetSize(pe->GetDof());
pe->Project(*le,Tr,T);
//The transformation matrix depends only on the geometry for change of basis
}
currentLvlSet=lvlset;
const IntegrationRule &ir=le->GetNodes();
lsvec.SetSize(ir.GetNPoints());
lsfun.SetSize(ir.GetNPoints());
for (int i=0; i<ir.GetNPoints(); i++)
{
const IntegrationPoint &ip = ir.IntPoint(i);
Tr.SetIntPoint(&ip);
lsfun(i)=lvlset->Eval(Tr,ip);
}
T.Mult(lsfun,lsvec);
}
#endif
#ifdef MFEM_USE_LAPACK
void MomentFittingIntRules::InitSurface(int order, Coefficient& levelset,
+353
View File
@@ -18,6 +18,16 @@
#include "eltrans.hpp"
#include "coefficient.hpp"
#ifdef MFEM_USE_ALGOIM
#ifdef MFEM_HAVE_GCC_PRAGMA_DIAGNOSTIC
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#include <algoim_quad.hpp>
#pragma GCC diagnostic pop
#endif
namespace mfem
{
/**
@@ -116,6 +126,349 @@ public:
virtual ~CutIntegrationRules() {}
};
#ifdef MFEM_USE_ALGOIM
// define templated element bases
namespace TmplPoly_1D
{
/// Templated version of CalcBinomTerms
template<typename float_type>
void CalcBinomTerms(const int p, const float_type x, const float_type y,
float_type* u)
{
if (p == 0)
{
u[0] = float_type(1.);
}
else
{
int i;
const int *b = Poly_1D::Binom(p);
float_type z = x;
for (i = 1; i < p; i++)
{
u[i] = b[i]*z;
z *= x;
}
u[p] = z;
z = y;
for (i--; i > 0; i--)
{
u[i] *= z;
z *= y;
}
u[0] = z;
}
}
/// Templated version of CalcBinomTerms
template<typename float_type>
void CalcBinomTerms(const int p, const float_type x, const float_type y,
float_type* u, float_type* d)
{
if (p == 0)
{
u[0] = float_type(1.);
d[0] = float_type(0.);
}
else
{
int i;
const int *b = Poly_1D::Binom(p);
const float_type xpy = x + y, ptx = p*x;
float_type z = float_type(1.);
for (i = 1; i < p; i++)
{
d[i] = b[i]*z*(i*xpy - ptx);
z *= x;
u[i] = b[i]*z;
}
d[p] = p*z;
u[p] = z*x;
z = float_type(1.);
for (i--; i > 0; i--)
{
d[i] *= z;
z *= y;
u[i] *= z;
}
d[0] = -p*z;
u[0] = z*y;
}
}
/// Templated evaluation of Bernstein basis
template <typename float_type>
void CalcBernstein(const int p, const float_type x, float_type *u)
{
CalcBinomTerms(p, x, 1. - x, u);
}
/// Templated evaluation of Bernstein basis
template <typename float_type>
void CalcBernstein(const int p, const float_type x,
float_type *u, float_type *d)
{
CalcBinomTerms(p, x, 1. - x, u, d);
}
}
class AlgoimIntegrationRules : public CutIntegrationRules
{
public:
/** @brief Constructor to set up the generated cut IntegrationRules.
@param [in] order Order of the constructed IntegrationRule.
@param [in] lvlset Coefficient whose zero level set specifies the cut.
@param [in] lsO Polynomial degree for projecting the level-set
Coefficient to a GridFunction, which is used to
compute gradients and normals. */
AlgoimIntegrationRules(int order, Coefficient &lvlset, int lsO = 2)
: CutIntegrationRules(order, lvlset, lsO)
{
pe=nullptr;
le=nullptr;
currentLvlSet=nullptr;
currentGeometry=Geometry::Type::INVALID;
currentElementNo = -1;
}
virtual ~AlgoimIntegrationRules()
{
delete pe;
delete le;
}
virtual void SetOrder(int order) override
{
MFEM_VERIFY(order > 0, "Invalid input");
Order = order;
delete pe;
delete le;
pe=nullptr;
le=nullptr;
currentLvlSet=nullptr;
currentGeometry=Geometry::Type::INVALID;
currentElementNo=-1;
}
virtual void SetLevelSetProjectionOrder(int order) override
{
MFEM_VERIFY(order > 0, "Invalid input");
lsOrder = order;
delete pe;
delete le;
pe=nullptr;
le=nullptr;
currentLvlSet=nullptr;
currentGeometry=Geometry::Type::INVALID;
currentElementNo=-1;
}
/**
@brief Construct a cut-surface IntegrationRule.
Construct an IntegrationRule to integrate on the surface given by the
already specified level set function, for the element given by @a Tr.
@param [in] Tr Specifies the IntegrationRule's associated mesh element.
@param [out] result IntegrationRule on the cut-surface
*/
virtual
void GetSurfaceIntegrationRule(ElementTransformation &Tr,
IntegrationRule &result) override;
/**
@brief Construct a cut-volume IntegrationRule.
Construct an IntegrationRule to integrate in the subdomain given by the
positive values of the already specified level set function, for the element
given by @a Tr.
@param [in] Tr Specifies the IntegrationRule's associated mesh element.
@param [out] result IntegrationRule for the cut-volume
@param [in] sir Corresponding IntegrationRule for the surface, which can
be used to avoid computations.
*/
virtual
void GetVolumeIntegrationRule(ElementTransformation &Tr,
IntegrationRule &result,
const IntegrationRule *sir = nullptr) override;
/**
@brief Compute transformation quadrature weights for surface integration.
Compute the transformation weights for integration over the cut-surface in
reference space.
@param [in] Tr Specifies the IntegrationRule's associated element.
@param [in] sir IntegrationRule defining the IntegrationPoints
@param [out] weights Vector containing the transformation weights.
*/
virtual
void GetSurfaceWeights(ElementTransformation &Tr,
const IntegrationRule &sir,
Vector &weights) override;
private:
/// projects the lvlset coefficient onto the lsvec,
/// i.e., represent the level-set using Bernstein bases
void GenerateLSVector(ElementTransformation &Tr, Coefficient* lvlset);
/// Lagrange finite element used for converting coefficients to positive basis
FiniteElement* le;
PositiveTensorFiniteElement *pe;
DenseMatrix T; //Projection matrix from nodal basis to positive basis
Vector lsvec; // level-set in Bernstein basis
Vector lsfun; // level-set in nodal basis
Geometry::Type currentGeometry; // the current element geometry
Coefficient* currentLvlSet; //the current level-set coefficient
int currentElementNo; //the current element No
/// 3D level-set function object required by Algoim.
struct LevelSet3D
{
/// Constructor for 3D level-set function object required by Algoim.
LevelSet3D(PositiveTensorFiniteElement* el_, Vector& lsfun_)
: el(el_), lsfun(lsfun_) { }
/// Returns the value of the LSF for point x.
template<typename T>
T operator() (const blitz::TinyVector<T,3>& x) const
{
int el_order=el->GetOrder();
T u1[el_order+1];
T u2[el_order+1];
T u3[el_order+1];
TmplPoly_1D::CalcBernstein(el_order, x[0], u1);
TmplPoly_1D::CalcBernstein(el_order, x[1], u2);
TmplPoly_1D::CalcBernstein(el_order, x[2], u3);
const Array<int>& dof_map=el->GetDofMap();
T res=T(0.0);
for (int oo = 0, kk = 0; kk <= el_order; kk++)
for (int jj = 0; jj <= el_order; jj++)
for (int ii = 0; ii <= el_order; ii++)
{
res=res-u1[ii]*u2[jj]*u3[kk]*lsfun(dof_map[oo++]);
}
return res;
}
/// Returns the gradients of the LSF for point x.
template<typename T>
blitz::TinyVector<T,3> grad(const blitz::TinyVector<T,3>& x) const
{
int el_order=el->GetOrder();
T u1[el_order+1];
T u2[el_order+1];
T u3[el_order+1];
T d1[el_order+1];
T d2[el_order+1];
T d3[el_order+1];
TmplPoly_1D::CalcBernstein(el_order,x[0], u1, d1);
TmplPoly_1D::CalcBernstein(el_order,x[1], u2, d2);
TmplPoly_1D::CalcBernstein(el_order,x[2], u3, d3);
blitz::TinyVector<T,3> res(T(0.0),T(0.0),T(0.0));
const Array<int>& dof_map=el->GetDofMap();
for (int oo = 0, kk = 0; kk <= el_order; kk++)
for (int jj = 0; jj <= el_order; jj++)
for (int ii = 0; ii <= el_order; ii++)
{
res[0]=res[0]-d1[ii]*u2[jj]*u3[kk]*lsfun(dof_map[oo]);
res[1]=res[1]-u1[ii]*d2[jj]*u3[kk]*lsfun(dof_map[oo]);
res[2]=res[2]-u1[ii]*u2[jj]*d3[kk]*lsfun(dof_map[oo]);
oo++;
}
return res;
}
private:
PositiveTensorFiniteElement* el;
Vector& lsfun;
};
/// 2D level-set function object required by Algoim.
struct LevelSet2D
{
/// Constructor for 2D level-set function object required by Algoim.
LevelSet2D(PositiveTensorFiniteElement* el_, Vector& lsfun_)
:el(el_), lsfun(lsfun_) { }
/// Returns the value of the LSF for point x.
template<typename T>
T operator() (const blitz::TinyVector<T,2>& x) const
{
int el_order=el->GetOrder();
T u1[el_order+1];
T u2[el_order+1];
TmplPoly_1D::CalcBernstein(el_order, x[0], u1);
TmplPoly_1D::CalcBernstein(el_order, x[1], u2);
const Array<int>& dof_map=el->GetDofMap();
T res=T(0.0);
for (int oo = 0, jj = 0; jj <= el_order; jj++)
for (int ii = 0; ii <= el_order; ii++)
{
res=res-u1[ii]*u2[jj]*lsfun(dof_map[oo++]);
}
return res;
}
/// Returns the gradients of the LSF for point x.
template<typename T>
blitz::TinyVector<T,2> grad(const blitz::TinyVector<T,2>& x) const
{
int el_order=el->GetOrder();
T u1[el_order+1];
T u2[el_order+1];
T d1[el_order+1];
T d2[el_order+1];
TmplPoly_1D::CalcBernstein(el_order,x[0], u1, d1);
TmplPoly_1D::CalcBernstein(el_order,x[1], u2, d2);
blitz::TinyVector<T,2> res(T(0.0),T(0.0));
const Array<int>& dof_map=el->GetDofMap();
for (int oo = 0, jj = 0; jj <= el_order; jj++)
for (int ii = 0; ii <= el_order; ii++)
{
res[0]=res[0]-(d1[ii]*u2[jj])*lsfun(dof_map[oo]);
res[1]=res[1]-(u1[ii]*d2[jj])*lsfun(dof_map[oo]);
oo++;
}
return res;
}
private:
PositiveTensorFiniteElement* el;
Vector& lsfun;
};
};
#endif //MFEM_USE_ALGOIM
#ifdef MFEM_USE_LAPACK
/**
+2 -4
View File
@@ -160,16 +160,14 @@ public:
/// bigger value. A node in the target grid function is matching
/// a point with coordinates specified in the vector coords if the
/// distance between them is smaller than lerr.
virtual
void Project(const Vector& coords,const Vector& src,
int ordering=Ordering::byNODES, real_t lerr=1e-8);
int ordering=Ordering::byNODES, real_t lerr=1e-8) override;
/// The project method can be called as many times as necessary with
/// different grid functions gf. A node in the target grid function is
/// matching a node from the source grid function if the distance
/// between them is smaller than lerr.
virtual
void Project(const GridFunction& gf, real_t lerr=1e-8);
void Project(const GridFunction& gf, real_t lerr=1e-8) override;
};
} // namespace mfem
+189
View File
@@ -0,0 +1,189 @@
// Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.
#ifndef MFEM_KERNEL_DISPATCH_HPP
#define MFEM_KERNEL_DISPATCH_HPP
#include "../config/config.hpp"
#include "kernel_reporter.hpp"
#include <unordered_map>
#include <tuple>
#include <cstddef>
namespace mfem
{
// The MFEM_REGISTER_KERNELS macro registers kernels for runtime dispatch using
// a dispatch map.
//
// This creates a dispatch table (a static member variable) named @a KernelName
// containing function points of type @a KernelType. These are followed by one
// or two sets of parenthesized argument types.
//
// The first set of argument types contains the types that are used to dispatch
// to either specialized or fallback kernels. The second set of argument types
// can be used to further specialize the kernel without participating in
// dispatch (a canonical example is NBZ, determining the size of the thread
// blocks; this is required to specialize kernels for optimal performance, but
// is not relevant for dispatch).
//
// After calling this macro, the user must implement the Kernel and Fallback
// static member functions, which return pointers to the appropriate kernel
// functions depending on the parameters.
//
// Specialized functions can be registered using the static AddSpecialization
// member function.
#define MFEM_EXPAND(X) X // Workaround needed for MSVC compiler
#define MFEM_REGISTER_KERNELS(KernelName, KernelType, ...) \
MFEM_EXPAND(MFEM_EXPAND(MFEM_REGISTER_KERNELS_N(__VA_ARGS__,2,1,)) \
(KernelName,KernelType,__VA_ARGS__))
#define MFEM_REGISTER_KERNELS_N(_1, _2, N, ...) MFEM_REGISTER_KERNELS_##N
// Expands a variable length macro parameter so that multiple variable length
// parameters can be passed to the same macro.
#define MFEM_PARAM_LIST(...) __VA_ARGS__
// Version of MFEM_REGISTER_KERNELS without any "optional" (non-dispatch)
// parameters.
#define MFEM_REGISTER_KERNELS_1(KernelName, KernelType, Params) \
MFEM_REGISTER_KERNELS_(KernelName, KernelType, Params, (), Params)
// Version of MFEM_REGISTER_KERNELS without any optional (non-dispatch)
// parameters (e.g. NBZ).
#define MFEM_REGISTER_KERNELS_2(KernelName, KernelType, Params, OptParams) \
MFEM_REGISTER_KERNELS_(KernelName, KernelType, Params, OptParams, \
(MFEM_PARAM_LIST Params, MFEM_PARAM_LIST OptParams))
// P1 are the parameters, P2 are the optional (non-dispatch parameters), and P3
// is the concatenation of P1 and P2. We need to pass it as a separate argument
// to avoid a trailing comma in the case that P2 is empty.
#define MFEM_REGISTER_KERNELS_(KernelName, KernelType, P1, P2, P3) \
class KernelName : public \
KernelDispatchTable<KernelName, KernelType, \
internal::KernelTypeList<MFEM_PARAM_LIST P1>, \
internal::KernelTypeList<MFEM_PARAM_LIST P2>> \
{ \
public: \
const char *kernel_name = MFEM_KERNEL_NAME(KernelName); \
using KernelSignature = KernelType; \
template <MFEM_PARAM_LIST P3> \
static MFEM_EXPORT KernelSignature Kernel(); \
static MFEM_EXPORT KernelSignature Fallback(MFEM_PARAM_LIST P1); \
static MFEM_EXPORT KernelName &Get() \
{ static KernelName table; return table;} \
}
/// @brief Hashes variadic packs for which each type contained in the variadic
/// pack has a specialization of `std::hash` available.
///
/// For example, packs containing int, bool, enum values, etc.
template<typename ...KernelParameters>
struct KernelDispatchKeyHash
{
private:
template<int N>
size_t operator()(std::tuple<KernelParameters...> value) const { return 0; }
// The hashing formula here is taken directly from the Boost library, with
// the magic number 0x9e3779b9 chosen to minimize hashing collisions.
template<std::size_t N, typename THead, typename... TTail>
size_t operator()(std::tuple<KernelParameters...> value) const
{
constexpr int Index = N - sizeof...(TTail) - 1;
auto lhs_hash = std::hash<THead>()(std::get<Index>(value));
auto rhs_hash = operator()<N, TTail...>(value);
return lhs_hash^(rhs_hash + 0x9e3779b9 + (lhs_hash<<6) + (lhs_hash>>2));
}
public:
/// Returns the hash of the given @a value.
size_t operator()(std::tuple<KernelParameters...> value) const
{
return operator()<sizeof...(KernelParameters),KernelParameters...>(value);
}
};
namespace internal { template<typename... Types> struct KernelTypeList { }; }
template<typename... T> class KernelDispatchTable { };
template <typename Kernels,
typename Signature,
typename... Params,
typename... OptParams>
class KernelDispatchTable<Kernels,
Signature,
internal::KernelTypeList<Params...>,
internal::KernelTypeList<OptParams...>>
{
using TableType = std::unordered_map<std::tuple<Params...>,
Signature, KernelDispatchKeyHash<Params...>>;
TableType table;
public:
/// @brief Run the kernel with the given dispatch parameters and arguments.
///
/// If a compile-time specialized version of the kernel with the given
/// parameters has been registered, it will be called. Otherwise, the
/// fallback kernel will be called.
template<typename... Args>
static void Run(Params... params, Args&&... args)
{
const auto &table = Kernels::Get().table;
const std::tuple<Params...> key = std::make_tuple(params...);
const auto it = table.find(key);
if (it != table.end())
{
it->second(std::forward<Args>(args)...);
}
else
{
KernelReporter::ReportFallback(Kernels::Get().kernel_name, params...);
Kernels::Fallback(params...)(std::forward<Args>(args)...);
}
}
/// Register a specialized kernel for dispatch.
template <Params... PARAMS>
struct Specialization
{
// Version without optional parameters
static void Add()
{
std::tuple<Params...> param_tuple(PARAMS...);
Kernels::Get().table[param_tuple] =
Kernels:: template Kernel<PARAMS..., OptParams{}...>();
};
// Version with optional parameters
template <OptParams... OPT_PARAMS>
struct Opt
{
static void Add()
{
std::tuple<Params...> param_tuple(PARAMS...);
Kernels::Get().table[param_tuple] =
Kernels:: template Kernel<PARAMS..., OPT_PARAMS...>();
}
};
};
/// Return the dispatch map table
static const TableType &GetDispatchTable()
{
return Kernels::Get().table;
}
};
}
#endif
+102
View File
@@ -0,0 +1,102 @@
// Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.
#ifndef MFEM_KERNEL_REPORTER_HPP
#define MFEM_KERNEL_REPORTER_HPP
#include "../general/globals.hpp"
#include <set>
#include <sstream>
#include <string>
#define MFEM_STR_(X) #X
#define MFEM_STR(X) MFEM_STR_(X)
#define MFEM_KERNEL_NAME(KernelName) \
__FILE__ ":" MFEM_STR(__LINE__) " : " #KernelName
namespace mfem
{
namespace internal
{
template <typename Last>
static void Stringify_(std::ostream &o, Last &&arg)
{
o << arg;
}
template <typename T1, typename T2, typename... Rest>
static void Stringify_(std::ostream &o, T1 &&a1, T2 &&a2, Rest&&... rest)
{
o << int(a1) << ",";
Stringify_(o, a2, rest...);
}
template <typename... Args>
static std::string Stringify(Args&&... args)
{
std::stringstream o;
Stringify_(o, args...);
return o.str();
}
} // namespace
/// @brief Singleton class to report fallback kernels.
///
/// Writes the first call to a fallback kernel to mfem::err
///
/// @note This class is only enabled when the environment variable
/// MFEM_REPORT_KERNELS is set to a value other than 'NO' or if
/// KernelReporter::Enable() is called.
class KernelReporter
{
bool enabled = false;
std::set<std::string> reported_fallbacks;
KernelReporter()
{
const char *env = getenv("MFEM_REPORT_KERNELS");
if (env)
{
if (std::string(env) != "NO") { enabled = true; }
}
}
static KernelReporter &Instance()
{
static KernelReporter instance;
return instance;
}
public:
/// Enable reporting of fallback kernels.
static void Enable() { Instance().enabled = true; }
/// Disable reporting of fallback kernels.
static void Disable() { Instance().enabled = false; }
/// Report the fallback kernel with given parameters.
template <typename... Params>
static void ReportFallback(const std::string &kernel_name, Params&&... params)
{
if (!Instance().enabled) { return; }
auto &reported_fallbacks = Instance().reported_fallbacks;
const std::string requested_kernel =
kernel_name + "<" + internal::Stringify(params...) + ">";
if (reported_fallbacks.find(requested_kernel) == reported_fallbacks.end())
{
reported_fallbacks.insert(requested_kernel);
mfem::err << "Fallback kernel. Requested "
<< requested_kernel << std::endl;
}
}
};
} // namespace mfem
#endif
+130 -130
View File
@@ -121,22 +121,22 @@ public:
DomainLFIntegrator(Coefficient &QF, const IntegrationRule *ir)
: DeltaLFIntegrator(QF, ir), Q(QF), oa(1), ob(1) { }
virtual bool SupportsDevice() const { return true; }
bool SupportsDevice() const override { return true; }
/// Method defining assembly on device
virtual void AssembleDevice(const FiniteElementSpace &fes,
const Array<int> &markers,
Vector &b);
void AssembleDevice(const FiniteElementSpace &fes,
const Array<int> &markers,
Vector &b) override;
/** Given a particular Finite Element and a transformation (Tr)
computes the element right hand side element vector, elvect. */
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect);
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override;
virtual void AssembleDeltaElementVect(const FiniteElement &fe,
ElementTransformation &Trans,
Vector &elvect);
void AssembleDeltaElementVect(const FiniteElement &fe,
ElementTransformation &Trans,
Vector &elvect) override;
using LinearFormIntegrator::AssembleRHSElementVect;
};
@@ -154,22 +154,22 @@ public:
DomainLFGradIntegrator(VectorCoefficient &QF)
: DeltaLFIntegrator(QF), Q(QF) { }
virtual bool SupportsDevice() const { return true; }
bool SupportsDevice() const override { return true; }
/// Method defining assembly on device
virtual void AssembleDevice(const FiniteElementSpace &fes,
const Array<int> &markers,
Vector &b);
void AssembleDevice(const FiniteElementSpace &fes,
const Array<int> &markers,
Vector &b) override;
/** Given a particular Finite Element and a transformation (Tr)
computes the element right hand side element vector, elvect. */
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect);
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override;
virtual void AssembleDeltaElementVect(const FiniteElement &fe,
ElementTransformation &Trans,
Vector &elvect);
void AssembleDeltaElementVect(const FiniteElement &fe,
ElementTransformation &Trans,
Vector &elvect) override;
using LinearFormIntegrator::AssembleRHSElementVect;
};
@@ -187,21 +187,21 @@ public:
BoundaryLFIntegrator(Coefficient &QG, int a = 1, int b = 1)
: Q(QG), oa(a), ob(b) { }
virtual bool SupportsDevice() const { return true; }
bool SupportsDevice() const override { return true; }
/// Method defining assembly on device
virtual void AssembleDevice(const FiniteElementSpace &fes,
const Array<int> &markers,
Vector &b);
void AssembleDevice(const FiniteElementSpace &fes,
const Array<int> &markers,
Vector &b) override;
/** Given a particular boundary Finite Element and a transformation (Tr)
computes the element boundary vector, elvect. */
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect);
virtual void AssembleRHSElementVect(const FiniteElement &el,
FaceElementTransformations &Tr,
Vector &elvect);
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override;
void AssembleRHSElementVect(const FiniteElement &el,
FaceElementTransformations &Tr,
Vector &elvect) override;
using LinearFormIntegrator::AssembleRHSElementVect;
};
@@ -217,16 +217,16 @@ public:
BoundaryNormalLFIntegrator(VectorCoefficient &QG, int a = 1, int b = 1)
: Q(QG), oa(a), ob(b) { }
virtual bool SupportsDevice() const { return true; }
bool SupportsDevice() const override { return true; }
/// Method defining assembly on device
virtual void AssembleDevice(const FiniteElementSpace &fes,
const Array<int> &markers,
Vector &b);
void AssembleDevice(const FiniteElementSpace &fes,
const Array<int> &markers,
Vector &b) override;
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect);
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override;
using LinearFormIntegrator::AssembleRHSElementVect;
};
@@ -242,9 +242,9 @@ public:
BoundaryTangentialLFIntegrator(VectorCoefficient &QG, int a = 1, int b = 1)
: Q(QG), oa(a), ob(b) { }
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect);
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override;
using LinearFormIntegrator::AssembleRHSElementVect;
};
@@ -262,22 +262,22 @@ public:
VectorDomainLFIntegrator(VectorCoefficient &QF)
: DeltaLFIntegrator(QF), Q(QF) { }
virtual bool SupportsDevice() const { return true; }
bool SupportsDevice() const override { return true; }
/// Method defining assembly on device
virtual void AssembleDevice(const FiniteElementSpace &fes,
const Array<int> &markers,
Vector &b);
void AssembleDevice(const FiniteElementSpace &fes,
const Array<int> &markers,
Vector &b) override;
/** Given a particular Finite Element and a transformation (Tr)
computes the element right hand side element vector, elvect. */
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect);
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override;
virtual void AssembleDeltaElementVect(const FiniteElement &fe,
ElementTransformation &Trans,
Vector &elvect);
void AssembleDeltaElementVect(const FiniteElement &fe,
ElementTransformation &Trans,
Vector &elvect) override;
using LinearFormIntegrator::AssembleRHSElementVect;
};
@@ -296,22 +296,22 @@ public:
VectorDomainLFGradIntegrator(VectorCoefficient &QF)
: DeltaLFIntegrator(QF), Q(QF) { }
virtual bool SupportsDevice() const override { return true; }
bool SupportsDevice() const override { return true; }
/// Method defining assembly on device
virtual void AssembleDevice(const FiniteElementSpace &fes,
const Array<int> &markers,
Vector &b) override;
void AssembleDevice(const FiniteElementSpace &fes,
const Array<int> &markers,
Vector &b) override;
/** Given a particular Finite Element and a transformation (Tr)
computes the element right hand side element vector, elvect. */
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override;
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override;
virtual void AssembleDeltaElementVect(const FiniteElement &fe,
ElementTransformation &Trans,
Vector &elvect) override;
void AssembleDeltaElementVect(const FiniteElement &fe,
ElementTransformation &Trans,
Vector &elvect) override;
using LinearFormIntegrator::AssembleRHSElementVect;
};
@@ -330,14 +330,14 @@ public:
/** Given a particular boundary Finite Element and a transformation (Tr)
computes the element boundary vector, elvect. */
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect);
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override;
// For DG spaces
virtual void AssembleRHSElementVect(const FiniteElement &el,
FaceElementTransformations &Tr,
Vector &elvect);
void AssembleRHSElementVect(const FiniteElement &el,
FaceElementTransformations &Tr,
Vector &elvect) override;
using LinearFormIntegrator::AssembleRHSElementVect;
};
@@ -354,19 +354,19 @@ public:
VectorFEDomainLFIntegrator(VectorCoefficient &F)
: DeltaLFIntegrator(F), QF(F) { }
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect);
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override;
virtual void AssembleDeltaElementVect(const FiniteElement &fe,
ElementTransformation &Trans,
Vector &elvect);
void AssembleDeltaElementVect(const FiniteElement &fe,
ElementTransformation &Trans,
Vector &elvect) override;
virtual bool SupportsDevice() const { return true; }
bool SupportsDevice() const override { return true; }
virtual void AssembleDevice(const FiniteElementSpace &fes,
const Array<int> &markers,
Vector &b);
void AssembleDevice(const FiniteElementSpace &fes,
const Array<int> &markers,
Vector &b) override;
using LinearFormIntegrator::AssembleRHSElementVect;
};
@@ -384,13 +384,13 @@ public:
VectorFEDomainLFCurlIntegrator(VectorCoefficient &F)
: DeltaLFIntegrator(F), QF(&F) { }
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect);
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override;
virtual void AssembleDeltaElementVect(const FiniteElement &fe,
ElementTransformation &Trans,
Vector &elvect);
void AssembleDeltaElementVect(const FiniteElement &fe,
ElementTransformation &Trans,
Vector &elvect) override;
using LinearFormIntegrator::AssembleRHSElementVect;
};
@@ -408,13 +408,13 @@ public:
/** Given a particular Finite Element and a transformation (Tr)
computes the element right hand side element vector, elvect. */
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect);
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override;
virtual void AssembleDeltaElementVect(const FiniteElement &fe,
ElementTransformation &Trans,
Vector &elvect);
void AssembleDeltaElementVect(const FiniteElement &fe,
ElementTransformation &Trans,
Vector &elvect) override;
using LinearFormIntegrator::AssembleRHSElementVect;
};
@@ -434,9 +434,9 @@ public:
const IntegrationRule *ir = NULL)
: LinearFormIntegrator(ir), Sign(s), F(&f) { }
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect);
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override;
using LinearFormIntegrator::AssembleRHSElementVect;
};
@@ -457,17 +457,17 @@ public:
VectorFEBoundaryFluxLFIntegrator(Coefficient &f, int a = 2, int b = 0)
: F(&f), oa(a), ob(b) { }
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect);
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override;
using LinearFormIntegrator::AssembleRHSElementVect;
virtual bool SupportsDevice() const { return true; }
bool SupportsDevice() const override { return true; }
virtual void AssembleDevice(const FiniteElementSpace &fes,
const Array<int> &markers,
Vector &b);
void AssembleDevice(const FiniteElementSpace &fes,
const Array<int> &markers,
Vector &b) override;
};
/** Class for boundary integration of (f.n, v.n) for vector coefficient f and
@@ -501,9 +501,9 @@ public:
int a = 2, int b = 0)
: f(QG), oa(a), ob(b) { }
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect);
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override;
using LinearFormIntegrator::AssembleRHSElementVect;
};
@@ -531,12 +531,12 @@ public:
real_t a, real_t b)
{ f = &f_; u = &u_; alpha = a; beta = b; }
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect);
virtual void AssembleRHSElementVect(const FiniteElement &el,
FaceElementTransformations &Tr,
Vector &elvect);
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override;
void AssembleRHSElementVect(const FiniteElement &el,
FaceElementTransformations &Tr,
Vector &elvect) override;
using LinearFormIntegrator::AssembleRHSElementVect;
};
@@ -573,12 +573,12 @@ public:
const real_t s, const real_t k)
: uD(&u), Q(NULL), MQ(&q), sigma(s), kappa(k) { }
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect);
virtual void AssembleRHSElementVect(const FiniteElement &el,
FaceElementTransformations &Tr,
Vector &elvect);
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override;
void AssembleRHSElementVect(const FiniteElement &el,
FaceElementTransformations &Tr,
Vector &elvect) override;
using LinearFormIntegrator::AssembleRHSElementVect;
};
@@ -618,12 +618,12 @@ public:
real_t alpha_, real_t kappa_)
: uD(uD_), lambda(&lambda_), mu(&mu_), alpha(alpha_), kappa(kappa_) { }
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect);
virtual void AssembleRHSElementVect(const FiniteElement &el,
FaceElementTransformations &Tr,
Vector &elvect);
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override;
void AssembleRHSElementVect(const FiniteElement &el,
FaceElementTransformations &Tr,
Vector &elvect) override;
using LinearFormIntegrator::AssembleRHSElementVect;
};
@@ -695,9 +695,9 @@ public:
}
using LinearFormIntegrator::AssembleRHSElementVect;
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect);
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override;
/** @brief Saves the lower triangular matrices in the element-wise Cholesky
decomposition. The parameter @a NE should be the number of elements in
@@ -758,11 +758,11 @@ public:
}
using LinearFormIntegrator::AssembleRHSElementVect;
virtual void AssembleRHSElementVect(const FiniteElement &fe,
ElementTransformation &Tr,
Vector &elvect);
void AssembleRHSElementVect(const FiniteElement &fe,
ElementTransformation &Tr,
Vector &elvect) override;
virtual void SetIntRule(const IntegrationRule *ir)
void SetIntRule(const IntegrationRule *ir) override
{
MFEM_WARNING("Integration rule not used in this class. "
"The QuadratureFunction integration rules are used instead");
@@ -790,11 +790,11 @@ public:
}
using LinearFormIntegrator::AssembleRHSElementVect;
virtual void AssembleRHSElementVect(const FiniteElement &fe,
ElementTransformation &Tr,
Vector &elvect);
void AssembleRHSElementVect(const FiniteElement &fe,
ElementTransformation &Tr,
Vector &elvect) override;
virtual void SetIntRule(const IntegrationRule *ir)
void SetIntRule(const IntegrationRule *ir) override
{
MFEM_WARNING("Integration rule not used in this class. "
"The QuadratureFunction integration rules are used instead");
+7 -13
View File
@@ -242,13 +242,13 @@ void BatchedLOR_AMS::FormGradientMatrix()
template <typename T>
static inline const T *HypreRead(const Memory<T> &mem)
{
return mem.Read(GetHypreMemoryClass(), mem.Capacity());
return mem.Read(GetHypreForallMemoryClass(), mem.Capacity());
}
template <typename T>
static inline T *HypreWrite(Memory<T> &mem)
{
return mem.Write(GetHypreMemoryClass(), mem.Capacity());
return mem.Write(GetHypreForallMemoryClass(), mem.Capacity());
}
void BatchedLOR_AMS::FormCoordinateVectors(const Vector &X_vert)
@@ -278,10 +278,7 @@ void BatchedLOR_AMS::FormCoordinateVectors(const Vector &X_vert)
const int sdim = vert_fes.GetMesh()->SpaceDimension();
const int ntdofs = R->Height();
const MemoryClass mc = GetHypreMemoryClass();
bool dev = (mc == MemoryClass::DEVICE);
xyz_tvec = new Vector(ntdofs*sdim);
xyz_tvec = new Vector(ntdofs*sdim, GetHypreMemoryType());
auto xyz_tv = Reshape(HypreWrite(xyz_tvec->GetMemory()), ntdofs, sdim);
const auto xyz_e =
@@ -304,15 +301,12 @@ void BatchedLOR_AMS::FormCoordinateVectors(const Vector &X_vert)
// Make x, y, z HypreParVectors point to T-vector data
HYPRE_BigInt glob_size = vert_fes.GlobalTrueVSize();
HYPRE_BigInt *cols = vert_fes.GetTrueDofOffsets();
real_t *d_x_ptr = xyz_tv + 0*ntdofs;
x = new HypreParVector(vert_fes.GetComm(), glob_size, d_x_ptr, cols, dev);
real_t *d_y_ptr = xyz_tv + 1*ntdofs;
y = new HypreParVector(vert_fes.GetComm(), glob_size, d_y_ptr, cols, dev);
MPI_Comm comm = vert_fes.GetComm();
x = new HypreParVector(comm, glob_size, *xyz_tvec, 0*ntdofs, cols);
y = new HypreParVector(comm, glob_size, *xyz_tvec, 1*ntdofs, cols);
if (sdim == 3)
{
real_t *d_z_ptr = xyz_tv + 2*ntdofs;
z = new HypreParVector(vert_fes.GetComm(), glob_size, d_z_ptr, cols, dev);
z = new HypreParVector(comm, glob_size, *xyz_tvec, 2*ntdofs, cols);
}
else
{
+5 -5
View File
@@ -106,12 +106,12 @@ public:
int postSmoothingSteps_);
/// Application of the multigrid as a preconditioner
virtual void Mult(const Vector& x, Vector& y) const override;
virtual void ArrayMult(const Array<const Vector*>& X_,
Array<Vector*>& Y_) const override;
void Mult(const Vector& x, Vector& y) const override;
void ArrayMult(const Array<const Vector*>& X_,
Array<Vector*>& Y_) const override;
/// Not supported for multigrid
virtual void SetOperator(const Operator& op) override
void SetOperator(const Operator& op) override
{
MFEM_ABORT("SetOperator is not supported in Multigrid!");
}
@@ -155,7 +155,7 @@ public:
private:
/// Returns prolongation operator at given level
virtual const Operator* GetProlongationAtLevel(int level) const override
const Operator* GetProlongationAtLevel(int level) const override
{
return prolongations[level];
}
+6 -6
View File
@@ -204,7 +204,7 @@ public:
Both the input and the output vectors, @a x and @a y, must be true-dof
vectors, i.e. their size must be fes->GetTrueVSize(). */
virtual void Mult(const Vector &x, Vector &y) const;
void Mult(const Vector &x, Vector &y) const override;
/** @brief Compute the gradient Operator of the NonlinearForm corresponding
to the state @a x. */
@@ -217,7 +217,7 @@ public:
In general, @a x may have non-homogeneous essential boundary values.
The state @a x must be a true-dof vector. */
virtual Operator &GetGradient(const Vector &x) const;
Operator &GetGradient(const Vector &x) const override;
/// Update the NonlinearForm to propagate updates of the associated FE space.
/** After calling this method, the essential boundary conditions need to be
@@ -233,9 +233,9 @@ public:
virtual void Setup();
/// Get the finite element space prolongation matrix
virtual const Operator *GetProlongation() const { return P; }
const Operator *GetProlongation() const override { return P; }
/// Get the finite element space restriction matrix
virtual const Operator *GetRestriction() const
const Operator *GetRestriction() const override
{ return fes->GetRestrictionMatrix(); }
/// Indicate that integrators are not owned by the NonlinearForm
@@ -370,11 +370,11 @@ public:
/// Method is only called in serial, the parallel version calls MultBlocked
/// directly.
virtual void Mult(const Vector &x, Vector &y) const;
void Mult(const Vector &x, Vector &y) const override;
/// Method is only called in serial, the parallel version calls
/// GetGradientBlocked directly.
virtual Operator &GetGradient(const Vector &x) const;
Operator &GetGradient(const Vector &x) const override;
/// Destructor.
virtual ~BlockNonlinearForm();
+3 -3
View File
@@ -68,17 +68,17 @@ private:
Gradient(const PANonlinearFormExtension &ext);
/// Assumes that @a x and @a y are ldof Vector%s.
virtual void Mult(const Vector &x, Vector &y) const;
void Mult(const Vector &x, Vector &y) const override;
/// Assumes that @a g is an ldof Vector.
void AssembleGrad(const Vector &g);
/// Assemble the diagonal of the gradient into the ldof Vector @a diag.
virtual void AssembleDiagonal(Vector &diag) const;
void AssembleDiagonal(Vector &diag) const override;
/** @brief Define the prolongation Operator for use with methods like
FormSystemOperator. */
virtual const Operator *GetProlongation() const
const Operator *GetProlongation() const override
{
return ext.fes.GetProlongationMatrix();
}
+48 -48
View File
@@ -267,12 +267,12 @@ protected:
mutable DenseMatrix G, C; // dof x dim
public:
virtual real_t EvalW(const DenseMatrix &J) const;
real_t EvalW(const DenseMatrix &J) const override;
virtual void EvalP(const DenseMatrix &J, DenseMatrix &P) const;
void EvalP(const DenseMatrix &J, DenseMatrix &P) const override;
virtual void AssembleH(const DenseMatrix &J, const DenseMatrix &DS,
const real_t weight, DenseMatrix &A) const;
void AssembleH(const DenseMatrix &J, const DenseMatrix &DS,
const real_t weight, DenseMatrix &A) const override;
};
@@ -301,12 +301,12 @@ public:
: mu(0.0), K(0.0), g(1.0), c_mu(&mu_), c_K(&K_), c_g(g_),
have_coeffs(true) { }
virtual real_t EvalW(const DenseMatrix &J) const;
real_t EvalW(const DenseMatrix &J) const override;
virtual void EvalP(const DenseMatrix &J, DenseMatrix &P) const;
void EvalP(const DenseMatrix &J, DenseMatrix &P) const override;
virtual void AssembleH(const DenseMatrix &J, const DenseMatrix &DS,
const real_t weight, DenseMatrix &A) const;
void AssembleH(const DenseMatrix &J, const DenseMatrix &DS,
const real_t weight, DenseMatrix &A) const override;
};
@@ -342,17 +342,17 @@ public:
@param[in] el Type of FiniteElement.
@param[in] Ttr Represents ref->target coordinates transformation.
@param[in] elfun Physical coordinates of the zone. */
virtual real_t GetElementEnergy(const FiniteElement &el,
ElementTransformation &Ttr,
const Vector &elfun);
real_t GetElementEnergy(const FiniteElement &el,
ElementTransformation &Ttr,
const Vector &elfun) override;
virtual void AssembleElementVector(const FiniteElement &el,
ElementTransformation &Ttr,
const Vector &elfun, Vector &elvect);
void AssembleElementVector(const FiniteElement &el,
ElementTransformation &Ttr,
const Vector &elfun, Vector &elvect) override;
virtual void AssembleElementGrad(const FiniteElement &el,
ElementTransformation &Ttr,
const Vector &elfun, DenseMatrix &elmat);
void AssembleElementGrad(const FiniteElement &el,
ElementTransformation &Ttr,
const Vector &elfun, DenseMatrix &elmat) override;
};
/** Hyperelastic incompressible Neo-Hookean integrator with the PK1 stress
@@ -369,21 +369,21 @@ private:
public:
IncompressibleNeoHookeanIntegrator(Coefficient &mu_) : c_mu(&mu_) { }
virtual real_t GetElementEnergy(const Array<const FiniteElement *>&el,
ElementTransformation &Tr,
const Array<const Vector *> &elfun);
real_t GetElementEnergy(const Array<const FiniteElement *>&el,
ElementTransformation &Tr,
const Array<const Vector *> &elfun) override;
/// Perform the local action of the NonlinearFormIntegrator
virtual void AssembleElementVector(const Array<const FiniteElement *> &el,
ElementTransformation &Tr,
const Array<const Vector *> &elfun,
const Array<Vector *> &elvec);
void AssembleElementVector(const Array<const FiniteElement *> &el,
ElementTransformation &Tr,
const Array<const Vector *> &elfun,
const Array<Vector *> &elvec) override;
/// Assemble the local gradient matrix
virtual void AssembleElementGrad(const Array<const FiniteElement*> &el,
ElementTransformation &Tr,
const Array<const Vector *> &elfun,
const Array2D<DenseMatrix *> &elmats);
void AssembleElementGrad(const Array<const FiniteElement*> &el,
ElementTransformation &Tr,
const Array<const Vector *> &elfun,
const Array2D<DenseMatrix *> &elmats) override;
};
@@ -407,25 +407,25 @@ public:
static const IntegrationRule &GetRule(const FiniteElement &fe,
ElementTransformation &T);
virtual void AssembleElementVector(const FiniteElement &el,
ElementTransformation &trans,
const Vector &elfun,
Vector &elvect);
void AssembleElementVector(const FiniteElement &el,
ElementTransformation &trans,
const Vector &elfun,
Vector &elvect) override;
virtual void AssembleElementGrad(const FiniteElement &el,
ElementTransformation &trans,
const Vector &elfun,
DenseMatrix &elmat);
void AssembleElementGrad(const FiniteElement &el,
ElementTransformation &trans,
const Vector &elfun,
DenseMatrix &elmat) override;
using NonlinearFormIntegrator::AssemblePA;
virtual void AssemblePA(const FiniteElementSpace &fes);
void AssemblePA(const FiniteElementSpace &fes) override;
virtual void AssembleMF(const FiniteElementSpace &fes);
void AssembleMF(const FiniteElementSpace &fes) override;
virtual void AddMultPA(const Vector &x, Vector &y) const;
void AddMultPA(const Vector &x, Vector &y) const override;
virtual void AddMultMF(const Vector &x, Vector &y) const;
void AddMultMF(const Vector &x, Vector &y) const override;
};
@@ -444,10 +444,10 @@ public:
ConvectiveVectorConvectionNLFIntegrator() = default;
virtual void AssembleElementGrad(const FiniteElement &el,
ElementTransformation &trans,
const Vector &elfun,
DenseMatrix &elmat);
void AssembleElementGrad(const FiniteElement &el,
ElementTransformation &trans,
const Vector &elfun,
DenseMatrix &elmat) override;
};
@@ -467,10 +467,10 @@ public:
SkewSymmetricVectorConvectionNLFIntegrator() = default;
virtual void AssembleElementGrad(const FiniteElement &el,
ElementTransformation &trans,
const Vector &elfun,
DenseMatrix &elmat);
void AssembleElementGrad(const FiniteElement &el,
ElementTransformation &trans,
const Vector &elfun,
DenseMatrix &elmat) override;
};
}
+17 -17
View File
@@ -99,7 +99,7 @@ public:
of the parallel/conforming prolongation, and |.| denotes the entry-wise
absolute value. In general, this is just an approximation of the exact
diagonal for this case. */
virtual void AssembleDiagonal(Vector &diag) const;
void AssembleDiagonal(Vector &diag) const override;
/// Returns the matrix assembled on the true dofs, i.e. P^t A P.
/** The returned matrix has to be deleted by the caller. */
@@ -212,31 +212,31 @@ public:
{ return static_cond ? static_cond->GetParTraceFESpace() : NULL; }
/// Get the parallel finite element space prolongation matrix
virtual const Operator *GetProlongation() const
const Operator *GetProlongation() const override
{ return pfes->GetProlongationMatrix(); }
/// Get the transpose of GetRestriction, useful for matrix-free RAP
virtual const Operator *GetRestrictionTranspose() const
{ return pfes->GetRestrictionTransposeOperator(); }
/// Get the parallel finite element space restriction matrix
virtual const Operator *GetRestriction() const
const Operator *GetRestriction() const override
{ return pfes->GetRestrictionMatrix(); }
using BilinearForm::FormLinearSystem;
using BilinearForm::FormSystemMatrix;
virtual void FormLinearSystem(const Array<int> &ess_tdof_list, Vector &x,
Vector &b, OperatorHandle &A, Vector &X,
Vector &B, int copy_interior = 0);
void FormLinearSystem(const Array<int> &ess_tdof_list, Vector &x,
Vector &b, OperatorHandle &A, Vector &X,
Vector &B, int copy_interior = 0) override;
virtual void FormSystemMatrix(const Array<int> &ess_tdof_list,
OperatorHandle &A);
void FormSystemMatrix(const Array<int> &ess_tdof_list,
OperatorHandle &A) override;
/** Call this method after solving a linear system constructed using the
FormLinearSystem method to recover the solution as a ParGridFunction-size
vector in x. Use the same arguments as in the FormLinearSystem call. */
virtual void RecoverFEMSolution(const Vector &X, const Vector &b, Vector &x);
void RecoverFEMSolution(const Vector &X, const Vector &b, Vector &x) override;
virtual void Update(FiniteElementSpace *nfes = NULL);
void Update(FiniteElementSpace *nfes = NULL) override;
void EliminateVDofsInRHS(const Array<int> &vdofs, const Vector &x, Vector &b);
@@ -312,9 +312,9 @@ public:
This returns the same operator as FormRectangularLinearSystem(), but does
without the transformations of the right-hand side. */
virtual void FormRectangularSystemMatrix(const Array<int> &trial_tdof_list,
const Array<int> &test_tdof_list,
OperatorHandle &A);
void FormRectangularSystemMatrix(const Array<int> &trial_tdof_list,
const Array<int> &test_tdof_list,
OperatorHandle &A) override;
/** @brief Form the parallel linear system A X = B, corresponding to this mixed
bilinear form and the linear form @a b(.).
@@ -322,10 +322,10 @@ public:
Return in @a A a *reference* to the system matrix that is column-constrained.
The reference will be invalidated when SetOperatorType(), Update(), or the
destructor is called. */
virtual void FormRectangularLinearSystem(const Array<int> &trial_tdof_list,
const Array<int> &test_tdof_list, Vector &x,
Vector &b, OperatorHandle &A, Vector &X,
Vector &B);
void FormRectangularLinearSystem(const Array<int> &trial_tdof_list,
const Array<int> &test_tdof_list, Vector &x,
Vector &b, OperatorHandle &A, Vector &X,
Vector &B) override;
/// Compute y += a (P^t A P) x, where x and y are vectors on the true dofs
void TrueAddMult(const Vector &x, Vector &y, const real_t a = 1.0) const;
+2 -2
View File
@@ -101,7 +101,7 @@ public:
@note This version of the method will also perform bounds checks when the
build option MFEM_DEBUG is enabled. */
virtual void MakeRef(FiniteElementSpace *f, Vector &v, int v_offset);
void MakeRef(FiniteElementSpace *f, Vector &v, int v_offset) override;
/** @brief Make the ParLinearForm reference external data on a new
ParFiniteElementSpace. */
@@ -120,7 +120,7 @@ public:
void Assemble();
/// Return true if assembly on device is supported, false otherwise.
virtual bool SupportsDevice() const;
bool SupportsDevice() const override;
void AssembleSharedFaces();
+9 -9
View File
@@ -46,16 +46,16 @@ public:
real_t GetEnergy(const ParGridFunction &x) const
{ return GetParGridFunctionEnergy(x); }
virtual real_t GetEnergy(const Vector &x) const
real_t GetEnergy(const Vector &x) const override
{ return GetParGridFunctionEnergy(Prolongate(x)); }
virtual void Mult(const Vector &x, Vector &y) const;
void Mult(const Vector &x, Vector &y) const override;
/// Return the local gradient matrix for the given true-dof vector x.
/** The returned matrix does NOT have any boundary conditions imposed. */
const SparseMatrix &GetLocalGradient(const Vector &x) const;
virtual Operator &GetGradient(const Vector &x) const;
Operator &GetGradient(const Vector &x) const override;
/// Set the operator type id for the parallel gradient matrix/operator.
void SetGradientType(Operator::Type tid) { pGrad.SetType(tid); }
@@ -64,7 +64,7 @@ public:
parallel FE space. */
/** After calling this method, the essential boundary conditions need to be
set again. */
virtual void Update();
void Update() override;
virtual ~ParNonlinearForm() { }
};
@@ -83,7 +83,7 @@ protected:
public:
/// Computes the energy of the system
virtual real_t GetEnergy(const Vector &x) const;
real_t GetEnergy(const Vector &x) const override;
/// Construct an empty ParBlockNonlinearForm. Initialize with SetParSpaces().
ParBlockNonlinearForm() : pBlockGrad(NULL) { }
@@ -103,16 +103,16 @@ public:
void SetParSpaces(Array<ParFiniteElementSpace *> &pf);
// Here, rhs is a true dof vector
virtual void SetEssentialBC(const Array<Array<int> *>&bdr_attr_is_ess,
Array<Vector *> &rhs);
void SetEssentialBC(const Array<Array<int> *>&bdr_attr_is_ess,
Array<Vector *> &rhs) override;
/// Block T-Vector to Block T-Vector
virtual void Mult(const Vector &x, Vector &y) const;
void Mult(const Vector &x, Vector &y) const override;
/// Return the local block gradient matrix for the given true-dof vector x
const BlockOperator &GetLocalGradient(const Vector &x) const;
virtual BlockOperator &GetGradient(const Vector &x) const;
BlockOperator &GetGradient(const Vector &x) const override;
/** @brief Set the operator type id for the blocks of the parallel gradient
matrix/operator. The default type is Operator::Hypre_ParCSR. */
+68 -87
View File
@@ -27,12 +27,16 @@ namespace quadrature_interpolator
{
static void Det1D(const int NE,
const real_t *b,
const real_t *g,
const real_t *x,
real_t *y,
const int d1d,
const int q1d)
const int q1d,
Vector *d_buff = nullptr)
{
MFEM_CONTRACT_VAR(b);
MFEM_CONTRACT_VAR(d_buff);
const auto G = Reshape(g, q1d, d1d);
const auto X = Reshape(x, d1d, NE);
@@ -59,8 +63,10 @@ static void Det2D(const int NE,
const real_t *x,
real_t *y,
const int d1d = 0,
const int q1d = 0)
const int q1d = 0,
Vector *d_buff = nullptr)
{
MFEM_CONTRACT_VAR(d_buff);
static constexpr int SDIM = 2;
static constexpr int NBZ = 1;
@@ -109,8 +115,11 @@ static void Det2DSurface(const int NE,
const real_t *x,
real_t *y,
const int d1d = 0,
const int q1d = 0)
const int q1d = 0,
Vector *d_buff = nullptr)
{
MFEM_CONTRACT_VAR(d_buff);
static constexpr int SDIM = 3;
static constexpr int NBZ = 1;
@@ -222,8 +231,8 @@ static void Det3D(const int NE,
if (!SMEM)
{
const DeviceDofQuadLimits &limits = DeviceDofQuadLimits::Get();
const int max_q1d = T_Q1D ? T_Q1D : limits.MAX_D1D;
const int max_d1d = T_D1D ? T_D1D : limits.MAX_Q1D;
const int max_q1d = T_Q1D ? T_Q1D : limits.MAX_Q1D;
const int max_d1d = T_D1D ? T_D1D : limits.MAX_D1D;
const int max_qd = std::max(max_q1d, max_d1d);
const int mem_size = max_qd * max_qd * max_qd * 9;
d_buff->SetSize(2*mem_size*GRID);
@@ -233,9 +242,9 @@ static void Det3D(const int NE,
mfem::forall_3D_grid(NE, Q1D, Q1D, Q1D, GRID, [=] MFEM_HOST_DEVICE (int e)
{
static constexpr int MQ1 = T_Q1D ? T_Q1D :
(SMEM ? DofQuadLimits::MAX_DET_1D : DofQuadLimits::MAX_D1D);
static constexpr int MD1 = T_D1D ? T_D1D :
(SMEM ? DofQuadLimits::MAX_DET_1D : DofQuadLimits::MAX_Q1D);
static constexpr int MD1 = T_D1D ? T_D1D :
(SMEM ? DofQuadLimits::MAX_DET_1D : DofQuadLimits::MAX_D1D);
static constexpr int MDQ = MQ1 > MD1 ? MQ1 : MD1;
static constexpr int MSZ = MDQ * MDQ * MDQ * 9;
@@ -272,91 +281,63 @@ static void Det3D(const int NE,
});
}
// Tensor-product evaluation of quadrature point determinants: dispatch
// function.
void TensorDeterminants(const int NE,
const int vdim,
const DofToQuad &maps,
const Vector &e_vec,
Vector &q_det,
Vector &d_buff)
void InitDetKernels()
{
if (NE == 0) { return; }
const int dim = maps.FE->GetDim();
const int D1D = maps.ndof;
const int Q1D = maps.nqpt;
const real_t *B = maps.B.Read();
const real_t *G = maps.G.Read();
const real_t *X = e_vec.Read();
real_t *Y = q_det.Write();
const int id = (vdim<<8) | (D1D<<4) | Q1D;
if (dim == 1)
{
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D,
"Orders higher than " << DeviceDofQuadLimits::Get().MAX_D1D-1
<< " are not supported!");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D,
"Quadrature rules with more than "
<< DeviceDofQuadLimits::Get().MAX_Q1D << " 1D points are not supported!");
Det1D(NE, G, X, Y, D1D, Q1D);
return;
}
if (dim == 2)
{
switch (id)
{
case 0x222: return Det2D<2,2>(NE,B,G,X,Y);
case 0x223: return Det2D<2,3>(NE,B,G,X,Y);
case 0x224: return Det2D<2,4>(NE,B,G,X,Y);
case 0x226: return Det2D<2,6>(NE,B,G,X,Y);
case 0x234: return Det2D<3,4>(NE,B,G,X,Y);
case 0x236: return Det2D<3,6>(NE,B,G,X,Y);
case 0x244: return Det2D<4,4>(NE,B,G,X,Y);
case 0x246: return Det2D<4,6>(NE,B,G,X,Y);
case 0x256: return Det2D<5,6>(NE,B,G,X,Y);
default:
{
const int MD = DeviceDofQuadLimits::Get().MAX_D1D;
const int MQ = DeviceDofQuadLimits::Get().MAX_Q1D;
MFEM_VERIFY(D1D <= MD, "Orders higher than " << MD-1
<< " are not supported!");
MFEM_VERIFY(Q1D <= MQ, "Quadrature rules with more than "
<< MQ << " 1D points are not supported!");
if (vdim == 2) { Det2D(NE,B,G,X,Y,D1D,Q1D); }
else if (vdim == 3) { Det2DSurface(NE,B,G,X,Y,D1D,Q1D); }
else { MFEM_ABORT("Invalid space dimension."); }
return;
}
}
}
if (dim == 3)
{
switch (id)
{
case 0x324: return Det3D<2,4>(NE,B,G,X,Y);
case 0x333: return Det3D<3,3>(NE,B,G,X,Y);
case 0x335: return Det3D<3,5>(NE,B,G,X,Y);
case 0x336: return Det3D<3,6>(NE,B,G,X,Y);
default:
{
const int MD = DeviceDofQuadLimits::Get().MAX_DET_1D;
const int MQ = DeviceDofQuadLimits::Get().MAX_DET_1D;
// Highest orders that fit in shared memory
if (D1D <= MD && Q1D <= MQ)
{ return Det3D<0,0,true>(NE,B,G,X,Y,D1D,Q1D); }
// Last fall-back will use global memory
return Det3D<0,0,false>(
NE,B,G,X,Y,D1D,Q1D,&d_buff);
}
}
}
MFEM_ABORT("Kernel " << std::hex << id << std::dec << " not supported yet");
using k = QuadratureInterpolator::DetKernels;
// 2D
k::Specialization<2,2,2,2>::Add();
k::Specialization<2,2,2,3>::Add();
k::Specialization<2,2,2,4>::Add();
k::Specialization<2,2,2,6>::Add();
k::Specialization<2,2,3,4>::Add();
k::Specialization<2,2,3,6>::Add();
k::Specialization<2,2,4,4>::Add();
k::Specialization<2,2,4,6>::Add();
k::Specialization<2,2,5,6>::Add();
// 3D
k::Specialization<3,3,2,4>::Add();
k::Specialization<3,3,3,3>::Add();
k::Specialization<3,3,3,5>::Add();
k::Specialization<3,3,3,6>::Add();
}
} // namespace quadrature_interpolator
} // namespace internal
/// @cond Suppress_Doxygen_warnings
namespace
{
using DetKernel = QuadratureInterpolator::DetKernelType;
}
template<int DIM, int SDIM, int D1D, int Q1D>
DetKernel QuadratureInterpolator::DetKernels::Kernel()
{
if (DIM == 1) { return internal::quadrature_interpolator::Det1D; }
else if (DIM == 2 && SDIM == 2) { return internal::quadrature_interpolator::Det2D<D1D, Q1D>; }
else if (DIM == 2 && SDIM == 3) { return internal::quadrature_interpolator::Det2DSurface<D1D, Q1D>; }
else if (DIM == 3) { return internal::quadrature_interpolator::Det3D<D1D, Q1D>; }
else { MFEM_ABORT(""); }
}
DetKernel QuadratureInterpolator::DetKernels::Fallback(
int DIM, int SDIM, int D1D, int Q1D)
{
if (DIM == 1) { return internal::quadrature_interpolator::Det1D; }
else if (DIM == 2 && SDIM == 2) { return internal::quadrature_interpolator::Det2D; }
else if (DIM == 2 && SDIM == 3) { return internal::quadrature_interpolator::Det2DSurface; }
else if (DIM == 3)
{
const int MD = DeviceDofQuadLimits::Get().MAX_DET_1D;
const int MQ = DeviceDofQuadLimits::Get().MAX_DET_1D;
if (D1D <= MD && Q1D <= MQ) { return internal::quadrature_interpolator::Det3D<0,0,true>; }
else { return internal::quadrature_interpolator::Det3D<0,0,false>; }
}
else { MFEM_ABORT(""); }
}
/// @endcond
} // namespace mfem
-64
View File
@@ -1,64 +0,0 @@
// Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.
// Internal header, included only by .cpp files
#include "../quadinterpolator.hpp"
namespace mfem
{
namespace internal
{
namespace quadrature_interpolator
{
// Tensor-product evaluation of quadrature point values: dispatch function.
template<QVectorLayout VL>
void TensorValues(const int NE,
const int vdim,
const DofToQuad &maps,
const Vector &e_vec,
Vector &q_val);
// Tensor-product evaluation of quadrature point derivatives: dispatch function.
template<QVectorLayout VL>
void TensorDerivatives(const int NE,
const int vdim,
const DofToQuad &maps,
const Vector &e_vec,
Vector &q_der);
// Tensor-product evaluation of quadrature point physical derivatives: dispatch
// function.
template<QVectorLayout VL>
void TensorPhysDerivatives(const int NE,
const int vdim,
const DofToQuad &maps,
const GeometricFactors &geom,
const Vector &e_vec,
Vector &q_der);
// Tensor-product evaluation of quadrature point determinants: dispatch
// function.
void TensorDeterminants(const int NE,
const int vdim,
const DofToQuad &maps,
const Vector &e_vec,
Vector &q_det,
Vector &d_buff);
} // namespace quadrature_interpolator
} // namespace internal
} // namespace mfem
+21 -1
View File
@@ -12,6 +12,9 @@
// Internal header, included only by .cpp files.
// Template function implementations.
#ifndef MFEM_QUADINTERP_EVAL
#define MFEM_QUADINTERP_EVAL
#include "../quadinterpolator.hpp"
#include "../../general/forall.hpp"
#include "../../linalg/dtensor.hpp"
@@ -63,7 +66,7 @@ static void Values1D(const int NE,
// Template compute kernel for Values in 2D: tensor product version.
template<QVectorLayout Q_LAYOUT,
int T_VDIM = 0, int T_D1D = 0, int T_Q1D = 0,
int T_NBZ = 1, int MAX_D1D = 0, int MAX_Q1D = 0>
int T_NBZ = 1>
static void Values2D(const int NE,
const real_t *b_,
const real_t *x_,
@@ -193,4 +196,21 @@ static void Values3D(const int NE,
} // namespace internal
/// @cond Suppress_Doxygen_warnings
template<int DIM, QVectorLayout Q_LAYOUT,
int VDIM, int D1D, int Q1D, int NBZ>
QuadratureInterpolator::TensorEvalKernelType
QuadratureInterpolator::TensorEvalKernels::Kernel()
{
if (DIM == 1) { return internal::quadrature_interpolator::Values1D<Q_LAYOUT>; }
else if (DIM == 2) { return internal::quadrature_interpolator::Values2D<Q_LAYOUT, VDIM, D1D, Q1D, NBZ>; }
else if (DIM == 3) { return internal::quadrature_interpolator::Values3D<Q_LAYOUT, VDIM, D1D, Q1D>; }
else { MFEM_ABORT(""); }
}
/// @endcond
} // namespace mfem
#endif
+47 -115
View File
@@ -10,143 +10,75 @@
// CONTRIBUTING.md for details.
#include "../quadinterpolator.hpp"
#include "dispatch.hpp"
#include "eval.hpp"
namespace mfem
{
namespace internal
{
namespace quadrature_interpolator
{
// Tensor-product evaluation of quadrature point values: dispatch function.
// Instantiation for the case QVectorLayout::byNODES.
template<>
void TensorValues<QVectorLayout::byNODES>(const int NE,
const int vdim,
const DofToQuad &maps,
const Vector &e_vec,
Vector &q_val)
void InitEvalByNodesKernels()
{
if (NE == 0) { return; }
const int dim = maps.FE->GetDim();
const int D1D = maps.ndof;
const int Q1D = maps.nqpt;
const real_t *B = maps.B.Read();
const real_t *X = e_vec.Read();
real_t *Y = q_val.Write();
using k = QuadratureInterpolator::TensorEvalKernels;
constexpr QVectorLayout L = QVectorLayout::byNODES;
// 2D
k::Specialization<2,QVectorLayout::byNODES,1,3,3>::Opt<1>::Add();
k::Specialization<2,QVectorLayout::byNODES,1,2,4>::Opt<1>::Add();
k::Specialization<2,QVectorLayout::byNODES,1,3,2>::Opt<1>::Add();
k::Specialization<2,QVectorLayout::byNODES,1,3,4>::Opt<1>::Add();
k::Specialization<2,QVectorLayout::byNODES,1,4,3>::Opt<1>::Add();
k::Specialization<2,QVectorLayout::byNODES,1,4,4>::Opt<1>::Add();
const int id = (vdim<<8) | (D1D<<4) | Q1D;
k::Specialization<2,QVectorLayout::byNODES,2,2,2>::Opt<1>::Add();
k::Specialization<2,QVectorLayout::byNODES,2,2,3>::Opt<1>::Add();
k::Specialization<2,QVectorLayout::byNODES,2,2,4>::Opt<1>::Add();
k::Specialization<2,QVectorLayout::byNODES,2,2,5>::Opt<1>::Add();
k::Specialization<2,QVectorLayout::byNODES,2,2,6>::Opt<1>::Add();
if (dim == 1)
{
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D,
"Orders higher than " << DeviceDofQuadLimits::Get().MAX_D1D-1
<< " are not supported!");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D,
"Quadrature rules with more than "
<< DeviceDofQuadLimits::Get().MAX_Q1D << " 1D points are not supported!");
Values1D<L>(NE, B, X, Y, vdim, D1D, Q1D);
return;
}
if (dim == 2)
{
switch (id)
{
case 0x133: return Values2D<L,1,3,3>(NE,B,X,Y);
case 0x124: return Values2D<L,1,2,4>(NE,B,X,Y);
case 0x132: return Values2D<L,1,3,2>(NE,B,X,Y);
case 0x134: return Values2D<L,1,3,4>(NE,B,X,Y);
case 0x143: return Values2D<L,1,4,3>(NE,B,X,Y);
case 0x144: return Values2D<L,1,4,4>(NE,B,X,Y);
k::Specialization<2,QVectorLayout::byNODES,2,3,3>::Opt<1>::Add();
k::Specialization<2,QVectorLayout::byNODES,2,3,4>::Opt<1>::Add();
k::Specialization<2,QVectorLayout::byNODES,2,3,6>::Opt<1>::Add();
case 0x222: return Values2D<L,2,2,2>(NE,B,X,Y);
case 0x223: return Values2D<L,2,2,3>(NE,B,X,Y);
case 0x224: return Values2D<L,2,2,4>(NE,B,X,Y);
case 0x225: return Values2D<L,2,2,5>(NE,B,X,Y);
case 0x226: return Values2D<L,2,2,6>(NE,B,X,Y);
k::Specialization<2,QVectorLayout::byNODES,2,4,3>::Opt<1>::Add();
k::Specialization<2,QVectorLayout::byNODES,2,4,4>::Opt<1>::Add();
k::Specialization<2,QVectorLayout::byNODES,2,4,5>::Opt<1>::Add();
k::Specialization<2,QVectorLayout::byNODES,2,4,6>::Opt<1>::Add();
k::Specialization<2,QVectorLayout::byNODES,2,4,7>::Opt<1>::Add();
case 0x233: return Values2D<L,2,3,3>(NE,B,X,Y);
case 0x234: return Values2D<L,2,3,4>(NE,B,X,Y);
case 0x236: return Values2D<L,2,3,6>(NE,B,X,Y);
k::Specialization<2,QVectorLayout::byNODES,2,5,6>::Opt<1>::Add();
case 0x243: return Values2D<L,2,4,3>(NE,B,X,Y);
case 0x244: return Values2D<L,2,4,4>(NE,B,X,Y);
case 0x245: return Values2D<L,2,4,5>(NE,B,X,Y);
case 0x246: return Values2D<L,2,4,6>(NE,B,X,Y);
case 0x247: return Values2D<L,2,4,7>(NE,B,X,Y);
// 3D
k::Specialization<3,QVectorLayout::byNODES,1,2,4>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byNODES,1,3,3>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byNODES,1,3,4>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byNODES,1,3,6>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byNODES,1,4,3>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byNODES,1,4,4>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byNODES,1,4,8>::Opt<1>::Add();
case 0x256: return Values2D<L,2,5,6>(NE,B,X,Y);
k::Specialization<3,QVectorLayout::byNODES,2,2,2>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byNODES,2,2,3>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byNODES,2,3,4>::Opt<1>::Add();
default:
{
const int MD = DeviceDofQuadLimits::Get().MAX_D1D;
const int MQ = DeviceDofQuadLimits::Get().MAX_Q1D;
MFEM_VERIFY(D1D <= MD, "Orders higher than " << MD-1
<< " are not supported!");
MFEM_VERIFY(Q1D <= MQ, "Quadrature rules with more than "
<< MQ << " 1D points are not supported!");
Values2D<L>(NE,B,X,Y,vdim,D1D,Q1D);
return;
}
}
}
if (dim == 3)
{
switch (id)
{
case 0x124: return Values3D<L,1,2,4>(NE,B,X,Y);
case 0x133: return Values3D<L,1,3,3>(NE,B,X,Y);
case 0x134: return Values3D<L,1,3,4>(NE,B,X,Y);
case 0x136: return Values3D<L,1,3,6>(NE,B,X,Y);
case 0x143: return Values3D<L,1,4,3>(NE,B,X,Y);
case 0x144: return Values3D<L,1,4,4>(NE,B,X,Y);
case 0x148: return Values3D<L,1,4,8>(NE,B,X,Y);
k::Specialization<3,QVectorLayout::byNODES,3,2,3>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byNODES,3,2,4>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byNODES,3,2,5>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byNODES,3,2,6>::Opt<1>::Add();
case 0x222: return Values3D<L,2,2,2>(NE,B,X,Y);
case 0x223: return Values3D<L,2,2,3>(NE,B,X,Y);
case 0x234: return Values3D<L,2,3,4>(NE,B,X,Y);
k::Specialization<3,QVectorLayout::byNODES,3,3,3>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byNODES,3,3,4>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byNODES,3,3,5>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byNODES,3,3,6>::Opt<1>::Add();
case 0x323: return Values3D<L,3,2,3>(NE,B,X,Y);
case 0x324: return Values3D<L,3,2,4>(NE,B,X,Y);
case 0x325: return Values3D<L,3,2,5>(NE,B,X,Y);
case 0x326: return Values3D<L,3,2,6>(NE,B,X,Y);
case 0x333: return Values3D<L,3,3,3>(NE,B,X,Y);
case 0x334: return Values3D<L,3,3,4>(NE,B,X,Y);
case 0x335: return Values3D<L,3,3,5>(NE,B,X,Y);
case 0x336: return Values3D<L,3,3,6>(NE,B,X,Y);
case 0x343: return Values3D<L,3,4,3>(NE,B,X,Y);
case 0x344: return Values3D<L,3,4,4>(NE,B,X,Y);
case 0x346: return Values3D<L,3,4,6>(NE,B,X,Y);
case 0x347: return Values3D<L,3,4,7>(NE,B,X,Y);
case 0x348: return Values3D<L,3,4,8>(NE,B,X,Y);
default:
{
const int MD = DeviceDofQuadLimits::Get().MAX_INTERP_1D;
const int MQ = DeviceDofQuadLimits::Get().MAX_INTERP_1D;
MFEM_VERIFY(D1D <= MD, "Orders higher than " << MD-1
<< " are not supported!");
MFEM_VERIFY(Q1D <= MQ, "Quadrature rules with more than "
<< MQ << " 1D points are not supported!");
Values3D<L>(NE,B,X,Y,vdim,D1D,Q1D);
return;
}
}
}
mfem::out << "Unknown kernel 0x" << std::hex << id << std::endl;
MFEM_ABORT("Kernel not supported yet");
k::Specialization<3,QVectorLayout::byNODES,3,4,3>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byNODES,3,4,4>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byNODES,3,4,6>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byNODES,3,4,7>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byNODES,3,4,8>::Opt<1>::Add();
}
} // namespace quadrature_interpolator
} // namespace internal
} // namespace mfem
+25 -97
View File
@@ -10,117 +10,45 @@
// CONTRIBUTING.md for details.
#include "../quadinterpolator.hpp"
#include "dispatch.hpp"
#include "eval.hpp"
namespace mfem
{
namespace internal
{
namespace quadrature_interpolator
{
// Tensor-product evaluation of quadrature point values: dispatch function.
// Instantiation for the case QVectorLayout::byVDIM.
template<>
void TensorValues<QVectorLayout::byVDIM>(const int NE,
const int vdim,
const DofToQuad &maps,
const Vector &e_vec,
Vector &q_val)
void InitEvalByVDimKernels()
{
if (NE == 0) { return; }
const int dim = maps.FE->GetDim();
const int D1D = maps.ndof;
const int Q1D = maps.nqpt;
const real_t *B = maps.B.Read();
const real_t *X = e_vec.Read();
real_t *Y = q_val.Write();
using k = QuadratureInterpolator::TensorEvalKernels;
// 2D
k::Specialization<2,QVectorLayout::byVDIM,1,2,4>::Opt<8>::Add();
k::Specialization<2,QVectorLayout::byVDIM,1,3,6>::Opt<4>::Add();
k::Specialization<2,QVectorLayout::byVDIM,1,4,8>::Opt<2>::Add();
constexpr QVectorLayout L = QVectorLayout::byVDIM;
k::Specialization<2,QVectorLayout::byVDIM,2,2,4>::Opt<8>::Add();
k::Specialization<2,QVectorLayout::byVDIM,2,3,4>::Opt<8>::Add();
k::Specialization<2,QVectorLayout::byVDIM,2,3,6>::Opt<4>::Add();
k::Specialization<2,QVectorLayout::byVDIM,2,4,8>::Opt<2>::Add();
// 3D
k::Specialization<3,QVectorLayout::byVDIM,1,2,4>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byVDIM,1,3,6>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byVDIM,1,4,8>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byVDIM,3,2,4>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byVDIM,3,3,6>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byVDIM,3,4,8>::Opt<1>::Add();
const int id = (vdim<<8) | (D1D<<4) | Q1D;
if (dim == 1)
{
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D,
"Orders higher than " << DeviceDofQuadLimits::Get().MAX_D1D-1
<< " are not supported!");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D,
"Quadrature rules with more than "
<< DeviceDofQuadLimits::Get().MAX_Q1D << " 1D points are not supported!");
Values1D<L>(NE, B, X, Y, vdim, D1D, Q1D);
return;
}
if (dim == 2)
{
switch (id)
{
case 0x124: return Values2D<L,1,2,4,8>(NE,B,X,Y);
case 0x136: return Values2D<L,1,3,6,4>(NE,B,X,Y);
case 0x148: return Values2D<L,1,4,8,2>(NE,B,X,Y);
case 0x224: return Values2D<L,2,2,4,8>(NE,B,X,Y);
case 0x234: return Values2D<L,2,3,4,8>(NE,B,X,Y);
case 0x236: return Values2D<L,2,3,6,4>(NE,B,X,Y);
case 0x248: return Values2D<L,2,4,8,2>(NE,B,X,Y);
default:
{
const int MD = DeviceDofQuadLimits::Get().MAX_D1D;
const int MQ = DeviceDofQuadLimits::Get().MAX_Q1D;
MFEM_VERIFY(D1D <= MD, "Orders higher than " << MD-1
<< " are not supported!");
MFEM_VERIFY(Q1D <= MQ, "Quadrature rules with more than "
<< MQ << " 1D points are not supported!");
Values2D<L>(NE,B,X,Y,vdim,D1D,Q1D);
return;
}
}
}
if (dim == 3)
{
switch (id)
{
case 0x124: return Values3D<L,1,2,4>(NE,B,X,Y);
case 0x136: return Values3D<L,1,3,6>(NE,B,X,Y);
case 0x148: return Values3D<L,1,4,8>(NE,B,X,Y);
case 0x324: return Values3D<L,3,2,4>(NE,B,X,Y);
case 0x336: return Values3D<L,3,3,6>(NE,B,X,Y);
case 0x348: return Values3D<L,3,4,8>(NE,B,X,Y);
// Used for LOR batched assembly
case 0x322: return Values3D<L,3,2,2>(NE,B,X,Y);
case 0x333: return Values3D<L,3,3,3>(NE,B,X,Y);
case 0x344: return Values3D<L,3,4,4>(NE,B,X,Y);
case 0x355: return Values3D<L,3,5,5>(NE,B,X,Y);
case 0x366: return Values3D<L,3,6,6>(NE,B,X,Y);
case 0x377: return Values3D<L,3,7,7>(NE,B,X,Y);
case 0x388: return Values3D<L,3,8,8>(NE,B,X,Y);
case 0x399: return Values3D<L,3,9,9>(NE,B,X,Y);
default:
{
const int MD = DeviceDofQuadLimits::Get().MAX_INTERP_1D;
const int MQ = DeviceDofQuadLimits::Get().MAX_INTERP_1D;
MFEM_VERIFY(D1D <= MD, "Orders higher than " << MD-1
<< " are not supported!");
MFEM_VERIFY(Q1D <= MQ, "Quadrature rules with more than "
<< MQ << " 1D points are not supported!");
Values3D<L>(NE,B,X,Y,vdim,D1D,Q1D);
return;
}
}
}
mfem::out << "Unknown kernel 0x" << std::hex << id << std::endl;
MFEM_ABORT("Kernel not supported yet");
k::Specialization<3,QVectorLayout::byVDIM,3,2,2>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byVDIM,3,3,3>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byVDIM,3,4,4>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byVDIM,3,5,5>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byVDIM,3,6,6>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byVDIM,3,7,7>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byVDIM,3,8,8>::Opt<1>::Add();
k::Specialization<3,QVectorLayout::byVDIM,3,9,9>::Opt<1>::Add();
}
} // namespace quadrature_interpolator
} // namespace internal
} // namespace mfem
+250 -7
View File
@@ -12,6 +12,9 @@
// Internal header, included only by .cpp files.
// Template function implementations.
#ifndef MFEM_QUADINTERP_GRAD
#define MFEM_QUADINTERP_GRAD
#include "../quadinterpolator.hpp"
#include "../../general/forall.hpp"
#include "../../linalg/dtensor.hpp"
@@ -29,6 +32,7 @@ namespace quadrature_interpolator
template<QVectorLayout Q_LAYOUT, bool GRAD_PHYS>
static void Derivatives1D(const int NE,
const real_t *b_,
const real_t *g_,
const real_t *j_,
const real_t *x_,
@@ -38,12 +42,14 @@ static void Derivatives1D(const int NE,
const int d1d,
const int q1d)
{
MFEM_CONTRACT_VAR(b_);
const int SDIM = GRAD_PHYS ? sdim : 1;
const auto g = Reshape(g_, q1d, d1d);
const auto j = Reshape(j_, q1d, sdim, NE);
const auto j = Reshape(j_, q1d, SDIM, NE);
const auto x = Reshape(x_, d1d, vdim, NE);
auto y = Q_LAYOUT == QVectorLayout::byNODES ?
Reshape(y_, q1d, vdim, sdim, NE):
Reshape(y_, vdim, sdim, q1d, NE);
Reshape(y_, q1d, vdim, SDIM, NE):
Reshape(y_, vdim, SDIM, q1d, NE);
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
@@ -58,8 +64,8 @@ static void Derivatives1D(const int NE,
}
if (GRAD_PHYS)
{
if (sdim == 1) { du[0] /= j(q, 0, e); }
else if (sdim == 2)
if (SDIM == 1) { du[0] /= j(q, 0, e); }
else if (SDIM == 2)
{
const real_t Jloc[2] = {j(q,0,e), j(q,1,e)};
real_t Jinv[3];
@@ -69,7 +75,7 @@ static void Derivatives1D(const int NE,
du[0] = U;
du[1] = V;
}
else // sdim == 3
else // SDIM == 3
{
const real_t Jloc[3] = {j(q,0,e), j(q,1,e), j(q,2,e)};
real_t Jinv[3];
@@ -82,7 +88,7 @@ static void Derivatives1D(const int NE,
du[2] = W;
}
}
for (int d = 0; d < sdim; ++d)
for (int d = 0; d < SDIM; ++d)
{
if (Q_LAYOUT == QVectorLayout::byVDIM) { y(c, d, q, e) = du[d]; }
if (Q_LAYOUT == QVectorLayout::byNODES) { y(q, c, d, e) = du[d]; }
@@ -232,6 +238,7 @@ static void Derivatives3D(const int NE,
const real_t *j_,
const real_t *x_,
real_t *y_,
const int sdim = 3,
const int vdim = 0,
const int d1d = 0,
const int q1d = 0)
@@ -366,8 +373,244 @@ static void Derivatives3D(const int NE,
});
}
template<QVectorLayout Q_LAYOUT, bool GRAD_PHYS>
static void CollocatedDerivatives1D(const int NE,
const real_t *g_,
const real_t *j_,
const real_t *x_,
real_t *y_,
const int sdim,
const int vdim,
const int d1d)
{
Derivatives1D<Q_LAYOUT, GRAD_PHYS>(
NE, nullptr, g_, j_, x_, y_, sdim, vdim, d1d, d1d);
}
// Template compute kernel for derivatives in 2D: tensor product version.
template<QVectorLayout Q_LAYOUT, bool GRAD_PHYS,
int T_VDIM = 0, int T_D1D = 0,
int T_NBZ = 1>
static void CollocatedDerivatives2D(const int NE,
const real_t *g_,
const real_t *j_,
const real_t *x_,
real_t *y_,
const int sdim = 2,
const int vdim = 0,
const int d1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int VDIM = T_VDIM ? T_VDIM : vdim;
const int SDIM = GRAD_PHYS ? sdim : 2;
static constexpr int NBZ = T_NBZ ? T_NBZ : 1;
const auto g = Reshape(g_, D1D, D1D);
const auto j = Reshape(j_, D1D, D1D, SDIM, 2, NE);
const auto x = Reshape(x_, D1D, D1D, VDIM, NE);
auto y = Q_LAYOUT == QVectorLayout:: byNODES ?
Reshape(y_, D1D, D1D, VDIM, SDIM, NE):
Reshape(y_, VDIM, SDIM, D1D, D1D, NE);
mfem::forall_2D_batch(NE, D1D, D1D, NBZ, [=] MFEM_HOST_DEVICE (int e)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int VDIM = T_VDIM ? T_VDIM : vdim;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
const int tidz = MFEM_THREAD_ID(z);
MFEM_SHARED real_t XY[NBZ][MD1*MD1];
DeviceTensor<2> X((real_t*)(XY+tidz), D1D, D1D);
for (int c = 0; c < VDIM; ++c)
{
kernels::internal::LoadX<MD1,NBZ>(e,D1D,c,x,XY);
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
{
real_t u = 0.0;
real_t v = 0.0;
real_t w = 0.0;
for (int dxy = 0; dxy < D1D; ++dxy)
{
u += X(dxy, dy) * g(dx,dxy);
v += X(dx, dxy) * g(dy,dxy);
}
if (GRAD_PHYS)
{
if (SDIM == 2)
{
real_t Jloc[4], Jinv[4];
Jloc[0] = j(dx,dy,0,0,e);
Jloc[1] = j(dx,dy,1,0,e);
Jloc[2] = j(dx,dy,0,1,e);
Jloc[3] = j(dx,dy,1,1,e);
kernels::CalcInverse<2>(Jloc, Jinv);
const real_t U = Jinv[0]*u + Jinv[1]*v;
const real_t V = Jinv[2]*u + Jinv[3]*v;
u = U;
v = V;
}
else
{
real_t Jloc[6], Jinv[6];
Jloc[0] = j(dx,dy,0,0,e);
Jloc[1] = j(dx,dy,1,0,e);
Jloc[2] = j(dx,dy,2,0,e);
Jloc[3] = j(dx,dy,0,1,e);
Jloc[4] = j(dx,dy,1,1,e);
Jloc[5] = j(dx,dy,2,1,e);
kernels::CalcLeftInverse<3,2>(Jloc, Jinv);
const real_t U = Jinv[0]*u + Jinv[1]*v;
const real_t V = Jinv[2]*u + Jinv[3]*v;
const real_t W = Jinv[4]*u + Jinv[5]*v;
u = U;
v = V;
w = W;
}
}
if (Q_LAYOUT == QVectorLayout::byVDIM)
{
y(c,0,dx,dy,e) = u;
y(c,1,dx,dy,e) = v;
if (SDIM == 3) { y(c,2,dx,dy,e) = w; }
}
if (Q_LAYOUT == QVectorLayout::byNODES)
{
y(dx,dy,c,0,e) = u;
y(dx,dy,c,1,e) = v;
if (SDIM == 3) { y(dx,dy,c,2,e) = w; }
}
}
}
MFEM_SYNC_THREAD;
}
});
}
// Template compute kernel for derivatives in 3D: tensor product version.
template<QVectorLayout Q_LAYOUT, bool GRAD_PHYS,
int T_VDIM = 0, int T_D1D = 0>
static void CollocatedDerivatives3D(const int NE,
const real_t *g_,
const real_t *j_,
const real_t *x_,
real_t *y_,
const int sdim = 3,
const int vdim = 0,
const int d1d = 0)
{
MFEM_VERIFY(sdim == 3, "");
const int D1D = T_D1D ? T_D1D : d1d;
const int VDIM = T_VDIM ? T_VDIM : vdim;
const auto g = Reshape(g_, D1D, D1D);
const auto j = Reshape(j_, D1D, D1D, D1D, 3, 3, NE);
const auto x = Reshape(x_, D1D, D1D, D1D, VDIM, NE);
auto y = Q_LAYOUT == QVectorLayout:: byNODES ?
Reshape(y_, D1D, D1D, D1D, VDIM, 3, NE):
Reshape(y_, VDIM, 3, D1D, D1D, D1D, NE);
mfem::forall_3D(NE, D1D, D1D, D1D, [=] MFEM_HOST_DEVICE (int e)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int VDIM = T_VDIM ? T_VDIM : vdim;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_INTERP_1D;
MFEM_SHARED real_t uvw[MD1*MD1*MD1];
DeviceTensor<3> X(uvw, D1D, D1D, D1D);
for (int c = 0; c < VDIM; ++c)
{
kernels::internal::LoadX(e,D1D,c,x,X);
MFEM_FOREACH_THREAD(dz,z,D1D)
{
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
{
real_t u = 0.0;
real_t v = 0.0;
real_t w = 0.0;
for (int dxyz = 0; dxyz < D1D; ++dxyz)
{
u += X(dxyz, dy, dz) * g(dx,dxyz);
v += X(dx, dxyz, dz) * g(dy,dxyz);
w += X(dx, dy, dxyz) * g(dz,dxyz);
}
if (GRAD_PHYS)
{
real_t Jloc[9], Jinv[9];
for (int col = 0; col < 3; col++)
{
for (int row = 0; row < 3; row++)
{
Jloc[row+3*col] = j(dx,dy,dz,row,col,e);
}
}
kernels::CalcInverse<3>(Jloc, Jinv);
const real_t U = Jinv[0]*u + Jinv[1]*v + Jinv[2]*w;
const real_t V = Jinv[3]*u + Jinv[4]*v + Jinv[5]*w;
const real_t W = Jinv[6]*u + Jinv[7]*v + Jinv[8]*w;
u = U; v = V; w = W;
}
if (Q_LAYOUT == QVectorLayout::byVDIM)
{
y(c,0,dx,dy,dz,e) = u;
y(c,1,dx,dy,dz,e) = v;
y(c,2,dx,dy,dz,e) = w;
}
if (Q_LAYOUT == QVectorLayout::byNODES)
{
y(dx,dy,dz,c,0,e) = u;
y(dx,dy,dz,c,1,e) = v;
y(dx,dy,dz,c,2,e) = w;
}
}
}
}
MFEM_SYNC_THREAD;
}
});
}
} // namespace quadrature_interpolator
} // namespace internal
/// @cond Suppress_Doxygen_warnings
template<int DIM, QVectorLayout Q_LAYOUT, bool GRAD_PHYS, int VDIM, int D1D,
int Q1D, int NBZ>
QuadratureInterpolator::GradKernelType
QuadratureInterpolator::GradKernels::Kernel()
{
if (DIM == 1) { return internal::quadrature_interpolator::Derivatives1D<Q_LAYOUT, GRAD_PHYS>; }
else if (DIM == 2) { return internal::quadrature_interpolator::Derivatives2D<Q_LAYOUT, GRAD_PHYS, VDIM, D1D, Q1D, NBZ>; }
else if (DIM == 3) { return internal::quadrature_interpolator::Derivatives3D<Q_LAYOUT, GRAD_PHYS, VDIM, D1D, Q1D>; }
else { MFEM_ABORT(""); }
}
template<int DIM, QVectorLayout Q_LAYOUT, bool GRAD_PHYS, int VDIM, int D1D,
int NBZ>
QuadratureInterpolator::CollocatedGradKernelType
QuadratureInterpolator::CollocatedGradKernels::Kernel()
{
if (DIM == 1) { return internal::quadrature_interpolator::CollocatedDerivatives1D<Q_LAYOUT, GRAD_PHYS>; }
else if (DIM == 2) { return internal::quadrature_interpolator::CollocatedDerivatives2D<Q_LAYOUT, GRAD_PHYS, VDIM, D1D, NBZ>; }
else if (DIM == 3) { return internal::quadrature_interpolator::CollocatedDerivatives3D<Q_LAYOUT, GRAD_PHYS, VDIM, D1D>; }
else { MFEM_ABORT(""); }
}
/// @endcond
} // namespace mfem
#endif
+65 -101
View File
@@ -9,128 +9,92 @@
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.
#include "dispatch.hpp"
#include "../quadinterpolator.hpp"
#include "grad.hpp"
namespace mfem
{
namespace internal
{
namespace quadrature_interpolator
{
// Tensor-product evaluation of quadrature point derivatives: dispatch function.
// Instantiation for the case QVectorLayout::byNODES.
template<>
void TensorDerivatives<QVectorLayout::byNODES>(const int NE,
const int vdim,
const DofToQuad &maps,
const Vector &e_vec,
Vector &q_der)
template <bool P>
void InitGradByNodesKernels()
{
if (NE == 0) { return; }
const int dim = maps.FE->GetDim();
const int D1D = maps.ndof;
const int Q1D = maps.nqpt;
const real_t *B = maps.B.Read();
const real_t *G = maps.G.Read();
const real_t *J = nullptr; // not used in DERIVATIVES (non-GRAD_PHYS) mode
const real_t *X = e_vec.Read();
real_t *Y = q_der.Write();
using k = QuadratureInterpolator::GradKernels;
constexpr auto L = QVectorLayout::byNODES;
// 2D
k::Specialization<2,L,P,1,3,3>::template Opt<16>::Add();
k::Specialization<2,L,P,1,3,4>::template Opt<16>::Add();
k::Specialization<2,L,P,1,4,3>::template Opt<16>::Add();
k::Specialization<2,L,P,1,4,4>::template Opt<16>::Add();
constexpr QVectorLayout L = QVectorLayout::byNODES;
constexpr bool P = false; // GRAD_PHYS
k::Specialization<2,L,P,2,2,2>::template Opt<16>::Add();
k::Specialization<2,L,P,2,2,3>::template Opt<8>::Add();
k::Specialization<2,L,P,2,2,4>::template Opt<4>::Add();
k::Specialization<2,L,P,2,2,5>::template Opt<4>::Add();
k::Specialization<2,L,P,2,2,6>::template Opt<2>::Add();
const int id = (vdim<<8) | (D1D<<4) | Q1D;
k::Specialization<2,L,P,2,3,3>::template Opt<2>::Add();
k::Specialization<2,L,P,2,3,4>::template Opt<4>::Add();
k::Specialization<2,L,P,2,4,3>::template Opt<4>::Add();
k::Specialization<2,L,P,2,3,6>::template Opt<2>::Add();
if (dim == 1)
{
return Derivatives1D<L,P>(NE,G,J,X,Y,dim,vdim,D1D,Q1D);
}
if (dim == 2)
{
switch (id)
{
case 0x133: return Derivatives2D<L,P,1,3,3,16>(NE,B,G,J,X,Y);
case 0x134: return Derivatives2D<L,P,1,3,4,16>(NE,B,G,J,X,Y);
case 0x143: return Derivatives2D<L,P,1,4,3,16>(NE,B,G,J,X,Y);
case 0x144: return Derivatives2D<L,P,1,4,4,16>(NE,B,G,J,X,Y);
k::Specialization<2,L,P,2,4,4>::template Opt<2>::Add();
k::Specialization<2,L,P,2,4,5>::template Opt<2>::Add();
k::Specialization<2,L,P,2,4,6>::template Opt<2>::Add();
k::Specialization<2,L,P,2,4,7>::template Opt<2>::Add();
case 0x222: return Derivatives2D<L,P,2,2,2,16>(NE,B,G,J,X,Y);
case 0x223: return Derivatives2D<L,P,2,2,3,8>(NE,B,G,J,X,Y);
case 0x224: return Derivatives2D<L,P,2,2,4,4>(NE,B,G,J,X,Y);
case 0x225: return Derivatives2D<L,P,2,2,5,4>(NE,B,G,J,X,Y);
case 0x226: return Derivatives2D<L,P,2,2,6,2>(NE,B,G,J,X,Y);
k::Specialization<2,L,P,2,5,6>::template Opt<2>::Add();
// 3D
k::Specialization<3,L,P,1,2,4>::Add();
k::Specialization<3,L,P,1,3,3>::Add();
k::Specialization<3,L,P,1,3,4>::Add();
k::Specialization<3,L,P,1,3,6>::Add();
k::Specialization<3,L,P,1,4,4>::Add();
k::Specialization<3,L,P,1,4,8>::Add();
case 0x233: return Derivatives2D<L,P,2,3,3,2>(NE,B,G,J,X,Y);
case 0x234: return Derivatives2D<L,P,2,3,4,4>(NE,B,G,J,X,Y);
case 0x243: return Derivatives2D<L,P,2,4,3,4>(NE,B,G,J,X,Y);
case 0x236: return Derivatives2D<L,P,2,3,6,2>(NE,B,G,J,X,Y);
k::Specialization<3,L,P,3,2,3>::Add();
k::Specialization<3,L,P,3,2,4>::Add();
k::Specialization<3,L,P,3,2,5>::Add();
k::Specialization<3,L,P,3,2,6>::Add();
case 0x244: return Derivatives2D<L,P,2,4,4,2>(NE,B,G,J,X,Y);
case 0x245: return Derivatives2D<L,P,2,4,5,2>(NE,B,G,J,X,Y);
case 0x246: return Derivatives2D<L,P,2,4,6,2>(NE,B,G,J,X,Y);
case 0x247: return Derivatives2D<L,P,2,4,7,2>(NE,B,G,J,X,Y);
k::Specialization<3,L,P,3,3,3>::Add();
k::Specialization<3,L,P,3,3,4>::Add();
k::Specialization<3,L,P,3,3,5>::Add();
k::Specialization<3,L,P,3,3,6>::Add();
k::Specialization<3,L,P,3,4,4>::Add();
k::Specialization<3,L,P,3,4,6>::Add();
k::Specialization<3,L,P,3,4,7>::Add();
k::Specialization<3,L,P,3,4,8>::Add();
case 0x256: return Derivatives2D<L,P,2,5,6,2>(NE,B,G,J,X,Y);
default:
{
const int MD = DeviceDofQuadLimits::Get().MAX_D1D;
const int MQ = DeviceDofQuadLimits::Get().MAX_Q1D;
if (D1D > MD || Q1D > MQ)
{
MFEM_ABORT("");
}
Derivatives2D<L,P>(NE,B,G,J,X,Y,dim,vdim,D1D,Q1D);
return;
}
}
}
if (dim == 3)
{
switch (id)
{
case 0x124: return Derivatives3D<L,P,1,2,4>(NE,B,G,J,X,Y);
case 0x133: return Derivatives3D<L,P,1,3,3>(NE,B,G,J,X,Y);
case 0x134: return Derivatives3D<L,P,1,3,4>(NE,B,G,J,X,Y);
case 0x136: return Derivatives3D<L,P,1,3,6>(NE,B,G,J,X,Y);
case 0x144: return Derivatives3D<L,P,1,4,4>(NE,B,G,J,X,Y);
case 0x148: return Derivatives3D<L,P,1,4,8>(NE,B,G,J,X,Y);
using k2 = QuadratureInterpolator::CollocatedGradKernels;
case 0x323: return Derivatives3D<L,P,3,2,3>(NE,B,G,J,X,Y);
case 0x324: return Derivatives3D<L,P,3,2,4>(NE,B,G,J,X,Y);
case 0x325: return Derivatives3D<L,P,3,2,5>(NE,B,G,J,X,Y);
case 0x326: return Derivatives3D<L,P,3,2,6>(NE,B,G,J,X,Y);
// 2D
k2::Specialization<2,L,P,1,2>::template Opt<16>::Add();
k2::Specialization<2,L,P,1,3>::template Opt<16>::Add();
k2::Specialization<2,L,P,1,4>::template Opt<16>::Add();
k2::Specialization<2,L,P,2,2>::template Opt<16>::Add();
k2::Specialization<2,L,P,2,3>::template Opt<4>::Add();
k2::Specialization<2,L,P,2,4>::template Opt<2>::Add();
case 0x333: return Derivatives3D<L,P,3,3,3>(NE,B,G,J,X,Y);
case 0x334: return Derivatives3D<L,P,3,3,4>(NE,B,G,J,X,Y);
case 0x335: return Derivatives3D<L,P,3,3,5>(NE,B,G,J,X,Y);
case 0x336: return Derivatives3D<L,P,3,3,6>(NE,B,G,J,X,Y);
case 0x344: return Derivatives3D<L,P,3,4,4>(NE,B,G,J,X,Y);
case 0x346: return Derivatives3D<L,P,3,4,6>(NE,B,G,J,X,Y);
case 0x347: return Derivatives3D<L,P,3,4,7>(NE,B,G,J,X,Y);
case 0x348: return Derivatives3D<L,P,3,4,8>(NE,B,G,J,X,Y);
default:
{
const int MD = DeviceDofQuadLimits::Get().MAX_INTERP_1D;
const int MQ = DeviceDofQuadLimits::Get().MAX_INTERP_1D;
MFEM_VERIFY(D1D <= MD, "Orders higher than " << MD-1
<< " are not supported!");
MFEM_VERIFY(Q1D <= MQ, "Quadrature rules with more than "
<< MQ << " 1D points are not supported!");
Derivatives3D<L,P>(NE,B,G,J,X,Y,vdim,D1D,Q1D);
return;
}
}
}
mfem::out << "Unknown kernel 0x" << std::hex << id << std::endl;
MFEM_ABORT("Kernel not supported yet");
k2::Specialization<3,L,P,1,2>::Add();
k2::Specialization<3,L,P,1,3>::Add();
k2::Specialization<3,L,P,1,4>::Add();
k2::Specialization<3,L,P,2,2>::Add();
k2::Specialization<3,L,P,2,3>::Add();
k2::Specialization<3,L,P,2,4>::Add();
k2::Specialization<3,L,P,3,2>::Add();
k2::Specialization<3,L,P,3,3>::Add();
k2::Specialization<3,L,P,3,4>::Add();
}
template void InitGradByNodesKernels<true>();
template void InitGradByNodesKernels<false>();
} // namespace quadrature_interpolator
} // namespace internal
} // namespace mfem
+42 -77
View File
@@ -9,100 +9,65 @@
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.
#include "dispatch.hpp"
#include "../quadinterpolator.hpp"
#include "grad.hpp"
namespace mfem
{
namespace internal
{
namespace quadrature_interpolator
{
// Tensor-product evaluation of quadrature point derivatives: dispatch function.
// Instantiation for the case QVectorLayout::byVDIM.
template<>
void TensorDerivatives<QVectorLayout::byVDIM>(const int NE,
const int vdim,
const DofToQuad &maps,
const Vector &e_vec,
Vector &q_der)
template <bool P>
void InitGradByVDimKernels()
{
if (NE == 0) { return; }
const int dim = maps.FE->GetDim();
const int D1D = maps.ndof;
const int Q1D = maps.nqpt;
const real_t *B = maps.B.Read();
const real_t *G = maps.G.Read();
const real_t *J = nullptr; // not used in DERIVATIVES (non-GRAD_PHYS) mode
const real_t *X = e_vec.Read();
real_t *Y = q_der.Write();
using k = QuadratureInterpolator::GradKernels;
constexpr auto L = QVectorLayout::byVDIM;
// 2D
k::Specialization<2,L,P,1,3,4>::template Opt<8>::Add();
k::Specialization<2,L,P,1,4,6>::template Opt<4>::Add();
k::Specialization<2,L,P,1,5,8>::template Opt<2>::Add();
constexpr QVectorLayout L = QVectorLayout::byVDIM;
constexpr bool P = false; // GRAD_PHYS
k::Specialization<2,L,P,2,3,3>::template Opt<8>::Add();
k::Specialization<2,L,P,2,3,4>::template Opt<8>::Add();
k::Specialization<2,L,P,2,4,6>::template Opt<4>::Add();
k::Specialization<2,L,P,2,5,8>::template Opt<2>::Add();
// 3D
k::Specialization<3,L,P,1,3,4>::Add();
k::Specialization<3,L,P,1,4,6>::Add();
k::Specialization<3,L,P,1,5,8>::Add();
k::Specialization<3,L,P,3,3,4>::Add();
k::Specialization<3,L,P,3,4,6>::Add();
k::Specialization<3,L,P,3,5,8>::Add();
const int id = (vdim<<8) | (D1D<<4) | Q1D;
using k2 = QuadratureInterpolator::CollocatedGradKernels;
// 2D
k2::Specialization<2,L,P,1,2>::template Opt<16>::Add();
k2::Specialization<2,L,P,1,3>::template Opt<16>::Add();
k2::Specialization<2,L,P,1,4>::template Opt<16>::Add();
if (dim == 1)
{
return Derivatives1D<L,P>(NE,G,J,X,Y,dim,vdim,D1D,Q1D);
}
if (dim == 2)
{
switch (id)
{
case 0x134: return Derivatives2D<L,P,1,3,4,8>(NE,B,G,J,X,Y);
case 0x146: return Derivatives2D<L,P,1,4,6,4>(NE,B,G,J,X,Y);
case 0x158: return Derivatives2D<L,P,1,5,8,2>(NE,B,G,J,X,Y);
k2::Specialization<2,L,P,2,2>::template Opt<16>::Add();
k2::Specialization<2,L,P,2,3>::template Opt<4>::Add();
k2::Specialization<2,L,P,2,4>::template Opt<2>::Add();
case 0x234: return Derivatives2D<L,P,2,3,4,8>(NE,B,G,J,X,Y);
case 0x246: return Derivatives2D<L,P,2,4,6,4>(NE,B,G,J,X,Y);
case 0x258: return Derivatives2D<L,P,2,5,8,2>(NE,B,G,J,X,Y);
default:
{
const int MD = DeviceDofQuadLimits::Get().MAX_D1D;
const int MQ = DeviceDofQuadLimits::Get().MAX_Q1D;
MFEM_VERIFY(D1D <= MD, "Orders higher than " << MD-1
<< " are not supported!");
MFEM_VERIFY(Q1D <= MQ, "Quadrature rules with more than "
<< MQ << " 1D points are not supported!");
Derivatives2D<L,P>(NE,B,G,J,X,Y,dim,vdim,D1D,Q1D);
return;
}
}
}
if (dim == 3)
{
switch (id)
{
case 0x134: return Derivatives3D<L,P,1,3,4>(NE,B,G,J,X,Y);
case 0x146: return Derivatives3D<L,P,1,4,6>(NE,B,G,J,X,Y);
case 0x158: return Derivatives3D<L,P,1,5,8>(NE,B,G,J,X,Y);
// 3D
k2::Specialization<3,L,P,1,2>::Add();
k2::Specialization<3,L,P,1,3>::Add();
k2::Specialization<3,L,P,1,4>::Add();
case 0x334: return Derivatives3D<L,P,3,3,4>(NE,B,G,J,X,Y);
case 0x346: return Derivatives3D<L,P,3,4,6>(NE,B,G,J,X,Y);
case 0x358: return Derivatives3D<L,P,3,5,8>(NE,B,G,J,X,Y);
default:
{
const int MD = DeviceDofQuadLimits::Get().MAX_INTERP_1D;
const int MQ = DeviceDofQuadLimits::Get().MAX_INTERP_1D;
MFEM_VERIFY(D1D <= MD, "Orders higher than " << MD-1
<< " are not supported!");
MFEM_VERIFY(Q1D <= MQ, "Quadrature rules with more than "
<< MQ << " 1D points are not supported!");
Derivatives3D<L,P>(NE,B,G,J,X,Y,vdim,D1D,Q1D);
return;
}
}
}
mfem::out << "Unknown kernel 0x" << std::hex << id << std::endl;
MFEM_ABORT("Kernel not supported yet");
k2::Specialization<3,L,P,2,2>::Add();
k2::Specialization<3,L,P,2,3>::Add();
k2::Specialization<3,L,P,2,4>::Add();
k2::Specialization<3,L,P,3,2>::Add();
k2::Specialization<3,L,P,3,3>::Add();
k2::Specialization<3,L,P,3,4>::Add();
}
template void InitGradByVDimKernels<true>();
template void InitGradByVDimKernels<false>();
} // namespace quadrature_interpolator
} // namespace internal
} // namespace mfem
-123
View File
@@ -1,123 +0,0 @@
// Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.
#include "dispatch.hpp"
#include "grad.hpp"
namespace mfem
{
namespace internal
{
namespace quadrature_interpolator
{
// Tensor-product evaluation of quadrature point physical derivatives: dispatch
// function.
// Instantiation for the case QVectorLayout::byNODES.
template<>
void TensorPhysDerivatives<QVectorLayout::byNODES>(const int NE,
const int vdim,
const DofToQuad &maps,
const GeometricFactors &geom,
const Vector &e_vec,
Vector &q_der)
{
if (NE == 0) { return; }
const int dim = maps.FE->GetDim();
const int D1D = maps.ndof;
const int Q1D = maps.nqpt;
const int sdim = geom.mesh->SpaceDimension();
const real_t *B = maps.B.Read();
const real_t *G = maps.G.Read();
const real_t *J = geom.J.Read();
const real_t *X = e_vec.Read();
real_t *Y = q_der.Write();
constexpr QVectorLayout L = QVectorLayout::byNODES;
constexpr bool P = true; // GRAD_PHYS
const int id = (vdim<<8) | (D1D<<4) | Q1D;
if (dim == 1)
{
return Derivatives1D<L,P>(NE,G,J,X,Y,sdim,vdim,D1D,Q1D);
}
if (dim == 2)
{
switch (id)
{
case 0x133: return Derivatives2D<L,P,1,3,3,8>(NE,B,G,J,X,Y,sdim);
case 0x134: return Derivatives2D<L,P,1,3,4,8>(NE,B,G,J,X,Y,sdim);
case 0x143: return Derivatives2D<L,P,1,4,3,4>(NE,B,G,J,X,Y,sdim);
case 0x144: return Derivatives2D<L,P,1,4,4,4>(NE,B,G,J,X,Y,sdim);
case 0x146: return Derivatives2D<L,P,1,4,6,4>(NE,B,G,J,X,Y,sdim);
case 0x158: return Derivatives2D<L,P,1,5,8,2>(NE,B,G,J,X,Y,sdim);
case 0x233: return Derivatives2D<L,P,2,3,3,8>(NE,B,G,J,X,Y,sdim);
case 0x234: return Derivatives2D<L,P,2,3,4,8>(NE,B,G,J,X,Y,sdim);
case 0x243: return Derivatives2D<L,P,2,4,3,4>(NE,B,G,J,X,Y,sdim);
case 0x244: return Derivatives2D<L,P,2,4,4,4>(NE,B,G,J,X,Y,sdim);
case 0x246: return Derivatives2D<L,P,2,4,6,4>(NE,B,G,J,X,Y,sdim);
case 0x258: return Derivatives2D<L,P,2,5,8,2>(NE,B,G,J,X,Y,sdim);
default:
{
const int MD = DeviceDofQuadLimits::Get().MAX_D1D;
const int MQ = DeviceDofQuadLimits::Get().MAX_Q1D;
MFEM_VERIFY(D1D <= MD, "Orders higher than " << MD-1
<< " are not supported!");
MFEM_VERIFY(Q1D <= MQ, "Quadrature rules with more than "
<< MQ << " 1D points are not supported!");
Derivatives2D<L,P>(NE,B,G,J,X,Y,sdim,vdim,D1D,Q1D);
return;
}
}
}
if (dim == 3)
{
switch (id)
{
case 0x133: return Derivatives3D<L,P,1,3,3>(NE,B,G,J,X,Y);
case 0x134: return Derivatives3D<L,P,1,3,4>(NE,B,G,J,X,Y);
case 0x144: return Derivatives3D<L,P,1,4,4>(NE,B,G,J,X,Y);
case 0x146: return Derivatives3D<L,P,1,4,6>(NE,B,G,J,X,Y);
case 0x158: return Derivatives3D<L,P,1,5,8>(NE,B,G,J,X,Y);
case 0x333: return Derivatives3D<L,P,3,3,3>(NE,B,G,J,X,Y);
case 0x334: return Derivatives3D<L,P,3,3,4>(NE,B,G,J,X,Y);
case 0x344: return Derivatives3D<L,P,3,4,4>(NE,B,G,J,X,Y);
case 0x346: return Derivatives3D<L,P,3,4,6>(NE,B,G,J,X,Y);
case 0x358: return Derivatives3D<L,P,3,5,8>(NE,B,G,J,X,Y);
default:
{
const int MD = DeviceDofQuadLimits::Get().MAX_INTERP_1D;
const int MQ = DeviceDofQuadLimits::Get().MAX_INTERP_1D;
MFEM_VERIFY(D1D <= MD, "Orders higher than " << MD-1
<< " are not supported!");
MFEM_VERIFY(Q1D <= MQ, "Quadrature rules with more than "
<< MQ << " 1D points are not supported!");
Derivatives3D<L,P>(NE,B,G,J,X,Y,vdim,D1D,Q1D);
return;
}
}
}
mfem::out << "Unknown kernel 0x" << std::hex << id << std::endl;
MFEM_ABORT("Unknown kernel");
}
} // namespace quadrature_interpolator
} // namespace internal
} // namespace mfem
-114
View File
@@ -1,114 +0,0 @@
// Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.
#include "dispatch.hpp"
#include "grad.hpp"
namespace mfem
{
namespace internal
{
namespace quadrature_interpolator
{
// Tensor-product evaluation of quadrature point physical derivatives: dispatch
// function.
// Instantiation for the case QVectorLayout::byVDIM.
template<>
void TensorPhysDerivatives<QVectorLayout::byVDIM>(const int NE,
const int vdim,
const DofToQuad &maps,
const GeometricFactors &geom,
const Vector &e_vec,
Vector &q_der)
{
if (NE == 0) { return; }
const int dim = maps.FE->GetDim();
const int D1D = maps.ndof;
const int Q1D = maps.nqpt;
const int sdim = geom.mesh->SpaceDimension();
const real_t *B = maps.B.Read();
const real_t *G = maps.G.Read();
const real_t *J = geom.J.Read();
const real_t *X = e_vec.Read();
real_t *Y = q_der.Write();
constexpr QVectorLayout L = QVectorLayout::byVDIM;
constexpr bool P = true; // GRAD_PHYS
const int id = (vdim<<8) | (D1D<<4) | Q1D;
if (dim == 1)
{
return Derivatives1D<L,P>(NE,G,J,X,Y,sdim,vdim,D1D,Q1D);
}
if (dim == 2)
{
switch (id)
{
case 0x134: return Derivatives2D<L,P,1,3,4,8>(NE,B,G,J,X,Y,sdim);
case 0x146: return Derivatives2D<L,P,1,4,6,4>(NE,B,G,J,X,Y,sdim);
case 0x158: return Derivatives2D<L,P,1,5,8,2>(NE,B,G,J,X,Y,sdim);
case 0x233: return Derivatives2D<L,P,2,3,3,8>(NE,B,G,J,X,Y,sdim);
case 0x234: return Derivatives2D<L,P,2,3,4,8>(NE,B,G,J,X,Y,sdim);
case 0x246: return Derivatives2D<L,P,2,4,6,4>(NE,B,G,J,X,Y,sdim);
case 0x258: return Derivatives2D<L,P,2,5,8,2>(NE,B,G,J,X,Y,sdim);
default:
{
const int MD = DeviceDofQuadLimits::Get().MAX_D1D;
const int MQ = DeviceDofQuadLimits::Get().MAX_Q1D;
MFEM_VERIFY(D1D <= MD, "Orders higher than " << MD-1
<< " are not supported!");
MFEM_VERIFY(Q1D <= MQ, "Quadrature rules with more than "
<< MQ << " 1D points are not supported!");
Derivatives2D<L,P>(NE,B,G,J,X,Y,sdim,vdim,D1D,Q1D);
return;
}
}
}
if (dim == 3)
{
switch (id)
{
case 0x134: return Derivatives3D<L,P,1,3,4>(NE,B,G,J,X,Y);
case 0x146: return Derivatives3D<L,P,1,4,6>(NE,B,G,J,X,Y);
case 0x158: return Derivatives3D<L,P,1,5,8>(NE,B,G,J,X,Y);
case 0x334: return Derivatives3D<L,P,3,3,4>(NE,B,G,J,X,Y);
case 0x346: return Derivatives3D<L,P,3,4,6>(NE,B,G,J,X,Y);
case 0x358: return Derivatives3D<L,P,3,5,8>(NE,B,G,J,X,Y);
default:
{
const int MD = DeviceDofQuadLimits::Get().MAX_INTERP_1D;
const int MQ = DeviceDofQuadLimits::Get().MAX_INTERP_1D;
MFEM_VERIFY(D1D <= MD, "Orders higher than " << MD-1
<< " are not supported!");
MFEM_VERIFY(Q1D <= MQ, "Quadrature rules with more than "
<< MQ << " 1D points are not supported!");
Derivatives3D<L,P>(NE,B,G,J,X,Y,vdim,D1D,Q1D);
return;
}
}
}
mfem::out << "Unknown kernel 0x" << std::hex << id << std::endl;
MFEM_ABORT("Unknown kernel");
}
} // namespace quadrature_interpolator
} // namespace internal
} // namespace mfem
+265 -187
View File
@@ -10,7 +10,8 @@
// CONTRIBUTING.md for details.
#include "quadinterpolator.hpp"
#include "qinterp/dispatch.hpp"
#include "qinterp/grad.hpp"
#include "qinterp/eval.hpp"
#include "qspace.hpp"
#include "../general/forall.hpp"
#include "../linalg/dtensor.hpp"
@@ -19,6 +20,39 @@
namespace mfem
{
namespace internal
{
namespace quadrature_interpolator
{
void InitEvalByNodesKernels();
void InitEvalByVDimKernels();
void InitEvalKernels();
void InitDetKernels();
template <bool P> void InitGradByNodesKernels();
template <bool P> void InitGradByVDimKernels();
struct Kernels
{
Kernels()
{
using namespace internal::quadrature_interpolator;
InitEvalByNodesKernels();
InitEvalByVDimKernels();
// Non-phys grad kernels
InitGradByNodesKernels<false>();
InitGradByVDimKernels<false>();
// Phys grad kernels
InitGradByNodesKernels<true>();
InitGradByVDimKernels<true>();
// Determinants
InitDetKernels();
// Non-tensor
InitEvalKernels();
}
};
}
}
QuadratureInterpolator::QuadratureInterpolator(const FiniteElementSpace &fes,
const IntegrationRule &ir):
@@ -28,6 +62,8 @@ QuadratureInterpolator::QuadratureInterpolator(const FiniteElementSpace &fes,
q_layout(QVectorLayout::byNODES),
use_tensor_products(UsesTensorBasis(fes))
{
static internal::quadrature_interpolator::Kernels kernels;
d_buffer.UseDevice(true);
if (fespace->GetNE() == 0) { return; }
const FiniteElement *fe = fespace->GetFE(0);
@@ -467,6 +503,7 @@ void QuadratureInterpolator::Mult(const Vector &e_vec,
const int ne = fespace->GetNE();
if (ne == 0) { return; }
const int vdim = fespace->GetVDim();
const int sdim = fespace->GetMesh()->SpaceDimension();
const FiniteElement *fe = fespace->GetFE(0);
const bool use_tensor_eval =
use_tensor_products &&
@@ -477,6 +514,8 @@ void QuadratureInterpolator::Mult(const Vector &e_vec,
use_tensor_eval ? DofToQuad::TENSOR : DofToQuad::FULL;
const DofToQuad &maps = fe->GetDofToQuad(*ir, mode);
const int dim = maps.FE->GetDim();
const int nd = maps.ndof;
const int nq = maps.nqpt;
const GeometricFactors *geom = nullptr;
if (eval_flags & PHYSICAL_DERIVATIVES)
{
@@ -492,202 +531,31 @@ void QuadratureInterpolator::Mult(const Vector &e_vec,
if (use_tensor_eval)
{
// TODO: use fused kernels
if (q_layout == QVectorLayout::byNODES)
if (eval_flags & VALUES)
{
if (eval_flags & VALUES)
{
TensorValues<QVectorLayout::byNODES>(ne, vdim, maps, e_vec, q_val);
}
if (eval_flags & DERIVATIVES)
{
TensorDerivatives<QVectorLayout::byNODES>(
ne, vdim, maps, e_vec, q_der);
}
if (eval_flags & PHYSICAL_DERIVATIVES)
{
TensorPhysDerivatives<QVectorLayout::byNODES>(
ne, vdim, maps, *geom, e_vec, q_der);
}
TensorEvalKernels::Run(dim, q_layout, vdim, nd, nq, ne, maps.B.Read(),
e_vec.Read(), q_val.Write(), vdim, nd, nq);
}
if (q_layout == QVectorLayout::byVDIM)
if (eval_flags & (DERIVATIVES | PHYSICAL_DERIVATIVES))
{
if (eval_flags & VALUES)
{
TensorValues<QVectorLayout::byVDIM>(ne, vdim, maps, e_vec, q_val);
}
if (eval_flags & DERIVATIVES)
{
TensorDerivatives<QVectorLayout::byVDIM>(
ne, vdim, maps, e_vec, q_der);
}
if (eval_flags & PHYSICAL_DERIVATIVES)
{
TensorPhysDerivatives<QVectorLayout::byVDIM>(
ne, vdim, maps, *geom, e_vec, q_der);
}
const bool phys = (eval_flags & PHYSICAL_DERIVATIVES);
const real_t *J = phys ? geom->J.Read() : nullptr;
const int s_dim = phys ? sdim : dim;
GradKernels::Run(dim, q_layout, phys, vdim, nd, nq, ne,
maps.B.Read(), maps.G.Read(), J, e_vec.Read(),
q_der.Write(), s_dim, vdim, nd, nq);
}
if (eval_flags & DETERMINANTS)
{
TensorDeterminants(ne, vdim, maps, e_vec, q_det, d_buffer);
DetKernels::Run(dim, vdim, nd, nq, ne, maps.B.Read(),
maps.G.Read(), e_vec.Read(), q_det.Write(), nd,
nq, &d_buffer);
}
}
else // use_tensor_eval == false
{
const int nd = maps.ndof;
const int nq = maps.nqpt;
void (*mult)(const int NE,
const int vdim,
const QVectorLayout q_layout,
const GeometricFactors *geom,
const DofToQuad &maps,
const Vector &e_vec,
Vector &q_val,
Vector &q_der,
Vector &q_det,
const int eval_flags) = NULL;
if (dim == 1)
{
mult = &Eval1D;
}
else if (vdim == 1) // dim == 2 || dim == 3
{
if (dim == 2)
{
switch (100*nd + nq)
{
// Q0
case 101: mult = &Eval2D<1,1,1>; break;
case 104: mult = &Eval2D<1,1,4>; break;
// Q1
case 404: mult = &Eval2D<1,4,4>; break;
case 409: mult = &Eval2D<1,4,9>; break;
// Q2
case 909: mult = &Eval2D<1,9,9>; break;
case 916: mult = &Eval2D<1,9,16>; break;
// Q3
case 1616: mult = &Eval2D<1,16,16>; break;
case 1625: mult = &Eval2D<1,16,25>; break;
case 1636: mult = &Eval2D<1,16,36>; break;
// Q4
case 2525: mult = &Eval2D<1,25,25>; break;
case 2536: mult = &Eval2D<1,25,36>; break;
case 2549: mult = &Eval2D<1,25,49>; break;
case 2564: mult = &Eval2D<1,25,64>; break;
}
if (nq >= 100 || !mult)
{
mult = &Eval2D<1,0,0>;
}
}
else if (dim == 3)
{
switch (1000*nd + nq)
{
// Q0
case 1001: mult = &Eval3D<1,1,1>; break;
case 1008: mult = &Eval3D<1,1,8>; break;
// Q1
case 8008: mult = &Eval3D<1,8,8>; break;
case 8027: mult = &Eval3D<1,8,27>; break;
// Q2
case 27027: mult = &Eval3D<1,27,27>; break;
case 27064: mult = &Eval3D<1,27,64>; break;
// Q3
case 64064: mult = &Eval3D<1,64,64>; break;
case 64125: mult = &Eval3D<1,64,125>; break;
case 64216: mult = &Eval3D<1,64,216>; break;
// Q4
case 125125: mult = &Eval3D<1,125,125>; break;
case 125216: mult = &Eval3D<1,125,216>; break;
}
if (nq >= 1000 || !mult)
{
mult = &Eval3D<1,0,0>;
}
}
}
else if (vdim == 3 && dim == 2)
{
switch (100*nd + nq)
{
// Q0
case 101: mult = &Eval2D<3,1,1>; break;
case 104: mult = &Eval2D<3,1,4>; break;
// Q1
case 404: mult = &Eval2D<3,4,4>; break;
case 409: mult = &Eval2D<3,4,9>; break;
// Q2
case 904: mult = &Eval2D<3,9,4>; break;
case 909: mult = &Eval2D<3,9,9>; break;
case 916: mult = &Eval2D<3,9,16>; break;
case 925: mult = &Eval2D<3,9,25>; break;
// Q3
case 1616: mult = &Eval2D<3,16,16>; break;
case 1625: mult = &Eval2D<3,16,25>; break;
case 1636: mult = &Eval2D<3,16,36>; break;
// Q4
case 2525: mult = &Eval2D<3,25,25>; break;
case 2536: mult = &Eval2D<3,25,36>; break;
case 2549: mult = &Eval2D<3,25,49>; break;
case 2564: mult = &Eval2D<3,25,64>; break;
default: mult = &Eval2D<3,0,0>;
}
}
else if (vdim == dim)
{
if (dim == 2)
{
switch (100*nd + nq)
{
// Q1
case 404: mult = &Eval2D<2,4,4>; break;
case 409: mult = &Eval2D<2,4,9>; break;
// Q2
case 909: mult = &Eval2D<2,9,9>; break;
case 916: mult = &Eval2D<2,9,16>; break;
// Q3
case 1616: mult = &Eval2D<2,16,16>; break;
case 1625: mult = &Eval2D<2,16,25>; break;
case 1636: mult = &Eval2D<2,16,36>; break;
// Q4
case 2525: mult = &Eval2D<2,25,25>; break;
case 2536: mult = &Eval2D<2,25,36>; break;
case 2549: mult = &Eval2D<2,25,49>; break;
case 2564: mult = &Eval2D<2,25,64>; break;
}
if (nq >= 100 || !mult) { mult = &Eval2D<2,0,0>; }
}
else if (dim == 3)
{
switch (1000*nd + nq)
{
// Q1
case 8008: mult = &Eval3D<3,8,8>; break;
case 8027: mult = &Eval3D<3,8,27>; break;
// Q2
case 27027: mult = &Eval3D<3,27,27>; break;
case 27064: mult = &Eval3D<3,27,64>; break;
case 27125: mult = &Eval3D<3,27,125>; break;
// Q3
case 64064: mult = &Eval3D<3,64,64>; break;
case 64125: mult = &Eval3D<3,64,125>; break;
case 64216: mult = &Eval3D<3,64,216>; break;
// Q4
case 125125: mult = &Eval3D<3,125,125>; break;
case 125216: mult = &Eval3D<3,125,216>; break;
}
if (nq >= 1000 || !mult) { mult = &Eval3D<3,0,0>; }
}
}
if (mult)
{
mult(ne,vdim,q_layout,geom,maps,e_vec,q_val,q_der,q_det,eval_flags);
}
else { MFEM_ABORT("case not supported yet"); }
EvalKernels::Run(dim, vdim, maps.ndof, maps.nqpt, ne,vdim,q_layout,
geom, maps,e_vec, q_val,q_der,q_det,eval_flags);
}
}
@@ -731,4 +599,214 @@ void QuadratureInterpolator::Determinants(const Vector &e_vec,
Mult(e_vec, DETERMINANTS, empty, empty, q_det);
}
/// @cond Suppress_Doxygen_warnings
namespace
{
using namespace internal::quadrature_interpolator;
using EvalKernel = QuadratureInterpolator::EvalKernelType;
using TensorEvalKernel = QuadratureInterpolator::TensorEvalKernelType;
using GradKernel = QuadratureInterpolator::GradKernelType;
using CollocatedGradKernel = QuadratureInterpolator::CollocatedGradKernelType;
template <QVectorLayout Q_LAYOUT>
TensorEvalKernel FallbackTensorEvalKernel(int DIM)
{
if (DIM == 1) { return Values1D<Q_LAYOUT>; }
else if (DIM == 2) { return Values2D<Q_LAYOUT>; }
else if (DIM == 3) { return Values3D<Q_LAYOUT>; }
else { MFEM_ABORT(""); }
}
template<QVectorLayout Q_LAYOUT, bool GRAD_PHYS>
GradKernel GetGradKernel(int DIM)
{
if (DIM == 1) { return Derivatives1D<Q_LAYOUT, GRAD_PHYS>; }
else if (DIM == 2) { return Derivatives2D<Q_LAYOUT, GRAD_PHYS>; }
else if (DIM == 3) { return Derivatives3D<Q_LAYOUT, GRAD_PHYS>; }
else { MFEM_ABORT(""); }
}
template<QVectorLayout Q_LAYOUT>
GradKernel GetGradKernel(int DIM, bool GRAD_PHYS)
{
if (GRAD_PHYS) { return GetGradKernel<Q_LAYOUT, true>(DIM); }
else { return GetGradKernel<Q_LAYOUT, false>(DIM); }
}
template<QVectorLayout Q_LAYOUT, bool GRAD_PHYS>
CollocatedGradKernel GetCollocatedGradKernel(int DIM)
{
if (DIM == 1) { return CollocatedDerivatives1D<Q_LAYOUT, GRAD_PHYS>; }
else if (DIM == 2) { return CollocatedDerivatives2D<Q_LAYOUT, GRAD_PHYS>; }
else if (DIM == 3) { return CollocatedDerivatives3D<Q_LAYOUT, GRAD_PHYS>; }
else { MFEM_ABORT(""); }
}
template<QVectorLayout Q_LAYOUT>
CollocatedGradKernel GetCollocatedGradKernel(int DIM, bool GRAD_PHYS)
{
if (GRAD_PHYS) { return GetCollocatedGradKernel<Q_LAYOUT, true>(DIM); }
else { return GetCollocatedGradKernel<Q_LAYOUT, false>(DIM); }
}
} // namespace
template <int DIM, int VDIM, int ND, int NQ>
EvalKernel QuadratureInterpolator::EvalKernels::Kernel()
{
using namespace internal::quadrature_interpolator;
if (DIM == 1) { return Eval1D; }
else if (DIM == 2) { return Eval2D<VDIM,ND,NQ>; }
else if (DIM == 3) { return Eval3D<VDIM,ND,NQ>; }
else { MFEM_ABORT(""); }
}
template <int DIM>
EvalKernel GetEvalKernelVDimFallback(int VDIM)
{
using EvalKernels = QuadratureInterpolator::EvalKernels;
if (VDIM == 1) { return EvalKernels::Kernel<DIM,1,0,0>(); }
else if (VDIM == 2) { return EvalKernels::Kernel<DIM,2,0,0>(); }
else if (VDIM == 3) { return EvalKernels::Kernel<DIM,3,0,0>(); }
else { MFEM_ABORT(""); }
}
EvalKernel QuadratureInterpolator::EvalKernels::Fallback(
int DIM, int VDIM, int ND, int NQ)
{
if (DIM == 1) { return GetEvalKernelVDimFallback<1>(VDIM); }
else if (DIM == 2) { return GetEvalKernelVDimFallback<2>(VDIM); }
else if (DIM == 3) { return GetEvalKernelVDimFallback<3>(VDIM); }
else { MFEM_ABORT(""); }
}
TensorEvalKernel QuadratureInterpolator::TensorEvalKernels::Fallback(
int DIM, QVectorLayout Q_LAYOUT, int, int, int)
{
if (Q_LAYOUT == QVectorLayout::byNODES) { return FallbackTensorEvalKernel<QVectorLayout::byNODES>(DIM); }
else { return FallbackTensorEvalKernel<QVectorLayout::byVDIM>(DIM); }
}
GradKernel QuadratureInterpolator::GradKernels::Fallback(
int DIM, QVectorLayout Q_LAYOUT, bool GRAD_PHYS, int, int, int)
{
if (Q_LAYOUT == QVectorLayout::byNODES) { return GetGradKernel<QVectorLayout::byNODES>(DIM, GRAD_PHYS); }
else { return GetGradKernel<QVectorLayout::byVDIM>(DIM, GRAD_PHYS); }
}
CollocatedGradKernel QuadratureInterpolator::CollocatedGradKernels::Fallback(
int DIM, QVectorLayout Q_LAYOUT, bool GRAD_PHYS, int, int)
{
if (Q_LAYOUT == QVectorLayout::byNODES) { return GetCollocatedGradKernel<QVectorLayout::byNODES>(DIM, GRAD_PHYS); }
else { return GetCollocatedGradKernel<QVectorLayout::byVDIM>(DIM, GRAD_PHYS); }
}
/// @endcond
namespace internal
{
namespace quadrature_interpolator
{
void InitEvalKernels()
{
using k = QuadratureInterpolator::EvalKernels;
// 2D, VDIM = 1
k::Specialization<2,1,1,1>::Add();
k::Specialization<2,1,1,4>::Add();
// Q1
k::Specialization<2,1,4,4>::Add();
k::Specialization<2,1,4,9>::Add();
// Q2
k::Specialization<2,1,9,9>::Add();
k::Specialization<2,1,9,16>::Add();
// Q3
k::Specialization<2,1,16,16>::Add();
k::Specialization<2,1,16,25>::Add();
k::Specialization<2,1,16,36>::Add();
// Q4
k::Specialization<2,1,25,25>::Add();
k::Specialization<2,1,25,36>::Add();
k::Specialization<2,1,25,49>::Add();
k::Specialization<2,1,25,64>::Add();
// 3D, VDIM = 1
// Q0
k::Specialization<3,1,1,1>::Add();
k::Specialization<3,1,1,8>::Add();
// Q1
k::Specialization<3,1,8,8>::Add();
k::Specialization<3,1,8,27>::Add();
// Q2
k::Specialization<3,1,27,27>::Add();
k::Specialization<3,1,27,64>::Add();
// Q3
k::Specialization<3,1,64,64>::Add();
k::Specialization<3,1,64,125>::Add();
k::Specialization<3,1,64,216>::Add();
// Q4
k::Specialization<3,1,125,125>::Add();
k::Specialization<3,1,125,216>::Add();
// 2D, VDIM = 3
// Q0
k::Specialization<2,3,1,1>::Add();
k::Specialization<2,3,1,4>::Add();
// Q1
k::Specialization<2,3,4,4>::Add();
k::Specialization<2,3,4,9>::Add();
// Q2
k::Specialization<2,3,9,4>::Add();
k::Specialization<2,3,9,9>::Add();
k::Specialization<2,3,9,16>::Add();
k::Specialization<2,3,9,25>::Add();
// Q3
k::Specialization<2,3,16,16>::Add();
k::Specialization<2,3,16,25>::Add();
k::Specialization<2,3,16,36>::Add();
// Q4
k::Specialization<2,3,25,25>::Add();
k::Specialization<2,3,25,36>::Add();
k::Specialization<2,3,25,49>::Add();
k::Specialization<2,3,25,64>::Add();
// 2D, VDIM = 2
// Q1
k::Specialization<2,2,4,4>::Add();
k::Specialization<2,2,4,9>::Add();
// Q2
k::Specialization<2,2,9,9>::Add();
k::Specialization<2,2,9,16>::Add();
// Q3
k::Specialization<2,2,16,16>::Add();
k::Specialization<2,2,16,25>::Add();
k::Specialization<2,2,16,36>::Add();
// Q4
k::Specialization<2,2,25,25>::Add();
k::Specialization<2,2,25,36>::Add();
k::Specialization<2,2,25,49>::Add();
k::Specialization<2,2,25,64>::Add();
// 3D, VDIM = 3
// Q1
k::Specialization<3,3,8,8>::Add();
k::Specialization<3,3,8,27>::Add();
// Q2
k::Specialization<3,3,27,27>::Add();
k::Specialization<3,3,27,64>::Add();
k::Specialization<3,3,27,125>::Add();
// Q3
k::Specialization<3,3,64,64>::Add();
k::Specialization<3,3,64,125>::Add();
k::Specialization<3,3,64,216>::Add();
// Q4
k::Specialization<3,3,125,125>::Add();
k::Specialization<3,3,125,216>::Add();
}
} // namespace quadrature_Interpolator
} // namespace internal
} // namespace mfem
+28
View File
@@ -13,6 +13,7 @@
#define MFEM_QUADINTERP
#include "fespace.hpp"
#include "kernel_dispatch.hpp"
namespace mfem
{
@@ -130,6 +131,33 @@ public:
/// Perform the transpose operation of Mult(). (TODO)
void MultTranspose(unsigned eval_flags, const Vector &q_val,
const Vector &q_der, Vector &e_vec) const;
using TensorEvalKernelType = void(*)(const int, const real_t *, const real_t *,
real_t *, const int, const int, const int);
using GradKernelType = void(*)(const int, const real_t *, const real_t *,
const real_t *, const real_t *, real_t *,
const int, const int, const int, const int);
using CollocatedGradKernelType = void(*)(const int, const real_t *,
const real_t *, const real_t *,
real_t *, const int, const int,
const int);
using DetKernelType = void(*)(const int NE, const real_t *, const real_t *,
const real_t *, real_t *, const int, const int,
Vector *);
using EvalKernelType = void(*)(const int, const int, const QVectorLayout,
const GeometricFactors *, const DofToQuad &,
const Vector &, Vector &, Vector &, Vector &,
const int);
MFEM_REGISTER_KERNELS(TensorEvalKernels, TensorEvalKernelType,
(int, QVectorLayout, int, int, int), (int));
MFEM_REGISTER_KERNELS(GradKernels, GradKernelType,
(int, QVectorLayout, bool, int, int, int), (int));
MFEM_REGISTER_KERNELS(DetKernels, DetKernelType, (int, int, int, int));
MFEM_REGISTER_KERNELS(EvalKernels, EvalKernelType, (int, int, int, int));
MFEM_REGISTER_KERNELS(CollocatedGradKernels, CollocatedGradKernelType,
(int, QVectorLayout, bool, int, int), (int));
};
}
+2 -2
View File
@@ -184,8 +184,8 @@ public:
face degrees of freedom.
@param[in] a Scalar coefficient for addition.
*/
virtual void AddMultTranspose(const Vector &x, Vector &y,
const real_t a = 1.0) const override = 0;
void AddMultTranspose(const Vector &x, Vector &y,
const real_t a = 1.0) const override = 0;
/** @brief Add the face degrees of freedom @a x to the element degrees of
freedom @a y ignoring the signs from DOF orientation. */
+3 -3
View File
@@ -151,13 +151,13 @@ public:
}
/// Get the input finite element space prolongation matrix
virtual const Operator *GetProlongation() const
const Operator *GetProlongation() const override
{ return ((FiniteElementSpace &)in_fes).GetProlongationMatrix(); }
/// Get the input finite element space restriction matrix
virtual const Operator *GetRestriction() const
const Operator *GetRestriction() const override
{ return ((FiniteElementSpace &)in_fes).GetRestrictionMatrix(); }
virtual void Mult(const Vector &x, Vector &y) const
void Mult(const Vector &x, Vector &y) const override
{
if (!assembled_data.Empty())
{

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