Compare commits

..
Author SHA1 Message Date
Dylan Copeland 199560d0fe Small bug fix 2021-12-04 19:40:25 -08:00
Dylan Copeland ff43a53599 Fixing DiffusionIntegrator::ComputeFluxEnergy in the case with_coef = true. 2021-12-03 18:32:16 -08:00
Tzanio Kolev 539f663fe6 Merge pull request #2570 from mdeuse/complex_fem-improvement
Added AddDomainIntegrator with marker for (Par)ComplexLinearForm and (Par)SesquilinearForm
2021-11-30 14:21:05 -08:00
mdeuse 104abd56e1 Merge branch 'master' into complex_fem-improvement 2021-11-30 21:25:29 +01:00
Will Pazner 68b4445893 Merge remote-tracking branch 'origin/master' into complex_fem-improvement 2021-11-30 11:04:45 -08:00
Tzanio Kolev de9110300d Merge pull request #2383 from mfem/pr_autodiff
AD capabilities in mfem - autodiff
2021-11-30 09:59:27 -08:00
Will Pazner cbff87a616 Merge pull request #2639 from mfem/hyperparvec-move-dev
Add move constructors/assignment for Vector and HypreParVector [hypreparvec-move-dev]
2021-11-30 09:48:10 -08:00
blaz 139ce00846 new .gitignore 2021-11-24 22:11:45 -08:00
blaz 465459bc94 new .gitignore 2021-11-24 21:54:58 -08:00
blaz 0487599b56 .gitignore 2021-11-24 21:38:05 -08:00
blaz a85687d0cb move caliper configuration 2021-11-24 21:14:07 -08:00
blaz 03b9eb4b53 style 2021-11-24 17:45:20 -08:00
blaz 293acb99d9 small amendments 2021-11-24 17:32:44 -08:00
Josh Essman 8c5e3c4e08 Merge branch 'master' into hyperparvec-move-dev 2021-11-22 10:25:05 -06:00
Josh Essman 620b2590a3 tests: make sure that moved-from hpvec is empty 2021-11-22 10:24:10 -06:00
Tzanio 247818aaa6 More styling 2021-11-14 12:36:43 -08:00
Tzanio e5e4a7e753 Merge branch 'master' into pr_autodiff 2021-11-14 12:08:07 -08:00
Tzanio 20cb878f5f Styling 2021-11-14 12:07:15 -08:00
Tzanio 4cc03b4238 Small adjustments 2021-11-14 11:54:02 -08:00
Tzanio Kolev 0843a87d79 Merge pull request #2661 from mfem/gitlab-disable-rebaseline
In Gitlab CI, disable the `rebaseline` job for `master`
2021-11-12 08:11:57 -08:00
Tzanio Kolev 9c34c32ae6 Merge pull request #2652 from mfem/hypre-update
Update with latest changes in hypre
2021-11-12 08:10:42 -08:00
Tzanio Kolev 9a12cedd5e Merge pull request #2358 from mfem/yohann/mem/min-default-constr
Use `Reset()` in default constructor of `Memory<T>`.
2021-11-11 16:21:12 -08:00
Tzanio Kolev f9f3f11818 Merge pull request #2638 from mfem/diffusion-kernel-dev
More threads/block for SmemPADiffusionApply3D
2021-11-11 16:20:44 -08:00
Tzanio Kolev b2df200f3d Merge pull request #2659 from mfem/deps-flags
Allow for customizing compiler flags for generating dependencies
2021-11-11 15:39:52 -08:00
Veselin Dobrev 6d102971c9 In Gitlab CI, disable the rebaseline job for 'master' 2021-11-11 14:28:49 -08:00
Victor A. P. Magri ba1e213c19 Add check on hypre version 2021-11-11 11:05:03 -08:00
Will Pazner acbe45ea91 Allow for customizing compiler flags for generating dependencies
On Mac, by default, add the flag -Wno-unused-command-line-argument
2021-11-10 14:34:52 -08:00
Tzanio 0cc104331c Merge branch 'master' into yohann/mem/min-default-constr 2021-11-10 12:52:15 -08:00
Tzanio Kolev d7e87fda54 Merge pull request #2366 from xjrc/ciurej/feature/conduit-data-collection-adjsets
extend `ConduitDataCollection` to support `adjsets` exporting
2021-11-10 11:21:12 -08:00
Josh Essman bd1dbd3754 refactor: add CreateCompatibleVector method to HypreParVector 2021-11-09 15:45:39 -06:00
Tzanio Kolev d6924d1b3f Merge pull request #2649 from mfem/gh-actions-fix
Small fix in Github actions
2021-11-08 20:11:38 -08:00
Victor A. P. Magri 7a6758a53b Update prepocessor macros 2021-11-08 15:27:06 -08:00
Josh Essman 143b0378e5 cleanup: remove redundant code 2021-11-08 17:11:01 -06:00
Victor A. P. Magri 39b2f27dc2 Merge branch 'master' into hypre-update 2021-11-08 14:50:15 -08:00
Tzanio f9e9f5b22e minor 2021-11-08 10:36:31 -08:00
Cyrus Harrison 882883a650 Update CHANGELOG 2021-11-08 10:35:58 -08:00
Tzanio Kolev 2519a91d01 Merge pull request #2645 from mfem/omp-macos
Include `omp` header on macOS [omp-macos]
2021-11-08 07:39:10 -08:00
Josh Essman 12cc340afb cleanup: apply suggestions from @pazner 2021-11-08 08:08:30 -06:00
Veselin Dobrev 88a190e034 In Github CI, remove testing change 'v2.0-tweak' -> 'v2.0' 2021-11-06 18:51:36 -07:00
Veselin Dobrev 9f64008a55 Fix the 'gitignore' github action.
Test with the external github action (remove before merge):
   mfem/github-actions/build-mfem@v2.0-tweak
2021-11-06 17:30:26 -07:00
Tzanio Kolev 7127265fde Merge pull request #2634 from mfem/gitlab-ci-updates
Gitlab CI updates
2021-11-06 15:57:22 -07:00
mdeuse f6f702c522 Minor, updated comment 2021-11-06 14:48:56 +01:00
Veselin Dobrev 29fc4c45b6 In Gitlab CI, apply another set of tweaks 2021-11-05 12:16:09 -07:00
Veselin Dobrev f6f802e0cd In Gitlab CI, test another tweak 2021-11-05 11:26:22 -07:00
Tobias Duswald 0ccc63af04 Include omp headers on macOS 2021-11-05 08:43:30 +01:00
Veselin Dobrev 2ec5efc7d5 In Gitlab CI, in sub-pipeline definitions, explicitly pass
some global variables
2021-11-04 20:37:10 -07:00
Veselin Dobrev c8a8ab5cba In Gitlab CI, attempt to explicitly inherit global variables
in the sub-pipelines
2021-11-04 20:21:35 -07:00
Veselin Dobrev aeac01c130 In Gitlab CI, add some debug "echo" commands 2021-11-04 19:15:29 -07:00
Veselin Dobrev a25c9c575b In Gitlab CI, move the definitions of some global variables from
.gitlab/configs/common.yml to .gitlab-ci.yml
2021-11-04 18:48:38 -07:00
Will Pazner 2900a6ecd0 Remove testing data_dir symlink if it exists 2021-11-04 16:25:17 -07:00
Will Pazner 134780da77 Try to fix hipcc errors in shifted miniapp 2021-11-04 12:37:05 -07:00
Josh Essman c85f81f9b4 fix: update hypreparvec copy ctor to copy local data 2021-11-04 12:22:25 -05:00
Josh Essman 72331717c7 tests: add tests for new functionality and fix other hypreparvec test 2021-11-04 10:15:23 -05:00
Josh Essman e96e88d543 feat: add vector move ctor/assignment 2021-11-04 09:01:28 -05:00
Veselin Dobrev a0172dfeb3 In Gitlab CI, remove some debug output 2021-11-03 21:42:47 -07:00
Tom Stitt 2efaaaaffa remove added blank lines 2021-11-03 17:07:12 -07:00
Tom Stitt 70422ccf14 switch threading order 2021-11-03 17:04:57 -07:00
Tom Stitt 716df18263 Merge remote-tracking branch 'origin/master' into diffusion-kernel-dev 2021-11-03 16:23:50 -07:00
Josh Essman 2337137f33 feat: add move constructor for hypreparvec 2021-11-03 17:31:19 -05:00
Tzanio Kolev 167ff72edc Merge pull request #2406 from SCOREC/installExamples
cmake: install examples when enabled
2021-11-03 08:02:37 -07:00
Veselin Dobrev 3f036b943e Add a new Gitlab CI file forgotten in the previous commit 2021-11-03 02:32:28 -07:00
Veselin Dobrev 5565b5066f Update Gitlab CI to fix some issues:
- Use a single (per user) clone of the internal MFEM/autotests repo
- Use a single (per user) clone of the Github MFEM/data repo
- Properly set the location for the pipeline-common temporary directory,
  BUILD_ROOT; add a cleanup step for BUILD_ROOT
- Various other small tweaks and additions
2021-11-03 02:15:58 -07:00
blaz 269eb6b7d1 fix in the makefile configuration 2021-11-02 17:51:24 -07:00
Tom Stitt 2558593206 threads in z; seems like ~10% faster on v100... 2021-11-02 17:19:22 -07:00
Tzanio Kolev d09ab725b5 Merge pull request #2367 from mfem/yohann/mem/delete-reset
Make `Memory<T>::Delete()` reset the `Memory<T>` object.
2021-11-02 06:45:51 -07:00
Tzanio Kolev 41bb7c5d4e Merge pull request #2423 from mfem/additional-device-kernels
Additional Device Kernels
2021-11-02 06:44:46 -07:00
Tzanio Kolev a0166719e6 Merge pull request #2607 from mfem/size-mt-array-ctor
Add Size & MemoryType Array Constructor
2021-11-02 06:44:01 -07:00
Tzanio Kolev 26200dafed Merge pull request #2611 from mfem/hypre-par-vector-read
Add HypreParVector::Read
2021-11-02 06:43:24 -07:00
Tzanio b8b2d23087 Merge branch 'master' into ciurej/feature/conduit-data-collection-adjsets 2021-10-31 14:44:55 -07:00
Tzanio Kolev ef656f03e9 Merge pull request #2507 from mfem/coarse-fine-map-fix-dev
Proposed fix for GetCoarseFineMap() for Derefinement in parallel
2021-10-31 14:40:38 -07:00
Tzanio Kolev c1c98ca52c Merge pull request #2448 from mfem/shifted-dirichletplusneumann
Shifted boundary method - Neumann boundary condition + multiple level sets
2021-10-31 14:40:00 -07:00
Tzanio 405a6d2f0d Merge branch 'master' into yohann/mem/delete-reset 2021-10-29 18:16:09 -07:00
Veselin Dobrev ba73a40ce9 Merge pull request #2598 from mfem/ceed-int-rule-fix
Fix bug in CEED integration
2021-10-29 16:04:36 -07:00
Ketan Mittal fa2e6fa2f4 minor 2021-10-29 13:58:29 -07:00
blaz a42ee48079 interface modifications and fixes 2021-10-29 12:13:33 -07:00
blaz bfafa6c97e fixed kapa -> kappa 2021-10-29 11:24:44 -07:00
blaz eeb0ede002 Merge branch 'master' into pr_autodiff 2021-10-29 11:21:47 -07:00
blaz ef5cc5aa5d Merge branch 'pr_autodiff' of https://github.com/mfem/mfem into pr_autodiff 2021-10-29 11:11:07 -07:00
Ketan Mittal b8590d7c0f set level set if none is specified 2021-10-29 09:02:46 -07:00
Tzanio Kolev bf616ac6ec Merge pull request #2493 from mfem/vqfluxfix
Bug fix for DiffusionIntegrator
2021-10-29 08:17:55 -07:00
Tzanio Kolev 0526a67b92 Merge pull request #2612 from mfem/yohann/wrapwrap
Improved device compilation.
2021-10-29 08:05:25 -07:00
Tzanio Kolev 59a950e1c6 Merge pull request #2616 from mfem/additional-template-instances
additional template instances
2021-10-29 07:57:33 -07:00
Ketan Mittal 26fdb711bc remove default dirichlet level set 2021-10-27 16:45:13 -07:00
Joseph Ciurej 8d76e7462a fixed the wording in a code comment 2021-10-27 13:40:09 -07:00
mdeuse 92710559c0 Merge branch 'master' of https://github.com/mfem/mfem into complex_fem-improvement 2021-10-27 22:28:49 +02:00
Tzanio Kolev 17537c506f Merge pull request #1915 from mfem/tmop-align-surface
Initial surface alignment TMOP capability
2021-10-27 09:05:00 -07:00
Will Pazner d9eec2acd8 Merge pull request #2619 from mfem/PrintMatlab
Fixed function signature which creates PyMFEM conflict
2021-10-25 16:09:53 -07:00
Tzanio 7d5bf6e3e1 square01_tri.mesh -> square01-tri.mesh; other minor 2021-10-25 10:17:05 -07:00
Tzanio Kolev 4d6c90d4fc Merge pull request #2511 from mfem/contrib-doc-mod
Proposed changes to documentation requirements [contrib-doc-mod]
2021-10-24 20:04:32 -07:00
Tzanio Kolev efb97380e3 Merge pull request #2510 from mfem/nonlinearform-doftrans-dev
Adding DofTransformations NonlinearForm methods [nonlinearform-doftrans-dev]
2021-10-24 19:58:54 -07:00
Tzanio Kolev 1f7e9f0f23 Merge pull request #2433 from mfem/oscillation
Data oscillation refinement / mesh pre-processing
2021-10-24 19:57:12 -07:00
Tzanio Kolev ca612b872f Update ex30p.cpp 2021-10-24 19:52:46 -07:00
Tzanio Kolev f991e44f2e Update ex30.cpp 2021-10-24 19:51:52 -07:00
Tzanio Kolev 3b232cd0c1 Update CHANGELOG 2021-10-24 19:50:19 -07:00
Joseph Ciurej cecda6b411 fixed a few bugs w/ neighbor/rank distinction between MFEM and Blueprint 2021-10-24 11:52:17 -07:00
Joseph Ciurej 8145b4c377 removed invalid boundary topology and added a note about its exclusion 2021-10-21 12:29:36 -07:00
Joseph Ciurej 2c1a39031e extend 'ConduitDataCollection' adjacency information to include shared boundaries 2021-10-21 12:29:36 -07:00
Joseph Ciurej ded707375a add basic support to 'ConduitDataCollection' for outputting adjacency information 2021-10-21 12:29:35 -07:00
Keith be505c9af0 fixed function signature which creates PyMFEM conflict 2021-10-20 17:00:50 -07:00
Tom Stitt 4056c529a1 additional template instances 2021-10-19 15:06:15 -07:00
Tzanio Kolev 23f110f9b7 Adding Mark and Will as MFEM editors 2021-10-19 12:13:59 -07:00
Keith 1ed1a29e68 PR checklist 2021-10-18 12:07:22 -07:00
Tzanio Kolev f428d03583 Merge pull request #2609 from mfem/changelog-fix
Fix CHANGELOG entries
2021-10-17 09:01:56 -07:00
Yohann Dudouit ddf40b7909 Use static method. 2021-10-15 16:34:54 -07:00
Yohann Dudouit 21417add4b Dim -> DIM. 2021-10-15 16:32:35 -07:00
Yohann Dudouit 5f68f31a73 Wrap exec policies to avoid triple compilation. 2021-10-15 16:30:54 -07:00
Will Pazner 407a3321aa Add unit test for HypreParVector::Read 2021-10-15 13:25:23 -07:00
Will Pazner c76cbfa010 Add HypreParVector::Read 2021-10-15 13:03:13 -07:00
Veselin Dobrev 8a67918a24 Merge pull request #2577 from mfem/artv3/bugfix/hypre-amgx-host-device
Host/Device fix for Hypre-AMGX solver.
2021-10-14 17:55:00 -07:00
Veselin Dobrev 7f0b52ccc0 Merge pull request #2556 from mfem/par-get-deriv
Parallel implementation of GridFunction::GetDerivative()
2021-10-14 16:33:09 -07:00
Veselin Dobrev 6298a3ce47 Merge pull request #2508 from mfem/bugfix/lin-penta-dev
Fixing special cases in RT pyramids [bugfix/lin-penta-dev]
2021-10-14 16:31:25 -07:00
Veselin Dobrev 000d018d1a Merge pull request #2471 from mfem/coef-set-time-dev
Propagating Coefficient::time [coef-set-time-dev]
2021-10-14 16:27:18 -07:00
Veselin Dobrev b938ea0286 Merge pull request #2579 from mfem/br2-fix
Fix for BR2 integrator [br2-fix]
2021-10-14 16:25:03 -07:00
Veselin Dobrev b773b012c7 Merge pull request #2376 from mfem/lor-solvers-p-ref
LOR solvers: device and p-refinement [lor-solvers-p-ref]
2021-10-14 16:13:28 -07:00
Veselin Dobrev f1e503e70f Move or remove CHANGELOG entries in the v4.3 section which
were added/changed after v4.3.

Update the RAJA version requirement in INSTALL.
2021-10-14 15:59:58 -07:00
Tom Stitt 320bf0a980 add new ctor to array that takes a size and a memorytype 2021-10-14 10:48:43 -07:00
Stowell, Mark L 47008f92fb Adding statement about documenting pointer arguments/return values 2021-10-12 11:40:30 -07:00
Veselin Dobrev 1fe4bfc1d8 Merge pull request #2529 from mfem/artv3/compatibility-with-RAJA_014
RAJA 0.14 update
2021-10-11 13:17:15 -07:00
Veselin Dobrev b9368fc9c0 Merge pull request #2595 from mfem/umpire-6-compatibility
Umpire 6 Compatibility
2021-10-11 13:16:05 -07:00
Will Pazner d72cd3f5f7 Small modifications to CEED convection unit test 2021-10-09 09:32:23 -06:00
Julian AndrejandYohann 8bb634ffcb Update tests/unit/ceed/test_ceed.cpp
Co-authored-by: Yohann <dudouit1@llnl.gov>
2021-10-08 13:44:58 -07:00
Vladimir Z Tomov af6426d240 Addressed reviewer comments. 2021-10-08 13:09:17 -07:00
Julian Andrej 15b9085ad5 add unit test 2021-10-08 11:39:33 -07:00
Will Pazner cbc44b22b6 Fix bug in CEED integration
The requested integration rule was assumed to be GaussLegendre, but this is not
always the case.
2021-10-08 11:07:52 -07:00
Veselin Dobrev e9af593bd3 Update an MFEM_ASSERT for a special case that comes up when
using 'host-umpire' memory which is the default when MFEM is
built with Umpire.
2021-10-07 19:04:12 -07:00
Tom Stitt 0bd6208942 use QuickPool instead of DynamicPool; requires Umpire >=3 so bump the version in INSTALL 2021-10-07 16:44:48 -07:00
Victor A. P. Magri 28369b9be2 Update BoomerAMGCoarseParms call 2021-10-07 13:54:25 -07:00
Veselin Dobrev 4bcbff0a57 Merge pull request #2594 from mfem/gitlab-update-builds-dir
Specify a custom directory to be used by the Gitlab CI
2021-10-06 20:49:01 -07:00
Tom Stitt 3db650c24f umpire 6 requires us to include the specifc strategy header we are using 2021-10-06 18:04:05 -07:00
Veselin Dobrev d6c70dd077 Specify a custom directory to be used by the Gitlab CI. 2021-10-06 16:46:19 -07:00
Will Pazner 31545fb3d7 Comments and fix for BR2 integrator.
Use SetAllIntPoints for the face transformation, re-add factor of 0.5
corresponding to average term in lifting operator. Also revert ex14p sample
run.
2021-10-06 13:25:13 -07:00
Will Pazner c0486fec51 Take average of coefficient across face in BR2 integrator 2021-10-05 10:25:07 -07:00
Will Pazner 5df3ef4b9e Pass fespace by reference to BR2 integrator in ex14 and ex14p 2021-10-04 16:56:43 -07:00
Will Pazner d9b1f2409c Merge remote-tracking branch 'origin/master' into br2-fix 2021-10-04 15:50:55 -07:00
Will Pazner 1441a6e636 Merge remote-tracking branch 'origin/master' into lor-solvers-p-ref 2021-10-04 15:50:34 -07:00
Will Pazner 2fe688deea Add version of BR2 integrator with coefficient 2021-10-04 15:45:55 -07:00
Will Pazner c7856f70ea Fix possible dereferencing of NULL pointer 2021-10-04 15:34:28 -07:00
Tzanio Kolev cb1eaa1b81 Merge pull request #2558 from mfem/testing/bernede1/gitlab-revamping
Testing/bernede1/gitlab revamping
2021-09-30 18:23:53 -07:00
Will Pazner ee8578e22a Take sqrt of BR2 factor 2021-09-30 17:37:44 -07:00
Will Pazner 2888c61e59 Increase maximum iterations in ex14p. 2021-09-30 08:28:07 -07:00
Tzanio Kolev a3f0a5bb7c Merge pull request #2573 from mfem/hypre-cuda-lobpcg-fix
Fix an issue in HypreLOBPCG when HYPRE is built with CUDA
2021-09-29 20:58:42 -07:00
Tzanio Kolev 55addd4496 Merge pull request #2578 from mfem/print-matlab
Improvements to PrintMatlab [print-matlab]
2021-09-29 20:57:59 -07:00
Tzanio 8f59bf3005 minor 2021-09-29 20:55:20 -07:00
Adrien M. Bernede 6a2e355536 Minor change 2021-09-29 17:15:12 -07:00
Will Pazner 037855173e Use smaller problem for ex14 sample run 2021-09-29 15:32:13 -07:00
Tzanio Kolev b49c9e089b Merge pull request #2580 from mfem/fix/bernede1/master-use-upstream
Do not re-install all the dependencies when CI is running on master
2021-09-29 15:19:44 -07:00
Keith d6a5eea4e7 const member function fix 2021-09-29 14:37:32 -07:00
Adrien M. Bernede 53ee33a967 Apply a missing fix to report scripts 2021-09-29 13:55:31 -07:00
Vladimir Z Tomov 092b5079fd Used HostReadWrite as suggested. 2021-09-29 13:12:08 -07:00
Keith 3b325a597c supress warnings by default 2021-09-29 13:02:24 -07:00
Vladimir Z Tomov 8880e17cd5 Unit test. 2021-09-29 12:48:39 -07:00
Adrien M. Bernede 2ccf31dfbb Make sure the AUTOTEST_ROOT exists 2021-09-29 12:29:13 -07:00
Adrien M. Bernede 1a4616a145 Make autotest clone specific to the type of test.
The goal is to have one autotest clone per type of pipeline to avoid conflicts,
and share this instance between subsequent runs so that we save storage space
2021-09-29 12:24:59 -07:00
Adrien M. Bernede d888b63bc9 Workaround that stupid Gitlab bug 2021-09-29 11:55:32 -07:00
Adrien M. Bernede be82f44cf6 Fix: missing autotest clone for build-and-test jobs 2021-09-29 11:52:59 -07:00
Vladimir Z Tomov 22a0fa48d3 Merge branch 'master' into par-get-deriv 2021-09-29 11:44:33 -07:00
Adrien M. Bernede 635f394a69 Do not re-install all the dependencies when CI is running on master 2021-09-29 10:44:36 -07:00
Stowell, Mark L 98be69f851 Adding MatrixFunctionCoefficient::SetTime thanks to @vladotomov 2021-09-29 09:53:11 -07:00
Arturo Vargas 3f78a06411 add hypre read call 2021-09-29 09:44:32 -07:00
Stowell, Mark L d40305077c Merge remote-tracking branch 'origin/master' into bugfix/lin-penta-dev
# Conflicts:
#	fem/fe.cpp
2021-09-29 09:42:17 -07:00
Vladimir Z Tomov 1e5602f139 Removed the mesh curvature output, as it doesn't take
into account the user-selected mesh order.
2021-09-28 22:41:50 -07:00
Vladimir Z Tomov bb085f9866 Aborts for unsupported setups, mem leak. 2021-09-28 22:24:40 -07:00
Vladimir Z Tomov e7a7bfe3fb Removed unused function.
Better computation and output of fitting errors.
2021-09-28 18:11:45 -07:00
Vladimir Z Tomov 76617db79e Serial miniapp and some comments. 2021-09-28 17:24:23 -07:00
Tzanio f491fe30c3 Merge branch 'master' into lor-solvers-p-ref 2021-09-28 16:31:10 -07:00
Vladimir Z Tomov a1ba9f93c4 Reverted changes in pmesh.cpp. 2021-09-28 16:09:21 -07:00
Vladimir Z Tomov 211a221c50 Fixed a merge issue. 2021-09-28 16:00:10 -07:00
Vladimir Z Tomov a194cdacce Merge branch 'master' into tmop-align-surface 2021-09-28 15:54:35 -07:00
Vladimir Z Tomov 3829693441 Better triangular mesh, added parallel sample runs. 2021-09-28 15:35:26 -07:00
Adrien M. Bernede ccbed7cbe3 fix location of script 2021-09-28 14:56:51 -07:00
Will Pazner 233bee6188 Add comment to PrintMatlab 2021-09-28 14:17:59 -07:00
Tzanio Kolev 1e91b0bc06 Merge branch 'master' into coef-set-time-dev 2021-09-28 14:04:42 -07:00
Tzanio Kolev f66ddbc394 Merge pull request #2335 from mfem/fe-split-dev
Splitting fe.[ch]pp
2021-09-28 13:49:04 -07:00
Will Pazner e424d758be Remove factor of 0.5 in BR2 integrator 2021-09-28 12:40:48 -07:00
Will Pazner 9e67380171 Improvements to PrintMatlab
Make Operator::PrintMatlab virtual, output zero entry in last row and column to
preserve matrix size.
2021-09-28 12:01:04 -07:00
Arturo Vargas fc070abf6b make style 2021-09-28 11:35:01 -07:00
Adrien M. Bernede 55c35b945e Propagate AUTOTEST value to sub-pipelines _AUTOTEST 2021-09-28 11:01:11 -07:00
Arturo Vargas 7bac717364 Host/Device fix for Hypre-AMGX solver. 2021-09-28 10:58:28 -07:00
Adrien M. Bernede 6f9ae7fe66 Do not set AUTOTEST to see if source of issue 2021-09-28 10:52:48 -07:00
Tzanio Kolev 4fb1a5494d Merge pull request #2561 from mfem/fix_petsc
Small fix for petsc vectors
2021-09-28 09:43:25 -07:00
Tzanio Kolev 309928b152 Merge pull request #2567 from mfem/rbm_hypre
Elasticity RB modes - NCMesh
2021-09-28 09:42:43 -07:00
Tzanio Kolev 09c49c75e4 Merge pull request #2505 from adrienbernede/bernede1/actions-on-fork
Compare PRs from forks with mfem/mfem:master
2021-09-28 09:42:13 -07:00
Tzanio Kolev 169bcf2353 Merge pull request #2279 from mfem/google-benchmark
Add Google benchmarks [google-benchmark]
2021-09-27 21:03:14 -07:00
Tzanio 79032f3048 Minor 2021-09-27 21:01:10 -07:00
Veselin Dobrev 8c3ca133f5 Fix an issue in HypreLOBPCG when HYPRE is built with CUDA 2021-09-27 17:09:12 -07:00
Keith 5231ec314a Socratis's comments 2021-09-27 15:01:01 -07:00
Keith a33f29549a Merge branch 'master' into oscillation 2021-09-27 15:00:11 -07:00
Tzanio Kolev 0a9ec5bcf9 Merge pull request #2491 from mfem/hypre-bigint-fixes
Fixes for HYPRE_BIGINT and HYPRE_MIXEDINT
2021-09-27 12:55:56 -07:00
Tzanio Kolev 0b6f29ac67 Merge pull request #2566 from mfem/vtk-surface-fix
Fix reading VTK surface meshes [vtk-surface-fix]
2021-09-27 12:52:00 -07:00
Stowell, Mark L 0e48fd5f94 Fixing a small typo 2021-09-27 09:29:20 -07:00
Adrien Bernede cd45fd8cbd Warning on same line 2021-09-27 09:25:26 -07:00
Adrien Bernede 997e5ecaa1 Use warning icon 2021-09-27 09:23:10 -07:00
Tzanio 946ab2a893 Incorporate suggestion from Denis 2021-09-26 19:02:31 -07:00
Tzanio b34831a308 Incorporate Aaron suggestions 2021-09-26 18:48:00 -07:00
Tzanio c753e3bf8e Incorporater PR review rules in CONTRIBUTING.md 2021-09-26 18:35:02 -07:00
Tzanio f25aa615da Merge branch 'master' into contrib-doc-mod 2021-09-26 18:34:52 -07:00
Tzanio 850738703c minor 2021-09-26 18:18:27 -07:00
camierjs b705c964d6 Merge branch 'master' into google-benchmark 2021-09-26 18:13:48 -07:00
Tzanio 6c56ad3d7a Merge branch 'master' into fe-split-dev 2021-09-26 18:05:36 -07:00
Tzanio Kolev 1e82e22374 Merge pull request #2424 from mfem/parelag_miniapps
ParELAG miniapps: AMGe for H(curl) and H(div) [parelag-miniapps-dev]
2021-09-26 17:53:48 -07:00
Tzanio 0902484c73 Small adjustments 2021-09-26 17:51:55 -07:00
Tzanio 34d0bc4de3 Merge branch 'master' into parelag_miniapps 2021-09-26 17:45:50 -07:00
Tzanio Kolev 6c2e0aa4e8 Merge pull request #2553 from mfem/hypre-intarray
Use hypre_IntArray
2021-09-26 17:43:50 -07:00
Tzanio Kolev 782410e070 Update README.md 2021-09-26 17:35:20 -07:00
Tzanio Kolev 1fd69ad669 Merge pull request #2477 from mfem/binder
Binder (Jupyter Notebook) Example w/ GLVis
2021-09-26 17:34:07 -07:00
Tzanio Kolev a303bcdf0a Merge branch 'master' into pr_autodiff 2021-09-26 17:28:25 -07:00
Tzanio f7b7c5388b make style 2021-09-26 17:26:44 -07:00
Tzanio b704fa15b1 Merge branch 'master' into additional-device-kernels 2021-09-26 17:25:53 -07:00
Tzanio 88b96292e9 Gitlab -> GitLab 2021-09-26 17:10:12 -07:00
mdeuse e533a91560 Added AddDomainIntegrator with marker for (Par)ComplexLinearForm and (Par)SesquilinearForm 2021-09-26 22:14:01 +02:00
Tom Stitt b74049fff1 MultT -> MultTranspose 2021-09-24 14:46:12 -07:00
Tom StittandYohann 7e9dd26f57 fix empty mat check
Co-authored-by: Yohann <dudouit1@llnl.gov>
2021-09-24 14:45:09 -07:00
Vladimir Z Tomov 621a7842b1 AMR - sample run for the distance app, abort for the diffusion app. 2021-09-24 14:43:56 -07:00
Vladimir Z Tomov 7cf96edc2f Makefile improvements to avoid extra recompilation. 2021-09-24 14:23:22 -07:00
Adrien M. Bernede 00b585e0b6 Revert to using regular tests repo 2021-09-24 12:00:53 -07:00
camierjs fb6a084795 Merge branch 'master' into google-benchmark 2021-09-24 11:39:35 -07:00
Adrien M. Bernede 7ca4e9dfa2 Fix typos in doc 2021-09-24 11:15:00 -07:00
Adrien M. Bernede 234de3415c Some documentation 2021-09-24 10:56:49 -07:00
Adrien M. Bernede d641346991 Remove lassen and corona baseline for a simpler PR 2021-09-24 10:23:58 -07:00
blaz c023bd7ce2 Elasticity RB modes - NCMesh 2021-09-23 21:48:30 -07:00
Adrien M. Bernede 34ff55c688 Fix corona allocation 2021-09-23 18:23:23 -07:00
Vladimir Z Tomov e04fc27673 Moved the reproducer to tmp.cpp and reverted ex1p.cpp. 2021-09-23 13:27:31 -07:00
Adrien M. Bernede b8ccd71c6c Fix support for another baseline type (baseline-gpu) + improved variables management 2021-09-23 11:11:22 -07:00
Will Pazner 08728089c4 Fix reading VTK surface meshes
The space dimension was not set correctly when reading straight sided surface
meshes.
2021-09-23 10:07:11 -07:00
Tom Stitt d47f7ff51e update pyglvis requirement 2021-09-22 19:54:58 -07:00
blaz 4fe8308527 Small fix for petsc vectors 2021-09-22 15:01:54 -07:00
Adrien M. Bernede a39e900a36 Testing baseline-gpu on lassen 2021-09-22 14:13:10 -07:00
Adrien M. Bernede 1f58cadff2 Remove unnecessary prefix 2021-09-22 13:42:27 -07:00
Adrien M. Bernede 9089e1b1ff Simplify the configuration 2021-09-22 13:28:19 -07:00
Sebastian Grimberg 5361848341 ParMesh fixes for MIXEDINT 2021-09-22 08:51:28 -07:00
Vladimir Z Tomov c216a86943 Minor edits. 2021-09-21 18:06:44 -07:00
Veselin Dobrev 0b21949cef Update .gitignore 2021-09-21 16:36:50 -07:00
Sebastian Grimberg cd9d131acd Merge branch 'master' into hypre-bigint-fixes 2021-09-21 13:47:11 -07:00
Sebastian Grimberg 97db5b9145 Alternative fix for ParMesh test 2021-09-21 13:45:03 -07:00
Adrien M. Bernede e13626076a Fix missing rules for reporting on lassen 2021-09-21 10:46:32 -07:00
victor e6647ee265 Avoid unecessary copy when using hypre with gpu support 2021-09-20 15:59:18 -07:00
victor 1264d9906c Move mapping pointer to device when hypre_IntArray is defined (suggested by @waynemitchell) 2021-09-20 15:40:58 -07:00
Veselin Dobrev 5a9c15ef8b Update HypreParMatrix::ExtractSubmatrix to do the work on
host because hypre_ParCSRMatrixExtractSubmatrixFC works on
host only.
2021-09-20 14:53:25 -07:00
Vladimir Z Tomov 3562662d93 Revert ex1p. 2021-09-20 14:50:17 -07:00
Vladimir Z Tomov a13a1bf95c Merge branch 'par-get-deriv' into shifted-dirichletplusneumann 2021-09-20 14:48:32 -07:00
Vladimir Z Tomov 654663a221 Parallel implementation of GridFunction::GetDerivative(). 2021-09-20 14:22:48 -07:00
Veselin Dobrev b7b1907b37 Add clarification comments in HypreParMatrix::ExtractSubmatrix 2021-09-20 12:55:47 -07:00
Veselin Dobrev 681098ca4b In HypreParMatrix::ExtractSubmatrix, error out if hypre is
built with CUDA without UVM -- this is required by the
function hypre_ParCSRMatrixExtractSubmatrixFC, at least.
2021-09-20 12:47:55 -07:00
victor 796c4b2a89 Fix CF_marker computation for the old code branch (without hypre_IntArray) 2021-09-20 08:18:08 -07:00
Tzanio Kolev 9a73c2d94c Merge pull request #2552 from mfem/branch-history-detect-renames
Detect renames in branch-history [branch-history-detect-renames]
2021-09-20 08:16:04 -07:00
Tzanio Kolev ad60dac701 Merge pull request #2518 from mfem/arflags
Archive flags update [arflags]
2021-09-19 16:28:15 -07:00
Tzanio Kolev db6f2b3ce6 Merge pull request #2520 from mfem/nd-project-fix
Fix ProjectBdrCoefficientTangent
2021-09-18 18:58:52 -07:00
Tzanio Kolev 4937ee34fa Merge pull request #2526 from mfem/nedelec-nc-tet-warning
Add a check to prevent bad parallel results on Nedelec NC tets of order >= 2 [nedelec-nc-tet-warning]
2021-09-18 18:58:29 -07:00
victor 0e3c902fff Apply astyle 2021-09-18 00:00:40 -07:00
victor 182b215126 Replace preprocessor variable with hypre_IntArrayData 2021-09-17 23:35:22 -07:00
victor ef75de02d7 Update CF_marker object type to hypre_IntArray 2021-09-17 23:03:20 -07:00
Will Pazner 4118de2fb9 Detect renames in branch-history
Reduce false positives when renaming/moving large files.
2021-09-17 13:04:55 -07:00
Stowell, Mark L 7c5d9d4a1e Adding a unit test to demonstrate the issue 2021-09-17 11:28:46 -07:00
Jakub Červený 6708f9c19b Fix Doxygen error 2021-09-17 14:17:32 +02:00
Jakub Červený 4f0c54ff06 Updated derefinement test in test_derefine.cpp 2021-09-17 14:12:23 +02:00
Jakub Červený a53706b57c Simplified CoarseFineTransformations::MakeCoarseToFineTable. 2021-09-17 13:53:45 +02:00
Jakub Červený 61e9c368d7 DerefinementOperator: uses original GetCoarseToFineMap, now in fespace.cpp. 2021-09-17 12:52:20 +02:00
Stowell, Mark L 6060741350 merge with master 2021-09-16 09:34:21 -07:00
Tzanio Kolev 042d9cc886 Merge pull request #2517 from mfem/hiop-inttypes-fix
Fixing HiOp int types
2021-09-16 08:28:45 -07:00
Tzanio Kolev 407cda524c Merge pull request #2472 from mfem/bugfix/thread-safe-dev
Adding missing variables when MFEM_THREAD_SAFE is ON [bugfix/thread-safe-dev]
2021-09-16 08:28:31 -07:00
Tzanio d5d7828285 Merge branch 'master' into parelag_miniapps 2021-09-16 08:27:13 -07:00
Adrien M. Bernede 1ccc5df423 Merge branch 'master' into testing/bernede1/gitlab-revamping 2021-09-15 18:17:53 -07:00
Tom Stitt 893360dd9d better pragma cling load line 2021-09-15 18:04:09 -07:00
Tom Stitt ea2050f8d7 update kernelspec with LD_LIBRARY_PATH
don't download mfem twice
2021-09-15 17:41:52 -07:00
Tom Stitt 7ba11098d7 install lab extension 2021-09-15 17:01:38 -07:00
Stowell, Mark L 04ac947a4c Merge remote-tracking branch 'origin/master' into fe-split-dev 2021-09-15 12:03:45 -07:00
Stowell, Mark L 6c8b907f6f Bringing the split files up to date with fe.[ch]pp from master branch 2021-09-15 12:01:37 -07:00
Adrien M. Bernede 2f6dddb012 Remove module loads now that tpls platform file for lassen was created 2021-09-15 10:47:39 -07:00
Adrien M. Bernede 14c1280f9e Clean baseline run dir if exists to allow for re-run 2021-09-15 10:30:13 -07:00
Tzanio Kolev 02ff18e17e Merge pull request #2530 from mfem/faceinfo-doc-fix
Update documentation comments for `Mesh::FaceInfo`
2021-09-14 18:02:26 -07:00
Tzanio Kolev 77784da4ba Merge pull request #2428 from mfem/build/bernede1/corona-build
Add corona to Gitlab CI, CI hardening, and documentation
2021-09-14 18:02:01 -07:00
camierjs fffd2de5d4 Fix duplicate INSTALL entry 2021-09-14 13:04:48 -07:00
camierjs 5c02f574e7 Merge master in google-benchmark 2021-09-14 12:08:28 -07:00
Stowell, Mark L 3c0b0896e6 Merge remote-tracking branch 'origin/master' into fe-split-dev
# Conflicts:
#	fem/fe.cpp
#	fem/fe.hpp
2021-09-14 12:00:07 -07:00
camierjs 9bf05f6018 Merge master in arflags 2021-09-14 11:58:38 -07:00
camierjs 7027cf41f2 Adding explaination 2021-09-14 11:52:45 -07:00
Adrien M. Bernede bd5a5924fe Increase allocation time for corona baseline 2021-09-14 10:47:08 -07:00
Adrien M. Bernede 727d320330 Define missing LAPACK_LIB 2021-09-14 10:42:56 -07:00
Adrien M. Bernede f7fcc5f8f0 load coherent xl/cuda/lapack set 2021-09-14 08:54:51 -07:00
Jakub Červený a747244a6f WIP refactoring DerefinementOperator constructor 2021-09-14 13:08:58 +02:00
Jakub Červený 9b05700cb5 Initialization of Embedding::geom and ::ghost in NCMesh and Mesh. 2021-09-14 11:23:49 +02:00
Adrien M. Bernede 754f568d4b Adapt baseline allocation to machines 2021-09-13 22:43:22 -07:00
Tzanio 8e629d6b14 Small edits 2021-09-13 18:13:21 -07:00
Tzanio 79a68dff18 Merge branch 'master' into binder 2021-09-13 17:51:51 -07:00
Tom Stitt 2b88a865fa bump pyglvis requirement, update CHANGELOG 2021-09-13 14:29:10 -07:00
Vladimir Z Tomov 27dfa26f0d Improved the marking algorithm. 2021-09-13 14:12:21 -07:00
Veselin Dobrev 8a365820c8 Some fixes and additions to the Mesh::FaceInfo documentation in
comments.
2021-09-13 12:25:02 -07:00
Arturo Vargas 895293f55e changelog 2021-09-13 11:59:38 -07:00
Arturo Vargas 32cc4c3198 Resources->Grid 2021-09-13 11:58:27 -07:00
Tzanio Kolev 81493c10bb Merge pull request #2506 from mfem/bernede1/astyle-3.1
Bernede1/astyle 3.1
2021-09-13 11:15:58 -07:00
camierjs 7146f4d8f9 Merge master in google-benchmark 2021-09-13 09:10:07 -07:00
Adrien M. Bernede 64659188ae Add safe creation of parent in case it’s missing 2021-09-13 09:01:01 -07:00
Jakub Červený 83c11c4ea5 Refactoring coarse/fine: added MakeCoarseToFineTable, Embedding::geom/ghost. 2021-09-13 16:01:36 +02:00
Adrien M. Bernede d45f9a0b28 Merge branch 'master' into build/bernede1/corona-build 2021-09-10 12:04:04 -07:00
Tzanio Kolev 1e94f9c8a3 Merge pull request #2522 from mfem/get-values-fix-dev
Remove redundant outer loop in GetValues()
2021-09-10 11:02:56 -07:00
Jakub Červený 2b90ec7c07 Add a check to prevent bad results on parallel shared faces in case
of Nedelec NC tets of order >= 2.
2021-09-10 13:24:11 +02:00
Tzanio Kolev 5273864847 Merge pull request #2509 from mfem/ex27-oversight-dev
Removing unnecessary mass matrix from example 27 [ex27-oversight-dev]
2021-09-09 20:29:47 -07:00
Tzanio Kolev 2ed61b9888 Merge pull request #2446 from mfem/jacobf/2021-08-02/feature/jacobi23-on-device
Feature: Jacobi2/3 device
2021-09-09 20:29:29 -07:00
Stowell, Mark L 09b5b1f184 Mention of new function usage 2021-09-09 14:48:58 -07:00
Stowell, Mark L 7b64d8739a Adjusting statements based on input obtained during MFEM developer meeting 2021-09-09 14:29:17 -07:00
Robert W. Anderson d69c48be40 remove redundant outer loop in GetValues() 2021-09-09 11:41:11 -07:00
Adrien M. Bernede cee1829b29 Fix: expand MACHINE_NAME definition to all pipelines 2021-09-08 22:24:54 -07:00
Kalchev, Delyan dce8cfd5ef Merge branch 'master' into parelag_miniapps 2021-09-08 15:22:38 -07:00
Kalchev, Delyan b95daadf07 Edit README 2021-09-08 15:10:23 -07:00
Vladimir Z Tomov 36e2e4d37f Some additional tests. 2021-09-08 14:38:39 -07:00
Ketan Mittal 44d71cfdbf Merge branch 'master' of https://github.com/mfem/mfem into shifted-dirichletplusneumann 2021-09-08 13:58:37 -07:00
Ketan Mittal 4806441a03 make sure normal vector is pointing outside the domain 2021-09-08 13:58:20 -07:00
Kalchev, Delyan 674b6efc1e Changed 'ParElag' to 'ParELAG' and added more info to the README. 2021-09-08 12:51:28 -07:00
camierjs 1f77f9e1a5 Fix cmake warning 2021-09-08 12:50:01 -07:00
camierjs 008364305f Fix GaussLobatto ir orders and Simplify 2021-09-08 11:44:08 -07:00
Sebastian Grimberg 2cda4083b8 Fix ProjectBdrCoefficientTangent 2021-09-08 11:15:07 -07:00
Adrien BernedeandWill Pazner cb4902e7dd Update tests/gitlab/build_and_test
Co-authored-by: Will Pazner <11493037+pazner@users.noreply.github.com>
2021-09-08 09:53:47 -07:00
Adrien M. Bernede fd31a5b16c Fix stage name, permissions issues and one autotest instance per machine 2021-09-07 22:27:24 -07:00
Adrien M. Bernede 9b2ef6b06f Fix issues with build-and-test jobs 2021-09-07 22:21:24 -07:00
Adrien M. Bernede 13639ac94f Add corona and lassen baselines 2021-09-07 21:25:22 -07:00
Adrien M. Bernede 107d3e25db Small improvements and preparing for corona/quartz collision 2021-09-07 21:21:34 -07:00
Adrien M. Bernede 7787640816 Move (re)baseline commands to scripts 2021-09-07 20:20:51 -07:00
Adrien M. Bernede 23735cda9e Switch from "template" to "config" 2021-09-07 19:23:46 -07:00
Adrien M. Bernede 504fb46cf4 Merge branch 'build/bernede1/corona-build' into testing/bernede1/gitlab-revamping 2021-09-07 19:18:25 -07:00
Adrien M. Bernede dc68138ed2 Put scripts outside CI, use same script for all machines 2021-09-07 18:50:20 -07:00
camierjs f4ecc15cc8 Rename internal CEED BP/BK methods 2021-09-07 17:43:42 -07:00
camierjs a5bfad14e8 Remove ambiguous overloaded VectorDiffusionIntegrator 2021-09-07 17:32:48 -07:00
camierjs 5a2e992b90 Update CMakeLists.txt with new test name 2021-09-07 17:27:32 -07:00
camierjs 81dbb0a967 Update bench kernels to CEED benchmarks (BP & BK) 2021-09-07 17:25:15 -07:00
Tucker Babcock 5ad64b058b fix compile error, changed ComputeGradientBlocked doftrans usage to be similar to MixedBilinearForm::Assemble. 2021-09-07 14:35:00 -06:00
Tucker Babcock dd5f50bb40 store DofTransformations in Array for BlockNonlinearForm::MultBlocked and ::ComputeGradientBlocked since they need to be reused 2021-09-07 14:24:33 -06:00
Tucker Babcock 3a8908e6bf add DofTransformation to BlockNonlinearForm methods 2021-09-07 14:16:08 -06:00
Cosmin G Petra 57d4f68528 codestyle take 3 2021-09-07 12:48:34 -07:00
camierjs 5dc354233b Update CHANGELOG 2021-09-07 12:42:33 -07:00
Cosmin G Petra 2b6a78bd1c codestyle take 2 2021-09-07 12:42:28 -07:00
camierjs cd6b697ad0 Remove the 'u' flag in the ar command 2021-09-07 12:40:31 -07:00
Cosmin G Petra cb05233e82 fixed codestyle issue 2021-09-07 11:51:48 -07:00
Cosmin G Petra dd204948fd bumped up HiOp version requirement 2021-09-07 11:41:14 -07:00
Cosmin G Petra b45941cc2f corrected size and index type in the HiOp solver class 2021-09-07 11:30:52 -07:00
camierjs 0a3a9e79c7 Merge master in google-benchmark 2021-09-07 07:54:57 -07:00
Tzanio 8a12f7aa45 Mentioned the switch to astyle-3.1 in CHANGELOG 2021-09-05 18:07:18 -07:00
Tzanio c2f9d3f5b1 Better formatting in fem/restriction.cpp mesh/mesh.cpp 2021-09-05 18:06:54 -07:00
Tzanio 3eaa2c788d Disabled astyle indent for a list in RT1QuadFiniteElement::Project 2021-09-05 17:51:56 -07:00
Tzanio 966cc30615 Better formatting in fem/ceed/solvers-atpmg.cpp 2021-09-05 17:39:17 -07:00
Tzanio Kolev adab7bb460 Merge pull request #2475 from mfem/atmcadd
atomicAdd for previous versions of CUDA [atmcadd]
2021-09-05 16:52:53 -07:00
Tzanio Kolev 635a878129 Merge pull request #2497 from wo80/mingw-dev
Fix MinGW compilation errors
2021-09-05 16:51:48 -07:00
Tzanio f9e2241db6 Mentioned in CHANGELOG 2021-09-05 16:50:16 -07:00
Tzanio 460f9a4c95 Merge branch 'master' into mingw-dev 2021-09-05 16:47:22 -07:00
Tzanio Kolev e3615eebe3 Merge pull request #2501 from Andr00dz/matrix-coefficient-fix
fixed MatrixArrayCoefficient::Eval bug
2021-09-05 16:45:25 -07:00
Stowell, Mark L f53e14016d Separate statements for public and private entities. 2021-09-03 19:20:07 -07:00
Stowell, Mark L 70bb02a0c7 Proposed changes to documentation requirements 2021-09-03 17:37:03 -07:00
Stowell, Mark L d4f4016c12 Removing unnecessary mass matrix from example 27 2021-09-03 17:25:13 -07:00
Tucker Babcock 091ff0c475 adding DofTransformation objects to NonlinearForm Mult, GetGridFunctionEnergy, and GetGradient methods similar to those used in BilinearForm::Assemble and LinearForm::Assemble 2021-09-03 18:13:19 -06:00
Robert W. Anderson 583024eaa7 keep track of # of nonghost elements in derefinement, use this to fix GetCoarseFineMap in the case of derefinement 2021-09-03 17:12:18 -07:00
Stowell, Mark L 1d5df46cdb Adding rescaling to special case at apex of RT pyramid 2021-09-03 15:01:25 -07:00
Stowell, Mark L 68fabe1cfa Adding GetVectorFieldValues check to GetVectorValue unit test 2021-09-03 15:00:55 -07:00
Adrien M. Bernede 0cefe2abbf A real astyle version 2021-09-03 12:41:19 -07:00
Adrien Bernede b2c9e7541f Apply improvements and testing how astyle reacts 2021-09-03 12:38:10 -07:00
Adrien M. Bernede f1194a6900 Fix: update ubuntu 2021-09-03 12:27:26 -07:00
Adrien M. Bernede f4dbd3743d Applying Astyle 3.1 2021-09-03 12:14:24 -07:00
Adrien M. Bernede 89fdb3c909 Bump astyle version 2021-09-03 12:13:56 -07:00
Adrien M. Bernede 582180f2e1 Improved fix 2021-09-03 10:26:37 -07:00
Adrien M. Bernede 7aa323cf35 Document expected failure 2021-09-03 10:21:11 -07:00
Adrien M. Bernede e857613e55 Fix repo-check history GHA history on forks.
On a fork, the repo-check history action was using the state of master
on the fork repo instead of the main repo. This made repo-check fail if
the master branch was not up-to-date.

The goal is to have branches from forks reporting repo-check correctly
when a PR is created in the main repo. This is an attempt to acheive
that.
2021-09-03 10:06:38 -07:00
Dylan Copeland 3c82571b68 Small comment. 2021-09-03 09:55:32 -07:00
Dylan Copeland 3388160761 Fixing some unsupported coefficients in ComputeFluxEnergy. 2021-09-02 21:25:49 -07:00
Keith c8f6d1ad4f Socratis's comments 2021-09-02 12:40:36 -07:00
blaz 7b9d5d0084 Merge branch 'master' into pr_autodiff 2021-09-02 12:40:08 -07:00
blaz d41b7f7e83 Documentation 2021-09-02 12:37:18 -07:00
camierjs 4b46081b4b Merge master in atmcadd 2021-09-02 08:56:14 -07:00
camierjs 49d670c8b7 Merge master in google-benchmark 2021-09-02 08:56:04 -07:00
Tzanio Kolev 6095628e27 Merge pull request #2489 from mfem/gmsh-zero-attributes
Allow reading Gmsh meshes where all elements have attribute zero [gmsh-zero-attributes]
2021-09-02 08:48:04 -07:00
Will Pazner 8506904200 Update CHANGELOG 2021-09-02 08:43:18 -07:00
Andi 2595af0f72 fixed MatrixArrayCoefficient::Eval bug 2021-09-02 11:19:56 +02:00
wo80 c2449661b1 Move MPI_CXX to the end of linked libraries list to fix linking issues with MinGW/gcc 2021-09-02 11:03:41 +02:00
wo80 f2ae460ec3 Remove redundant CMake version check and make linking to ws2_32 private. 2021-09-02 10:49:04 +02:00
Vladimir Z Tomov 1459c4f5a6 Minor. 2021-09-01 18:14:25 -07:00
Adrien M. Bernede 445c7de9d3 fix 2021-09-01 14:50:58 -07:00
Adrien M. Bernede 8fb3cdbd9c Fix 2021-09-01 12:15:39 -07:00
Adrien M. Bernede ce77041a5f Fix 2021-09-01 12:00:45 -07:00
Adrien M. Bernede d3456d18e4 Update documentation with latest changes 2021-09-01 11:59:38 -07:00
Adrien M. Bernede 128034a644 fix 2021-09-01 11:52:31 -07:00
Adrien M. Bernede 7a069a3940 fix 2021-09-01 11:28:52 -07:00
Adrien M. Bernede 3a14e511fb Apply changes in the CI 2021-09-01 10:56:25 -07:00
Veselin Dobrev 9011871767 In CMake builds using MinGW, set CMAKE_CXX_EXTENSIONS=ON, i.e.
use the flag '-std=gnu++11'. Without this, MinGW GCC does not
expose the functions jn/_jn, yn/_yn which are used by Example
25/25p.
2021-08-31 23:17:31 -07:00
Kalchev, Delyan 93bd4a7d36 Cleaning up depricated mesh reorientation after master merge 2021-08-31 18:33:17 -07:00
Adrien M. Bernede 04003411ee Fix unbound variable 2021-08-31 18:15:55 -07:00
Kalchev, Delyan d1a1f7b6ff minor 2021-08-31 18:03:37 -07:00
Kalchev, Delyan 67b6f6ecfb Merge conflicts resolved. 2021-08-31 17:58:19 -07:00
Kalchev, Delyan 915897a95c Minor 2021-08-31 16:26:22 -07:00
Kalchev, Delyan 42e5827cb0 Fix style 2021-08-31 16:18:06 -07:00
Kalchev, Delyan 2404931609 A variety of small changes. The main thing is that the two ParElag solver miniapps are now combined into one. 2021-08-31 16:10:08 -07:00
Will Pazner 1fce1b6306 Add device configuration to plor_solvers 2021-08-31 14:44:20 -07:00
Keith 6b33ad4abf Jakub's changes 2021-08-31 12:58:44 -07:00
Keith 5f6fda1bf3 Jakub's changes 2021-08-31 11:55:22 -07:00
Vladimir Z Tomov d0831c2f11 Minor edits in the miniapp. 2021-08-31 10:46:21 -07:00
Jakub Červený cfd1442180 Minor whitespace and typos. 2021-08-31 16:55:27 +02:00
Will Pazner 75cd104d12 ParaView bug: flush stream before calling tellp
When compiling on Windows with MinGW, tellp does not return
the updated file position unless flush is called first.
2021-08-30 17:02:40 -07:00
Adrien M. Bernede 3b1006ddd6 Point to uberenv with simplified MFEM package 2021-08-30 15:01:48 -07:00
Adrien M. Bernede dd3e7c837d Revamping build-and-test: use bash options, add --data option, simplify config file management 2021-08-30 14:48:44 -07:00
Will Pazner 063598fa0d Fix ParaView restart mode on Windows 2021-08-30 14:39:08 -07:00
wo80 68aad702e6 Fix MinGW compilation errors 2021-08-30 17:04:23 +02:00
Tzanio Kolev a685e9a570 Merge branch 'master' into google-benchmark 2021-08-29 18:48:15 -07:00
Tzanio Kolev d36a120e5f Merge branch 'master' into atmcadd 2021-08-29 18:47:52 -07:00
Tzanio Kolev 0f7529465b Merge branch 'master' into coef-set-time-dev 2021-08-29 18:46:58 -07:00
camierjs ceebe284bb Merge master in google-benchmark 2021-08-28 13:12:38 -07:00
Dylan Copeland 08715a83cf Fixing with_coef logic in flux calculation. 2021-08-28 12:54:47 -07:00
Dylan Copeland 4aaa441d70 Fixing a bug in DiffusionIntegrator in the case of a vector (diagonal matrix) coefficient. 2021-08-27 15:40:21 -07:00
Vladimir Z Tomov bba6e27f85 Minor edits. 2021-08-27 14:57:23 -07:00
Adrien Bernede b89a56fe14 Merge pull request #2483 from mfem/scripts/bernede1/build-and-test-improved
Scripts/bernede1/build and test improved
2021-08-27 09:54:47 -07:00
Adrien Bernede d5d984af2b Merge branch 'build/bernede1/corona-build' into scripts/bernede1/build-and-test-improved 2021-08-27 09:54:10 -07:00
Keith 4d48ddb566 fix unit tests after constructor redefinition 2021-08-26 13:53:47 -07:00
Keith 6bdd079b40 fix style 2021-08-26 13:37:07 -07:00
Keith 71c4967e80 added Coefficient & as argument in constructor 2021-08-26 13:34:08 -07:00
Keith 165f4301d8 make gf local 2021-08-26 13:09:40 -07:00
Keith 7d309b3d9e initialize gf 2021-08-26 12:30:58 -07:00
Keith 7246251b52 const Vector & GetLocalOscs() const 2021-08-26 12:24:34 -07:00
Keith 4d40b7536f make GetOsc at const member function 2021-08-26 11:47:40 -07:00
Keith eb195d1cb3 Addressing comments: Change default value 2021-08-26 09:30:52 -07:00
Brendan Keith ebddfa7114 Addressing comments: Added period for conformity. 2021-08-26 09:12:50 -07:00
Brendan Keith a5be9f36ed Addressing comments: Added period for conformity. 2021-08-26 09:09:47 -07:00
Sebastian Grimberg 722d4dd741 Fixes for style check 2021-08-26 08:28:10 -07:00
Sebastian Grimberg af21f7258e Fix HYPRE_BigInt bugs for HYPRE_BIGINT and HYPRE_MIXEDINT 2021-08-25 22:01:49 -07:00
Will Pazner b76734c582 Add warning if changing element attributes to 1 in gmsh reader 2021-08-25 20:30:16 -07:00
Will Pazner 1ddd1f0f3b Allow reading Gmsh meshes where all elements have attribute zero 2021-08-25 16:06:37 -07:00
Adrien M. Bernede 322cd2a2eb Re-organizing 2021-08-25 11:24:28 -07:00
blaz 1c4602cf64 More documentation 2021-08-25 09:34:03 -07:00
blaz 2fd06ce867 documentation 2021-08-24 23:48:26 -07:00
blaz 435d542208 All functors are created as private objects 2021-08-24 20:32:06 -07:00
blaz bd155a672e FDual documentation 2021-08-24 18:07:18 -07:00
blaz afacaa7cad Documentation 2021-08-24 17:36:17 -07:00
blaz f9811d774c FDual name changed for FDualNumber 2021-08-24 16:58:25 -07:00
blaz 3e0b76a048 Changed names for the vector and the matrix classes 2021-08-24 16:53:16 -07:00
tom 1063fb165a fix glvis install
update info on glvis widget
2021-08-24 13:10:57 -07:00
Adrien M. Bernede d379d5db23 At last, the fix 2021-08-24 13:07:19 -07:00
Adrien M. Bernede 5e3b37df1e Test 2021-08-24 13:03:40 -07:00
tom 206eba58e6 update to new versions 2021-08-24 12:51:18 -07:00
Adrien M. Bernede ea2ec2d577 Try to fix include mess 2021-08-24 11:52:09 -07:00
Adrien M. Bernede 044f217796 Anchors does not seem to work well through includes 2021-08-24 11:30:50 -07:00
Tom Stitt 3d59d3a23a readme for jupyter 2021-08-23 15:26:51 -07:00
Adrien M. Bernede ac72ca8524 Fix 2021-08-23 15:17:42 -07:00
tom babd1614f3 new install location allows headers to be found but not libs.. unless we load a header from the conda include dir first.. idk. instead we can use the full libmfem path so that there is only 1 line 2021-08-23 14:53:53 -07:00
Adrien M. Bernede bed4b9a913 Transition to sub-pipelines 2021-08-23 14:07:24 -07:00
tom 91c9794ed0 install mfem/glvis in cling's default search space 2021-08-23 13:24:02 -07:00
tom bccd5a8fb2 use .binder instead of binder and move notebooks to examples/jupyter 2021-08-23 12:57:45 -07:00
Adrien M. Bernede 0bbd8a206d Add warning reproducing CI interactively 2021-08-23 12:14:17 -07:00
Adrien M. Bernede af5111ba2d Explain how to setup corona pipelines 2021-08-23 12:10:58 -07:00
Adrien M. Bernede d7613d27df Apply correct permissions to blueos machines (from mfem-uberenv) 2021-08-23 11:11:47 -07:00
Adrien M. Bernede e1c4b5e9ad Apply correct permissions to blueos machines (from mfem-uberenv) 2021-08-23 10:57:56 -07:00
Adrien M. Bernede 0d30380635 Cosmetic fix 2021-08-23 10:36:58 -07:00
Adrien M. Bernede de5cb2f515 notes formatting was confusing 2021-08-23 10:34:39 -07:00
Tom Stitt 8c83105250 revert kernel type w/ downloaded ipynb from binder. looks like it's a newer notebook version too with the 'id' field? 2021-08-22 20:12:27 -07:00
Tzanio Kolev 356fd50444 Merge branch 'master' into atmcadd 2021-08-22 14:19:20 -07:00
Tzanio c54549d06e Some comments and formatiing in notebooks/ex.ipynb 2021-08-22 13:22:37 -07:00
camierjs 884d972673 Change default problem size and output unit 2021-08-20 15:18:16 -07:00
camierjs 83dcf7f4d0 Merge master in google-benchmark 2021-08-20 14:22:48 -07:00
Adrien Bernede aec5eb791f Minor change to trigger CI. 2021-08-20 13:34:45 -07:00
Jacob Faibussowitsch fa845400b1 style 2021-08-20 15:20:54 -05:00
Jacob Faibussowitsch 12b168018f switch printout based on template used 2021-08-20 15:20:33 -05:00
Adrien M. Bernede 9a3d263db1 Add documentation 2021-08-19 16:45:54 -07:00
camierjs 9e31a17cd9 MFEM_ENABLE_BENCHMARKS => MFEM_ENABLE_GOOGLE_BENCHMARKS 2021-08-19 12:59:59 -07:00
Stowell, Mark L 9dee99fbf1 Moving CHANGELOG entry (Oops) 2021-08-19 12:45:30 -07:00
Adrien M. BERNEDE 2c2e3b10b2 Merge remote-tracking branch 'origin/build/bernede1/corona-build' into scripts/bernede1/build-and-test-improved 2021-08-19 09:32:07 -07:00
Adrien M. BERNEDE 94f58c8dfc Change location of spack upstream installation 2021-08-18 18:03:46 -07:00
Adrien M. BERNEDE e112910cbf Remove unused variable 2021-08-18 17:53:02 -07:00
Adrien M. BERNEDE c6fd2d2d15 Simplify the management of host-config files 2021-08-18 17:51:43 -07:00
Will Pazner ca01ef44bf Merge branch 'ads-cuda-use-jacobi' into lor-solvers-p-ref 2021-08-18 17:28:48 -07:00
tom a88e0dd084 fix bad pip spec 2021-08-18 15:09:21 -07:00
tom ebef2470ef install pyglvis for notebook extension (is that enough?)
update notebook from interactive binder hacking
2021-08-18 15:05:08 -07:00
camierjs 91166f2d45 INSTALL update 2021-08-18 14:20:49 -07:00
tom ac9edbaa8a fix glvis include install 2021-08-18 14:16:32 -07:00
tom c5b2191291 okay we don't have root, install to /Users/stitt4/local instead 2021-08-18 14:00:11 -07:00
tom f1d61a020f add test notebook and ignore notebook checkpoints 2021-08-18 13:38:01 -07:00
tom 26a8cce3af first try at c++ binder env for mfem + xeus-glvis 2021-08-18 13:33:24 -07:00
camierjs 2051aed853 Update Google Benchmark library version to 1.5.6 2021-08-18 12:55:19 -07:00
camierjs 245a7eea7a Update changelog, gitignore and cmake cleanup 2021-08-18 12:50:51 -07:00
camierjs 0980db9fe6 Update all TMOP benchmarks 2021-08-18 12:37:05 -07:00
Adrien M. BERNEDE 4bf755ea08 Two fixes in the behavior of build_and_test 2021-08-18 11:57:20 -07:00
Adrien M. Bernede b5f2789f2f Using hostname to filter specs to install 2021-08-18 11:23:04 -07:00
Adrien M. BERNEDE 128ffe2eee Update mfem-uberenv to use new installation path 2021-08-18 11:19:34 -07:00
Adrien M. BERNEDE a7341d7aa8 Improve build and test for local use 2021-08-18 11:18:25 -07:00
camierjs e7555822b1 'double' atomicAdd implementation for previous versions of CUDA 2021-08-18 08:55:16 -07:00
Stowell, Mark L eb0d3dd036 Adding changes from bugfix/thread-safe-dev 2021-08-17 19:37:56 -07:00
Stowell, Mark L d6e27ad0e8 Adding missing variables when MFEM_THREAD_SAFE is ON 2021-08-17 19:30:52 -07:00
camierjs 7ac0a1881e TMOP AddMultPA_Kernel_3D benchmark 2021-08-17 15:28:47 -07:00
camierjs 17f58851ac Simplify kernel launch, remove fixture 2021-08-17 12:35:32 -07:00
Stowell, Mark L 31adbd89b5 Merge remote-tracking branch 'origin/master' into fe-split-dev 2021-08-17 12:02:44 -07:00
camierjs 42bc24eb79 CMake support for benchmarks 2021-08-17 11:39:38 -07:00
Adrien M. BERNEDE a591dad3e2 Merge branch 'master' into build/bernede1/corona-build 2021-08-17 10:49:43 -07:00
Adrien M. BERNEDE d953ce89e8 Update uberenv to master branch 2021-08-17 10:48:33 -07:00
Stowell, Mark L 4d4cf27264 Adding CHANGELOG entry 2021-08-17 10:45:37 -07:00
Stowell, Mark L 246f9bcec1 Making *Coefficient::SetTime virtual 2021-08-17 09:51:47 -07:00
camierjs c2c71fd0ab PA kernel tests on devices 2021-08-16 16:48:53 -07:00
camierjs 5df0a0e2a1 Merge master in google-benchmark 2021-08-16 08:28:56 -07:00
camierjs d1e29ceaff Update .gitignore 2021-08-16 08:26:40 -07:00
blaz 59151dbe58 documentation and small changes 2021-08-13 20:13:40 -07:00
blaz 002514c2e0 Merge branch 'master' into pr_autodiff 2021-08-13 16:20:11 -07:00
Ketan Mittal b133ec754e minor 2021-08-06 14:31:48 -07:00
blaz 23cd7f75bb changed back miniapp CMakefile 2021-08-06 11:12:32 -07:00
blaz 09b67ab18d Merge branch 'master' into pr_autodiff 2021-08-06 11:01:22 -07:00
blaz 6327127cdc cosmetics 2021-08-06 10:56:23 -07:00
Ketan Mittal d4c102b94c enable high-order terms for Neumann 2021-08-05 17:02:11 -07:00
Ketan Mittal bbba4d863f minor fix for inhomogeneous Neumann 2021-08-04 10:05:49 -07:00
Ketan Mittal 9bf2e813b0 make style 2021-08-03 14:13:58 -07:00
Ketan Mittal 838ac0cf36 improved documentation and other misc changes 2021-08-03 14:13:34 -07:00
Keith 7ec56ca61f FIX: Removed too much in last commit 2021-08-03 09:17:55 -07:00
Keith 1cd7bfb28d remove unused variables 2021-08-03 09:12:50 -07:00
Keith 6a63b46bd4 typo in comment 2021-08-02 23:34:33 -07:00
Ketan Mittal 81aacd2c9e documentation 2021-08-02 15:28:13 -07:00
Ketan Mittal 2077b076c8 Merge branch 'master' of https://github.com/mfem/mfem into shifted-dirichletplusneumann 2021-08-02 15:08:35 -07:00
Ketan Mittal 93be96fcc0 make style 2021-08-02 14:25:31 -07:00
Ketan Mittal 2cb619d9cf minor change to how level sets are indicated 2021-08-02 14:22:19 -07:00
Keith 6f2c580774 fixed style 2021-08-02 12:54:54 -07:00
Keith c0912fe75e added support to return local oscs 2021-08-02 12:53:29 -07:00
Keith 5ffd03a2da updated unit tests 2021-08-02 12:13:56 -07:00
Jacob Faibussowitsch 31c2100b6d make style 2021-08-02 12:06:44 -04:00
Jacob Faibussowitsch afa0c9707f port jacobi2 and jacobi3 to device 2021-08-02 09:05:33 -07:00
Keith ec09fe54e4 style 2021-07-30 23:13:23 -07:00
Keith 2a09088fb0 added some simple unit tests 2021-07-30 23:12:56 -07:00
Keith e93a3542c0 example files written 2021-07-30 21:14:04 -07:00
Keith bdcbfafb42 cleaning code 2021-07-30 20:39:02 -07:00
Keith b9eaa8c309 fix style 2021-07-30 19:45:52 -07:00
Keith 96a10dfa2e finalize serial examples 2021-07-30 19:44:54 -07:00
Keith e4cebc0f6a merged with bug fix 2021-07-30 17:20:52 -07:00
Keith 865b2facc2 verification with embedded meshes 2021-07-30 16:54:15 -07:00
Keith 8877f99da8 Fixed Mesh::GetElementSize(), which did not work for embedded meshes 2021-07-30 16:54:15 -07:00
Keith 8a61b3e27b adding extra features 2021-07-30 16:54:15 -07:00
psocratis 54676a17c2 Fixed bug for serial builds. Fixed comments 2021-07-30 16:54:15 -07:00
psocratis f47244859a fixing parallel implementation 2021-07-30 16:54:15 -07:00
Keith 2e6583650f debugging parallel implementation 2021-07-30 16:54:15 -07:00
Keith 2bc6f6146a cleaned up files 2021-07-30 16:54:15 -07:00
psocratis d2b8fa35bb Fixing setting intrule. Adding parallel example 2021-07-30 16:54:15 -07:00
Keith 1fdfa6d39a code compiles. Needs debugging 2021-07-30 16:54:15 -07:00
Stowell, Mark L 685f94888f merge with master 2021-07-30 13:30:20 -07:00
Adrien M. Bernede 0a0ec12d8a Fix the fix 2021-07-28 01:45:06 -07:00
Adrien M. Bernede 03eec43ce5 Fix resources -> resource. Trigger CI with variable ON_CORONA=YES in MFEM repo 2021-07-27 07:45:38 -07:00
Adrien M. Bernede 0e44229b85 Fix uberenv config 2021-07-27 05:01:12 -07:00
Adrien M. Bernede 8f29013794 Include corona jobs in CI 2021-07-27 03:42:40 -07:00
Adrien M. Bernede e29b811861 Fix uberenv config 2021-07-27 03:08:08 -07:00
Adrien M. Bernede ee38141939 Add missing CI config 2021-07-26 10:53:22 -07:00
Adrien M. Bernede 4863a9ef91 Add corona to gitlab 2021-07-26 10:46:22 -07:00
Adrien M. Bernede ce450a6aee Merge branch 'bernede1/autotest-improved' into build/bernede1/corona-build 2021-07-26 10:29:05 -07:00
camierjs 5382cc9831 Merge master in google-benchmark 2021-07-26 10:23:56 -07:00
Adrien M. Bernede d60ed2dc05 Fix Navier miniapp on corona 2021-07-26 08:29:09 -07:00
Stowell, Mark L e2e9154962 Merge remote-tracking branch 'origin/master' into fe-split-dev 2021-07-24 11:12:34 -07:00
Adrien M. Bernede 6715607678 Update hip 2021-07-23 06:15:34 -07:00
Kalchev, Delyan a92c9215c1 Minor README edit. 2021-07-22 20:53:47 -07:00
Kalchev, Delyan 1a8354db6d Minor 2021-07-22 18:14:39 -07:00
Kalchev, Delyan 78f1b7b534 Minor styling fix. 2021-07-22 17:49:57 -07:00
Kalchev, Delyan 689a6f3146 Fix styling manually. 2021-07-22 17:42:22 -07:00
Kalchev, Delyan 91863c74a1 Pre pull request adjustments 2021-07-22 16:05:08 -07:00
Tom Stitt f89d359d06 add MultAtB and MultT(vector)
and const qualifier to Mult(vector)
2021-07-22 15:58:54 -07:00
Kalchev, Delyan b7b9693e0f Merge branch 'master' into parelag_miniapps 2021-07-22 14:57:48 -07:00
Kalchev, Delyan 3ff3fd763e Small edits of the references in the README. 2021-07-22 13:14:22 -07:00
Ketan Mittal 31ce22595b work for multiple Dirichlet and Neumann conditions 2021-07-22 10:02:09 -07:00
Keith a6270b2582 update osc file 2021-07-19 19:52:33 -07:00
Ketan Mittal 1d84ae004c working dirichlet+neumann 2021-07-19 10:51:02 -07:00
camierjs 4624662515 Merge master in google-benchmark 2021-07-15 14:20:31 -07:00
Stowell, Mark L 099409bfc2 Removing unnecessary includes 2021-07-14 13:44:15 -07:00
Stowell, Mark L 99faa836d5 Expanding comments: Arbitrary -> Arbitrary order 2021-07-14 13:38:26 -07:00
Stowell, Mark L 0496b0806e Adding dependencies so that we can uncomment a few special classes 2021-07-14 13:37:53 -07:00
Ketan Mittal 1f35f2580d WIP - initial commit 2021-07-14 12:47:29 -07:00
blaz 86a297b34f Merge branch 'pr_autodiff' of https://github.com/mfem/mfem into pr_autodiff 2021-07-14 12:02:07 -07:00
blaz a9d6514fb6 cleaned version 2021-07-14 11:59:52 -07:00
Cameron Smith 4d51a907cf install examples if enabled
I don't think this has other significant side effects...
2021-07-14 16:16:58 +00:00
Cameron Smith a10fb1f421 install examples to examples dir 2021-07-14 16:14:01 +00:00
Cameron Smith afee0acf50 exes are RUNTIME comps, cmake sets the prefix 2021-07-14 13:18:11 +00:00
Cameron Smith 1d5ff54f4c install examples 2021-07-13 20:08:24 +00:00
Stowell, Mark L 606d5f2bb2 Adding fem/fe subdirectory to doxygen's input directories. 2021-07-08 11:36:39 -07:00
Stowell, Mark L 901eebd9e2 Merge remote-tracking branch 'origin/master' into fe-split-dev
# Conflicts:
#	fem/fe.cpp
#	fem/fe.hpp
2021-07-08 01:04:31 -07:00
Stowell, Mark L 2cffb578e2 Moving fe* files into subdirectory 2021-07-07 20:33:19 -07:00
Will Pazner e20ae257e5 Don't need LORSolver permutation anymore 2021-07-07 14:25:56 -07:00
blaz 7fcd181280 modified INSTALL 2021-07-03 23:47:06 -07:00
blaz d7ae085678 license check 2021-07-02 16:10:14 -07:00
blaz e967c8a7ef copyright check 2021-07-02 15:52:26 -07:00
blaz 1a6c24c5f2 bug in makefile 2021-07-02 15:42:31 -07:00
blaz 340e3ed188 autodiff makefile 2021-07-02 15:30:46 -07:00
blaz 1382ed617a Merge remote-tracking branch 'origin/master' into pr_autodiff 2021-07-02 15:08:41 -07:00
blaz 4d834ca852 cleaned code 2021-07-02 15:05:28 -07:00
blaz c8a8562ea4 modification and examples 2021-07-02 11:21:48 -07:00
Will Pazner 06032d9340 Add HostRead in BilinearForm::EliminateVDofs 2021-06-30 18:30:59 -07:00
Will Pazner 74710220a1 Remove need (mostly) for LOR DOF permutations
Build the permutation into the P and R operators of the LOR space, so that the
true DOF numbering corresponds to the same true DOF number of the high-order
space. This means the LORSolver does not need to perform any permutation, since
it is incorporated into the RAP.
2021-06-30 18:30:59 -07:00
Will Pazner 6e43e93144 Handle better support of LOR for nonconforming spaces 2021-06-30 18:30:59 -07:00
Will Pazner 0a9b0c681d Handle LOR permutation construction in variable-order case 2021-06-30 18:30:59 -07:00
Will Pazner 2657585cfe Enable LOR for variable-order spaces (in serial) 2021-06-30 18:30:59 -07:00
Will Pazner c2d96bebba Refactor LOR AssembleSystem 2021-06-30 18:30:59 -07:00
Will Pazner b69e30c2ab Add accessor for LORBase object from LORSolver 2021-06-30 18:30:59 -07:00
Will Pazner ec011048a0 Minor Doxygen comments edits 2021-06-30 18:30:59 -07:00
Yohann Dudouit 330f67cedc Reset with current MemoryType. 2021-06-30 10:06:23 -07:00
Yohann Dudouit 6651c80b27 Make Delete reset the Memory object. 2021-06-28 17:35:25 -07:00
Yohann Dudouit 3ac9eff225 Improve documentation. 2021-06-28 17:06:42 -07:00
Yohann Dudouit 3d399d8eb3 Remove unnecessary Reset. 2021-06-25 11:16:09 -07:00
Yohann Dudouit 216e0dfe08 Use Reset() in default constructor. 2021-06-24 19:08:38 -07:00
Stowell, Mark L b86256e768 Adding new files to cmakelists 2021-06-15 12:55:28 -07:00
Stowell, Mark L 5a9bf6853a Fixing construction order of global objects 2021-06-15 12:42:55 -07:00
Stowell, Mark L f1008f7441 Merge remote-tracking branch 'origin/master' into fe-split-dev 2021-06-15 11:11:53 -07:00
Stowell, Mark L 14c29f5814 make style 2021-06-15 11:05:28 -07:00
Stowell, Mark L 06dcdb75ac Splitting fe.[ch]pp 2021-06-15 10:55:27 -07:00
Will Pazner 08bf2f02ad Squashing commits on parelag_miniapps 2021-06-03 11:51:47 -07:00
camierjs 790195159b Move benchmarks to tests/benchmarks
Split the vector and the virtuals tests
2021-05-28 16:20:33 -07:00
camierjs cc6bb3ac35 Use Google benchmark to add unit tests 2021-05-27 16:39:06 -07:00
blaz a32ca0cb89 Another Lambda example 2021-05-26 15:53:39 -07:00
blaz 2e92b44070 Lambda function differentiation 2021-05-26 15:11:05 -07:00
blaz 2aa374efe8 Example of auto diff 2021-05-25 21:00:57 -07:00
blaz 476e642935 added cmake and make files for Eigen and CoDiPack 2021-05-25 17:53:33 -07:00
blaz 0da14179f7 initial copy frm fadg branch 2021-05-25 16:38:32 -07:00
Ketan Mittal ff940b8254 Merge branch 'tmop-align-surface' of https://github.com/mfem/mfem into tmop-align-surface 2021-02-04 10:04:32 -08:00
Ketan Mittal ec9c967b88 adding 3D combo metrics 2021-02-04 10:03:43 -08:00
Vladimir Z Tomov 966071f5ce Minor. 2021-02-02 22:55:28 -08:00
Vladimir Z Tomov ff6dc50d7f Computation of surface fitting errors. Changed the normalization. 2021-02-02 22:51:03 -08:00
Ketan Mittal a39f7635f5 bug fix for writing attribute 2021-01-25 10:42:04 -08:00
Ketan Mittal 7d2ce53a63 write element attribute in mesh file 2021-01-25 09:26:28 -08:00
Vladimir Z Tomov feca2f59dc Minor. 2021-01-14 12:26:28 -08:00
Vladimir Z Tomov 5e296c39c6 Minor. 2021-01-12 09:48:57 -08:00
Vladimir Z Tomov ec306e7166 Merge branch 'master' into tmop-align-surface 2021-01-12 08:49:06 -08:00
Vladimir Z Tomov 7588076853 3D surface fitting test. 2021-01-10 17:06:42 -08:00
Vladimir Z Tomov fbcc7406a7 Another option to diffuse fields. 2021-01-10 16:36:24 -08:00
Vladimir Z Tomov 06b40d8f9e Added a 2D triangle mesh. 2021-01-05 15:10:55 -08:00
Vladimir Z Tomov 944de5d51c Merge branch 'master' into tmop-align-surface 2021-01-04 16:05:28 -08:00
Vladimir Z Tomov 438fd06639 Minor. 2021-01-01 23:28:50 -08:00
Vladimir Z Tomov be26f52385 Improved the output for initial-vs-final energy. 2020-12-31 11:42:30 -08:00
Vladimir Z Tomov 94e16907c9 Minor. 2020-12-30 22:45:51 -08:00
Vladimir Z Tomov dd1fe9e7c3 Added FD support for surface fitting. 2020-12-30 22:39:39 -08:00
Vladimir Z Tomov caeecc0e6d Improved function arguments. 2020-12-30 22:12:43 -08:00
Vladimir Z Tomov 69f70eca5e Found a bug. 2020-12-29 15:10:10 -08:00
Vladimir Z Tomov dbbbf1f443 Merge branch 'master' into tmop-align-surface 2020-12-18 18:35:42 -08:00
Vladimir Z Tomov 2d39d300d1 Updated the fitting method. 2020-12-18 18:34:36 -08:00
Vladimir Z Tomov be3fb993f1 Non-variational form of the fitting term. 2020-11-02 10:06:18 -08:00
Vladimir Z Tomov 6e88331f87 Objective function, derivatives, normalization. 2020-10-28 22:51:43 -07:00
Tomov 0e195e2f87 wip surface alignment. 2020-09-21 22:21:47 -07:00
221 changed files with 38233 additions and 24373 deletions
+12
View File
@@ -0,0 +1,12 @@
# extends https://github.com/jupyterhub/repo2docker/blob/main/repo2docker/buildpacks/conda/environment.yml
# see https://mybinder.readthedocs.io/en/latest/using/config_files.html#environment-yml-install-a-conda-environment
channels:
- conda-forge
dependencies:
- xeus-cling=0.13.0
- xwidgets=0.26.0
# NOTE: it's possible these aren't needed for the lab frontend
- widgetsnbextension=3.5.1
- pip
- pip:
- glvis==0.3.2
+26
View File
@@ -0,0 +1,26 @@
#!/bin/bash
set -e
# cling is installed here (in bin) and will look in {dir}/include and {dir}/lib
# without extra intervention (jk it doesn't look in {dir}/lib unless something
# has been #included from {dir}/include first...)
install_dir=/srv/conda/envs/notebook
mkdir -p $install_dir
# build and install mfem, which is the directory we start in
make serial SHARED=YES -j8
make install PREFIX=$install_dir
# install xeus-glvis
git clone https://github.com/GLVis/xeus-glvis.git
pushd xeus-glvis
make install prefix=$install_dir
popd
# install jupyter-lab extension
jupyter labextension install @jupyter-widgets/jupyterlab-manager --no-build
jupyter labextension install glvis-jupyter
# fixup kernelspec, we could probably do this from sh but ¯\_(ツ)_/¯
python .binder/update_kernel_env.py
+14
View File
@@ -0,0 +1,14 @@
# Update the LD_LIBRARY_PATH of the C++14 kernel so it can find mfem without
# extra pragma cling statements
import json
kernelspec = "/srv/conda/envs/notebook/share/jupyter/kernels/xcpp14/kernel.json"
with open(kernelspec, "r") as f:
obj = json.load(f)
obj["env"] = {"LD_LIBRARY_PATH": "/srv/conda/envs/notebook/lib"}
with open(kernelspec, "w") as f:
json.dump(obj, f)
+2 -2
View File
@@ -82,9 +82,9 @@ jobs:
uses: mfem/github-actions/build-mfem@v2.0
with:
os: ${{ runner.os }}
target: optim
target: opt
codecov: NO
mpi: parallel
mpi: par
build-system: make
hypre-dir: ${{ env.HYPRE_TOP_DIR }}
metis-dir: ${{ env.METIS_TOP_DIR }}
+6 -3
View File
@@ -63,7 +63,7 @@ jobs:
exit 1
code-style:
runs-on: ubuntu-16.04 # needed for astyle 2.05.1
runs-on: ubuntu-18.04
steps:
- name: checkout mfem
@@ -71,7 +71,7 @@ jobs:
- name: get astyle
run: |
sudo apt-get install astyle=2.05.1-0ubuntu1
sudo apt-get install astyle=3.1-1ubuntu2
- name: style check
run: |
@@ -105,6 +105,9 @@ jobs:
- name: branch-history
run: |
git fetch origin master:master
# We override origin to make sure we point to the main repo.
# This is to have consistent test results on PRs from forks.
git remote remove origin
git remote add origin https://github.com/mfem/mfem.git
git checkout -b gh-actions-branch-history
./config/githooks/pre-push --history
+24
View File
@@ -51,6 +51,8 @@ examples/ex1[04-9]
examples/ex1[0-9]p
examples/ex2[0-9]
examples/ex2[0-9]p
examples/ex30
examples/ex30p
examples/refined.mesh
examples/displaced.mesh
@@ -223,6 +225,14 @@ miniapps/mtop/ParHeat*
miniapps/mtop/seqheat
miniapps/mtop/SeqHeat*
miniapps/autodiff/paradiff
miniapps/autodiff/seqadiff
miniapps/autodiff/seqtest
miniapps/autodiff/par_example
miniapps/autodiff/seq_example
miniapps/autodiff/seq_test
miniapps/autodiff/Exampl*
miniapps/navier/navier_mms
miniapps/navier/navier_kovasznay
miniapps/navier/navier_kovasznay_vs
@@ -288,10 +298,15 @@ miniapps/solvers/ParaView
miniapps/solvers/mesh.*
miniapps/solvers/sol.*
miniapps/parelag/MultilevelHcurlHdivSolver
miniapps/parelag/*.mesh
# Unit test binary and outputs
tests/unit/output_meshes
tests/unit/unit_tests
tests/unit/punit_tests
tests/unit/cunit_tests
tests/unit/pcunit_tests
tests/unit/sedov_tests_*
tests/unit/psedov_tests_*
tests/unit/tmop_pa_tests_*
@@ -299,6 +314,12 @@ tests/unit/ptmop_pa_tests_*
tests/unit/ceed_tests
tests/unit/debug_device_tests
# Benchmark binaries
tests/benchmarks/bench_ceed
tests/benchmarks/bench_tmop
tests/benchmarks/bench_vector
tests/benchmarks/bench_virtuals
# Test script output
tests/scripts/*.err
tests/scripts/*.out
@@ -315,3 +336,6 @@ build-*/*
# PETSc automated build
petsc-build/*
pkg.gitcommit
# Jupyter Notebook Checkpoints
.ipynb_checkpoints
+62 -221
View File
@@ -13,243 +13,84 @@
# at Lawrence Livermore National Laboratory (LLNL). This entire pipeline is
# LLNL-specific!
# We define the following GitLab pipeline variables:
#
# BUILD_ROOT:
# The path to the shared resources between all jobs. For example, external
# repositories like 'tests' and 'tpls' are cloned here. Also, 'tpls' is built
# once for all targets, so that build happen here. The BUILD_ROOT is unique to
# the pipeline, preventing any form of concurrency with other pipelines. This
# also means that the BUILD_ROOT directory will never be cleaned.
# TODO: add a clean-up mechanism
#
# REBASELINE:
# Defines the default choice for updating the saved baseline results. By default
# the baseline can only be updated from the master branch. This variable offers
# the option to manually ask for rebaselining from another branch if necessary.
#
# MFEM_ALLOC_NAME:
# On LLNL's quartz, there is only one allocation shared among jobs in order to
# save time and resources. This allocation has to be uniquely named so that we
# are sure to retrieve it.
#
# TPLS_REPO & TESTS_REPO:
# Git repositories used in the pipeline
#
# ARTIFACTS_DIR:
# Directory used to place artifacts.
variables:
BUILD_ROOT: ${CI_BUILDS_DIR}/MFEM/${CI_PROJECT_NAME}_${CI_COMMIT_REF_SLUG}_${CI_PIPELINE_ID}
AUTOTEST_ROOT: ${CI_BUILDS_DIR}/MFEM
REBASELINE: "NO"
AUTOTEST: "NO"
ALLOC_NAME: ${CI_PROJECT_NAME}_ci_${CI_PIPELINE_ID}
TPLS_REPO: ssh://git@mybitbucket.llnl.gov:7999/mfem/tpls.git
TESTS_REPO: ssh://git@mybitbucket.llnl.gov:7999/mfem/tests.git
AUTOTEST_REPO: ssh://git@mybitbucket.llnl.gov:7999/mfem/autotest.git
MFEM_DATA_REPO: https://github.com/mfem/data.git
ARTIFACTS_DIR: artifacts
SLURM_OVERLAP: 1
# The pipeline is divided into stages. Usually, jobs in a given stage wait for
# the preceding stages to complete before to start. However, we sometimes use
# the "needs" keyword and express the DAG of jobs for more efficiency.
# - We use setup and setup_baseline phases to download content outside of mfem
# directory.
# - Allocate/Release is where quartz resources are allocated/released once for all.
# - Allocate/Release is where quartz resource are allocated/released once for all.
# - Build and Test is where we build and MFEM for multiple toolchains.
# - Baseline_checks gathers baseline-type test suites execution
# - Baseline_publish, only available on master, allows to update baseline
# results
stages:
- setup
- q_allocate_resources
- q_build_and_test
- q_release_resources
- l_build_and_test
- c_build_and_test
- setup_baseline
- baseline_check
- baseline_to_autotest
- baseline_publish
- sub-pipelines
# setup clones the mfem/data repo in ${BUILD_ROOT}. The build_and_test script
# then symlinks the repo to the parent directory of the MFEM source directory.
# Unit tests that depend on the mfem/data repo will then detect that this
# directory is present and be enabled.
setup:
tags:
- shell
- quartz
stage: setup
variables:
CUSTOM_CI_BUILDS_DIR: "/usr/workspace/mfem/gitlab-runner"
USER_CI_TOP_DIR: "${CUSTOM_CI_BUILDS_DIR}/${GITLAB_USER_LOGIN}"
SHARED_REPOS_DIR: "${USER_CI_TOP_DIR}/repos"
AUTOTEST_ROOT: "${SHARED_REPOS_DIR}"
# MFEM_DATA_DIR is setup in '.gitlab/configs/setup-build-and-test.yml' and
# used in '.gitlab/configs/<machine>-config.yml':
MFEM_DATA_DIR: "${SHARED_REPOS_DIR}/mfem-data"
# Defines the default choice for updating the saved baseline results. By default
# the baseline can only be updated from the master branch. This variable offers
# the option to manually ask for rebaselining from another branch if necessary.
REBASELINE: "NO"
AUTOTEST: "NO"
# AUTOTEST_COMMIT: used only when AUTOTEST is set to YES.
# * If AUTOTEST_COMMIT is NOT set to NO, reporting jobs will commit their
# files to the MFEM/autotest repo.
# * If AUTOTEST_COMMIT is set to NO, reporting jobs will NOT commit their
# files to the MFEM/autotest repo. Instead they will just show the contents
# of the report files and remove them.
AUTOTEST_COMMIT: "YES"
# Trigger subpipelines:
quartz-build-and-test:
stage: sub-pipelines
variables:
GIT_STRATEGY: none
script:
- mkdir -p ${BUILD_ROOT} && cd ${BUILD_ROOT}
- if [ ! -d data ]; then git clone ${MFEM_DATA_REPO}; fi
# Explicitly pass down values that we want to be able to set when triggering
# pipelines manually or using scheduling
AUTOTEST: "${AUTOTEST}"
AUTOTEST_COMMIT: "${AUTOTEST_COMMIT}"
trigger:
include: .gitlab/quartz-build-and-test.yml
strategy: depend
# The setup_baseline job in setup stage_baseline doesn't rely on MFEM git repo.
# It prepares a pipeline-wide working directory downloading/updating external
# repos. TODO: updating tests and tpls is not necessary anymore since pipelines
# are now using unique directories so repo are never shared with another
# pipeline. This is not memory efficient (we keep a lot of data), hence this
# reminder.
# Note: This job can start immediately.
setup_baseline:
tags:
- shell
- quartz
stage: setup_baseline
quartz-baseline:
stage: sub-pipelines
variables:
GIT_STRATEGY: none
script:
- mkdir -p ${BUILD_ROOT} && cd ${BUILD_ROOT}
- if [ ! -d "tpls" ]; then git clone ${TPLS_REPO}; fi
- if [ ! -d "tests" ]; then git clone ${TESTS_REPO}; fi
- cd tpls && git pull && cd ..
- cd tests && git pull && cd ..
- cd ${AUTOTEST_ROOT}
- if [ ! -d "autotest" ]; then git clone ${AUTOTEST_REPO}; fi
- cd autotest && git pull && cd ..
needs: []
# Explicitly pass down values that we want to be able to set when triggering
# pipelines manually or using scheduling
REBASELINE: "${REBASELINE}"
AUTOTEST: "${AUTOTEST}"
AUTOTEST_COMMIT: "${AUTOTEST_COMMIT}"
trigger:
include: .gitlab/quartz-baseline.yml
strategy: depend
.build_toss_3_x86_64_ib_script:
script:
- export THREADS=12
- echo ${ALLOC_NAME}
- export JOBID=$(squeue -h --name=${ALLOC_NAME} --format=%A)
- echo ${JOBID}
- srun $( [[ -n "${JOBID}" ]] && echo "--jobid=${JOBID}" ) -t 30 -N 1 tests/gitlab/build_and_test
.build_toss_3_x86_64_ib_corona_script:
script:
- srun -p mi60 -t 15 -N 1 tests/gitlab/build_and_test
# Lassen uses a different job scheduler (spectrum lsf) that does not allow
# pre-allocation the same way slurm does. We use pdebug queue on lassen to
# speed-up the allocation. However this would not be scalable to multiple
# builds.
.build_blueos_3_ppc64le_ib_script:
script:
- lalloc 1 -W 30 -q pdebug tests/gitlab/build_and_test
# Shared script for baseline and sample-run-baseline, the value of BASELINE_TEST
# differentiates between the two tests.
.baseline_script: &baseline_script |
# locals
_glob_err=${BASELINE_TEST}.err
_base_diff=${BASELINE_TEST}-${SYS_TYPE}.diff
_base_patch=${BASELINE_TEST}-${SYS_TYPE}.patch
_base_out=${BASELINE_TEST}-${SYS_TYPE}.out
# prepare
cd ${BUILD_ROOT}
ln -snf ${CI_PROJECT_DIR} mfem
cd tests
mkdir _${BASELINE_TEST} && cd _${BASELINE_TEST}
# run
srun --nodes=1 -p pdebug ../runtest ../../mfem "${BASELINE_TEST} ${ADDITIONAL_DIR}"
# post
mkdir ${CI_PROJECT_DIR}/${ARTIFACTS_DIR}
if [[ -s ${_glob_err} ]]
then
echo "ERROR during ${BASELINE_TEST} execution";
echo "Here is the ${_glob_err} file content";
cat ${_glob_err}
cp ${_glob_err} ${CI_PROJECT_DIR}/${ARTIFACTS_DIR}/${_glob_err}
exit 1;
elif [[ ! -f ${_base_patch} && ! -f ${_base_out} ]]
then
echo "Something went WRONG in ${BASELINE_TEST}:";
echo "Either ${_base_patch} or ${_base_out} should exists";
exit 1;
elif [[ -f ${_base_patch} ]]
then
echo "${BASELINE_TEST}: Differences found, patch generated"
cp ${_base_patch} ${CI_PROJECT_DIR}/${ARTIFACTS_DIR}/${_base_patch}
elif [[ -f ${_base_out} ]]
then
echo "${BASELINE_TEST}: Differences found, replacement file generated"
cp ${_base_out} ${CI_PROJECT_DIR}/${ARTIFACTS_DIR}/${_base_out}
fi
# _base_diff won't even exist if there is no difference.
if [[ -f ${_base_diff} ]]
then
echo "${BASELINE_TEST}: Relevant differences (filtered diff) ..."
cat ${_base_diff}
cp ${_base_diff} ${CI_PROJECT_DIR}/${ARTIFACTS_DIR}/${_base_diff}
# We create a .err file, because that's how we signal that there was a diff.
cp ${_base_diff} ${CI_PROJECT_DIR}/${ARTIFACTS_DIR}/gitlab-${BASELINE_TEST}-${SYS_TYPE}.err
fi
if [[ ! -s ${_base_diff} ]]
then
echo "${BASELINE_TEST}: PASSED"
true
else
echo "${BASELINE_TEST}: FAILED"
false
fi
# Actual templates for baseline checks
.baselinecheck_mfem:
stage: baseline_check
lassen-build-and-test:
stage: sub-pipelines
variables:
BASELINE_TEST: baseline
ADDITIONAL_DIR: ${BUILD_ROOT}/tpls
script:
- *baseline_script
artifacts:
when: always
paths:
- ${ARTIFACTS_DIR}
allow_failure: true
# Explicitly pass down values that we want to be able to set when triggering
# pipelines manually or using scheduling
AUTOTEST: "${AUTOTEST}"
AUTOTEST_COMMIT: "${AUTOTEST_COMMIT}"
trigger:
include: .gitlab/lassen-build-and-test.yml
strategy: depend
.samplebaselinecheck_mfem:
stage: baseline_check
corona-build-and-test:
stage: sub-pipelines
variables:
BASELINE_TEST: sample-runs-baseline
ADDITIONAL_DIR: ""
script:
- *baseline_script
timeout: 4h
artifacts:
when: always
paths:
- ${ARTIFACTS_DIR}
allow_failure: true
# This job can only be manually triggered on a pipeline for master branch, or if
# the pipeline was triggered with REBASELINE="YES"
.rebaseline_mfem:
stage: baseline_publish
rules:
- if: '$CI_COMMIT_BRANCH == "master" || $REBASELINE == "YES"'
when: manual
script:
- export PATCH_FILE=${CI_PROJECT_DIR}/${ARTIFACTS_DIR}/baseline-${SYS_TYPE}.patch
- export FULL_FILE=${CI_PROJECT_DIR}/${ARTIFACTS_DIR}/baseline-${SYS_TYPE}.out
- export DIFF_FILE=${CI_PROJECT_DIR}/${ARTIFACTS_DIR}/baseline-${SYS_TYPE}.diff
- cd ${BUILD_ROOT}/tests
- |
if [[ ! -f "${DIFF_FILE}" ]]
then
echo "Nothing to be done: no relevant change in baseline"
exit 0
elif [[ -f "${PATCH_FILE}" ]]
then
patch "./baseline-${SYS_TYPE}.saved" < "${PATCH_FILE}"
elif [[ -f "${FULL_FILE}t" ]]
then
cp "${FULL_FILE}" "./baseline-${SYS_TYPE}.saved"
else
echo "File missing: expected ${PATCH_FILE} or ${FULL_FILE}"
exit 1
fi
- git add baseline-${SYS_TYPE}.saved
- git commit -m "${SYS_TYPE} rebaselined in GitLab pipeline ${CI_PIPELINE_ID}"
- git push origin master
# The list on jobs is defined in machine-specific files.
include:
- local: .gitlab/quartz.yml
- local: .gitlab/lassen.yml
# Explicitly pass down values that we want to be able to set when triggering
# pipelines manually or using scheduling
AUTOTEST: "${AUTOTEST}"
AUTOTEST_COMMIT: "${AUTOTEST_COMMIT}"
trigger:
include: .gitlab/corona-build-and-test.yml
strategy: depend
+94
View File
@@ -0,0 +1,94 @@
Finite Element Discretization Library
__
_ __ ___ / _| ___ _ __ ___
| '_ ` _ \ | |_ / _ \| '_ ` _ \
| | | | | || _|| __/| | | | | |
|_| |_| |_||_| \___||_| |_| |_|
https://mfem.org
This directory contains most of the GitLab CI configuration. MFEM runs both PR
and nightly testing on GitLab.
# Structure
## Top level
The root configuration file is `.gitlab-ci.yml` at the root of MFEM repo.
This file only defines one stage, in which we trigger several
sub-pipelines.
We use sub-pipelines to isolate the test for one combination of `machine`
and `test type`.
Machines typically include:
* Quartz: Intel bi-socket x86
* Lassen: Power9 + Nvidia GPU
* Corona: AMD GPU
Test types include:
* Build and test: Spack driven build of dependencies, mfem build, mfem
test
* Baseline: Script driven build of dependencies, thorough testing
⚠️ The sub-pipeline design allows to add a new machine or a new test type without
altering the scheduling, execution and displaying of the others.
## Sub-pipelines
Each file is this directory is the root configuration file for one
sub-pipeline. The naming reflects the corresponding couple (`machine`,
`test_type`).
Those files define the *stages* and the *jobs* for the sub-pipeline. They
also contain any configuration that cannot be shared. For the most part
though, the configuration is shared and is placed in `.gitlab/configs`.
We try to keep scripts out of the CI config and share them among similar
jobs. They are gathered in `.gitlab/scripts`.
## Scripts
Scripts specific to the CI only are in `.gitlab/scripts`. It is best practice
to keep scripts outside the CI configuration (no bash scripts embedded in a
yaml file) because it helps with readability, maintenance and also with
transition to another CI system.
⚠️ Most of the scripts there are driven by environment variables and do not have a
usage function. This should be improved.
# More testing
## Adding a new target to a build_and_test pipeline
`build_and_test` pipelines rely on Spack to install dependencies. Spack is
driven by Uberenv which helps freezing Spack configuration: the goal being to
point to specific commit in Spack and isolate its configuration so that it is
not influenced by the user environment. More documentation about this can be
found in `tests/gitlab`.
In the end, the MFEM target for which to build the dependencies is expressed
with a spack spec of MFEM, within the limits permitted by the MFEM spack
package.
In any build-and-test sub-pipeline a job basically consists in defining the
spack spec to use. Adding a job on quartz for example resumes to:
```yaml
<job_name>:
variables:
SPEC: "<spack_spec>"
extends: .build_and_test_on_quartz
```
The remaining and non trivial work is to make sure this spec is working. To
test a spec before adding it, or reproduce a CI configuration, please refer to
`tests/gitlab/reproduce-ci-jobs-interactively.md`.
⚠️ It is assumed that the spack spec applies to `mfem@develop`. That's why in the
CI all the specs start with the compiler or the variants to apply to mfem. The
mechanism still works with a full spec.
+36
View File
@@ -0,0 +1,36 @@
# Copyright (c) 2010-2021, 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.
# We define the following GitLab pipeline variables:
variables:
# The path to the shared resource between all jobs. For example, external
# repositories like 'tests' and 'tpls' are cloned here. Also, 'tpls' is built
# once for all targets, so that build happen here. The BUILD_ROOT is unique to
# the pipeline, preventing any form of concurrency with other pipelines. This
# also means that the BUILD_ROOT directory will never be cleaned.
# TODO: add a clean-up mechanism
BUILD_ROOT: ${USER_CI_TOP_DIR}/${CI_PROJECT_NAME}-${MACHINE_NAME}-pipeline-${CI_PIPELINE_ID}
# On LLNL's quartz, there is only one allocation shared among jobs in order to
# save time and resource. This allocation has to be uniquely named so that we
# are sure to retrieve it.
ALLOC_NAME: ${CI_PROJECT_NAME}_ci_${CI_PIPELINE_ID}
# Git repositories used in the pipeline
TPLS_REPO: ssh://git@mybitbucket.llnl.gov:7999/mfem/tpls.git
TESTS_REPO: ssh://git@mybitbucket.llnl.gov:7999/mfem/tests.git
AUTOTEST_REPO: ssh://git@mybitbucket.llnl.gov:7999/mfem/autotest.git
MFEM_DATA_REPO: https://github.com/mfem/data.git
# Directory used to place artifacts.
ARTIFACTS_DIR: artifacts
SLURM_OVERLAP: 1
+59
View File
@@ -0,0 +1,59 @@
# Copyright (c) 2010-2021, 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.
# GitLab pipeline configuration for the Corona machine at LLNL
variables:
MACHINE_NAME: corona
.on_corona:
tags:
- shell
- corona
rules:
# Dont run corona jobs if...
# Note: This makes corona an "opt-in" machine. To activate builds on corona
# for a given GitLab clone of MFEM, go to Setting/CI-CD/variables, and set
# "ON_CORONA" to "ON". An LC account on for corona is required to trigger a
# pipeline there.
- if: '$CI_COMMIT_BRANCH =~ /_cnone/ || $ON_CORONA != "ON"'
when: never
# Dont run autotest update if...
- if: '$CI_JOB_NAME =~ /report/ && $AUTOTEST != "YES"'
when: never
# Report success on success status
- if: '$CI_JOB_NAME =~ /report_job_success/ && $AUTOTEST == "YES"'
when: on_success
# Report failure on failure status
- if: '$CI_JOB_NAME =~ /report_job_failure/ && $AUTOTEST == "YES"'
when: on_failure
# Always release resource
- if: '$CI_JOB_NAME =~ /release_resource/'
when: always
# Always cleanup
- if: '$CI_JOB_NAME =~ /cleanup/'
when: always
# Default is to run if previous stage succeeded
- when: on_success
# Spack helped builds
# Generic corona build job, extending build script
.build_and_test_on_corona:
extends: [.on_corona]
stage: build_and_test
script:
# THREADS is used by 'tests/gitlab/build_and_test', run below
- export THREADS=12
- echo ${ALLOC_NAME}
- export JOBID=$(squeue -h --name=${ALLOC_NAME} --format=%A)
- echo ${JOBID}
- echo ${MFEM_DATA_DIR}
- echo ${SPEC}
- srun $( [[ -n "${JOBID}" ]] && echo "--jobid=${JOBID}" ) -t 15 -N 1 tests/gitlab/build_and_test --spec "${SPEC}" --data-dir "${MFEM_DATA_DIR}" --data
+49
View File
@@ -0,0 +1,49 @@
# Copyright (c) 2010-2021, 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.
# GitLab pipelines configurations for the Lassen machine at LLNL
variables:
MACHINE_NAME: lassen
.on_lassen:
tags:
- shell
- lassen
rules:
- if: '$CI_COMMIT_BRANCH =~ /_lnone/ || $ON_LASSEN == "OFF"' #run except if ...
when: never
# Don't run autotest update if...
- if: '$CI_JOB_NAME =~ /report/ && $AUTOTEST != "YES"'
when: never
# Report success on success status
- if: '$CI_JOB_NAME =~ /report_job_success/ && $AUTOTEST == "YES"'
when: on_success
# Report failure on failure status
- if: '$CI_JOB_NAME =~ /report_job_failure/ && $AUTOTEST == "YES"'
when: on_failure
# Always cleanup
- if: '$CI_JOB_NAME =~ /cleanup/'
when: always
- when: on_success
# Lassen uses a different job scheduler (spectrum lsf) that does not allow
# pre-allocation the same way slurm does. We use pdebug queue on lassen
# to speed-up the allocation. However this would not be scalable to
# multiple builds.
.build_and_test_on_lassen:
extends: [.on_lassen]
stage: build_and_test
script:
- echo ${MFEM_DATA_DIR}
- echo ${SPEC}
# Next script uses 'THREADS': leaving it empty --> it uses 'make all -j'
- lalloc 1 -W 30 -q pdebug tests/gitlab/build_and_test --spec "${SPEC}" --data-dir "${MFEM_DATA_DIR}" --data
needs: [setup]
+55
View File
@@ -0,0 +1,55 @@
# Copyright (c) 2010-2021, 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.
# GitLab pipelines configurations for the Quartz machine at LLNL
variables:
MACHINE_NAME: quartz
.on_quartz:
tags:
- shell
- quartz
rules:
# Don't run quartz jobs if...
- if: '$CI_COMMIT_BRANCH =~ /_qnone/ || $ON_QUARTZ == "OFF"'
when: never
# Don't run autotest update if...
- if: '$CI_JOB_NAME =~ /report/ && $AUTOTEST != "YES"'
when: never
# Report success on success status
- if: '$CI_JOB_NAME =~ /report_job_success/ && $AUTOTEST == "YES"'
when: on_success
# Report failure on failure status
- if: '$CI_JOB_NAME =~ /report_job_failure/ && $AUTOTEST == "YES"'
when: on_failure
# Always release resource
- if: '$CI_JOB_NAME =~ /release_resource/'
when: always
# Always cleanup
- if: '$CI_JOB_NAME =~ /cleanup/'
when: always
# Default is to run if previous stage succeeded
- when: on_success
# Spack helped builds
# Generic quartz build job, extending build script
.build_and_test_on_quartz:
extends: [.on_quartz]
stage: build_and_test
script:
# THREADS is used by 'tests/gitlab/build_and_test', run below
- export THREADS=12
- echo ${ALLOC_NAME}
- export JOBID=$(squeue -h --name=${ALLOC_NAME} --format=%A)
- echo ${JOBID}
- echo ${MFEM_DATA_DIR}
- echo ${SPEC}
- srun $( [[ -n "${JOBID}" ]] && echo "--jobid=${JOBID}" ) -t 30 -N 1 tests/gitlab/build_and_test --spec "${SPEC}" --data-dir "${MFEM_DATA_DIR}" --data
+81
View File
@@ -0,0 +1,81 @@
# Copyright (c) 2010-2021, 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.
# Jobs report
.report_job_success:
script:
- echo ${MACHINE_NAME}
- echo ${AUTOTEST}
- echo ${AUTOTEST_COMMIT}
- echo "AUTOTEST_ROOT ${AUTOTEST_ROOT}"
- cd ${AUTOTEST_ROOT}
- |
(
date
echo "Waiting to aquire lock on '$PWD/autotest.lock' ..."
# try to get an excusive lock on fd 9 (autotest.lock) repeating the try
# every 5 seconds; simply using no timeout, i.e. 'flock 9', causes the
# command to hang indefinitely sometimes, so we use the timeout & retry
# as a workaround; we may want to add a counter for the number of
# retries to interrupt a potential infinite loop
while ! flock -w 5 9; do
true
done
echo "Aquired lock on '$PWD/autotest.lock'"
date
# Report SUCCESS while holding the file lock on 'autotest.lock'.
# The next script uses the following environment variables:
# - MACHINE_NAME, AUTOTEST_ROOT, AUTOTEST_COMMIT
# - CI_COMMIT_REF_SLUG, CI_PROJECT_DIR, CI_PIPELINE_URL
# It also calls the script '.gitlab/scripts/safe_create_rundir'.
${CI_PROJECT_DIR}/.gitlab/scripts/report_build_and_test_success
err=$?
# sleep for a period to allow NFS to propagate the above changes;
# clearly, there is no guarantee that other NFS clients will see the
# changes even after the timeout
sleep 10
exit $err
) 9> autotest.lock
.report_job_failure:
script:
- echo ${MACHINE_NAME}
- echo ${AUTOTEST}
- echo ${AUTOTEST_COMMIT}
- echo "AUTOTEST_ROOT ${AUTOTEST_ROOT}"
- cd ${AUTOTEST_ROOT}
- |
(
date
echo "Waiting to aquire lock on '$PWD/autotest.lock' ..."
# try to get an excusive lock on fd 9 (autotest.lock) repeating the try
# every 5 seconds; simply using no timeout, i.e. 'flock 9', causes the
# command to hang indefinitely sometimes, so we use the timeout & retry
# as a workaround; we may want to add a counter for the number of
# retries to interrupt a potential infinite loop
while ! flock -w 5 9; do
true
done
echo "Aquired lock on '$PWD/autotest.lock'"
date
# Report FAILURE while holding the file lock on 'autotest.lock'.
# The next script uses the following environment variables:
# - MACHINE_NAME, AUTOTEST_ROOT, AUTOTEST_COMMIT
# - CI_COMMIT_REF_SLUG, CI_PROJECT_DIR, CI_PIPELINE_URL
# It also calls the script '.gitlab/scripts/safe_create_rundir'.
${CI_PROJECT_DIR}/.gitlab/scripts/report_build_and_test_failure
err=$?
# sleep for a period to allow NFS to propagate the above changes;
# clearly, there is no guarantee that other NFS clients will see the
# changes even after the timeout
sleep 10
exit $err
) 9> autotest.lock
+72
View File
@@ -0,0 +1,72 @@
# Copyright (c) 2010-2021, 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.
# The setup_baseline job doesn't rely on MFEM git repo. It prepares a
# pipeline-wide working directory downloading/updating external repos.
# TODO:
# updating tests and tpls is not necessary anymore since pipelines are now
# using unique directories so repo are never shared with another pipeline. This
# is not memory efficient (we keep a lot of data), hence this reminder.
setup_baseline:
tags:
- shell
- quartz
stage: setup
variables:
GIT_STRATEGY: none
script:
#
# Setup ${BUILD_ROOT}/tpls and ${BUILD_ROOT}/tests:
#
- echo "MACHINE_NAME = ${MACHINE_NAME}"
- echo "REBASELINE = ${REBASELINE}"
- echo "AUTOTEST = ${AUTOTEST}"
- echo "AUTOTEST_COMMIT = ${AUTOTEST_COMMIT}"
- echo "BUILD_ROOT ${BUILD_ROOT}"
- mkdir -p ${BUILD_ROOT} && cd ${BUILD_ROOT}
- if [ ! -d "tpls" ]; then git clone ${TPLS_REPO}; fi
- if [ ! -d "tests" ]; then git clone ${TESTS_REPO}; fi
- cd tpls && git pull && cd ..
- cd tests && git pull origin && cd ..
#
# Setup ${AUTOTEST_ROOT}/autotest:
#
- echo "AUTOTEST_ROOT ${AUTOTEST_ROOT}"
- mkdir -p ${AUTOTEST_ROOT} && cd ${AUTOTEST_ROOT}
- command -v flock || echo "Required command 'flock' not found"
- |
(
date
echo "Waiting to aquire lock on '$PWD/autotest.lock' ..."
# try to get an excusive lock on fd 9 (autotest.lock) repeating the try
# every 5 seconds; simply using no timeout, i.e. 'flock 9', causes the
# command to hang indefinitely sometimes, so we use the timeout & retry
# as a workaround; we may want to add a counter for the number of
# retries to interrupt a potential infinite loop
while ! flock -w 5 9; do
true
done
echo "Aquired lock on '$PWD/autotest.lock'"
date
# clone/update the autotest repo while holding the file lock on
# 'autotest.lock'
err=0
if [[ ! -d "autotest" ]]; then
git clone ${AUTOTEST_REPO}
else
cd autotest && git pull && cd ..
fi || err=1
# sleep for a period to allow NFS to propagate the above changes;
# clearly, there is no guarantee that other NFS clients will see the
# changes even after the timeout
sleep 10
exit $err
) 9> autotest.lock
+94
View File
@@ -0,0 +1,94 @@
# Copyright (c) 2010-2021, 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.
# Setup clones the mfem/data repo in ${SHARED_REPOS_DIR}. The build_and_test
# script then symlinks the repo to the parent directory of the MFEM source
# directory. Unit tests that depend on the mfem/data repo will then detect that
# this directory is present and be enabled.
setup:
tags:
- shell
- quartz
stage: setup
variables:
GIT_STRATEGY: none
script:
#
# Setup MFEM_DATA_DIR=${SHARED_REPOS_DIR}/mfem-data, see '.gitlab-ci.yml'
# and '.gitlab/configs/<machine>-config.yml'
#
- echo "MACHINE_NAME = ${MACHINE_NAME}"
- echo "AUTOTEST = ${AUTOTEST}"
- echo "AUTOTEST_COMMIT = ${AUTOTEST_COMMIT}"
- echo "SHARED_REPOS_DIR ${SHARED_REPOS_DIR}"
- mkdir -p ${SHARED_REPOS_DIR} && cd ${SHARED_REPOS_DIR}
- command -v flock || echo "Required command 'flock' not found"
- |
(
date
echo "Waiting to aquire lock on '$PWD/mfem-data.lock' ..."
# try to get an excusive lock on fd 9 (mfem-data.lock) repeating the try
# every 5 seconds; simply using no timeout, i.e. 'flock 9', causes the
# command to hang indefinitely sometimes, so we use the timeout & retry
# as a workaround; we may want to add a counter for the number of
# retries to interrupt a potential infinite loop
while ! flock -w 5 9; do
true
done
echo "Aquired lock on '$PWD/mfem-data.lock'"
date
# clone/update the mfem/data repo while holding the file lock on
# 'mfem-data.lock'
err=0
if [[ ! -d "mfem-data" ]]; then
git clone ${MFEM_DATA_REPO} "mfem-data"
else
cd "mfem-data" && git pull && cd ..
fi || err=1
# sleep for a period to allow NFS to propagate the above changes;
# clearly, there is no guarantee that other NFS clients will see the
# changes even after the timeout
sleep 10
exit $err
) 9> mfem-data.lock
#
# Setup ${AUTOTEST_ROOT}/autotest:
#
- echo "AUTOTEST_ROOT ${AUTOTEST_ROOT}"
- mkdir -p ${AUTOTEST_ROOT} && cd ${AUTOTEST_ROOT}
- |
(
date
echo "Waiting to aquire lock on '$PWD/autotest.lock' ..."
# try to get an excusive lock on fd 9 (autotest.lock) repeating the try
# every 5 seconds; simply using no timeout, i.e. 'flock 9', causes the
# command to hang indefinitely sometimes, so we use the timeout & retry
# as a workaround; we may want to add a counter for the number of
# retries to interrupt a potential infinite loop
while ! flock -w 5 9; do
true
done
echo "Aquired lock on '$PWD/autotest.lock'"
date
# clone/update the autotest repo while holding the file lock on
# 'autotest.lock'
err=0
if [[ ! -d "autotest" ]]; then
git clone ${AUTOTEST_REPO}
else
cd autotest && git pull && cd ..
fi || err=1
# sleep for a period to allow NFS to propagate the above changes;
# clearly, there is no guarantee that other NFS clients will see the
# changes even after the timeout
sleep 10
exit $err
) 9> autotest.lock
+67
View File
@@ -0,0 +1,67 @@
# Copyright (c) 2010-2021, 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.
stages:
- setup
- allocate_resource
- build_and_test
- release_resource_and_report
# Slurm shared allocation
allocate_resource:
variables:
GIT_STRATEGY: none
extends: .on_corona
stage: allocate_resource
script:
- echo ${ALLOC_NAME}
- salloc --exclusive --nodes=1 --partition=mi60 --time=30 --no-shell --job-name=${ALLOC_NAME}
timeout: 6h
needs: [setup]
# Build and test jobs, simply provide a spec
rocm_gcc_8.3.1:
variables:
SPEC: "@develop%gcc@8.3.1+rocm amdgpu_target=gfx906"
extends: .build_and_test_on_corona
needs: [allocate_resource]
# Release slurm allocation
release_resource:
variables:
GIT_STRATEGY: none
extends: .on_corona
stage: release_resource_and_report
script:
- echo ${ALLOC_NAME}
- export JOBID=$(squeue -h --name=${ALLOC_NAME} --format=%A)
- echo ${JOBID}
- ([[ -n "${JOBID}" ]] && scancel ${JOBID})
needs: [rocm_gcc_8.3.1]
# Jobs report
report_job_success:
stage: release_resource_and_report
extends:
- .on_corona
- .report_job_success
report_job_failure:
stage: release_resource_and_report
extends:
- .on_corona
- .report_job_failure
include:
- local: .gitlab/configs/common.yml
- local: .gitlab/configs/corona-config.yml
- local: .gitlab/configs/setup-build-and-test.yml
- local: .gitlab/configs/report-build-and-test.yml
@@ -9,26 +9,31 @@
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.
# GitLab pipelines configurations for the Lassen machine at LLNL
.on_lassen:
tags:
- shell
- lassen
rules:
- if: '$CI_COMMIT_BRANCH =~ /_lnone/ || $ON_LASSEN == "OFF"' #run except if ...
when: never
- when: on_success
# Spack helped builds
# Generic lassen build job, extending build script
# Note: Lassen jobs can start as soon as the setup job is complete.
.build_and_test_on_lassen:
extends: [.build_blueos_3_ppc64le_ib_script, .on_lassen]
stage: l_build_and_test
needs: [setup]
stages:
- setup
- build_and_test
- report
opt_mpi_cuda_xl_16_1_1_8:
variables:
SPEC: "%xl@16.1.1.8 +mpi +cuda cuda_arch=70"
extends: .build_and_test_on_lassen
# Jobs report
report_job_success:
stage: report
extends:
- .on_lassen
- .report_job_success
report_job_failure:
stage: report
extends:
- .on_lassen
- .report_job_failure
include:
- local: .gitlab/configs/common.yml
- local: .gitlab/configs/lassen-config.yml
- local: .gitlab/configs/setup-build-and-test.yml
- local: .gitlab/configs/report-build-and-test.yml
+133
View File
@@ -0,0 +1,133 @@
# Copyright (c) 2010-2021, 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.
variables:
BASELINE_TEST: baseline
stages:
- setup
- baseline_check
- baseline_report
- cleanup
- baseline_publish
baselinecheck_mfem_intel_quartz:
extends: [.on_quartz]
stage: baseline_check
variables:
# TPLS_DIR is used in .gitlab/scripts/baseline to provide the tpls location
# when call the runtest script in MFEM test repo.
# Note: the value must be consistent with the setup performed in
# .gitlab/configs/setup-baseline.yml.
TPLS_DIR: ${BUILD_ROOT}/tpls
script:
- echo ${BUILD_ROOT}
- echo ${TPLS_DIR}
# Used by the tests in MFEM/tests:
- export MFEM_TEST_NP=32
# The next script uses the following environment variables:
# * BASELINE_TEST, SYS_TYPE, CI_PROJECT_DIR, ARTIFACTS_DIR,
# * BUILD_ROOT, TPLS_DIR, MACHINE_NAME
- .gitlab/scripts/baseline
artifacts:
when: always
paths:
- ${ARTIFACTS_DIR}
allow_failure: true
cleanup:
extends: .on_quartz
stage: cleanup
variables:
GIT_STRATEGY: none
script:
- echo "BUILD_ROOT=${BUILD_ROOT}"
- rm -rf "${BUILD_ROOT}" || true
report_baseline:
extends: [.on_quartz]
stage: baseline_report
script:
- echo ${MACHINE_NAME}
- echo ${AUTOTEST}
- echo ${AUTOTEST_COMMIT}
- echo "AUTOTEST_ROOT ${AUTOTEST_ROOT}"
- cd ${AUTOTEST_ROOT}
- |
(
date
echo "Waiting to aquire lock on '$PWD/autotest.lock' ..."
# try to get an excusive lock on fd 9 (autotest.lock) repeating the try
# every 5 seconds; simply using no timeout, i.e. 'flock 9', causes the
# command to hang indefinitely sometimes, so we use the timeout & retry
# as a workaround; we may want to add a counter for the number of
# retries to interrupt a potential infinite loop
while ! flock -w 5 9; do
true
done
echo "Aquired lock on '$PWD/autotest.lock'"
date
# ----------------------
cd ${AUTOTEST_ROOT}/autotest || \
{ echo "Invalid 'autotest' dir: ${AUTOTEST_ROOT}/autotest"; exit 1; }
mkdir -p ${MACHINE_NAME}
rundir="${MACHINE_NAME}/$(date +%Y-%m-%d)-gitlab-${BASELINE_TEST}-${CI_COMMIT_REF_SLUG}"
rundir=$(${CI_PROJECT_DIR}/.gitlab/scripts/safe_create_rundir ${rundir})
cp ${CI_PROJECT_DIR}/${ARTIFACTS_DIR}/* ${rundir}
# We create an autotest-email.html file, because that's how we signal that there was a diff (temporary).
if [[ -f ${rundir}/${BASELINE_TEST}.err ]]; then
cp ${rundir}/${BASELINE_TEST}.err ${rundir}/autotest-email.html
fi
printf "%s\n" "" "Pipeline URL:" "$CI_PIPELINE_URL" \
>> ${rundir}/pipeline.txt
msg="GitLab CI log for ${BASELINE_TEST} on ${MACHINE_NAME} ($(date +%Y-%m-%d))"
if [[ "$AUTOTEST_COMMIT" != "NO" ]]; then
git pull && \
git add ${rundir} && \
git commit -m "${msg}" && \
git push origin master
else
for file in ${rundir}/*; do
echo "------------------------------"
echo "Content of '$file'"
echo "******************************"
cat $file
echo "******************************"
done
rm -rf ${rundir} || true
fi
err=$?
# ----------------------
# sleep for a period to allow NFS to propagate the above changes;
# clearly, there is no guarantee that other NFS clients will see the
# changes even after the timeout
sleep 10
exit $err
) 9> autotest.lock
baselinepublish_mfem_quartz:
extends: [.on_quartz]
stage: baseline_publish
rules:
# - if: '$CI_COMMIT_BRANCH == "master" || $REBASELINE == "YES"'
- if: '$REBASELINE == "YES"'
when: manual
script:
- echo ${BUILD_ROOT}
- echo ${PWD}
- echo ${ARTIFACTS_DIR}
- ls -lA ${ARTIFACTS_DIR}
- .gitlab/scripts/rebaseline
include:
- local: .gitlab/configs/common.yml
- local: .gitlab/configs/quartz-config.yml
- local: .gitlab/configs/setup-baseline.yml
+99
View File
@@ -0,0 +1,99 @@
# Copyright (c) 2010-2021, 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.
stages:
- setup
- allocate_resource
- build_and_test
- release_resource_and_report
# Allocate
allocate_resource:
variables:
GIT_STRATEGY: none
extends: .on_quartz
stage: allocate_resource
script:
- echo ${ALLOC_NAME}
- salloc --exclusive --nodes=1 --partition=pdebug --time=30 --no-shell --job-name=${ALLOC_NAME}
timeout: 6h
# GitLab jobs for the Quartz machine at LLNL
debug_ser_gcc_4_9_3:
variables:
SPEC: "%gcc@4.9.3 +debug~mpi"
extends: .build_and_test_on_quartz
debug_ser_gcc_6_1_0:
variables:
SPEC: "%gcc@6.1.0 +debug~mpi"
extends: .build_and_test_on_quartz
debug_par_gcc_6_1_0:
variables:
SPEC: "%gcc@6.1.0 +debug+mpi"
extends: .build_and_test_on_quartz
opt_ser_gcc_6_1_0:
variables:
SPEC: "%gcc@6.1.0 ~mpi"
extends: .build_and_test_on_quartz
opt_par_gcc_6_1_0:
variables:
SPEC: "%gcc@6.1.0"
extends: .build_and_test_on_quartz
opt_par_gcc_6_1_0_sundials:
variables:
SPEC: "%gcc@6.1.0 +sundials"
extends: .build_and_test_on_quartz
opt_par_gcc_6_1_0_petsc:
variables:
SPEC: "%gcc@6.1.0 +petsc ^petsc+mumps"
extends: .build_and_test_on_quartz
opt_par_gcc_6_1_0_pumi:
variables:
SPEC: "%gcc@6.1.0 +pumi"
extends: .build_and_test_on_quartz
# Release
release_resource:
variables:
GIT_STRATEGY: none
extends: .on_quartz
stage: release_resource_and_report
script:
- echo ${ALLOC_NAME}
- export JOBID=$(squeue -h --name=${ALLOC_NAME} --format=%A)
- echo ${JOBID}
- ([[ -n "${JOBID}" ]] && scancel ${JOBID})
# Jobs report
report_job_success:
stage: release_resource_and_report
extends:
- .on_quartz
- .report_job_success
report_job_failure:
stage: release_resource_and_report
extends:
- .on_quartz
- .report_job_failure
include:
- local: .gitlab/configs/common.yml
- local: .gitlab/configs/quartz-config.yml
- local: .gitlab/configs/setup-build-and-test.yml
- local: .gitlab/configs/report-build-and-test.yml
-184
View File
@@ -1,184 +0,0 @@
# Copyright (c) 2010-2021, 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.
# GitLab pipelines configurations for the Quartz machine at LLNL
.on_quartz:
tags:
- shell
- quartz
rules:
# Don't run quartz jobs if...
- if: '$CI_COMMIT_BRANCH =~ /_qnone/ || $ON_QUARTZ == "OFF"'
when: never
# Don't run autotest update if...
- if: '$CI_JOB_NAME =~ /update_autotest/ && $AUTOTEST != "YES"'
when: never
# Don't run autotest update if...
- if: '$CI_JOB_NAME =~ /q_report/ && $AUTOTEST != "YES"'
when: never
# Report success on success status
- if: '$CI_JOB_NAME =~ /q_report_success/ && $AUTOTEST == "YES"'
when: on_success
# Report failure on failure status
- if: '$CI_JOB_NAME =~ /q_report_failure/ && $AUTOTEST == "YES"'
when: on_failure
# Always release resources
- if: '$CI_JOB_NAME =~ /release_resources/'
when: always
# Default is to run if previous stage succeeded
- when: on_success
# This is a yaml anchor, it can be used to avoid duplication like here.
# The code below will simply be pasted wherever the anchor is placed.
.safe_create_rundir: &safe_create_rundir |
if ! mkdir ${rundir}; then
n=1
while ! mkdir ${rundir}_${n}
do
n=$((n+1))
done
rundir=${rundir}_${n}
fi
# Allocate
q_allocate_resources:
variables:
GIT_STRATEGY: none
extends: .on_quartz
stage: q_allocate_resources
script:
- salloc --exclusive --nodes=1 --partition=pdebug --time=30 --no-shell --job-name=${ALLOC_NAME}
timeout: 6h
# Release
q_release_resources:
variables:
GIT_STRATEGY: none
extends: .on_quartz
stage: q_release_resources
script:
- export JOBID=$(squeue -h --name=${ALLOC_NAME} --format=%A)
- ([[ -n "${JOBID}" ]] && scancel ${JOBID})
# Release
q_report_success:
variables:
GIT_STRATEGY: none
extends: .on_quartz
stage: q_release_resources
script:
- echo "Can only run if all the quartz jobs passed"
- cd ${AUTOTEST_ROOT}/autotest && git pull
- rundir="gitlab/$(date +%Y-%m-%d)-github-${CI_COMMIT_REF_SLUG}"
- *safe_create_rundir
- echo "The Quartz jobs were successful" > ${rundir}/gitlab.out
- echo "See the pipeline here -> $CI_PIPELINE_URL" >> ${rundir}/gitlab.err
- git add ${rundir}
- git commit -am "Gitlab CI log for baseline on quartz with intel ($(date +%Y-%m-%d))"
- git push origin master
q_report_failure:
variables:
GIT_STRATEGY: none
extends: .on_quartz
stage: q_release_resources
script:
- echo "Runs if there was at least one failure on quartz"
- cd ${AUTOTEST_ROOT}/autotest && git pull
- rundir="gitlab/$(date +%Y-%m-%d)-github-${CI_COMMIT_REF_SLUG}"
- *safe_create_rundir
- echo "There was an error while running CI on Quartz" > ${rundir}/gitlab.err
- echo "See the pipeline here -> $CI_PIPELINE_URL" >> ${rundir}/gitlab.err
- cp ${rundir}/gitlab.err ${rundir}/autotest-email.html
- git add ${rundir}
- git commit -am "Gitlab CI log for baseline on quartz with intel ($(date +%Y-%m-%d))"
- git push origin master
# Spack helped builds
# Generic quartz build job, extending build script
.build_and_test_on_quartz:
extends: [.build_toss_3_x86_64_ib_script, .on_quartz]
stage: q_build_and_test
# Build MFEM
debug_ser_gcc_4_9_3:
variables:
SPEC: "%gcc@4.9.3 +debug~mpi"
extends: .build_and_test_on_quartz
debug_ser_gcc_6_1_0:
variables:
SPEC: "%gcc@6.1.0 +debug~mpi"
extends: .build_and_test_on_quartz
debug_par_gcc_6_1_0:
variables:
SPEC: "%gcc@6.1.0 +debug+mpi"
extends: .build_and_test_on_quartz
opt_ser_gcc_6_1_0:
variables:
SPEC: "%gcc@6.1.0 ~mpi"
extends: .build_and_test_on_quartz
opt_par_gcc_6_1_0:
variables:
SPEC: "%gcc@6.1.0"
extends: .build_and_test_on_quartz
opt_par_gcc_6_1_0_sundials:
variables:
SPEC: "%gcc@6.1.0 +sundials"
extends: .build_and_test_on_quartz
opt_par_gcc_6_1_0_petsc:
variables:
SPEC: "%gcc@6.1.0 +petsc ^petsc+mumps"
extends: .build_and_test_on_quartz
opt_par_gcc_6_1_0_pumi:
variables:
SPEC: "%gcc@6.1.0 +pumi"
extends: .build_and_test_on_quartz
# Baseline jobs form an independent set of jobs. We use `needs:[]` to specify
# that "setup-baseline" can start immediately. Then, we have to use needs for
# each one of the baseline jobs, otherwise they will wait for the rest of the
# pipeline.
baselinecheck_mfem_intel_quartz:
extends: [.baselinecheck_mfem, .on_quartz]
needs: [setup_baseline]
update_autotest:
extends: [.on_quartz]
needs: [baselinecheck_mfem_intel_quartz]
stage: baseline_to_autotest
script:
- cd ${AUTOTEST_ROOT}/autotest && git pull
- rundir="quartz/$(date +%Y-%m-%d)-github-${CI_COMMIT_REF_SLUG}"
- *safe_create_rundir
- cp ${CI_PROJECT_DIR}/${ARTIFACTS_DIR}/* ${rundir}
# We create an autotest-email.html file, because that's how we signal that there was a diff (temporary).
- |
if [[ -f ${rundir}/*.err ]]
then
echo "See the pipeline here -> $CI_PIPELINE_URL" >> ${rundir}/*.err
cp ${rundir}/*.err ${rundir}/autotest-email.html
fi
- git add ${rundir}
- git commit -am "Gitlab CI log for baseline on quartz with intel ($(date +%Y-%m-%d))"
- git push origin master
baselinepublish_mfem_quartz:
extends: [.on_quartz, .rebaseline_mfem]
needs: [baselinecheck_mfem_intel_quartz]
+88
View File
@@ -0,0 +1,88 @@
#!/bin/bash
# Copyright (c) 2010-2021, 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.
# locals
glob_err=${BASELINE_TEST}.err
base=${BASELINE_TEST}-${SYS_TYPE}
base_diff=${base}.diff
base_patch=${base}.patch
base_out=${base}.out
artifacts_path=${CI_PROJECT_DIR}/${ARTIFACTS_DIR}
# prepare
cd ${BUILD_ROOT} || \
{ echo "Invalid BUILD_ROOT=$BUILD_ROOT"; exit 1; }
ln -snf ${CI_PROJECT_DIR} mfem
cd tests
[[ -d _${BASELINE_TEST} ]] && rm -rf _${BASELINE_TEST}
mkdir _${BASELINE_TEST} && cd _${BASELINE_TEST}
# run
if [[ "${MACHINE_NAME}" == "quartz" || "${MACHINE_NAME}" == "ruby" ]]; then
srun --nodes=1 -p pdebug ../runtest ../../mfem "${BASELINE_TEST} ${TPLS_DIR}"
elif [[ ${MACHINE_NAME} == "corona" ]]; then
srun --nodes=1 -t 60 -p mi60 ../runtest ../../mfem "${BASELINE_TEST} ${TPLS_DIR}"
elif [[ ${MACHINE_NAME} == "lassen" ]]; then
lalloc 1 -q pdebug ../runtest ../../mfem "${BASELINE_TEST} ${TPLS_DIR}"
else
echo "Unknown machine: MACHINE_NAME=$MACHINE_NAME"
exit 1
fi
# post
mkdir ${artifacts_path}
if [[ -s ${glob_err} ]]
then
echo "ERROR during ${BASELINE_TEST} execution";
echo "Here is the ${glob_err} file content";
cat ${glob_err}
cp ${glob_err} ${artifacts_path}/${glob_err}
exit 1;
elif [[ ! -f ${base_patch} && ! -f ${base_out} ]]
then
echo "Something went WRONG in ${BASELINE_TEST}:";
echo "Either ${base_patch} or ${base_out} should exists";
exit 1;
elif [[ -f ${base_patch} ]]
then
echo "${BASELINE_TEST}: Differences found, patch generated"
cp ${base_patch} ${artifacts_path}/${base_patch}
elif [[ -f ${base_out} ]]
then
echo "${BASELINE_TEST}: Differences found, replacement file generated"
cp ${base_out} ${artifacts_path}/${base_out}
fi
if [[ -f ${BASELINE_TEST}.out ]]; then
cp ${BASELINE_TEST}.out ${artifacts_path}
fi
# base_diff won't even exist if there is no difference.
if [[ -f ${base_diff} ]]
then
echo "${BASELINE_TEST}: Relevant differences (filtered diff) ..."
cat ${base_diff}
cp ${base_diff} ${artifacts_path}/${base_diff}
# We create a .err file, because that's how we signal that there was a diff.
cp ${base_diff} ${artifacts_path}/gitlab-${BASELINE_TEST}-${MACHINE_NAME}.err
fi
if [[ ! -s ${base_diff} ]]
then
echo "${BASELINE_TEST}: PASSED"
true
else
echo "${BASELINE_TEST}: FAILED"
false
fi
+49
View File
@@ -0,0 +1,49 @@
#!/bin/bash
# Copyright (c) 2010-2021, 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.
# There will be collision between corona and quartz baselines.
# Once the corresponding files have been generated, we can switch to machine
# specific ref.
ARTIFACT_PATH=${CI_PROJECT_DIR}/${ARTIFACTS_DIR}/baseline-${SYS_TYPE}
#ARTIFACT_PATH=${CI_PROJECT_DIR}/${ARTIFACTS_DIR}/baseline-${SYS_TYPE}-${MACHINE_NAME}
PATCH_FILE=${ARTIFACT_PATH}.patch
FULL_FILE=${ARTIFACT_PATH}.out
DIFF_FILE=${ARTIFACT_PATH}.diff
# There will be collision between corona and quartz baselines.
# Once the corresponding files have been generated, we can switch to machine
# specific ref.
SAVED_NAME=baseline-${SYS_TYPE}.saved
#SAVED_NAME=baseline-${SYS_TYPE}-${MACHINE_NAME}.saved
cd ${BUILD_ROOT}/tests
if [[ ! -f "${DIFF_FILE}" ]]
then
echo "Nothing to be done: no relevant change in baseline"
exit 0
elif [[ -f "${PATCH_FILE}" ]]
then
patch "${SAVED_NAME}" < "${PATCH_FILE}"
elif [[ -f "${FULL_FILE}" ]]
then
cp "${FULL_FILE}" "${SAVED_NAME}"
else
echo "File missing: expected ${PATCH_FILE} or ${FULL_FILE}"
exit 1
fi
git add "${SAVED_NAME}"
git commit -m "${SYS_TYPE} (${MACHINE_NAME}) rebaselined in GitLab pipeline ${CI_PIPELINE_ID}"
git push origin master
+45
View File
@@ -0,0 +1,45 @@
#!/bin/bash
# Copyright (c) 2010-2021, 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.
echo "Runs if there was at least one failure on ${MACHINE_NAME}"
cd ${AUTOTEST_ROOT}/autotest || \
{ echo "Invalid 'autotest' dir: ${AUTOTEST_ROOT}/autotest"; exit 1; }
mkdir -p ${MACHINE_NAME}
rundir="${MACHINE_NAME}/$(date +%Y-%m-%d)-gitlab-ci-${CI_COMMIT_REF_SLUG}"
rundir=$(${CI_PROJECT_DIR}/.gitlab/scripts/safe_create_rundir $rundir)
printf "%s\n" "Some 'build-and-test' jobs on ${MACHINE_NAME} FAILED." \
"Pipeline URL:" "$CI_PIPELINE_URL" > ${rundir}/gitlab.err
msg="GitLab CI log for build-and-test on ${MACHINE_NAME} ($(date +%Y-%m-%d))"
# Create 'autotest-email.html' to indicate failure:
cp ${rundir}/gitlab.err ${rundir}/autotest-email.html
if [[ "$AUTOTEST_COMMIT" != "NO" ]]; then
git pull && \
git add ${rundir} && \
git commit -m "${msg}" && \
git push origin master
else
for file in ${rundir}/*; do
echo "------------------------------"
echo "Content of '$file'"
echo "******************************"
cat $file
echo "******************************"
done
rm -rf ${rundir} || true
fi
+42
View File
@@ -0,0 +1,42 @@
#!/bin/bash
# Copyright (c) 2010-2021, 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.
echo "Can only run if all the ${MACHINE_NAME} jobs passed"
cd ${AUTOTEST_ROOT}/autotest || \
{ echo "Invalid 'autotest' dir: ${AUTOTEST_ROOT}/autotest"; exit 1; }
mkdir -p ${MACHINE_NAME}
rundir="${MACHINE_NAME}/$(date +%Y-%m-%d)-gitlab-ci-${CI_COMMIT_REF_SLUG}"
rundir=$(${CI_PROJECT_DIR}/.gitlab/scripts/safe_create_rundir $rundir)
printf "%s\n" "The 'build-and-test' jobs on ${MACHINE_NAME} were SUCCESSFUL." \
"Pipeline URL:" "$CI_PIPELINE_URL" > ${rundir}/gitlab.out
msg="GitLab CI log for build-and-test on ${MACHINE_NAME} ($(date +%Y-%m-%d))"
if [[ "$AUTOTEST_COMMIT" != "NO" ]]; then
git pull && \
git add ${rundir} && \
git commit -m "${msg}" && \
git push origin master
else
for file in ${rundir}/*; do
echo "------------------------------"
echo "Content of '$file'"
echo "******************************"
cat $file
echo "******************************"
done
rm -rf ${rundir} || true
fi
+42
View File
@@ -0,0 +1,42 @@
#!/bin/bash
# Copyright (c) 2010-2021, 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.
# This script takes a seed for a directory name and appends it with a counter
# incremented until it can create a new directory with it.
# Usage:
#
# Expects 1 argument: a string that is use as a seed for the directory name.
#
# > rundir="desired_name"
# > rundir=$(./safe_create_rundir $rundir)
set -o errexit
set -o nounset
rundir=${1:-""}
if [[ -z ${rundir} ]]; then
>&2 echo "The script expects a string as argument for directory creation."
exit 1
fi
if ! mkdir ${rundir}; then
n=1
while ! mkdir ${rundir}_${n}
do
n=$((n+1))
done
rundir=${rundir}_${n}
fi
echo $rundir
+51
View File
@@ -10,8 +10,36 @@
Version 4.3.1 (development)
===========================
- Added support for automatic differentiation. Users can select between
native implementation and external library implementation at the
configuration phase. A parallel and two serial examples are implemented
in the autodiff miniapp directory.
- Added support for mesh preprocessing to resolve fine scale problem data
before simulation. This feature uses adaptive mesh refinement to control the
associated data oscillation error. See the new Example 30/30p.
- Switched from Artistic Style (astyle) version 2.05.1 to version 3.1 for code
formatting. See the "make style" target.
- Split the fem/fe.?pp files into separate files in the new fem/fe/ directory
to simplify and clarify the organization of FiniteElement classes.
- Added support for hr-adaptivity using TMOP-based error estimator.
- Coefficient::SetTime now propagates the new time into internally stored
Coefficient objects.
- Added initial support for google-benchmarks in the tests/benchmarks directory.
It can be enabled with MFEM_USE_BENCHMARK=YES.
- Added Binder (mybinder.org) configuration files for C++ MFEM Jupyter Notebooks
with inline GLVis visualization as well as a new examples/jupyter/ directory
with a sample notebook based on Example 1. Implementation based on xeus-cling,
github.com/jupyter-xeus/xeus-cling + xeus-glvis, github.com/GLVis/xeus-glvis.
- Added 'double' atomicAdd implementation for previous versions of CUDA.
- Adding lowest order Nedelec and Raviart-Thomas basis functions on wedge
shaped elements.
@@ -27,6 +55,29 @@ Version 4.3.1 (development)
functions on wedges and pyramids which are not amenable to reordering. The
ReorientTetMesh method of the Mesh and ParMesh classes has been deprecated.
- Gmsh meshes where all elements have zero physical tag (the default Gmsh
output format if no physical groups are defined) are now successfully loaded,
and elements are reassigned attribute number 1.
- Added new miniapps that use the ParELAG library, its hybrid smoothers, and the
hierarchy of spaces created by the element-based AMG (AMGe) methodology in
ParELAG to build multigrid solvers for H(curl) and H(div) forms. See the
miniapps/parelag directory for more details.
- Fixed several MinGW build issues on Windows.
- Remove the 'u' flag in the ar command, to update all files in the archive,
avoiding file name collisions from different subdirectories.
- Added initial TMOP-based capabilities for surface fitting and tangential
relaxation in the mesh-optimizer and pmesh-optimizer miniapps.
- Added ParMesh Adjaceny Set (adjset) creation support to the Conduit Mesh
Blueprint MFEM wrapper functions in ConduitDataCollection.
- `HypreParVector` and `Vector` now support move semantics, and the copy
constructor for `HypreParVector` now copies the local vector data.
Version 4.3, released on July 29, 2021
======================================
+46 -17
View File
@@ -90,6 +90,11 @@ include("${CMAKE_CURRENT_SOURCE_DIR}/config/XSDKDefaults.cmake")
# Enable languages.
enable_language(CXX)
if (MINGW)
# MinGW GCC does not expose the functions jn/_jn, yn/_yn (used in Example
# 25/25p) unless we use '-std=gnu++11':
set(CMAKE_CXX_EXTENSIONS ON)
endif()
if (MFEM_USE_CUDA)
if (MFEM_USE_HIP)
message(FATAL_ERROR " *** MFEM_USE_HIP cannot be combined with MFEM_USE_CUDA.")
@@ -175,10 +180,6 @@ else()
set(MFEM_DEBUG OFF)
endif()
if (WIN32)
add_definitions(-D_USE_MATH_DEFINES)
endif()
# MPI -> hypre; PETSc (optional)
if (MFEM_USE_MPI)
find_package(MPI REQUIRED)
@@ -251,6 +252,11 @@ if (MFEM_USE_OPENMP OR MFEM_USE_LEGACY_OPENMP)
endif()
find_package(OpenMP REQUIRED)
set(OPENMP_LIBRARIES ${OpenMP_CXX_LIBRARIES})
if(APPLE)
# On macOS, the compiler needs additional help to find the <omp.h> header.
# See issue #2642 for more information.
include_directories(${OpenMP_CXX_INCLUDE_DIRS})
endif(APPLE)
endif()
# SuiteSparse (before SUNDIALS which may depend on KLU)
@@ -332,11 +338,11 @@ if (MFEM_USE_AMGX)
endif()
if (MFEM_USE_CONDUIT)
find_package(Conduit REQUIRED conduit relay blueprint )
find_package(Conduit REQUIRED conduit relay blueprint)
endif()
if (MFEM_USE_FMS)
find_package(FMS REQUIRED fms )
find_package(FMS REQUIRED fms)
endif()
# Axom/Sidre
@@ -366,6 +372,12 @@ if (MFEM_USE_HIOP)
# find_package updates HIOP_FOUND, HIOP_INCLUDE_DIRS, HIOP_LIBRARIES
endif()
# CoDiPack package
if (MFEM_USE_CODIPACK)
find_package(CODIPACK REQUIRED)
# find_package updates CODIPACK_FOUND, CODIPACK_INCLUDE_DIRS, CODIPACK_LIBRARIES
endif()
# OCCA
if (MFEM_USE_OCCA)
find_package(OCCA REQUIRED)
@@ -381,6 +393,11 @@ if (MFEM_USE_UMPIRE)
find_package(UMPIRE REQUIRED)
endif()
# GOOGLE-BENCHMARK
if (MFEM_USE_BENCHMARK)
find_package(Benchmark REQUIRED)
endif()
# Caliper
if (MFEM_USE_CALIPER)
find_package(Caliper REQUIRED)
@@ -409,6 +426,11 @@ if (MFEM_USE_MKL_CPARDISO)
endif()
endif()
# PARELAG
if (MFEM_USE_PARELAG)
find_package(PARELAG REQUIRED)
endif()
# MFEM_TIMER_TYPE
if (NOT DEFINED MFEM_TIMER_TYPE)
if (APPLE)
@@ -432,10 +454,10 @@ endif()
# With newer versions of SuiteSparse which include METIS header using 64-bit
# integers, the METIS header (with 32-bit indices, as used by mfem) needs to
# be before SuiteSparse.
set(MFEM_TPLS MPI_CXX OPENMP HYPRE BLAS LAPACK SuperLUDist METIS SuiteSparse SUNDIALS PETSC
set(MFEM_TPLS OPENMP HYPRE BLAS LAPACK SuperLUDist METIS SuiteSparse SUNDIALS PETSC
SLEPC MESQUITE MUMPS STRUMPACK AXOM FMS CONDUIT Ginkgo GNUTLS GSLIB NETCDF
MPFR PUMI HIOP POSIXCLOCKS MFEMBacktrace ZLIB OCCA CEED RAJA UMPIRE ADIOS2
CUSPARSE MKL_CPARDISO AMGX CALIPER)
CUSPARSE MKL_CPARDISO AMGX CALIPER CODIPACK BENCHMARK PARELAG MPI_CXX)
# Add all *_FOUND libraries in the variable TPL_LIBRARIES.
set(TPL_LIBRARIES "")
@@ -500,13 +522,9 @@ set(MFEM_INSTALL_DIR ${CMAKE_INSTALL_PREFIX} CACHE PATH
# Declaring the library
mfem_add_library(mfem ${SOURCES} ${HEADERS} ${MASTER_HEADERS})
# message(STATUS "TPL_LIBRARIES = ${TPL_LIBRARIES}")
if (CMAKE_VERSION VERSION_GREATER 2.8.11)
target_link_libraries(mfem PUBLIC ${TPL_LIBRARIES})
else()
target_link_libraries(mfem ${TPL_LIBRARIES})
endif()
target_link_libraries(mfem PUBLIC ${TPL_LIBRARIES})
if (MINGW)
target_link_libraries(mfem ws2_32)
target_link_libraries(mfem PRIVATE ws2_32)
endif()
set_target_properties(mfem PROPERTIES VERSION "${mfem_VERSION}")
set_target_properties(mfem PROPERTIES SOVERSION "${mfem_VERSION}")
@@ -545,15 +563,21 @@ endif()
set(MFEM_CUSTOM_TARGET_PREFIX CACHE STRING "")
#-------------------------------------------------------------------------------
# Examples, miniapps, and testing
# Examples, miniapps, benchmarks and testing
#-------------------------------------------------------------------------------
# Enable testing if required
# Enable testing and benchmarks if required
if (MFEM_ENABLE_TESTING)
enable_testing()
set(MFEM_ALL_TESTS_TARGET_NAME tests)
add_mfem_target(${MFEM_ALL_TESTS_TARGET_NAME} OFF)
add_subdirectory(tests EXCLUDE_FROM_ALL)
# Create a target for all benchmarks and, optionally, enable it.
set(MFEM_ALL_BENCHMARKS_TARGET_NAME benchmarks)
add_mfem_target(${MFEM_ALL_BENCHMARKS_TARGET_NAME}
${MFEM_ENABLE_GOOGLE_BENCHMARKS})
add_subdirectory(tests/benchmarks EXCLUDE_FROM_ALL)
endif()
# Define a target that all examples and miniapps will depend on.
@@ -563,7 +587,11 @@ add_custom_target(${MFEM_EXEC_PREREQUISITES_TARGET_NAME})
# Create a target for all examples and, optionally, enable it.
set(MFEM_ALL_EXAMPLES_TARGET_NAME examples)
add_mfem_target(${MFEM_ALL_EXAMPLES_TARGET_NAME} ${MFEM_ENABLE_EXAMPLES})
add_subdirectory(examples EXCLUDE_FROM_ALL)
if (MFEM_ENABLE_EXAMPLES)
add_subdirectory(examples) #install examples if enabled
else()
add_subdirectory(examples EXCLUDE_FROM_ALL)
endif()
# Create a target for all miniapps and, optionally, enable it.
set(MFEM_ALL_MINIAPPS_TARGET_NAME miniapps)
@@ -573,6 +601,7 @@ add_subdirectory(miniapps EXCLUDE_FROM_ALL)
# Target to build all executables, i.e. everything.
add_custom_target(exec)
add_dependencies(exec
${MFEM_ALL_BENCHMARKS_TARGET_NAME}
${MFEM_ALL_EXAMPLES_TARGET_NAME}
${MFEM_ALL_MINIAPPS_TARGET_NAME}
${MFEM_ALL_TESTS_TARGET_NAME})
+107 -8
View File
@@ -42,6 +42,7 @@ back to them before issuing pull requests:
- [New Feature Development](#new-feature-development)
- [Developer Guidelines](#developer-guidelines)
- [Pull Requests](#pull-requests)
- [MFEM PR Rules](#mfem-pr-rules)
- [Pull Request Checklist](#pull-request-checklist)
- [Master/Next Workflow](#masternext-workflow)
- [Releases](#releases)
@@ -67,8 +68,9 @@ Origin](#developers-certificate-of-origin-11) at the end of this file.*
with regards to documentation and code styling.
- Please do not commit large/binary files to the central repository (use a fork
instead).
- Pull requests should be issued toward `mfem:master`. Make sure
to check the items off the [Pull Request Checklist](#pull-request-checklist).
- Pull requests should be issued toward `mfem:master`. Make sure
to check the items off the [Pull Request Checklist](#pull-request-checklist) and
follow the [MFEM PR Rules](#mfem-pr-rules).
- When your contribution is fully working and ready to be reviewed, add
the `ready-for-review` label.
- PRs are treated similarly to journal submission with an "editor" assigning two
@@ -105,12 +107,14 @@ The MFEM source code has the following structure:
│ ├── caliper
│ ├── ginkgo
│ ├── hiop
│ ├── jupyter
│ ├── petsc
│ ├── pumi
│ ├── sundials
| └── superlu
├── fem
│ ├── ceed
│ ├── fe
│ ├── qinterp
│ └── tmop
├── general
@@ -119,6 +123,7 @@ The MFEM source code has the following structure:
├── mesh
├── miniapps
│ ├── adjoint
│ ├── autodiff
│ ├── common
│ ├── electromagnetics
│ ├── gslib
@@ -126,6 +131,7 @@ The MFEM source code has the following structure:
│ ├── mtop
│ ├── navier
│ ├── nurbs
│ ├── parelag
│ ├── performance
│ ├── shifted
│ ├── solvers
@@ -323,15 +329,22 @@ Before you can start, you need a GitHub account, here are a few suggestions:
change the code by default.
- Code specifics
- All significant new classes, methods and functions have Doxygen-style
documentation in source comments.
- All new public, protected, and private classes, methods, data members, and
functions have Doxygen-style documentation in source comments.
- In addition to arguments and functionality, documentation should include the
current limitations of the code, any background information that is
implicitly assumed in the implementation, and the ownership and lifetime
of data.
- Consistent code styling is enforced with `make style` in the top-level
directory. This requires [Artistic Style](http://astyle.sourceforge.net) (we
specifically use version 2.05.1). See also the file `config/mfem.astylerc`.
specifically use version 3.1). See also the file `config/mfem.astylerc`.
- Use `mfem::out` and `mfem::err` instead of `std::cout` and `std::cerr` in
internal library code. (You can use `std` in examples and miniapps.)
- When manually resolving conflicts during a merge, make sure to mention the
conflicted files in the commit message.
- All significant new features and changes should be documented in CHANGELOG.
- New examples and miniapps should have documentation on the MFEM webpage.
### Pull Requests
@@ -397,6 +410,83 @@ Before you can start, you need a GitHub account, here are a few suggestions:
- If triggered, track the status of the LLNL GitLab tests. If failing, ask
one of the _LLNL developers_ for details.
### MFEM PR Rules
The Pull Request (PR) approval process in MFEM is similar to the approval of papers in a peer-reviewed journal. In particular:
1. There is an MFEM board of "editors" that evaluates new PRs and assigns "reviewers" for each PR.
2. The assigned reviewers are responsible to carefully review and test the proposed PR.
3. A PR can be (manually) merged in the *next* branch only if 2 of the assigned reviewers have approved it and it has passed internal testing. This merge can be performed by any of the assigned reviewers or by any of the editors.
4. A PR can be merged in the *master* branch only if it has been tested successfully for a week in *next* and an editor has (optionally) taken a final look. This merge can be performed only by one of the editors.
#### Responsibilities of Editors
The current list of MFEM editors is:
- @v-dobrev (Veselin Dobrev)
- @tzanio (Tzanio Kolev)
- @pazner (Will Pazner)
- @mlstowell (Mark Stowell)
**The responsibilities of the editors are:**
1. To assign appropriate milestone and labels for new PRs, e.g. *bugfix*, *minor*, *api-change*, *high-impact*, etc.
2. To assign at least 2 reviewers for new PRs. An editor can also be a reviewer. The editor, reviewers, and author should be listed as "Assignees" on the GitHub PR page. After assignment, the `in-review` label should be added.
3. To complete the initial PR evaluation and assignments in a timely manner: 1 week from submission.
4. To assist reviewers when they need help with their reviews (but also to stay out of the way when they don't).
5. To remind the reviewers about timely completion of their review.
6. To take a final look and complete the PR merge in *master*. The final look step is optional and shouldn't take more than 3 days.
7. The assignment of bugfixes should be expedited proportional to their importance, e.g. in some cases the editor can assign much shorter review window.
#### Responsibilities of Reviewers
Everyone on the MFEM team can be asked to serve as a reviewer on a PR in their area of expertise.
**The responsibilities of the reviewers are:**
1. To let the editors know if the proposed assignment is not a good match for them.
2. To communicate with the PR author, provide feedback and work with them to resolve issues.
3. To ensure the quality of the PR by making sure that the code adheres to the [Developer Guidelines](#developer-guidelines), e.g. all methods, data members, and functions have documentation, including data ownership and lifetime, new examples/miniapps have a corresponding PR in mfem/web, major features have `CHANGELOG` entries, etc.
3. To seek help from the editors in case of difficulties.
4. To complete the review in a timely manner: 3 weeks from assignment.
5. To test the PR thoroughly before merging in *next*. The PR author is also encouraged to perform testing and inform the reviewers about the results.
6. To monitor the PR impact on the testing in the *next* branch and alert the editors that the PR is ready for merging in *master*.
7. The review of bugfixes should be expedited proportional to their importance. The review window can be much less than three weeks in such cases.
#### Responsibilities of Authors
Authors should clearly indicate when a PR is ready for review (before that the PR should be marked as `Draft` or `[WIP]`).
**The responsibilities of the authors are:**
1. To follow the instructions and PR checklist in the `CONTRIBUTING.md` document in the MFEM repository.
2. To respond to reviewer feedback in a timely manner.
3. Authors are encouraged to perform testing and inform the reviewers about the results.
4. Authors can use the "Reviewers" section of the GitHub PR page to suggest reviewers, but the "Assignees" section will show who the editor has assigned to do the reviews.
5. To indicate when the PR is ready for review by adding the `ready-for-review` label.
### Pull Request Checklist
Before a PR can be merged, it should satisfy the following:
@@ -450,7 +540,9 @@ Before a PR can be merged, it should satisfy the following:
- [ ] The miniapps go at the end of the page, and are usually listed only under a specific "Application (PDE)" category.
- [ ] Add a short description of the miniapp in the "Extensive Examples" section of `features.md`.
- [ ] New capability:
- [ ] All significant new classes, methods and functions have Doxygen-style documentation in source comments.
- [ ] All new public, protected, and private classes, methods, data members, and functions have full Doxygen-style documentation in source comments. Documentation should include descriptions of member data, function arguments and return values, template parameters, and prerequisites for calling new functions.
- [ ] Pointer arguments and return values must specify whether ownership is being transferred or lent with the call.
- [ ] Any new functions should include descriptions of their intended use e.g. for internal use only, user-facing, etc., along with references to example code whenever possible/appropriate.
- [ ] Consider adding new sample runs in existing examples to highlight the new capability.
- [ ] Consider saving cool simulation pictures with the new capability in the Confluence gallery (LLNL only) or submitting them, via pull request, to the gallery section of the `mfem/web` repo.
- [ ] If this is a major new feature, consider mentioning it in the short summary inside `README` *(rare)*.
@@ -461,6 +553,7 @@ Before a PR can be merged, it should satisfy the following:
- [ ] (LLNL only) After merging:
- [ ] Update internal tests to include the new features.
### Master/Next Workflow
MFEM uses a `master`/`next`-branch workflow as described below:
@@ -552,8 +645,10 @@ MFEM uses a `master`/`next`-branch workflow as described below:
- Update version and shortlinks in `src/index.md` and `src/download.md`.
- Use [cloc-1.62.pl](http://cloc.sourceforge.net/) and `ls -lh` to estimate the SLOC and the tarball size in `src/download.md`.
## LLNL Workflow
### Mirroring on Bitbucket
- The GitHub `master` and `next` branches are mirrored to the LLNL institutional
@@ -573,16 +668,17 @@ MFEM uses a `master`/`next`-branch workflow as described below:
- `mfem:gh-next` -- Bleeding-edge development version, may be broken, use at
your own risk.
### Mirroring on GitLab
- MFEM repository is also mirrored on the LLNL GitLab instance, in a
semi-automated manner.
- This instance is meant to complete CI testing with tests on Livermore
Computing systems. Gitlab pipeline status is reported in the corresponding
Computing systems. GitLab pipeline status is reported in the corresponding
GitHub pull request.
- In Gitlab pipelines, TPLs (dependencies) are built using Spack, driven by Uberenv.
- In GitLab pipelines, TPLs (dependencies) are built using Spack, driven by Uberenv.
- No change to the MFEM repo can be made on this instance.
@@ -595,6 +691,7 @@ In addition, developers can set local git hooks to run some quick checks on
commit or push, see the [README](config/githooks/README.md) in the `config/githooks`
directory.
### Linux and Mac smoke tests
We use GitHub Actions to drive the default tests on the `master` and `next`
branches. See the `.github/workflows` files and the logs at
@@ -606,6 +703,7 @@ constraint on jobs. Two virtual machines are configured - Mac (OS X) and Linux.
- Tests on the `master` branch are triggered whenever a PR is issued on this branch.
- Tests on the `next` branch are currently scheduled to run each night.
### Windows smoke test
We use Appveyor to test building with the MS Visual C++ compiler in a Windows
environment, as well as to test the CMake build. See the `.appveyor` file and the
@@ -615,6 +713,7 @@ build logs at
CMake is used to generate the MSVC Project files and drive the build. A release
and debug build is performed with a simple run of `ex1` to verify the executable.
### Tests at LLNL
- We mirror the `master` and `next` branches internally (to `gh-master` and
+42 -4
View File
@@ -459,10 +459,22 @@ MFEM_USE_UMPIRE = YES/NO
discovery, provision, and management of memory on machines with multiple
memory devices like NUMA and GPUs.
MFEM_USE_BENCHMARK = YES/NO
Enables support for Google Benchmark, a library to support the benchmarking
of functions, in the tests/benchmarks directory.
MFEM_USE_HIOP = YES/NO
Enable the usage of HiOp (https://github.com/LLNL/hiop) in MFEM. HiOp is an
HPC solver for nonlinear optimization problems.
MFEM_USE_CODIPACK = YES/NO
Enable automatic differentiation using the CoDiPack library.
www.scicomp.uni-kl.de/codi/
MFEM_USE_ADFORWARD = YES/NO
Enable forward mode for AD packages. This option is valid
only if the AD package supports two modes (backward/forward).
MFEM_USE_CUDA = YES/NO
Enables support for CUDA devices in MFEM. CUDA is a parallel computing
platform and programming model for general computing on graphical processing
@@ -523,6 +535,11 @@ MFEM_USE_FMS = YES/NO
convetion routines between FMS's FmsDataCollection structure and MFEM's
DataCollection class, see the header file fem/fmsconvert.hpp.
MFEM_USE_PARELAG = YES/NO
Enables the miniapps that use the ParELAG library. MFEM does not currently
use ParELAG. In fact, ParELAG is dependent on MFEM. Therefore, this option
currently only concerns the miniapps.
MFEM_BUILD_TAG = (any value)
An optional tag to characterize the build. Exported to config/config.mk.
Can be used to identify the MFEM build from other makefiles.
@@ -692,7 +709,12 @@ The specific libraries and their options are:
- HiOp (optional), used when MFEM_USE_HIOP = YES.
URL: https://github.com/LLNL/hiop
Options: HIOP_OPT, HIOP_LIB.
Versions: HIOP >= 0.4.
Versions: HIOP >= 0.4.6.
- CoDiPack (optiobal), used with MFEM_USE_CODIPACK = YES
URL: https://www.scicomp.uni-kl.de/codi/
Options: CODIPACK_OPT
Versions: 1.9.3
- GSLIB (optional), used when MFEM_USE_GSLIB = YES. The gslib library must be
built prior to the MFEM build, as follows: download gslib-1.0.7, untar it at
@@ -730,10 +752,10 @@ The specific libraries and their options are:
Versions: libCEED >= 0.8.
- RAJA (optional), used when MFEM_USE_RAJA = YES.
Beginning with MFEM v4.3, only RAJA v0.13.0+ is supported.
Beginning with MFEM v4.3, only RAJA v0.14.0+ is supported.
URL: https://github.com/LLNL/RAJA
Options: RAJA_DIR, RAJA_OPT, RAJA_LIB.
Versions: RAJA >= 0.13.0.
Versions: RAJA >= 0.14.0.
- Caliper (optional), used when MFEM_USE_CALIPER = YES.
URL: https://github.com/LLNL/Caliper
@@ -744,7 +766,12 @@ The specific libraries and their options are:
Umpire requires camp when the Umpire version is >= 3.0.0.
URL: https://github.com/LLNL/Umpire
Options: UMPIRE_DIR, UMPIRE_OPT, UMPIRE_LIB.
Versions: Umpire >= 2.0.0.
Versions: Umpire >= 3.0.0.
- Benchmark, used when MFEM_USE_BENCHMARK = YES.
URL: https://github.com/google/benchmark
Options: BENCHMARK_DIR, BENCHMARK_LIB.
Versions: Benchmark >= 1.5.6.
- MPFR (optional), used when MFEM_USE_MPFR = YES.
URL: http://mpfr.org, it depends on the GMP library: https://gmplib.org
@@ -766,6 +793,10 @@ The specific libraries and their options are:
Options: FMS_OPT, FMS_LIB.
Versions: FMS >= 0.2.
- ParELAG, used when MFEM_USE_PARELAG = YES.
URL: https://github.com/LLNL/parelag
Options: PARELAG_DIR, PARELAG_OPT, PARELAG_LIB.
Building with CMake
===================
The MFEM build system consists of two steps: configuration and compilation.
@@ -890,6 +921,8 @@ MFEM_USE_MPFR
MFEM_USE_ZLIB
MFEM_USE_PUMI
MFEM_USE_HIOP
MFEM_USE_CODIPACK
MFEM_USE_ADFORWARD
MFEM_USE_CUDA
MFEM_USE_OCCA
MFEM_USE_CEED
@@ -898,6 +931,8 @@ MFEM_USE_UMPIRE
MFEM_USE_SIDRE
MFEM_USE_CALIPER
MFEM_USE_FMS
MFEM_USE_BENCHMARK
MFEM_USE_PARELAG
The following options are CMake specific:
@@ -947,12 +982,15 @@ The CMake build system adds auto-detection for the following packages/libraries:
- POSIXCLOCKS
- PUMI
- HIOP
- CoDiPack
- OCCA
- RAJA
- UMPIRE
- AXOM - Used when MFEM_USE_SIDRE is enabled
- CALIPER
- FMS
- BENCHMARK
- ParELAG
The following built-in CMake packages are also used:
+8
View File
@@ -283,3 +283,11 @@ ENDIF()
IF (DEFINED TPL_ENABLE_UMPIRE)
SET(MFEM_USE_UMPIRE ${TPL_ENABLE_UMPIRE} CACHE BOOL "Enable Umpire" FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_BENCHMARK)
SET(MFEM_USE_BENCHMARK ${TPL_ENABLE_BENCHMARK} CACHE BOOL "Enable Google-Benchmark" FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_PARELAG)
SET(MFEM_USE_PARELAG ${TPL_ENABLE_PARELAG} CACHE BOOL "Enable ParELAG" FORCE)
ENDIF()
+4
View File
@@ -54,7 +54,11 @@ set(MFEM_USE_CEED @MFEM_USE_CEED@)
set(MFEM_USE_UMPIRE @MFEM_USE_UMPIRE@)
set(MFEM_USE_SIMD @MFEM_USE_SIMD@)
set(MFEM_USE_ADIOS2 @MFEM_USE_ADIOS2@)
set(MFEM_USE_CODIPACK @MFEM_USE_CODIPACK@)
set(MFEM_USE_ADFORWARD @MFEM_USE_ADFORWARD@)
set(MFEM_USE_CALIPER @MFEM_USE_CALIPER@)
set(MFEM_USE_BENCHMARK @MFEM_USE_BENCHMARK@)
set(MFEM_USE_PARELAG @MFEM_USE_PARELAG@)
set(MFEM_CXX_COMPILER "@CMAKE_CXX_COMPILER@")
set(MFEM_CXX_FLAGS "@CMAKE_CXX_FLAGS@")
+9
View File
@@ -175,4 +175,13 @@
// Enable interface to the MKL CPardiso library.
#cmakedefine MFEM_USE_MKL_CPARDISO
// Use forward mode for automatic differentiation
#cmakedefine MFEM_USE_ADFORWARD
// Enable the use of the CoDiPack library for AD
#cmakedefine MFEM_USE_CODIPACK
// Enable MFEM functionality based on the Google Benchmark library.
#cmakedefine MFEM_USE_BENCHMARK
#endif // MFEM_CONFIG_HEADER
+22
View File
@@ -0,0 +1,22 @@
# Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-806117.
#
# This file is part of the MFEM library. For more information and source code
# availability visit https://mfem.org.
#
# MFEM is free software; you can redistribute it and/or modify it under the
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.
# Defines the following variables:
# - BENCHMARK_FOUND
# - BENCHMARK_LIBRARIES
# - BENCHMARK_INCLUDE_DIRS
include(MfemCmakeUtilities)
mfem_find_package(Benchmark BENCHMARK BENCHMARK_DIR
"include" "benchmark/benchmark.h"
"lib" "benchmark"
"Paths to headers required by Google Benchmark."
"Libraries required by Google Benchmark.")
+24
View File
@@ -0,0 +1,24 @@
# Copyright (c) 2010-2021, 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.
# Automatic differentiation using the CoDiPack library.
# www.scicomp.uni-kl.de/codi/
# Sets the following variables:
# - CODIPACK_FOUND
# - CODIPACK_INCLUDE_DIRS
# - CODIPACK_LIBRARIES
include(MfemCmakeUtilities)
mfem_find_package(CODIPACK CODIPACK CODIPACK_DIR
"include" "codi.h"
"lib" ""
"Paths to headers required by CODIPACK."
"Libraries required by CODIPACK.")
+19
View File
@@ -0,0 +1,19 @@
# Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-806117.
#
# This file is part of the MFEM library. For more information and source code
# availability visit https://mfem.org.
#
# MFEM is free software; you can redistribute it and/or modify it under the
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.
# Defines the following variables:
# - PARELAG_FOUND
# - PARELAG_LIBRARIES
# - PARELAG_INCLUDE_DIRS
include(MfemCmakeUtilities)
mfem_find_package(PARELAG PARELAG PARELAG_DIR "" "" "" ""
"Paths to headers required by ParELAG." "Libraries required by ParELAG.")
@@ -100,6 +100,8 @@ macro(add_mfem_examples EXE_SRCS)
string(REPLACE ".cpp" "" EXE_NAME "${EXE_PREFIX}${SRC_FILENAME}")
mfem_add_executable(${EXE_NAME} ${SRC_FILE})
install(TARGETS ${EXE_NAME}
RUNTIME DESTINATION examples)
add_dependencies(${MFEM_ALL_EXAMPLES_TARGET_NAME} ${EXE_NAME})
if (EXE_NEEDED_BY)
add_dependencies(${EXE_NEEDED_BY} ${EXE_NAME})
@@ -764,7 +766,7 @@ function(mfem_export_mk_files)
MFEM_USE_GNUTLS MFEM_USE_GSLIB MFEM_USE_NETCDF MFEM_USE_PETSC
MFEM_USE_SLEPC MFEM_USE_MPFR MFEM_USE_SIDRE MFEM_USE_CONDUIT MFEM_USE_PUMI
MFEM_USE_CUDA MFEM_USE_OCCA MFEM_USE_RAJA MFEM_USE_UMPIRE MFEM_USE_SIMD
MFEM_USE_ADIOS2)
MFEM_USE_ADIOS2 MFEM_USE_BENCHMARK MFEM_USE_PARELAG)
foreach(var ${CONFIG_MK_BOOL_VARS})
if (${var})
set(${var} YES)
+9
View File
@@ -180,4 +180,13 @@
// Enable interface to the MKL CPardiso library.
// #define MFEM_USE_MKL_CPARDISO
// Use forward mode for automatic differentiation
// #define MFEM_USE_ADFORWARD
// Enable the use of the CoDiPack library for AD
// #define MFEM_USE_CODIPACK
// Enable functionality based on the Google Benchmark library.
// #define MFEM_USE_BENCHMARK
#endif // MFEM_CONFIG_HEADER
+4
View File
@@ -58,6 +58,10 @@ MFEM_USE_UMPIRE = @MFEM_USE_UMPIRE@
MFEM_USE_SIMD = @MFEM_USE_SIMD@
MFEM_USE_ADIOS2 = @MFEM_USE_ADIOS2@
MFEM_USE_MKL_CPARDISO = @MFEM_USE_MKL_CPARDISO@
MFEM_USE_ADFORWARD = @MFEM_USE_ADFORWARD@
MFEM_USE_CODIPACK = @MFEM_USE_CODIPACK@
MFEM_USE_BENCHMARK = @MFEM_USE_BENCHMARK@
MFEM_USE_PARELAG = @MFEM_USE_PARELAG@
# Compiler, compile options, and link options
MFEM_CXX = @MFEM_CXX@
+18
View File
@@ -58,6 +58,10 @@ option(MFEM_USE_SIMD "Enable use of SIMD intrinsics" OFF)
option(MFEM_USE_ADIOS2 "Enable ADIOS2" OFF)
option(MFEM_USE_CALIPER "Enable Caliper support" OFF)
option(MFEM_USE_MKL_CPARDISO "Enable MKL CPardiso" OFF)
option(MFEM_USE_ADFORWARD "Enable forward mode for AD" OFF)
option(MFEM_USE_CODIPACK "Enable automatic differentiation (AD) using CoDiPack" OFF)
option(MFEM_USE_BENCHMARK "Enable Google Benchmark" OFF)
option(MFEM_USE_PARELAG "Enable ParELAG" OFF)
# Optional overrides for autodetected MPIEXEC and MPIEXEC_NUMPROC_FLAG
# set(MFEM_MPIEXEC "mpirun" CACHE STRING "Command for running MPI tests")
@@ -74,6 +78,7 @@ set(MFEM_MPI_NP 4 CACHE STRING "Number of processes used for MPI tests")
option(MFEM_ENABLE_TESTING "Enable the ctest framework for testing" ON)
option(MFEM_ENABLE_EXAMPLES "Build all of the examples" OFF)
option(MFEM_ENABLE_MINIAPPS "Build all of the miniapps" OFF)
option(MFEM_ENABLE_GOOGLE_BENCHMARKS "Build all of the Google benchmarks" OFF)
# Setting CXX/MPICXX on the command line or in user.cmake will overwrite the
# autodetected C++ compiler.
@@ -224,12 +229,25 @@ set(RAJA_DIR "${MFEM_DIR}/../raja" CACHE PATH "Path to RAJA")
set(CEED_DIR "${MFEM_DIR}/../libCEED" CACHE PATH "Path to libCEED")
set(UMPIRE_DIR "${MFEM_DIR}/../umpire" CACHE PATH "Path to Umpire")
set(CALIPER_DIR "${MFEM_DIR}/../caliper" CACHE PATH "Path to Caliper")
set(BENCHMARK_DIR "${MFEM_DIR}/../google-benchmark" CACHE PATH
"Path to Google Benchmark")
# Provide paths, since ParELAG is dependent on MFEM and MFEM needs to be
# compiled (or at least cmake needs to succeed) before compiling ParELAG.
set(PARELAG_DIR "${MFEM_DIR}/../parelag" CACHE PATH "Path to ParELAG")
set(PARELAG_INCLUDE_DIRS "${PARELAG_DIR}/src;${PARELAG_DIR}/build/src" CACHE
STRING "Path to ParELAG headers.")
set(PARELAG_LIBRARIES "${PARELAG_DIR}/build/src/libParELAG.a" CACHE STRING
"The ParELAG library.")
set(BLAS_INCLUDE_DIRS "" CACHE STRING "Path to BLAS headers.")
set(BLAS_LIBRARIES "" CACHE STRING "The BLAS library.")
set(LAPACK_INCLUDE_DIRS "" CACHE STRING "Path to LAPACK headers.")
set(LAPACK_LIBRARIES "" CACHE STRING "The LAPACK library.")
set(CODIPACK_INCLUDE_DIRS "${MFEM_DIR}/../CoDiPack/inlude" CACHE STRING "Path to CoDiPack headers.")
set(CODIPACK_LIBRARIES "")
# Some useful variables:
set(CMAKE_SKIP_PREPROCESSED_SOURCE_RULES ON) # Skip *.i rules
set(CMAKE_SKIP_ASSEMBLY_SOURCE_RULES ON) # Skip *.s rules
+27 -2
View File
@@ -59,9 +59,12 @@ HIP_FLAGS = --amdgpu-target=$(HIP_ARCH)
HIP_XCOMPILER =
HIP_XLINKER = -Wl,
# Flags for generating dependencies.
DEP_FLAGS = -MM -MT
ifneq ($(NOTMAC),)
AR = ar
ARFLAGS = cruv
ARFLAGS = crv
RANLIB = ranlib
PICFLAG = $(XCOMPILER)-fPIC
SO_EXT = so
@@ -73,7 +76,7 @@ ifneq ($(NOTMAC),)
else
# Silence "has no symbols" warnings on Mac OS X
AR = ar
ARFLAGS = Scruv
ARFLAGS = Scrv
RANLIB = ranlib -no_warning_for_no_symbols
PICFLAG = $(XCOMPILER)-fPIC
SO_EXT = dylib
@@ -86,6 +89,9 @@ else
BUILD_RPATH = $(XLINKER)-undefined,dynamic_lookup
INSTALL_SOFLAGS = $(subst $1 ,,$(call MAKE_SOFLAGS,$(MFEM_LIB_DIR)))
INSTALL_RPATH = $(XLINKER)-undefined,dynamic_lookup
# Silence unused command line argument warnings when generating dependencies
# with mpicxx and clang
DEP_FLAGS := -Wno-unused-command-line-argument $(DEP_FLAGS)
endif
# Set CXXFLAGS to overwrite the default selection of DEBUG_FLAGS/OPTIM_FLAGS
@@ -151,6 +157,10 @@ MFEM_USE_UMPIRE = NO
MFEM_USE_SIMD = NO
MFEM_USE_ADIOS2 = NO
MFEM_USE_MKL_CPARDISO = NO
MFEM_USE_ADFORWARD = NO
MFEM_USE_CODIPACK = NO
MFEM_USE_BENCHMARK = NO
MFEM_USE_PARELAG = NO
# MPI library compile and link flags
# These settings are used only when building MFEM with MPI + HIP
@@ -406,6 +416,11 @@ HIOP_DIR = @MFEM_DIR@/../hiop/install
HIOP_OPT = -I$(HIOP_DIR)/include
HIOP_LIB = -L$(HIOP_DIR)/lib -lhiop $(LAPACK_LIB)
# CoDiPack
CODIPACK_DIR = @MFEM_DIR@/../CoDiPack
CODIPACK_OPT = -I$(CODIPACK_DIR)
CODIPACK_LIB =
# GSLIB library
GSLIB_DIR = @MFEM_DIR@/../gslib/build
GSLIB_OPT = -I$(GSLIB_DIR)/include
@@ -429,6 +444,11 @@ CALIPER_DIR = @MFEM_DIR@/../caliper
CALIPER_OPT = -I$(CALIPER_DIR)/include
CALIPER_LIB = $(XLINKER)-rpath,$(CALIPER_DIR)/lib64 -L$(CALIPER_DIR)/lib64 -lcaliper
# BENCHMARK library configuration
BENCHMARK_DIR = @MFEM_DIR@/../google-benchmark
BENCHMARK_OPT = -I$(BENCHMARK_DIR)/include
BENCHMARK_LIB = -L$(BENCHMARK_DIR)/lib -lbenchmark -lpthread
# libCEED library configuration
CEED_DIR ?= @MFEM_DIR@/../libCEED
CEED_OPT = -I$(CEED_DIR)/include
@@ -459,6 +479,11 @@ MKL_CPARDISO_LIB = $(XLINKER)-rpath,$(MKL_CPARDISO_DIR)/$(MKL_LIBRARY_SUBDIR)\
-L$(MKL_CPARDISO_DIR)/$(MKL_LIBRARY_SUBDIR) -l$(MKL_MPI_WRAPPER)\
-lmkl_intel_lp64 -lmkl_sequential -lmkl_core
# PARELAG library configuration
PARELAG_DIR = @MFEM_DIR@/../parelag
PARELAG_OPT = -I$(PARELAG_DIR)/src -I$(PARELAG_DIR)/build/src
PARELAG_LIB = -L$(PARELAG_DIR)/build/src -lParELAG
# If YES, enable some informational messages
VERBOSE = NO
+2 -2
View File
@@ -87,12 +87,12 @@ fi
## style check
#if [[ "${option}" == "--style" || "${option}" == "" ]]; then
if [[ "${option}" == "--style" ]]; then
if which astyle && [[ "$(astyle --version)" == "Artistic Style Version 2.05.1" ]]; then
if which astyle && [[ "$(astyle --version)" == "Artistic Style Version 3.1" ]]; then
cd tests/scripts
if ! ./runtest code-style; then code=1; fi
cd -
else
echo "Warning: astyle not found or version is not 2.05.1"
echo "Warning: astyle not found or version is not 3.1"
fi
fi
+4 -1
View File
@@ -765,6 +765,7 @@ INPUT = @MFEM_SOURCE_DIR@/doc/CodeDocumentation.dox \
@MFEM_SOURCE_DIR@/linalg \
@MFEM_SOURCE_DIR@/mesh \
@MFEM_SOURCE_DIR@/fem \
@MFEM_SOURCE_DIR@/fem/fe \
@MFEM_SOURCE_DIR@/examples \
@MFEM_SOURCE_DIR@/examples/caliper \
@MFEM_SOURCE_DIR@/examples/amgx \
@@ -780,13 +781,15 @@ INPUT = @MFEM_SOURCE_DIR@/doc/CodeDocumentation.dox \
@MFEM_SOURCE_DIR@/miniapps/gslib \
@MFEM_SOURCE_DIR@/miniapps/meshing \
@MFEM_SOURCE_DIR@/miniapps/mtop \
@MFEM_SOURCE_DIR@/miniapps/autodiff \
@MFEM_SOURCE_DIR@/miniapps/navier \
@MFEM_SOURCE_DIR@/miniapps/nurbs \
@MFEM_SOURCE_DIR@/miniapps/performance \
@MFEM_SOURCE_DIR@/miniapps/shifted \
@MFEM_SOURCE_DIR@/miniapps/solvers \
@MFEM_SOURCE_DIR@/miniapps/tools \
@MFEM_SOURCE_DIR@/miniapps/toys
@MFEM_SOURCE_DIR@/miniapps/toys \
@MFEM_SOURCE_DIR@/miniapps/parelag
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+2
View File
@@ -194,6 +194,8 @@ namespace mfem {
* - <a class="el" href="parheat_8cpp_source.html">Optimization gradients</a>: Gradients of PDE-constrained function
* - <a class="el" href="miniapps_2performance_2ex1_8cpp_source.html">HPC Example 1</a>: high-performance nodal H1 FEM for the Laplace problem
* - <a class="el" href="miniapps_2performance_2ex1p_8cpp_source.html">HPC Example 1p</a>: high-performance parallel nodal H1 FEM for the Laplace problem
* - <a class="el" href="par__example_8cpp_source.html">Parallel pLaplacian example using AD</a>: Parallel pLaplacian example
* - <a class="el" href="seq__example_8cpp_source.html">Serial pLaplacian example using AD</a>: Serial pLaplacian example
*
* See also the <a class="el" href="https://mfem.org/examples/">examples documentation</a> online.
*/
+2
View File
@@ -37,6 +37,7 @@ list(APPEND ALL_EXE_SRCS
ex27.cpp
ex28.cpp
ex29.cpp
ex30.cpp
)
if (MFEM_USE_MPI)
@@ -70,6 +71,7 @@ if (MFEM_USE_MPI)
ex27p.cpp
ex28p.cpp
ex29p.cpp
ex30p.cpp
)
endif()
+2 -2
View File
@@ -135,8 +135,8 @@ int main(int argc, char *argv[])
a->AddBdrFaceIntegrator(new DGDiffusionIntegrator(one, sigma, kappa));
if (eta > 0)
{
a->AddInteriorFaceIntegrator(new DGDiffusionBR2Integrator(fespace, eta));
a->AddBdrFaceIntegrator(new DGDiffusionBR2Integrator(fespace, eta));
a->AddInteriorFaceIntegrator(new DGDiffusionBR2Integrator(*fespace, eta));
a->AddBdrFaceIntegrator(new DGDiffusionBR2Integrator(*fespace, eta));
}
a->Assemble();
a->Finalize();
+4 -4
View File
@@ -199,8 +199,8 @@ int main(int argc, char *argv[])
a->AddBdrFaceIntegrator(new DGDiffusionIntegrator(one, sigma, kappa));
if (eta > 0)
{
a->AddInteriorFaceIntegrator(new DGDiffusionBR2Integrator(fespace, eta));
a->AddBdrFaceIntegrator(new DGDiffusionBR2Integrator(fespace, eta));
a->AddInteriorFaceIntegrator(new DGDiffusionBR2Integrator(*fespace, eta));
a->AddBdrFaceIntegrator(new DGDiffusionBR2Integrator(*fespace, eta));
}
a->Assemble();
a->Finalize();
@@ -221,7 +221,7 @@ int main(int argc, char *argv[])
{
HyprePCG pcg(*A);
pcg.SetTol(1e-12);
pcg.SetMaxIter(200);
pcg.SetMaxIter(500);
pcg.SetPrintLevel(2);
pcg.SetPreconditioner(*amg);
pcg.Mult(*B, *X);
@@ -232,7 +232,7 @@ int main(int argc, char *argv[])
GMRESSolver gmres(MPI_COMM_WORLD);
gmres.SetAbsTol(0.0);
gmres.SetRelTol(1e-12);
gmres.SetMaxIter(200);
gmres.SetMaxIter(500);
gmres.SetKDim(10);
gmres.SetPrintLevel(1);
gmres.SetOperator(*A);
+4 -14
View File
@@ -295,17 +295,7 @@ int main(int argc, char *argv[])
// element solution.
a.RecoverFEMSolution(X, b, u);
// 13. Build a mass matrix to help solve for n.Grad(u) where 'n' is a surface
// normal.
BilinearForm m(&fespace);
m.AddDomainIntegrator(new MassIntegrator);
m.Assemble();
ess_tdof_list.SetSize(0);
OperatorPtr M;
m.FormSystemMatrix(ess_tdof_list, M);
// 14. Compute the various boundary integrals.
// 13. Compute the various boundary integrals.
mfem::out << endl
<< "Verifying boundary conditions" << endl
<< "=============================" << endl;
@@ -361,7 +351,7 @@ int main(int argc, char *argv[])
<< " error " << err << endl;
}
// 15. Save the refined mesh and the solution. This output can be viewed
// 14. Save the refined mesh and the solution. This output can be viewed
// later using GLVis: "glvis -m refined.mesh -g sol.gf".
{
ofstream mesh_ofs("refined.mesh");
@@ -372,7 +362,7 @@ int main(int argc, char *argv[])
u.Save(sol_ofs);
}
// 16. Send the solution by socket to a GLVis server.
// 15. Send the solution by socket to a GLVis server.
if (visualization)
{
string title_str = h1 ? "H1" : "DG";
@@ -385,7 +375,7 @@ int main(int argc, char *argv[])
<< " keys 'mmc'" << flush;
}
// 17. Free the used memory.
// 16. Free the used memory.
delete fec;
delete mesh;
+4 -14
View File
@@ -314,17 +314,7 @@ int main(int argc, char *argv[])
// local finite element solution on each processor.
a.RecoverFEMSolution(X, b, u);
// 14. Build a mass matrix to help solve for n.Grad(u) where 'n' is a surface
// normal.
ParBilinearForm m(&fespace);
m.AddDomainIntegrator(new MassIntegrator);
m.Assemble();
ess_tdof_list.SetSize(0);
OperatorPtr M;
m.FormSystemMatrix(ess_tdof_list, M);
// 15. Compute the various boundary integrals.
// 14. Compute the various boundary integrals.
mfem::out << endl
<< "Verifying boundary conditions" << endl
<< "=============================" << endl;
@@ -380,7 +370,7 @@ int main(int argc, char *argv[])
<< " error " << err << endl;
}
// 16. Save the refined mesh and the solution in parallel. This output can be
// 15. Save the refined mesh and the solution in parallel. This output can be
// viewed later using GLVis: "glvis -np <np> -m mesh -g sol".
{
ostringstream mesh_name, sol_name;
@@ -396,7 +386,7 @@ int main(int argc, char *argv[])
u.Save(sol_ofs);
}
// 17. Send the solution by socket to a GLVis server.
// 16. Send the solution by socket to a GLVis server.
if (visualization)
{
string title_str = h1 ? "H1" : "DG";
@@ -411,7 +401,7 @@ int main(int argc, char *argv[])
<< " keys 'mmc'" << flush;
}
// 18. Free the used memory.
// 17. Free the used memory.
delete fec;
return 0;
+195
View File
@@ -0,0 +1,195 @@
// MFEM Example 30
//
// Compile with: make ex30
//
// Sample runs: ex30 -m ../data/square-disc.mesh -o 1
// ex30 -m ../data/square-disc.mesh -o 2
// ex30 -m ../data/square-disc.mesh -o 2 -me 1e3
// ex30 -m ../data/square-disc-nurbs.mesh -o 2
// ex30 -m ../data/star.mesh -o 2 -eo 4
// ex30 -m ../data/fichera.mesh -o 2 -me 1e4
// ex30 -m ../data/disc-nurbs.mesh -o 2
// ex30 -m ../data/ball-nurbs.mesh -o 2 -eo 3 -e 1e-2 -me 1e4
// ex30 -m ../data/star-surf.mesh -o 2
// ex30 -m ../data/square-disc-surf.mesh -o 2
// ex30 -m ../data/amr-quad.mesh -l 2
//
// Description: This is an example of adaptive mesh refinement preprocessing
// which lowers the data oscillation [1] to a user-defined
// relative threshold. There is no PDE being solved.
//
// MFEM's capability to work with both conforming and
// nonconforming meshes is demonstrated in example 6. In some
// problems, the material data or loading data is not sufficiently
// resolved on the initial mesh. This missing fine scale data
// reduces the accuracy of the solution as well as the accuracy
// of some local error estimators. By preprocessing the mesh
// before solving the PDE, many issues can be avoided.
//
// [1] Morin, P., Nochetto, R. H., & Siebert, K. G. (2000).
// Data oscillation and convergence of adaptive FEM. SIAM
// Journal on Numerical Analysis, 38(2), 466-488.
//
// [2] Mitchell, W. F. (2013). A collection of 2D elliptic
// problems for testing adaptive grid refinement algorithms.
// Applied mathematics and computation, 220, 350-364.
#include "mfem.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
// Piecewise-affine function which is sometimes mesh-conforming
double affine_function(const Vector &p)
{
double x = p(0), y = p(1);
if (x < 0.0)
{
return 1.0 + x + y;
}
else
{
return 1.0;
}
}
// Piecewise-constant function which is never mesh-conforming
double jump_function(const Vector &p)
{
if (p.Normlp(2.0) > 0.4 && p.Normlp(2.0) < 0.6) { return 1.0; }
return 5.0;
}
// Singular function derived from the Laplacian of the "steep wavefront"
// problem in [2].
double singular_function(const Vector &p)
{
double x = p(0), y = p(1);
double alpha = 1000.0;
double xc = 0.75, yc = 0.5;
double r0 = 0.7;
double r = sqrt(pow(x - xc,2.0) + pow(y - yc,2.0));
double num = - ( alpha - pow(alpha,3) * (pow(r,2) - pow(r0,2)) );
double denom = pow(r * ( pow(alpha,2) * pow(r0,2) + pow(alpha,2) * pow(r,2) \
- 2 * pow(alpha,2) * r0 * r + 1.0 ),2);
denom = max(denom,1e-8);
return num / denom;
}
int main(int argc, char *argv[])
{
// 1. Parse command-line options.
const char *mesh_file = "../data/star.mesh";
int order = 1;
int nc_limit = 1;
int max_elems = 1e5;
double double_max_elems = double(max_elems);
bool visualization = true;
double osc_threshold = 1e-3;
int enriched_order = 5;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
"Mesh file to use.");
args.AddOption(&order, "-o", "--order",
"Finite element order (polynomial degree).");
args.AddOption(&nc_limit, "-l", "--nc-limit",
"Maximum level of hanging nodes.");
args.AddOption(&double_max_elems, "-me", "--max-elems",
"Stop after reaching this many elements.");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.AddOption(&osc_threshold, "-e", "--error",
"relative data oscillation threshold.");
args.AddOption(&enriched_order, "-eo", "--enriched_order",
"Enriched quadrature order.");
args.Parse();
if (!args.Good())
{
args.PrintUsage(cout);
return 1;
}
args.PrintOptions(cout);
max_elems = int(double_max_elems);
Mesh mesh(mesh_file, 1, 1);
// 2. Since a NURBS mesh can currently only be refined uniformly, we need to
// convert it to a piecewise-polynomial curved mesh. First we refine the
// NURBS mesh a bit more and then project the curvature to quadratic Nodes.
if (mesh.NURBSext)
{
for (int i = 0; i < 2; i++)
{
mesh.UniformRefinement();
}
mesh.SetCurvature(2);
}
// 3. Define functions and refiner.
FunctionCoefficient affine_coeff(affine_function);
FunctionCoefficient jump_coeff(jump_function);
FunctionCoefficient singular_coeff(singular_function);
CoefficientRefiner coeffrefiner(affine_coeff, order);
// 4. Connect to GLVis.
char vishost[] = "localhost";
int visport = 19916;
socketstream sol_sock;
if (visualization)
{
sol_sock.open(vishost, visport);
}
// 5. Define custom integration rule (optional).
const IntegrationRule *irs[Geometry::NumGeom];
int order_quad = 2*order + enriched_order;
for (int i = 0; i < Geometry::NumGeom; ++i)
{
irs[i] = &(IntRules.Get(i, order_quad));
}
// 6. Apply custom refiner settings.
coeffrefiner.SetIntRule(irs);
coeffrefiner.SetMaxElements(max_elems);
coeffrefiner.SetThreshold(osc_threshold);
coeffrefiner.SetNCLimit(nc_limit);
coeffrefiner.PrintWarnings();
// 7. Preprocess mesh to control osc (piecewise-affine function).
// This is mostly just a verification check. The oscillation should
// be zero if the function is mesh-conforming and order > 0.
coeffrefiner.PreprocessMesh(mesh);
mfem::out << "\n";
mfem::out << "Function 0 (affine) \n";
mfem::out << "Number of Elements " << mesh.GetNE() << "\n";
mfem::out << "Osc error " << coeffrefiner.GetOsc() << "\n";
// 8. Preprocess mesh to control osc (jump function).
coeffrefiner.ResetCoefficient(jump_coeff);
coeffrefiner.PreprocessMesh(mesh);
mfem::out << "\n";
mfem::out << "Function 1 (discontinuous) \n";
mfem::out << "Number of Elements " << mesh.GetNE() << "\n";
mfem::out << "Osc error " << coeffrefiner.GetOsc() << "\n";
// 9. Preprocess mesh to control osc (singular function).
coeffrefiner.ResetCoefficient(singular_coeff);
coeffrefiner.PreprocessMesh(mesh);
mfem::out << "\n";
mfem::out << "Function 2 (singular) \n";
mfem::out << "Number of Elements " << mesh.GetNE() << "\n";
mfem::out << "Osc error " << coeffrefiner.GetOsc() << "\n";
sol_sock.precision(8);
sol_sock << "mesh\n" << mesh << flush;
return 0;
}
+241
View File
@@ -0,0 +1,241 @@
// MFEM Example 30 - Parallel Version
//
// Compile with: make ex30p
//
// Sample runs: mpirun -np 4 ex30p -m ../data/square-disc.mesh -o 1
// mpirun -np 4 ex30p -m ../data/square-disc.mesh -o 2
// mpirun -np 4 ex30p -m ../data/square-disc.mesh -o 2 -me 1e3
// mpirun -np 4 ex30p -m ../data/square-disc-nurbs.mesh -o 2
// mpirun -np 4 ex30p -m ../data/star.mesh -o 2 -eo 4
// mpirun -np 4 oscp -m ../data/fichera.mesh -o 2 -me 1e4
// mpirun -np 4 ex30p -m ../data/disc-nurbs.mesh -o 2
// mpirun -np 4 ex30p -m ../data/ball-nurbs.mesh -o 2 -eo 3 -e 1e-2
// mpirun -np 4 ex30p -m ../data/star-surf.mesh -o 2
// mpirun -np 4 ex30p -m ../data/square-disc-surf.mesh -o 2
// mpirun -np 4 ex30p -m ../data/amr-quad.mesh -l 2
//
// Description: This is an example of adaptive mesh refinement preprocessing
// which lowers the data oscillation [1] to a user-defined
// relative threshold. There is no PDE being solved.
//
// MFEM's capability to work with both conforming and
// nonconforming meshes is demonstrated in example 6. In some
// problems, the material data or loading data is not sufficiently
// resolved on the initial mesh. This missing fine scale data
// reduces the accuracy of the solution as well as the accuracy
// of some local error estimators. By preprocessing the mesh
// before solving the PDE, many issues can be avoided.
//
// [1] Morin, P., Nochetto, R. H., & Siebert, K. G. (2000).
// Data oscillation and convergence of adaptive FEM. SIAM
// Journal on Numerical Analysis, 38(2), 466-488.
//
// [2] Mitchell, W. F. (2013). A collection of 2D elliptic
// problems for testing adaptive grid refinement algorithms.
// Applied mathematics and computation, 220, 350-364.
#include "mfem.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
// Piecewise-affine function which is sometimes mesh-conforming
double affine_function(const Vector &p)
{
double x = p(0), y = p(1);
if (x < 0.0)
{
return 1.0 + x + y;
}
else
{
return 1.0;
}
}
// Piecewise-constant function which is never mesh-conforming
double jump_function(const Vector &p)
{
if (p.Normlp(2.0) > 0.4 && p.Normlp(2.0) < 0.6) { return 1.0; }
return 5.0;
}
// Singular function derived from the Laplacian of the "steep wavefront"
// problem in [2].
double singular_function(const Vector &p)
{
double x = p(0), y = p(1);
double alpha = 1000.0;
double xc = 0.75, yc = 0.5;
double r0 = 0.7;
double r = sqrt(pow(x - xc,2.0) + pow(y - yc,2.0));
double num = - ( alpha - pow(alpha,3) * (pow(r,2) - pow(r0,2)) );
double denom = pow(r * ( pow(alpha,2) * pow(r0,2) + pow(alpha,2) * pow(r,2) \
- 2 * pow(alpha,2) * r0 * r + 1.0 ),2);
denom = max(denom,1e-8);
return num / denom;
}
int main(int argc, char *argv[])
{
// 0. Initialize MPI.
int num_procs, myid;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
// 1. Parse command-line options.
const char *mesh_file = "../data/star.mesh";
int order = 1;
int nc_limit = 1;
int max_elems = 1e5;
double double_max_elems = double(max_elems);
bool visualization = true;
bool nc_simplices = true;
double osc_threshold = 1e-3;
int enriched_order = 5;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
"Mesh file to use.");
args.AddOption(&order, "-o", "--order",
"Finite element order (polynomial degree).");
args.AddOption(&nc_limit, "-l", "--nc-limit",
"Maximum level of hanging nodes.");
args.AddOption(&double_max_elems, "-me", "--max-elems",
"Stop after reaching this many elements.");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.AddOption(&osc_threshold, "-e", "--error",
"relative data oscillation threshold.");
args.AddOption(&enriched_order, "-eo", "--enriched_order",
"Enriched quadrature order.");
args.AddOption(&nc_simplices, "-ns", "--nonconforming-simplices",
"-cs", "--conforming-simplices",
"For simplicial meshes, enable/disable nonconforming"
" refinement");
args.Parse();
if (!args.Good())
{
if (myid == 0)
{
args.PrintUsage(cout);
}
MPI_Finalize();
return 1;
}
if (myid == 0)
{
args.PrintOptions(cout);
}
max_elems = int(double_max_elems);
Mesh mesh(mesh_file, 1, 1);
// 2. Since a NURBS mesh can currently only be refined uniformly, we need to
// convert it to a piecewise-polynomial curved mesh. First we refine the
// NURBS mesh a bit more and then project the curvature to quadratic Nodes.
if (mesh.NURBSext)
{
for (int i = 0; i < 2; i++)
{
mesh.UniformRefinement();
}
mesh.SetCurvature(2);
}
// 3. Make sure the mesh is in the non-conforming mode to enable local
// refinement of quadrilaterals/hexahedra. Simplices can be refined
// either in conforming or in non-conforming mode. The conforming
// mode however does not support dynamic partitioning.
mesh.EnsureNCMesh(nc_simplices);
// 4. Define a parallel mesh by partitioning the serial mesh.
// Once the parallel mesh is defined, the serial mesh can be deleted.
ParMesh pmesh(MPI_COMM_WORLD, mesh);
mesh.Clear();
// 5. Define functions and refiner.
FunctionCoefficient affine_coeff(affine_function);
FunctionCoefficient jump_coeff(jump_function);
FunctionCoefficient singular_coeff(singular_function);
CoefficientRefiner coeffrefiner(affine_coeff,order);
// 6. Connect to GLVis.
char vishost[] = "localhost";
int visport = 19916;
socketstream sol_sock;
if (visualization)
{
sol_sock.open(vishost, visport);
}
// 7. Define custom integration rule (optional).
const IntegrationRule *irs[Geometry::NumGeom];
int order_quad = 2*order + enriched_order;
for (int i=0; i < Geometry::NumGeom; ++i)
{
irs[i] = &(IntRules.Get(i, order_quad));
}
// 8. Apply custom refiner settings.
coeffrefiner.SetIntRule(irs);
coeffrefiner.SetMaxElements(max_elems);
coeffrefiner.SetThreshold(osc_threshold);
coeffrefiner.SetNCLimit(nc_limit);
coeffrefiner.PrintWarnings();
// 9. Preprocess mesh to control osc (piecewise-affine function).
// This is mostly just a verification check. The oscillation should
// be zero if the function is mesh-conforming and order > 0.
coeffrefiner.PreprocessMesh(pmesh);
int globalNE = pmesh.GetGlobalNE();
double osc = coeffrefiner.GetOsc();
if (myid == 0)
{
mfem::out << "\n";
mfem::out << "Function 0 (affine) \n";
mfem::out << "Number of Elements " << globalNE << "\n";
mfem::out << "Osc error " << osc << "\n";
}
// 10. Preprocess mesh to control osc (jump function).
coeffrefiner.ResetCoefficient(jump_coeff);
coeffrefiner.PreprocessMesh(pmesh);
globalNE = pmesh.GetGlobalNE();
osc = coeffrefiner.GetOsc();
if (myid == 0)
{
mfem::out << "\n";
mfem::out << "Function 1 (discontinuous) \n";
mfem::out << "Number of Elements " << globalNE << "\n";
mfem::out << "Osc error " << osc << "\n";
}
// 11. Preprocess mesh to control osc (singular function).
coeffrefiner.ResetCoefficient(singular_coeff);
coeffrefiner.PreprocessMesh(pmesh);
globalNE = pmesh.GetGlobalNE();
osc = coeffrefiner.GetOsc();
if (myid == 0)
{
mfem::out << "\n";
mfem::out << "Function 2 (singular) \n";
mfem::out << "Number of Elements " << globalNE << "\n";
mfem::out << "Osc error " << osc << "\n";
}
sol_sock.precision(8);
sol_sock << "parallel " << num_procs << " " << myid << "\n";
sol_sock << "mesh\n" << pmesh << flush;
MPI_Finalize();
return 0;
}
+31
View File
@@ -0,0 +1,31 @@
# Jupyter Notebooks using xeus-cling
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/mfem/mfem/master?filepath=examples%2Fjupyter%2Fex.ipynb)
[xeus-cling](https://github.com/jupyter-xeus/xeus-cling) is a C++ Jupyter Kernel based on [cling](https://github.com/root-project/cling),
which can be used to create interactive C++ MFEM and GLVis notebooks.
Click on the `binder` button above for an interactive example.
## Installing Locally
In order to run notebooks locally you will need `xeus-cling` along with `mfem` and `xglvis`. We recommend you use
[miniconda](https://docs.conda.io/en/latest/miniconda.html) or, if you already have it installed,
[conda](https://docs.conda.io/projects/conda/en/latest/).
1. Follow the install steps on https://github.com/jupyter-xeus/xeus-cling to install the C++ kernels
2. Build and install a _shared_ version of mfem
* for example: `make serial SHARED=YES`
3. Install [pyglvis](https://github.com/glvis/pyglvis)
* for the widget frontend
4. Get [xeus-glvis](https://github.com/glvis/xeus-glvis) and `cp` the header to `{PREFIX}/glvis/xglvis.hpp`
* (this could be improved)
## Running Locally
Once you've installed Jupyter, the C++ Kernel, mfem, and glvis start the notebook server (`jupyter-notebook`)
and open an existing example or a new `C++ 1x` kernel.
You will _always_ need to `#pragma cling load("mfem")` and you may need to point the `cling` runtime at your
mfem and/or glvis installs, do this with the
`#pragma cling` [statements](https://xeus-cling.readthedocs.io/en/latest/build_options.html#using-third-party-libraries).
+155
View File
@@ -0,0 +1,155 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "owned-extraction",
"metadata": {},
"source": [
"## Load the MFEM library\n",
"\n",
"Any non-default libraries must be loaded before you can `#include` files that use them. For more info see the [xeus-cling help](https://xeus-cling.readthedocs.io/en/latest/build_options.html)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "waiting-portrait",
"metadata": {},
"outputs": [],
"source": [
"#pragma cling load(\"mfem\")"
]
},
{
"cell_type": "markdown",
"id": "foreign-recycling",
"metadata": {},
"source": [
"## MFEM Example 1"
]
},
{
"cell_type": "markdown",
"id": "public-white",
"metadata": {},
"source": [
"This is the simplest MFEM example and a good starting point for new users. The example demonstrates the use of MFEM to define and solve an $H^1$ finite element discretization of the Laplace problem\n",
"\n",
"$$\n",
"-\\Delta u = 1\n",
"$$\n",
"\n",
"with homogeneous Dirichlet boundary conditions $u=0$.\n",
"\n",
"The example illustrates the use of the basic MFEM classes for defining the mesh, finite element space, as well as linear and bilinear forms corresponding to the left-hand side and right-hand side of the discrete linear system.\n",
"\n",
"Compare with MFEM's [ex1.cpp](https://github.com/mfem/mfem/blob/master/examples/ex1.cpp) and PyMFEM's [ex1.py](https://github.com/mfem/PyMFEM/blob/master/examples/ex1.py)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "protective-darkness",
"metadata": {},
"outputs": [],
"source": [
"#include <fstream>\n",
"#include <iostream>\n",
"#include <sstream>\n",
"\n",
"#include <mfem.hpp>\n",
"#include <glvis/xglvis.hpp>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "falling-monkey",
"metadata": {},
"outputs": [],
"source": [
"using namespace std;\n",
"using namespace mfem;\n",
"\n",
"Mesh mesh = Mesh::MakeCartesian2D(5, 5, Element::TRIANGLE);\n",
"mesh.UniformRefinement();\n",
"\n",
"H1_FECollection fec(2, mesh.Dimension());\n",
"\n",
"FiniteElementSpace fespace(&mesh, &fec);\n",
"cout << \"Number of finite element unknowns: \" << fespace.GetTrueVSize() << endl;\n",
"\n",
"Array<int> ess_tdof_list;\n",
"if (mesh.bdr_attributes.Size())\n",
"{\n",
" Array<int> ess_bdr(mesh.bdr_attributes.Max());\n",
" ess_bdr = 1;\n",
" fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);\n",
"}\n",
"\n",
"LinearForm b(&fespace);\n",
"ConstantCoefficient one(1.0);\n",
"b.AddDomainIntegrator(new DomainLFIntegrator(one));\n",
"b.Assemble();\n",
"\n",
"GridFunction x(&fespace);\n",
"x = 0.0;\n",
"\n",
"BilinearForm a(&fespace);\n",
"a.AddDomainIntegrator(new DiffusionIntegrator(one));\n",
"a.Assemble();\n",
"\n",
"OperatorPtr A;\n",
"Vector B, X;\n",
"a.FormLinearSystem(ess_tdof_list, x, b, A, X, B);\n",
"\n",
"cout << \"Size of linear system: \" << A->Height() << endl;\n",
"\n",
"GSSmoother M((SparseMatrix&)(*A));\n",
"PCG(*A, M, B, X, 1, 200, 1e-12, 0.0);\n",
"a.RecoverFEMSolution(X, b, x);"
]
},
{
"cell_type": "markdown",
"id": "hawaiian-republican",
"metadata": {},
"source": [
"## GLVis Visualization\n",
"\n",
"For now we save the computational mesh and finite element solution in a string and pass that to the glvis widget, see https://github.com/glvis/xeus-glvis for the widget backend and https://github.com/GLVis/pyglvis/tree/master/js for the widget frontend."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ordinary-equation",
"metadata": {},
"outputs": [],
"source": [
"std::stringstream ss;\n",
"ss << \"solution\\n\" << mesh << x << flush;\n",
"\n",
"auto glv = glvis::glvis();\n",
"glv.plot(ss.str() + \"keys Rjml\"); // the `+ \"keys ....\"' is optional\n",
"glv"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "C++14",
"language": "C++14",
"name": "xcpp14"
},
"language_info": {
"codemirror_mode": "text/x-c++src",
"file_extension": ".cpp",
"mimetype": "text/x-c++src",
"name": "c++",
"version": "14"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
+2 -2
View File
@@ -22,10 +22,10 @@ MFEM_LIB_FILE = mfem_is_not_built
-include $(CONFIG_MK)
SEQ_EXAMPLES = ex0 ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 ex10 ex14 ex15 ex16 \
ex17 ex18 ex19 ex20 ex21 ex22 ex23 ex24 ex25 ex26 ex27 ex28 ex29
ex17 ex18 ex19 ex20 ex21 ex22 ex23 ex24 ex25 ex26 ex27 ex28 ex29 ex30
PAR_EXAMPLES = ex0p ex1p ex2p ex3p ex4p ex5p ex6p ex7p ex8p ex9p ex10p ex11p \
ex12p ex13p ex14p ex15p ex16p ex17p ex18p ex19p ex20p ex21p ex22p ex24p \
ex25p ex26p ex27p ex28p ex29p
ex25p ex26p ex27p ex28p ex29p ex30p
SEQ_DEVICE_EXAMPLES = ex1 ex3 ex4 ex5 ex6 ex9 ex22 ex24 ex25 ex26
PAR_DEVICE_EXAMPLES = ex1p ex2p ex3p ex4p ex5p ex6p ex7p ex9p ex13p ex22p \
ex24p ex25p ex26p
+18
View File
@@ -43,6 +43,15 @@ set(SRCS
eltrans.cpp
estimators.cpp
fe.cpp
fe/fe_base.cpp
fe/fe_fixed_order.cpp
fe/fe_h1.cpp
fe/fe_l2.cpp
fe/fe_nd.cpp
fe/fe_nurbs.cpp
fe/fe_pos.cpp
fe/fe_rt.cpp
fe/fe_ser.cpp
fe_coll.cpp
fespace.cpp
geom.cpp
@@ -124,6 +133,15 @@ set(HDRS
eltrans.hpp
estimators.hpp
fe.hpp
fe/fe_base.hpp
fe/fe_fixed_order.hpp
fe/fe_h1.hpp
fe/fe_l2.hpp
fe/fe_nd.hpp
fe/fe_nurbs.hpp
fe/fe_pos.hpp
fe/fe_rt.hpp
fe/fe_ser.hpp
fe_coll.hpp
fem.hpp
fespace.hpp
+1
View File
@@ -969,6 +969,7 @@ void BilinearForm::EliminateVDofs(const Array<int> &vdofs,
const Vector &sol, Vector &rhs,
DiagonalPolicy dpolicy)
{
vdofs.HostRead();
for (int i = 0; i < vdofs.Size(); i++)
{
int vdof = vdofs[i];
+76 -31
View File
@@ -747,6 +747,7 @@ void DiffusionIntegrator::AssembleElementMatrix
#ifdef MFEM_THREAD_SAFE
DenseMatrix dshape(nd, dim), dshapedxt(nd, spaceDim);
DenseMatrix dshapedxt_m(nd, MQ ? spaceDim : 0);
DenseMatrix M(MQ ? spaceDim : 0);
Vector D(VQ ? VQ->GetVDim() : 0);
#else
dshape.SetSize(nd, dim);
@@ -984,6 +985,8 @@ void DiffusionIntegrator::ComputeElementFlux
"Unexpected height for MatrixCoefficient");
}
MFEM_VERIFY(!SMQ, "SymmetricMatrixCoefficient not supported here");
#ifdef MFEM_THREAD_SAFE
DenseMatrix dshape(nd,dim), invdfdx(dim, spaceDim);
DenseMatrix M(MQ ? spaceDim : 0);
@@ -996,7 +999,7 @@ void DiffusionIntegrator::ComputeElementFlux
#endif
vec.SetSize(dim);
vecdxt.SetSize(spaceDim);
pointflux.SetSize(MQ ? spaceDim : 0);
pointflux.SetSize(MQ || VQ ? spaceDim : 0);
const IntegrationRule &ir = fluxelem.GetNodes();
fnd = ir.GetNPoints();
@@ -1012,36 +1015,45 @@ void DiffusionIntegrator::ComputeElementFlux
CalcInverse(Trans.Jacobian(), invdfdx);
invdfdx.MultTranspose(vec, vecdxt);
if (!MQ && !VQ)
if (with_coef)
{
if (Q && with_coef)
if (!MQ && !VQ)
{
vecdxt *= Q->Eval(Trans,ip);
if (Q)
{
vecdxt *= Q->Eval(Trans,ip);
}
for (j = 0; j < spaceDim; j++)
{
flux(fnd*j+i) = vecdxt(j);
}
}
for (j = 0; j < spaceDim; j++)
else
{
flux(fnd*j+i) = vecdxt(j);
if (MQ)
{
MQ->Eval(M, Trans, ip);
M.Mult(vecdxt, pointflux);
}
else
{
VQ->Eval(D, Trans, ip);
for (int j=0; j<spaceDim; ++j)
{
pointflux[j] = D[j] * vecdxt[j];
}
}
for (j = 0; j < spaceDim; j++)
{
flux(fnd*j+i) = pointflux(j);
}
}
}
else
{
if (MQ)
{
MQ->Eval(M, Trans, ip);
M.Mult(vecdxt, pointflux);
}
else
{
VQ->Eval(D, Trans, ip);
for (int j=0; j<spaceDim; ++j)
{
pointflux[j] = D[j] * vecdxt[j];
}
}
for (j = 0; j < spaceDim; j++)
{
flux(fnd*j+i) = pointflux(j);
flux(fnd*j+i) = vecdxt(j);
}
}
}
@@ -1049,7 +1061,7 @@ void DiffusionIntegrator::ComputeElementFlux
double DiffusionIntegrator::ComputeFluxEnergy
( const FiniteElement &fluxelem, ElementTransformation &Trans,
Vector &flux, Vector* d_energy)
Vector &flux, bool with_coef, Vector* d_energy)
{
int nd = fluxelem.GetDof();
int dim = fluxelem.GetDim();
@@ -1057,8 +1069,13 @@ double DiffusionIntegrator::ComputeFluxEnergy
#ifdef MFEM_THREAD_SAFE
DenseMatrix M;
Vector D(VQ ? VQ->GetVDim() : 0);
#else
D.SetSize(VQ ? VQ->GetVDim() : 0);
#endif
MFEM_VERIFY(!SMQ, "SymmetricMatrixCoefficient not supported here");
shape.SetSize(nd);
pointflux.SetSize(spaceDim);
if (d_energy) { vec.SetSize(spaceDim); }
@@ -1087,16 +1104,42 @@ double DiffusionIntegrator::ComputeFluxEnergy
Trans.SetIntPoint(&ip);
double w = Trans.Weight() * ip.weight;
if (!MQ)
if (MQ)
{
double e = (pointflux * pointflux);
if (Q) { e *= Q->Eval(Trans, ip); }
energy += w * e;
MQ->Eval(M, Trans, ip);
if (with_coef) { M.Invert(); }
energy += w * M.InnerProduct(pointflux, pointflux);
}
else if (VQ)
{
VQ->Eval(D, Trans, ip);
if (with_coef)
{
Vector Dinv(D.Size());
Dinv = 1.0;
Dinv /= D;
D = Dinv;
}
D *= pointflux;
energy += w * (D * pointflux);
}
else
{
MQ->Eval(M, Trans, ip);
energy += w * M.InnerProduct(pointflux, pointflux);
double e = (pointflux * pointflux);
if (Q)
{
if (with_coef)
{
e /= Q->Eval(Trans, ip);
}
else
{
e *= Q->Eval(Trans, ip);
}
}
energy += w * e;
}
if (d_energy)
@@ -1107,7 +1150,7 @@ double DiffusionIntegrator::ComputeFluxEnergy
{
(*d_energy)[k] += w * vec[k] * vec[k];
}
// TODO: Q, MQ
// TODO: Q, VQ, MQ
}
}
@@ -1935,7 +1978,8 @@ void CurlCurlIntegrator
double CurlCurlIntegrator::ComputeFluxEnergy(const FiniteElement &fluxelem,
ElementTransformation &Trans,
Vector &flux, Vector *d_energy)
Vector &flux, bool with_coef,
Vector *d_energy)
{
int nd = fluxelem.GetDof();
int dim = fluxelem.GetDim();
@@ -2828,7 +2872,8 @@ void ElasticityIntegrator::ComputeElementFlux(
double ElasticityIntegrator::ComputeFluxEnergy(const FiniteElement &fluxelem,
ElementTransformation &Trans,
Vector &flux, Vector *d_energy)
Vector &flux, bool with_coef,
Vector *d_energy)
{
const int dof = fluxelem.GetDof();
const int dim = fluxelem.GetDim();
+51 -19
View File
@@ -234,6 +234,8 @@ public:
position of the mesh element.
@param[in] flux "Flux" coefficients representing the expansion of the
"flux" function in the basis of @a fluxelem.
@param[in] wcoef If true, @a flux includes the coefficient of this
integrator.
@param[out] d_energy If not NULL, the given Vector should be set to
represent directional energy split that can be used
for anisotropic error estimation.
@@ -241,7 +243,8 @@ public:
*/
virtual double ComputeFluxEnergy(const FiniteElement &fluxelem,
ElementTransformation &Trans,
Vector &flux, Vector *d_energy = NULL)
Vector &flux, bool wcoef = true,
Vector *d_energy = NULL)
{ return 0.0; }
virtual ~BilinearFormIntegrator() { }
@@ -1982,24 +1985,32 @@ private:
public:
/// Construct a diffusion integrator with coefficient Q = 1
DiffusionIntegrator()
: Q(NULL), VQ(NULL), MQ(NULL), SMQ(NULL), maps(NULL), geom(NULL) { }
DiffusionIntegrator(const IntegrationRule *ir = nullptr)
: BilinearFormIntegrator(ir),
Q(NULL), VQ(NULL), MQ(NULL), SMQ(NULL), maps(NULL), geom(NULL) { }
/// Construct a diffusion integrator with a scalar coefficient q
DiffusionIntegrator(Coefficient &q)
: Q(&q), VQ(NULL), MQ(NULL), SMQ(NULL), maps(NULL), geom(NULL) { }
DiffusionIntegrator(Coefficient &q, const IntegrationRule *ir = nullptr)
: BilinearFormIntegrator(ir),
Q(&q), VQ(NULL), MQ(NULL), SMQ(NULL), maps(NULL), geom(NULL) { }
/// Construct a diffusion integrator with a vector coefficient q
DiffusionIntegrator(VectorCoefficient &q)
: Q(NULL), VQ(&q), MQ(NULL), SMQ(NULL), maps(NULL), geom(NULL) { }
DiffusionIntegrator(VectorCoefficient &q,
const IntegrationRule *ir = nullptr)
: BilinearFormIntegrator(ir),
Q(NULL), VQ(&q), MQ(NULL), SMQ(NULL), maps(NULL), geom(NULL) { }
/// Construct a diffusion integrator with a matrix coefficient q
DiffusionIntegrator(MatrixCoefficient &q)
: Q(NULL), VQ(NULL), MQ(&q), SMQ(NULL), maps(NULL), geom(NULL) { }
DiffusionIntegrator(MatrixCoefficient &q,
const IntegrationRule *ir = nullptr)
: BilinearFormIntegrator(ir),
Q(NULL), VQ(NULL), MQ(&q), SMQ(NULL), maps(NULL), geom(NULL) { }
/// Construct a diffusion integrator with a symmetric matrix coefficient q
DiffusionIntegrator(SymmetricMatrixCoefficient &q)
: Q(NULL), VQ(NULL), MQ(NULL), SMQ(&q), maps(NULL), geom(NULL) { }
DiffusionIntegrator(SymmetricMatrixCoefficient &q,
const IntegrationRule *ir = nullptr)
: BilinearFormIntegrator(ir),
Q(NULL), VQ(NULL), MQ(NULL), SMQ(&q), maps(NULL), geom(NULL) { }
/** Given a particular Finite Element computes the element stiffness matrix
elmat. */
@@ -2025,7 +2036,8 @@ public:
virtual double ComputeFluxEnergy(const FiniteElement &fluxelem,
ElementTransformation &Trans,
Vector &flux, Vector *d_energy = NULL);
Vector &flux, bool wcoef = true,
Vector *d_energy = NULL);
using BilinearFormIntegrator::AssemblePA;
@@ -2444,7 +2456,8 @@ public:
virtual double ComputeFluxEnergy(const FiniteElement &fluxelem,
ElementTransformation &Trans,
Vector &flux, Vector *d_energy = NULL);
Vector &flux, bool wcoef = true,
Vector *d_energy = NULL);
using BilinearFormIntegrator::AssemblePA;
virtual void AssemblePA(const FiniteElementSpace &fes);
@@ -2668,6 +2681,9 @@ public:
VectorDiffusionIntegrator(Coefficient &q)
: Q(&q) { }
VectorDiffusionIntegrator(Coefficient &q, const IntegrationRule *ir)
: BilinearFormIntegrator(ir), Q(&q) { }
/** \brief Integrator with scalar coefficient for caller-specified vector
dimension.
@@ -2774,7 +2790,8 @@ public:
s_yz in 3D. */
virtual double ComputeFluxEnergy(const FiniteElement &fluxelem,
ElementTransformation &Trans,
Vector &flux, Vector *d_energy = NULL);
Vector &flux, bool wcoef = true,
Vector *d_energy = NULL);
};
/** Integrator for the DG form:
@@ -2927,10 +2944,11 @@ public:
sum_e eta (r_e([u]), r_e([v]))
where r_e is the lifting operator defined on each edge e. The parameter eta
can be chosen to be one to obtain a stable discretization. The constructor
for this integrator requires the finite element space because the lifting
operator depends on the element-wise inverse mass matrix.
where r_e is the lifting operator defined on each edge e (potentially
weighted by a coefficient Q). The parameter eta can be chosen to be one to
obtain a stable discretization. The constructor for this integrator requires
the finite element space because the lifting operator depends on the
element-wise inverse mass matrix.
BR2 stands for the second method of Bassi and Rebay:
@@ -2953,14 +2971,28 @@ protected:
Array<int> ipiv;
Array<int> ipiv_offsets, Minv_offsets;
Coefficient *Q;
Vector shape1, shape2;
DenseMatrix R11, R12, R21, R22;
DenseMatrix MinvR11, MinvR12, MinvR21, MinvR22;
DenseMatrix Re, MinvRe;
/// Precomputes the inverses (LU factorizations) of the local mass matrices.
/** @a fes must be a DG space, so the mass matrix is block diagonal, and its
inverse can be computed locally. This is required for the computation of
the lifting operators @a r_e.
*/
void PrecomputeMassInverse(class FiniteElementSpace &fes);
public:
DGDiffusionBR2Integrator(class FiniteElementSpace *fes, double e = 1.0);
DGDiffusionBR2Integrator(class FiniteElementSpace &fes, double e = 1.0);
DGDiffusionBR2Integrator(class FiniteElementSpace &fes, Coefficient &Q_,
double e = 1.0);
MFEM_DEPRECATED DGDiffusionBR2Integrator(class FiniteElementSpace *fes,
double e = 1.0);
using BilinearFormIntegrator::AssembleFaceMatrix;
virtual void AssembleFaceMatrix(const FiniteElement &el1,
const FiniteElement &el2,
+40 -18
View File
@@ -16,20 +16,39 @@
namespace mfem
{
DGDiffusionBR2Integrator::DGDiffusionBR2Integrator(FiniteElementSpace *fes,
double e) : eta(e)
DGDiffusionBR2Integrator::DGDiffusionBR2Integrator(
FiniteElementSpace &fes, double e) : eta(e), Q(NULL)
{
PrecomputeMassInverse(fes);
}
DGDiffusionBR2Integrator::DGDiffusionBR2Integrator(
FiniteElementSpace &fes, Coefficient &Q_, double e) : eta(e), Q(&Q_)
{
PrecomputeMassInverse(fes);
}
DGDiffusionBR2Integrator::DGDiffusionBR2Integrator(
FiniteElementSpace *fes, double e) : eta(e), Q(NULL)
{
PrecomputeMassInverse(*fes);
}
void DGDiffusionBR2Integrator::PrecomputeMassInverse(FiniteElementSpace &fes)
{
MFEM_VERIFY(fes.IsDGSpace(),
"The BR2 integrator is only defined for DG spaces.");
// Precompute local mass matrix inverses needed for the lifting operators
// First compute offsets and total size needed (e.g. for mixed meshes or
// p-refinement)
int nel = fes->GetNE();
int nel = fes.GetNE();
Minv_offsets.SetSize(nel+1);
ipiv_offsets.SetSize(nel+1);
ipiv_offsets[0] = 0;
Minv_offsets[0] = 0;
for (int i=0; i<nel; ++i)
{
int dof = fes->GetFE(i)->GetDof();
int dof = fes.GetFE(i)->GetDof();
ipiv_offsets[i+1] = ipiv_offsets[i] + dof;
Minv_offsets[i+1] = Minv_offsets[i] + dof*dof;
}
@@ -37,7 +56,7 @@ DGDiffusionBR2Integrator::DGDiffusionBR2Integrator(FiniteElementSpace *fes,
#ifdef MFEM_USE_MPI
// When running in parallel, we also need to compute the local mass matrices
// of face neighbor elements
ParFiniteElementSpace *pfes = dynamic_cast<ParFiniteElementSpace *>(fes);
ParFiniteElementSpace *pfes = dynamic_cast<ParFiniteElementSpace *>(&fes);
if (pfes != NULL)
{
ParMesh *pmesh = pfes->GetParMesh();
@@ -64,15 +83,15 @@ DGDiffusionBR2Integrator::DGDiffusionBR2Integrator(FiniteElementSpace *fes,
{
const FiniteElement *fe = NULL;
ElementTransformation *tr = NULL;
if (i < fes->GetNE())
if (i < fes.GetNE())
{
fe = fes->GetFE(i);
tr = fes->GetElementTransformation(i);
fe = fes.GetFE(i);
tr = fes.GetElementTransformation(i);
}
else
{
#ifdef MFEM_USE_MPI
int inbr = i - fes->GetNE();
int inbr = i - fes.GetNE();
fe = pfes->GetFaceNbrFE(inbr);
tr = pfes->GetParMesh()->GetFaceNbrElementTransformation(inbr);
#endif
@@ -151,21 +170,24 @@ void DGDiffusionBR2Integrator::AssembleFaceMatrix(
for (int p = 0; p < ir->GetNPoints(); p++)
{
const IntegrationPoint &ip = ir->IntPoint(p);
IntegrationPoint eip1, eip2;
Trans.SetAllIntPoints(&ip);
Trans.Loc1.Transform(ip, eip1);
const IntegrationPoint &eip1 = Trans.Elem1->GetIntPoint();
el1.CalcShape(eip1, shape1);
double q = Q ? Q->Eval(*Trans.Elem1, eip1) : 1.0;
if (ndof2)
{
Trans.Loc2.Transform(ip, eip2);
const IntegrationPoint &eip2 = Trans.Elem2->GetIntPoint();
el2.CalcShape(eip2, shape2);
// Set coefficient value q to the average of the values on either side
if (Q) { q = 0.5*(q + Q->Eval(*Trans.Elem2, eip2)); }
}
double w = factor*sqrt(eta)*ip.weight*Trans.Face->Weight();
if (ndof2)
{
w /= 2;
}
// Take sqrt here because
// eta (r_e([u]), r_e([v])) = (sqrt(eta) r_e([u]), sqrt(eta) r_e([v]))
double w = sqrt((factor + 1)*eta*q)*ip.weight*Trans.Face->Weight();
// r_e is defined by, (r_e([u]), tau) = <[u], {tau}>, so we pick up a
// factor of 0.5 on interior faces from the average term.
if (ndof2) { w *= 0.5; }
for (int i = 0; i < ndof1; i++)
{
+24 -24
View File
@@ -17,14 +17,14 @@ namespace mfem
{
template<int T_D1D = 0, int T_Q1D = 0>
void EAConvectionAssemble1D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Vector &padata,
Vector &eadata,
const bool add,
const int d1d = 0,
const int q1d = 0)
static void EAConvectionAssemble1D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Vector &padata,
Vector &eadata,
const bool add,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -69,14 +69,14 @@ void EAConvectionAssemble1D(const int NE,
}
template<int T_D1D = 0, int T_Q1D = 0>
void EAConvectionAssemble2D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Vector &padata,
Vector &eadata,
const bool add,
const int d1d = 0,
const int q1d = 0)
static void EAConvectionAssemble2D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Vector &padata,
Vector &eadata,
const bool add,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -146,14 +146,14 @@ void EAConvectionAssemble2D(const int NE,
}
template<int T_D1D = 0, int T_Q1D = 0>
void EAConvectionAssemble3D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Vector &padata,
Vector &eadata,
const bool add,
const int d1d = 0,
const int q1d = 0)
static void EAConvectionAssemble3D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Vector &padata,
Vector &eadata,
const bool add,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
+18 -18
View File
@@ -21,13 +21,13 @@ namespace mfem
// PA Convection Integrator
// PA Convection Assemble 2D kernel
void PAConvectionSetup2D(const int NQ,
const int NE,
const Array<double> &w,
const Vector &j,
const Vector &vel,
const double alpha,
Vector &op)
static void PAConvectionSetup2D(const int NQ,
const int NE,
const Array<double> &w,
const Vector &j,
const Vector &vel,
const double alpha,
Vector &op)
{
constexpr int DIM = 2;
@@ -60,13 +60,13 @@ void PAConvectionSetup2D(const int NQ,
}
// PA Convection Assemble 3D kernel
void PAConvectionSetup3D(const int NQ,
const int NE,
const Array<double> &w,
const Vector &j,
const Vector &vel,
const double alpha,
Vector &op)
static void PAConvectionSetup3D(const int NQ,
const int NE,
const Array<double> &w,
const Vector &j,
const Vector &vel,
const double alpha,
Vector &op)
{
constexpr int DIM = 3;
constexpr int SDIM = DIM;
@@ -135,7 +135,7 @@ static void PAConvectionSetup(const int dim,
}
// PA Convection Apply 2D kernel
template<int T_D1D = 0, int T_Q1D = 0>
template<int T_D1D = 0, int T_Q1D = 0> static
void PAConvectionApply2D(const int ne,
const Array<double> &b,
const Array<double> &g,
@@ -254,7 +254,7 @@ void PAConvectionApply2D(const int ne,
}
// Optimized PA Convection 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, int T_NBZ = 0> static
void SmemPAConvectionApply2D(const int ne,
const Array<double> &b,
const Array<double> &g,
@@ -382,7 +382,7 @@ void SmemPAConvectionApply2D(const int ne,
}
// PA Convection Apply 3D kernel
template<int T_D1D = 0, int T_Q1D = 0>
template<int T_D1D = 0, int T_Q1D = 0> static
void PAConvectionApply3D(const int ne,
const Array<double> &b,
const Array<double> &g,
@@ -563,7 +563,7 @@ void PAConvectionApply3D(const int ne,
}
// Optimized PA Convection Apply 3D kernel
template<int T_D1D = 0, int T_Q1D = 0>
template<int T_D1D = 0, int T_Q1D = 0> static
void SmemPAConvectionApply3D(const int ne,
const Array<double> &b,
const Array<double> &g,
+41 -41
View File
@@ -16,12 +16,12 @@
namespace mfem
{
void EADGTraceAssemble1DInt(const int NF,
const Array<double> &basis,
const Vector &padata,
Vector &eadata_int,
Vector &eadata_ext,
const bool add)
static void EADGTraceAssemble1DInt(const int NF,
const Array<double> &basis,
const Vector &padata,
Vector &eadata_int,
Vector &eadata_ext,
const bool add)
{
auto D = Reshape(padata.Read(), 2, 2, NF);
auto A_int = Reshape(eadata_int.ReadWrite(), 2, NF);
@@ -50,11 +50,11 @@ void EADGTraceAssemble1DInt(const int NF,
});
}
void EADGTraceAssemble1DBdr(const int NF,
const Array<double> &basis,
const Vector &padata,
Vector &eadata_bdr,
const bool add)
static void EADGTraceAssemble1DBdr(const int NF,
const Array<double> &basis,
const Vector &padata,
Vector &eadata_bdr,
const bool add)
{
auto D = Reshape(padata.Read(), 2, 2, NF);
auto A_bdr = Reshape(eadata_bdr.ReadWrite(), NF);
@@ -72,14 +72,14 @@ void EADGTraceAssemble1DBdr(const int NF,
}
template<int T_D1D = 0, int T_Q1D = 0>
void EADGTraceAssemble2DInt(const int NF,
const Array<double> &basis,
const Vector &padata,
Vector &eadata_int,
Vector &eadata_ext,
const bool add,
const int d1d = 0,
const int q1d = 0)
static void EADGTraceAssemble2DInt(const int NF,
const Array<double> &basis,
const Vector &padata,
Vector &eadata_int,
Vector &eadata_ext,
const bool add,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -128,13 +128,13 @@ void EADGTraceAssemble2DInt(const int NF,
}
template<int T_D1D = 0, int T_Q1D = 0>
void EADGTraceAssemble2DBdr(const int NF,
const Array<double> &basis,
const Vector &padata,
Vector &eadata_bdr,
const bool add,
const int d1d = 0,
const int q1d = 0)
static void EADGTraceAssemble2DBdr(const int NF,
const Array<double> &basis,
const Vector &padata,
Vector &eadata_bdr,
const bool add,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -170,14 +170,14 @@ void EADGTraceAssemble2DBdr(const int NF,
}
template<int T_D1D = 0, int T_Q1D = 0>
void EADGTraceAssemble3DInt(const int NF,
const Array<double> &basis,
const Vector &padata,
Vector &eadata_int,
Vector &eadata_ext,
const bool add,
const int d1d = 0,
const int q1d = 0)
static void EADGTraceAssemble3DInt(const int NF,
const Array<double> &basis,
const Vector &padata,
Vector &eadata_int,
Vector &eadata_ext,
const bool add,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -268,13 +268,13 @@ void EADGTraceAssemble3DInt(const int NF,
}
template<int T_D1D = 0, int T_Q1D = 0>
void EADGTraceAssemble3DBdr(const int NF,
const Array<double> &basis,
const Vector &padata,
Vector &eadata_bdr,
const bool add,
const int d1d = 0,
const int q1d = 0)
static void EADGTraceAssemble3DBdr(const int NF,
const Array<double> &basis,
const Vector &padata,
Vector &eadata_bdr,
const bool add,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
+26 -26
View File
@@ -19,16 +19,16 @@ using namespace std;
namespace mfem
{
// PA DG Trace Integrator
void PADGTraceSetup2D(const int Q1D,
const int NF,
const Array<double> &w,
const Vector &det,
const Vector &nor,
const Vector &rho,
const Vector &vel,
const double alpha,
const double beta,
Vector &op)
static void PADGTraceSetup2D(const int Q1D,
const int NF,
const Array<double> &w,
const Vector &det,
const Vector &nor,
const Vector &rho,
const Vector &vel,
const double alpha,
const double beta,
Vector &op)
{
const int VDIM = 2;
@@ -61,16 +61,16 @@ void PADGTraceSetup2D(const int Q1D,
});
}
void PADGTraceSetup3D(const int Q1D,
const int NF,
const Array<double> &w,
const Vector &det,
const Vector &nor,
const Vector &rho,
const Vector &vel,
const double alpha,
const double beta,
Vector &op)
static void PADGTraceSetup3D(const int Q1D,
const int NF,
const Array<double> &w,
const Vector &det,
const Vector &nor,
const Vector &rho,
const Vector &vel,
const double alpha,
const double beta,
Vector &op)
{
const int VDIM = 3;
@@ -301,7 +301,7 @@ void DGTraceIntegrator::AssemblePABoundaryFaces(const FiniteElementSpace& fes)
}
// PA DGTrace Apply 2D kernel for Gauss-Lobatto/Bernstein
template<int T_D1D = 0, int T_Q1D = 0>
template<int T_D1D = 0, int T_Q1D = 0> static
void PADGTraceApply2D(const int NF,
const Array<double> &b,
const Array<double> &bt,
@@ -392,7 +392,7 @@ void PADGTraceApply2D(const int NF,
}
// PA DGTrace Apply 3D kernel for Gauss-Lobatto/Bernstein
template<int T_D1D = 0, int T_Q1D = 0>
template<int T_D1D = 0, int T_Q1D = 0> static
void PADGTraceApply3D(const int NF,
const Array<double> &b,
const Array<double> &bt,
@@ -537,7 +537,7 @@ void PADGTraceApply3D(const int NF,
}
// Optimized PA DGTrace Apply 3D kernel for Gauss-Lobatto/Bernstein
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0>
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0> static
void SmemPADGTraceApply3D(const int NF,
const Array<double> &b,
const Array<double> &bt,
@@ -701,7 +701,7 @@ static void PADGTraceApply(const int dim,
}
// PA DGTrace Apply 2D kernel for Gauss-Lobatto/Bernstein
template<int T_D1D = 0, int T_Q1D = 0>
template<int T_D1D = 0, int T_Q1D = 0> static
void PADGTraceApplyTranspose2D(const int NF,
const Array<double> &b,
const Array<double> &bt,
@@ -797,7 +797,7 @@ void PADGTraceApplyTranspose2D(const int NF,
}
// PA DGTrace Apply Transpose 3D kernel for Gauss-Lobatto/Bernstein
template<int T_D1D = 0, int T_Q1D = 0>
template<int T_D1D = 0, int T_Q1D = 0> static
void PADGTraceApplyTranspose3D(const int NF,
const Array<double> &b,
const Array<double> &bt,
@@ -953,7 +953,7 @@ void PADGTraceApplyTranspose3D(const int NF,
}
// Optimized PA DGTrace Apply Transpose 3D kernel for Gauss-Lobatto/Bernstein
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0>
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0> static
void SmemPADGTraceApplyTranspose3D(const int NF,
const Array<double> &b,
const Array<double> &bt,
+24 -24
View File
@@ -17,14 +17,14 @@ namespace mfem
{
template<int T_D1D = 0, int T_Q1D = 0>
void EADiffusionAssemble1D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Vector &padata,
Vector &eadata,
const bool add,
const int d1d = 0,
const int q1d = 0)
static void EADiffusionAssemble1D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Vector &padata,
Vector &eadata,
const bool add,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -68,14 +68,14 @@ void EADiffusionAssemble1D(const int NE,
}
template<int T_D1D = 0, int T_Q1D = 0>
void EADiffusionAssemble2D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Vector &padata,
Vector &eadata,
const bool add,
const int d1d = 0,
const int q1d = 0)
static void EADiffusionAssemble2D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Vector &padata,
Vector &eadata,
const bool add,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -145,14 +145,14 @@ void EADiffusionAssemble2D(const int NE,
}
template<int T_D1D = 0, int T_Q1D = 0>
void EADiffusionAssemble3D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Vector &padata,
Vector &eadata,
const bool add,
const int d1d = 0,
const int q1d = 0)
static void EADiffusionAssemble3D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Vector &padata,
Vector &eadata,
const bool add,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
+224 -255
View File
@@ -125,7 +125,7 @@ void PADiffusionSetup2D<2>(const int Q1D,
D(qx,qy,0,e) = w_detJ * ( J22*R11 - J12*R21); // 1,1
D(qx,qy,1,e) = w_detJ * (-J21*R11 + J11*R21); // 2,1
D(qx,qy,2,e) = w_detJ * (symmetric ? (-J21*R12 + J11*R22) :
(J22*R12 - J12*R22)); // 2,2 or 1,2
(J22*R12 - J12*R22)); // 2,2 or 1,2
if (!symmetric)
{
D(qx,qy,3,e) = w_detJ * (-J21*R12 + J11*R22); // 2,2
@@ -496,14 +496,14 @@ void DiffusionIntegrator::AssemblePA(const FiniteElementSpace &fes)
}
template<int T_D1D = 0, int T_Q1D = 0>
void PADiffusionDiagonal2D(const int NE,
const bool symmetric,
const Array<double> &b,
const Array<double> &g,
const Vector &d,
Vector &y,
const int d1d = 0,
const int q1d = 0)
static void PADiffusionDiagonal2D(const int NE,
const bool symmetric,
const Array<double> &b,
const Array<double> &g,
const Vector &d,
Vector &y,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -562,14 +562,14 @@ void PADiffusionDiagonal2D(const int NE,
// Shared memory PA Diffusion Diagonal 2D kernel
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0>
void SmemPADiffusionDiagonal2D(const int NE,
const bool symmetric,
const Array<double> &b_,
const Array<double> &g_,
const Vector &d_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
static void SmemPADiffusionDiagonal2D(const int NE,
const bool symmetric,
const Array<double> &b_,
const Array<double> &g_,
const Vector &d_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -656,14 +656,14 @@ void SmemPADiffusionDiagonal2D(const int NE,
}
template<int T_D1D = 0, int T_Q1D = 0>
void PADiffusionDiagonal3D(const int NE,
const bool symmetric,
const Array<double> &b,
const Array<double> &g,
const Vector &d,
Vector &y,
const int d1d = 0,
const int q1d = 0)
static void PADiffusionDiagonal3D(const int NE,
const bool symmetric,
const Array<double> &b,
const Array<double> &g,
const Vector &d,
Vector &y,
const int d1d = 0,
const int q1d = 0)
{
constexpr int DIM = 3;
const int D1D = T_D1D ? T_D1D : d1d;
@@ -757,14 +757,14 @@ void PADiffusionDiagonal3D(const int NE,
// Shared memory PA Diffusion Diagonal 3D kernel
template<int T_D1D = 0, int T_Q1D = 0>
void SmemPADiffusionDiagonal3D(const int NE,
const bool symmetric,
const Array<double> &b_,
const Array<double> &g_,
const Vector &d_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
static void SmemPADiffusionDiagonal3D(const int NE,
const bool symmetric,
const Array<double> &b_,
const Array<double> &g_,
const Vector &d_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
{
constexpr int DIM = 3;
const int D1D = T_D1D ? T_D1D : d1d;
@@ -903,9 +903,11 @@ static void PADiffusionAssembleDiagonal(const int dim,
{
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);
@@ -1034,17 +1036,17 @@ static void OccaPADiffusionApply3D(const int D1D,
// PA Diffusion Apply 2D kernel
template<int T_D1D = 0, int T_Q1D = 0>
void PADiffusionApply2D(const int NE,
const bool symmetric,
const Array<double> &b_,
const Array<double> &g_,
const Array<double> &bt_,
const Array<double> &gt_,
const Vector &d_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
static void PADiffusionApply2D(const int NE,
const bool symmetric,
const Array<double> &b_,
const Array<double> &g_,
const Array<double> &bt_,
const Array<double> &gt_,
const Vector &d_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -1156,15 +1158,15 @@ 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>
void SmemPADiffusionApply2D(const int NE,
const bool symmetric,
const Array<double> &b_,
const Array<double> &g_,
const Vector &d_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
static void SmemPADiffusionApply2D(const int NE,
const bool symmetric,
const Array<double> &b_,
const Array<double> &g_,
const Vector &d_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -1314,16 +1316,16 @@ void SmemPADiffusionApply2D(const int NE,
// PA Diffusion Apply 3D kernel
template<int T_D1D = 0, int T_Q1D = 0>
void PADiffusionApply3D(const int NE,
const bool symmetric,
const Array<double> &b,
const Array<double> &g,
const Array<double> &bt,
const Array<double> &gt,
const Vector &d_,
const Vector &x_,
Vector &y_,
int d1d = 0, int q1d = 0)
static void PADiffusionApply3D(const int NE,
const bool symmetric,
const Array<double> &b,
const Array<double> &g,
const Array<double> &bt,
const Array<double> &gt,
const Vector &d_,
const Vector &x_,
Vector &y_,
int d1d = 0, int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -1533,15 +1535,15 @@ static MFEM_HOST_DEVICE inline double sign(const int q, const int d)
}
template<int T_D1D = 0, int T_Q1D = 0>
void SmemPADiffusionApply3D(const int NE,
const bool symmetric,
const Array<double> &b_,
const Array<double> &g_,
const Vector &d_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
static void SmemPADiffusionApply3D(const int NE,
const bool symmetric,
const Array<double> &b_,
const Array<double> &g_,
const Vector &d_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -1554,7 +1556,7 @@ void SmemPADiffusionApply3D(const int NE,
auto d = Reshape(d_.Read(), Q1D, Q1D, Q1D, symmetric ? 6 : 9, NE);
auto x = Reshape(x_.Read(), D1D, D1D, D1D, NE);
auto y = Reshape(y_.ReadWrite(), D1D, D1D, D1D, NE);
MFEM_FORALL_3D(e, NE, Q1D, Q1D, 1,
MFEM_FORALL_3D(e, NE, Q1D, Q1D, Q1D,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -1583,118 +1585,102 @@ void SmemPADiffusionApply3D(const int NE,
double (*QDD0)[MD1][MD1] = (double (*)[MD1][MD1]) (sm0+0);
double (*QDD1)[MD1][MD1] = (double (*)[MD1][MD1]) (sm0+1);
double (*QDD2)[MD1][MD1] = (double (*)[MD1][MD1]) (sm0+2);
MFEM_FOREACH_THREAD(dy,y,D1D)
MFEM_FOREACH_THREAD(dz,z,D1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz)
MFEM_FOREACH_THREAD(dx,x,D1D)
{
X[dz][dy][dx] = x(dx,dy,dz,e);
}
}
MFEM_FOREACH_THREAD(qx,x,Q1D)
}
if (MFEM_THREAD_ID(z) == 0)
{
MFEM_FOREACH_THREAD(dy,y,D1D)
{
const int i = qi(qx,dy,Q1D);
const int j = dj(qx,dy,D1D);
const int k = qk(qx,dy,Q1D);
const int l = dl(qx,dy,D1D);
B[i][j] = b(qx,dy);
G[k][l] = g(qx,dy) * sign(qx,dy);
MFEM_FOREACH_THREAD(qx,x,Q1D)
{
const int i = qi(qx,dy,Q1D);
const int j = dj(qx,dy,D1D);
const int k = qk(qx,dy,Q1D);
const int l = dl(qx,dy,D1D);
B[i][j] = b(qx,dy);
G[k][l] = g(qx,dy) * sign(qx,dy);
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(dy,y,D1D)
MFEM_FOREACH_THREAD(dz,z,D1D)
{
MFEM_FOREACH_THREAD(qx,x,Q1D)
MFEM_FOREACH_THREAD(dy,y,D1D)
{
double u[D1D], v[D1D];
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; dz++) { u[dz] = v[dz] = 0.0; }
MFEM_UNROLL(MD1)
for (int dx = 0; dx < D1D; ++dx)
MFEM_FOREACH_THREAD(qx,x,Q1D)
{
const int i = qi(qx,dx,Q1D);
const int j = dj(qx,dx,D1D);
const int k = qk(qx,dx,Q1D);
const int l = dl(qx,dx,D1D);
const double s = sign(qx,dx);
double u = 0.0, v = 0.0;
MFEM_UNROLL(MD1)
for (int dx = 0; dx < D1D; ++dx)
{
const int i = qi(qx,dx,Q1D);
const int j = dj(qx,dx,D1D);
const int k = qk(qx,dx,Q1D);
const int l = dl(qx,dx,D1D);
const double s = sign(qx,dx);
const double coords = X[dz][dy][dx];
u += coords * B[i][j];
v += coords * G[k][l] * s;
}
DDQ0[dz][dy][qx] = u;
DDQ1[dz][dy][qx] = v;
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(dz,z,D1D)
{
MFEM_FOREACH_THREAD(qy,y,Q1D)
{
MFEM_FOREACH_THREAD(qx,x,Q1D)
{
double u = 0.0, v = 0.0, w = 0.0;
MFEM_UNROLL(MD1)
for (int dy = 0; dy < D1D; ++dy)
{
const int i = qi(qy,dy,Q1D);
const int j = dj(qy,dy,D1D);
const int k = qk(qy,dy,Q1D);
const int l = dl(qy,dy,D1D);
const double s = sign(qy,dy);
u += DDQ1[dz][dy][qx] * B[i][j];
v += DDQ0[dz][dy][qx] * G[k][l] * s;
w += DDQ0[dz][dy][qx] * B[i][j];
}
DQQ0[dz][qy][qx] = u;
DQQ1[dz][qy][qx] = v;
DQQ2[dz][qy][qx] = w;
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(qz,z,Q1D)
{
MFEM_FOREACH_THREAD(qy,y,Q1D)
{
MFEM_FOREACH_THREAD(qx,x,Q1D)
{
double u = 0.0, v = 0.0, w = 0.0;
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz)
{
const double coords = X[dz][dy][dx];
u[dz] += coords * B[i][j];
v[dz] += coords * G[k][l] * s;
}
}
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz)
{
DDQ0[dz][dy][qx] = u[dz];
DDQ1[dz][dy][qx] = v[dz];
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(qy,y,Q1D)
{
MFEM_FOREACH_THREAD(qx,x,Q1D)
{
double u[D1D], v[D1D], w[D1D];
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; dz++) { u[dz] = v[dz] = w[dz] = 0.0; }
MFEM_UNROLL(MD1)
for (int dy = 0; dy < D1D; ++dy)
{
const int i = qi(qy,dy,Q1D);
const int j = dj(qy,dy,D1D);
const int k = qk(qy,dy,Q1D);
const int l = dl(qy,dy,D1D);
const double s = sign(qy,dy);
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; dz++)
{
u[dz] += DDQ1[dz][dy][qx] * B[i][j];
v[dz] += DDQ0[dz][dy][qx] * G[k][l] * s;
w[dz] += DDQ0[dz][dy][qx] * B[i][j];
}
}
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; dz++)
{
DQQ0[dz][qy][qx] = u[dz];
DQQ1[dz][qy][qx] = v[dz];
DQQ2[dz][qy][qx] = w[dz];
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(qy,y,Q1D)
{
MFEM_FOREACH_THREAD(qx,x,Q1D)
{
double u[Q1D], v[Q1D], w[Q1D];
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; qz++) { u[qz] = v[qz] = w[qz] = 0.0; }
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz)
{
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; qz++)
{
const int i = qi(qz,dz,Q1D);
const int j = dj(qz,dz,D1D);
const int k = qk(qz,dz,Q1D);
const int l = dl(qz,dz,D1D);
const double s = sign(qz,dz);
u[qz] += DQQ0[dz][qy][qx] * B[i][j];
v[qz] += DQQ1[dz][qy][qx] * B[i][j];
w[qz] += DQQ2[dz][qy][qx] * G[k][l] * s;
u += DQQ0[dz][qy][qx] * B[i][j];
v += DQQ1[dz][qy][qx] * B[i][j];
w += DQQ2[dz][qy][qx] * G[k][l] * s;
}
}
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; qz++)
{
const double O11 = d(qx,qy,qz,0,e);
const double O12 = d(qx,qy,qz,1,e);
const double O13 = d(qx,qy,qz,2,e);
@@ -1704,9 +1690,9 @@ void SmemPADiffusionApply3D(const int NE,
const double O31 = symmetric ? O13 : d(qx,qy,qz,6,e);
const double O32 = symmetric ? O23 : d(qx,qy,qz,7,e);
const double O33 = symmetric ? d(qx,qy,qz,5,e) : d(qx,qy,qz,8,e);
const double gX = u[qz];
const double gY = v[qz];
const double gZ = w[qz];
const double gX = u;
const double gY = v;
const double gZ = w;
QQQ0[qz][qy][qx] = (O11*gX) + (O12*gY) + (O13*gZ);
QQQ1[qz][qy][qx] = (O21*gX) + (O22*gY) + (O23*gZ);
QQQ2[qz][qy][qx] = (O31*gX) + (O32*gY) + (O33*gZ);
@@ -1714,112 +1700,94 @@ void SmemPADiffusionApply3D(const int NE,
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(d,y,D1D)
if (MFEM_THREAD_ID(z) == 0)
{
MFEM_FOREACH_THREAD(q,x,Q1D)
MFEM_FOREACH_THREAD(d,y,D1D)
{
const int i = qi(q,d,Q1D);
const int j = dj(q,d,D1D);
const int k = qk(q,d,Q1D);
const int l = dl(q,d,D1D);
Bt[j][i] = b(q,d);
Gt[l][k] = g(q,d) * sign(q,d);
MFEM_FOREACH_THREAD(q,x,Q1D)
{
const int i = qi(q,d,Q1D);
const int j = dj(q,d,D1D);
const int k = qk(q,d,Q1D);
const int l = dl(q,d,D1D);
Bt[j][i] = b(q,d);
Gt[l][k] = g(q,d) * sign(q,d);
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(qy,y,Q1D)
MFEM_FOREACH_THREAD(qz,z,Q1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
MFEM_FOREACH_THREAD(qy,y,Q1D)
{
double u[Q1D], v[Q1D], w[Q1D];
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz) { u[qz] = v[qz] = w[qz] = 0.0; }
MFEM_UNROLL(MQ1)
for (int qx = 0; qx < Q1D; ++qx)
MFEM_FOREACH_THREAD(dx,x,D1D)
{
const int i = qi(qx,dx,Q1D);
const int j = dj(qx,dx,D1D);
const int k = qk(qx,dx,Q1D);
const int l = dl(qx,dx,D1D);
const double s = sign(qx,dx);
double u = 0.0, v = 0.0, w = 0.0;
MFEM_UNROLL(MQ1)
for (int qx = 0; qx < Q1D; ++qx)
{
const int i = qi(qx,dx,Q1D);
const int j = dj(qx,dx,D1D);
const int k = qk(qx,dx,Q1D);
const int l = dl(qx,dx,D1D);
const double s = sign(qx,dx);
u += QQQ0[qz][qy][qx] * Gt[l][k] * s;
v += QQQ1[qz][qy][qx] * Bt[j][i];
w += QQQ2[qz][qy][qx] * Bt[j][i];
}
QQD0[qz][qy][dx] = u;
QQD1[qz][qy][dx] = v;
QQD2[qz][qy][dx] = w;
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(qz,z,Q1D)
{
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
{
double u = 0.0, v = 0.0, w = 0.0;
MFEM_UNROLL(Q1D)
for (int qy = 0; qy < Q1D; ++qy)
{
const int i = qi(qy,dy,Q1D);
const int j = dj(qy,dy,D1D);
const int k = qk(qy,dy,Q1D);
const int l = dl(qy,dy,D1D);
const double s = sign(qy,dy);
u += QQD0[qz][qy][dx] * Bt[j][i];
v += QQD1[qz][qy][dx] * Gt[l][k] * s;
w += QQD2[qz][qy][dx] * Bt[j][i];
}
QDD0[qz][dy][dx] = u;
QDD1[qz][dy][dx] = v;
QDD2[qz][dy][dx] = w;
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(dz,z,D1D)
{
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
{
double u = 0.0, v = 0.0, w = 0.0;
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz)
{
u[qz] += QQQ0[qz][qy][qx] * Gt[l][k] * s;
v[qz] += QQQ1[qz][qy][qx] * Bt[j][i];
w[qz] += QQQ2[qz][qy][qx] * Bt[j][i];
}
}
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz)
{
QQD0[qz][qy][dx] = u[qz];
QQD1[qz][qy][dx] = v[qz];
QQD2[qz][qy][dx] = w[qz];
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
{
double u[Q1D], v[Q1D], w[Q1D];
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz) { u[qz] = v[qz] = w[qz] = 0.0; }
MFEM_UNROLL(MQ1)
for (int qy = 0; qy < Q1D; ++qy)
{
const int i = qi(qy,dy,Q1D);
const int j = dj(qy,dy,D1D);
const int k = qk(qy,dy,Q1D);
const int l = dl(qy,dy,D1D);
const double s = sign(qy,dy);
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz)
{
u[qz] += QQD0[qz][qy][dx] * Bt[j][i];
v[qz] += QQD1[qz][qy][dx] * Gt[l][k] * s;
w[qz] += QQD2[qz][qy][dx] * Bt[j][i];
}
}
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz)
{
QDD0[qz][dy][dx] = u[qz];
QDD1[qz][dy][dx] = v[qz];
QDD2[qz][dy][dx] = w[qz];
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
{
double u[D1D], v[D1D], w[D1D];
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz) { u[dz] = v[dz] = w[dz] = 0.0; }
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz)
{
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz)
{
const int i = qi(qz,dz,Q1D);
const int j = dj(qz,dz,D1D);
const int k = qk(qz,dz,Q1D);
const int l = dl(qz,dz,D1D);
const double s = sign(qz,dz);
u[dz] += QDD0[qz][dy][dx] * Bt[j][i];
v[dz] += QDD1[qz][dy][dx] * Bt[j][i];
w[dz] += QDD2[qz][dy][dx] * Gt[l][k] * s;
u += QDD0[qz][dy][dx] * Bt[j][i];
v += QDD1[qz][dy][dx] * Bt[j][i];
w += QDD2[qz][dy][dx] * Gt[l][k] * s;
}
}
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz)
{
y(dx,dy,dz,e) += (u[dz] + v[dz] + w[dz]);
y(dx,dy,dz,e) += (u + v + w);
}
}
}
@@ -1877,6 +1845,7 @@ static void PADiffusionApply(const int dim,
{
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);
+72 -72
View File
@@ -21,12 +21,12 @@ namespace mfem
// PA Divergence Integrator
// PA Divergence Assemble 2D kernel
void PADivergenceSetup2D(const int Q1D,
const int NE,
const Array<double> &w,
const Vector &j,
const double COEFF,
Vector &op)
static void PADivergenceSetup2D(const int Q1D,
const int NE,
const Array<double> &w,
const Vector &j,
const double COEFF,
Vector &op)
{
const int NQ = Q1D*Q1D;
auto W = w.Read();
@@ -51,12 +51,12 @@ void PADivergenceSetup2D(const int Q1D,
}
// PA Divergence Assemble 3D kernel
void PADivergenceSetup3D(const int Q1D,
const int NE,
const Array<double> &w,
const Vector &j,
const double COEFF,
Vector &op)
static void PADivergenceSetup3D(const int Q1D,
const int NE,
const Array<double> &w,
const Vector &j,
const double COEFF,
Vector &op)
{
const int NQ = Q1D*Q1D*Q1D;
auto W = w.Read();
@@ -160,16 +160,16 @@ void VectorDivergenceIntegrator::AssemblePA(const FiniteElementSpace &trial_fes,
// PA Divergence Apply 2D kernel
template<const int T_TR_D1D = 0, const int T_TE_D1D = 0, const int T_Q1D = 0>
void PADivergenceApply2D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Array<double> &bt,
const Vector &op_,
const Vector &x_,
Vector &y_,
const int tr_d1d = 0,
const int te_d1d = 0,
const int q1d = 0)
static void PADivergenceApply2D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Array<double> &bt,
const Vector &op_,
const Vector &x_,
Vector &y_,
const int tr_d1d = 0,
const int te_d1d = 0,
const int q1d = 0)
{
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
@@ -281,16 +281,16 @@ void PADivergenceApply2D(const int NE,
// Shared memory PA Divergence Apply 2D kernel
template<const int T_TR_D1D = 0, const int T_TE_D1D = 0, const int T_Q1D = 0,
const int T_NBZ = 0>
void SmemPADivergenceApply2D(const int NE,
const Array<double> &b_,
const Array<double> &g_,
const Array<double> &bt_,
const Vector &op_,
const Vector &x_,
Vector &y_,
const int tr_d1d = 0,
const int te_d1d = 0,
const int q1d = 0)
static void SmemPADivergenceApply2D(const int NE,
const Array<double> &b_,
const Array<double> &g_,
const Array<double> &bt_,
const Vector &op_,
const Vector &x_,
Vector &y_,
const int tr_d1d = 0,
const int te_d1d = 0,
const int q1d = 0)
{
// TODO
MFEM_ASSERT(false, "SHARED MEM NOT PROGRAMMED YET");
@@ -298,16 +298,16 @@ void SmemPADivergenceApply2D(const int NE,
// PA Divergence Apply 2D kernel transpose
template<const int T_TR_D1D = 0, const int T_TE_D1D = 0, const int T_Q1D = 0>
void PADivergenceApplyTranspose2D(const int NE,
const Array<double> &bt,
const Array<double> &gt,
const Array<double> &b,
const Vector &op_,
const Vector &x_,
Vector &y_,
const int tr_d1d = 0,
const int te_d1d = 0,
const int q1d = 0)
static void PADivergenceApplyTranspose2D(const int NE,
const Array<double> &bt,
const Array<double> &gt,
const Array<double> &b,
const Vector &op_,
const Vector &x_,
Vector &y_,
const int tr_d1d = 0,
const int te_d1d = 0,
const int q1d = 0)
{
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
@@ -414,16 +414,16 @@ void PADivergenceApplyTranspose2D(const int NE,
// PA Vector Divergence Apply 3D kernel
template<const int T_TR_D1D = 0, const int T_TE_D1D = 0, const int T_Q1D = 0>
void PADivergenceApply3D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Array<double> &bt,
const Vector &op_,
const Vector &x_,
Vector &y_,
int tr_d1d = 0,
int te_d1d = 0,
int q1d = 0)
static void PADivergenceApply3D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Array<double> &bt,
const Vector &op_,
const Vector &x_,
Vector &y_,
int tr_d1d = 0,
int te_d1d = 0,
int q1d = 0)
{
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
@@ -597,16 +597,16 @@ void PADivergenceApply3D(const int NE,
// PA Vector Divergence Apply 3D kernel
template<const int T_TR_D1D = 0, const int T_TE_D1D = 0, const int T_Q1D = 0>
void PADivergenceApplyTranspose3D(const int NE,
const Array<double> &bt,
const Array<double> &gt,
const Array<double> &b,
const Vector &op_,
const Vector &x_,
Vector &y_,
int tr_d1d = 0,
int te_d1d = 0,
int q1d = 0)
static void PADivergenceApplyTranspose3D(const int NE,
const Array<double> &bt,
const Array<double> &gt,
const Array<double> &b,
const Vector &op_,
const Vector &x_,
Vector &y_,
int tr_d1d = 0,
int te_d1d = 0,
int q1d = 0)
{
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
@@ -775,16 +775,16 @@ void PADivergenceApplyTranspose3D(const int NE,
// Shared memory PA Vector Divergence Apply 3D kernel
template<const int T_TR_D1D = 0, const int T_TE_D1D = 0, const int T_Q1D = 0>
void SmemPADivergenceApply3D(const int NE,
const Array<double> &b_,
const Array<double> &g_,
const Array<double> &bt_,
const Vector &q_,
const Vector &x_,
Vector &y_,
const int tr_d1d = 0,
const int te_d1d = 0,
const int q1d = 0)
static void SmemPADivergenceApply3D(const int NE,
const Array<double> &b_,
const Array<double> &g_,
const Array<double> &bt_,
const Vector &q_,
const Vector &x_,
Vector &y_,
const int tr_d1d = 0,
const int te_d1d = 0,
const int q1d = 0)
{
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
+42 -42
View File
@@ -70,12 +70,12 @@ namespace mfem
the \b MFEM_SHARED keyword for local arrays. */
// PA Gradient Assemble 2D kernel
void PAGradientSetup2D(const int Q1D,
const int NE,
const Array<double> &w,
const Vector &j,
const Vector &c,
Vector &op)
static void PAGradientSetup2D(const int Q1D,
const int NE,
const Array<double> &w,
const Vector &j,
const Vector &c,
Vector &op)
{
const int NQ = Q1D*Q1D;
auto W = w.Read();
@@ -105,12 +105,12 @@ void PAGradientSetup2D(const int Q1D,
}
// PA Gradient Assemble 3D kernel
void PAGradientSetup3D(const int Q1D,
const int NE,
const Array<double> &w,
const Vector &j,
const Vector &c,
Vector &op)
static void PAGradientSetup3D(const int Q1D,
const int NE,
const Array<double> &w,
const Vector &j,
const Vector &c,
Vector &op)
{
const int NQ = Q1D*Q1D*Q1D;
auto W = w.Read();
@@ -254,16 +254,16 @@ void GradientIntegrator::AssemblePA(const FiniteElementSpace &trial_fes,
// PA Gradient Apply 2D kernel
template<int T_TR_D1D = 0, int T_TE_D1D = 0, int T_Q1D = 0>
void PAGradientApply2D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Array<double> &bt,
const Vector &op_,
const Vector &x_,
Vector &y_,
const int tr_d1d = 0,
const int te_d1d = 0,
const int q1d = 0)
static void PAGradientApply2D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Array<double> &bt,
const Vector &op_,
const Vector &x_,
Vector &y_,
const int tr_d1d = 0,
const int te_d1d = 0,
const int q1d = 0)
{
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
@@ -384,16 +384,16 @@ static void PAGradientApplyTranspose2D(const int NE,
// PA Gradient Apply 3D kernel
template<const int T_TR_D1D = 0, const int T_TE_D1D = 0, const int T_Q1D = 0>
void PAGradientApply3D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Array<double> &bt,
const Vector &op_,
const Vector &x_,
Vector &y_,
int tr_d1d = 0,
int te_d1d = 0,
int q1d = 0)
static void PAGradientApply3D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Array<double> &bt,
const Vector &op_,
const Vector &x_,
Vector &y_,
int tr_d1d = 0,
int te_d1d = 0,
int q1d = 0)
{
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
@@ -579,16 +579,16 @@ static void PAGradientApplyTranspose3D(const int NE,
// Shared memory PA Gradient Apply 3D kernel
template<const int T_TR_D1D = 0, const int T_TE_D1D = 0, const int T_Q1D = 0>
void SmemPAGradientApply3D(const int NE,
const Array<double> &b_,
const Array<double> &g_,
const Array<double> &bt_,
const Vector &d_,
const Vector &x_,
Vector &y_,
const int tr_d1d = 0,
const int te_d1d = 0,
const int q1d = 0)
static void SmemPAGradientApply3D(const int NE,
const Array<double> &b_,
const Array<double> &g_,
const Array<double> &bt_,
const Vector &d_,
const Vector &x_,
Vector &y_,
const int tr_d1d = 0,
const int te_d1d = 0,
const int q1d = 0)
{
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
+196 -196
View File
@@ -186,7 +186,7 @@ void PAHcurlMassAssembleDiagonal2D(const int D1D,
const double wy = (c == 1) ? Bo(qy,dy) : Bc(qy,dy);
mass[qx] += wy * wy * ((c == 0) ? op(qx,qy,0,e) :
op(qx,qy,symmetric ? 2 : 3, e));
op(qx,qy,symmetric ? 2 : 3, e));
}
}
@@ -237,7 +237,7 @@ void PAHcurlMassAssembleDiagonal3D(const int D1D,
const int D1Dx = (c == 0) ? D1D - 1 : D1D;
const int opc = (c == 0) ? 0 : ((c == 1) ? (symmetric ? 3 : 4) :
(symmetric ? 5 : 8));
(symmetric ? 5 : 8));
double mass[MAX_Q1D];
@@ -791,12 +791,12 @@ void SmemPAHcurlMassApply3D(const int D1D,
}
// PA H(curl) curl-curl assemble 2D kernel
void PACurlCurlSetup2D(const int Q1D,
const int NE,
const Array<double> &w,
const Vector &j,
Vector &coeff,
Vector &op)
static void PACurlCurlSetup2D(const int Q1D,
const int NE,
const Array<double> &w,
const Vector &j,
Vector &coeff,
Vector &op)
{
const int NQ = Q1D*Q1D;
auto W = w.Read();
@@ -818,13 +818,13 @@ void PACurlCurlSetup2D(const int Q1D,
}
// PA H(curl) curl-curl assemble 3D kernel
void PACurlCurlSetup3D(const int Q1D,
const int coeffDim,
const int NE,
const Array<double> &w,
const Vector &j,
Vector &coeff,
Vector &op)
static void PACurlCurlSetup3D(const int Q1D,
const int coeffDim,
const int NE,
const Array<double> &w,
const Vector &j,
Vector &coeff,
Vector &op)
{
const int NQ = Q1D*Q1D*Q1D;
const bool symmetric = (coeffDim != 9);
@@ -1045,16 +1045,16 @@ void CurlCurlIntegrator::AssemblePA(const FiniteElementSpace &fes)
}
}
void PACurlCurlApply2D(const int D1D,
const int Q1D,
const int NE,
const Array<double> &bo,
const Array<double> &bot,
const Array<double> &gc,
const Array<double> &gct,
const Vector &pa_data,
const Vector &x,
Vector &y)
static void PACurlCurlApply2D(const int D1D,
const int Q1D,
const int NE,
const Array<double> &bo,
const Array<double> &bot,
const Array<double> &gc,
const Array<double> &gct,
const Vector &pa_data,
const Vector &x,
Vector &y)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = HCURL_MAX_D1D;
@@ -1166,19 +1166,19 @@ void PACurlCurlApply2D(const int D1D,
}
template<int MAX_D1D = HCURL_MAX_D1D, int MAX_Q1D = HCURL_MAX_Q1D>
void PACurlCurlApply3D(const int D1D,
const int Q1D,
const bool symmetric,
const int NE,
const Array<double> &bo,
const Array<double> &bc,
const Array<double> &bot,
const Array<double> &bct,
const Array<double> &gc,
const Array<double> &gct,
const Vector &pa_data,
const Vector &x,
Vector &y)
static void PACurlCurlApply3D(const int D1D,
const int Q1D,
const bool symmetric,
const int NE,
const Array<double> &bo,
const Array<double> &bc,
const Array<double> &bot,
const Array<double> &bct,
const Array<double> &gc,
const Array<double> &gct,
const Vector &pa_data,
const Vector &x,
Vector &y)
{
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
MFEM_VERIFY(Q1D <= MAX_Q1D, "Error: Q1D > MAX_Q1D");
@@ -1677,19 +1677,19 @@ void PACurlCurlApply3D(const int D1D,
}
template<int MAX_D1D = HCURL_MAX_D1D, int MAX_Q1D = HCURL_MAX_Q1D>
void SmemPACurlCurlApply3D(const int D1D,
const int Q1D,
const bool symmetric,
const int NE,
const Array<double> &bo,
const Array<double> &bc,
const Array<double> &bot,
const Array<double> &bct,
const Array<double> &gc,
const Array<double> &gct,
const Vector &pa_data,
const Vector &x,
Vector &y)
static void SmemPACurlCurlApply3D(const int D1D,
const int Q1D,
const bool symmetric,
const int NE,
const Array<double> &bo,
const Array<double> &bc,
const Array<double> &bot,
const Array<double> &bct,
const Array<double> &gc,
const Array<double> &gct,
const Vector &pa_data,
const Vector &x,
Vector &y)
{
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
MFEM_VERIFY(Q1D <= MAX_Q1D, "Error: Q1D > MAX_Q1D");
@@ -2032,13 +2032,13 @@ void CurlCurlIntegrator::AddMultPA(const Vector &x, Vector &y) const
}
}
void PACurlCurlAssembleDiagonal2D(const int D1D,
const int Q1D,
const int NE,
const Array<double> &bo,
const Array<double> &gc,
const Vector &pa_data,
Vector &diag)
static void PACurlCurlAssembleDiagonal2D(const int D1D,
const int Q1D,
const int NE,
const Array<double> &bo,
const Array<double> &gc,
const Vector &pa_data,
Vector &diag)
{
constexpr static int VDIM = 2;
constexpr static int MAX_Q1D = HCURL_MAX_Q1D;
@@ -2087,16 +2087,16 @@ void PACurlCurlAssembleDiagonal2D(const int D1D,
}
template<int MAX_D1D = HCURL_MAX_D1D, int MAX_Q1D = HCURL_MAX_Q1D>
void PACurlCurlAssembleDiagonal3D(const int D1D,
const int Q1D,
const bool symmetric,
const int NE,
const Array<double> &bo,
const Array<double> &bc,
const Array<double> &go,
const Array<double> &gc,
const Vector &pa_data,
Vector &diag)
static void PACurlCurlAssembleDiagonal3D(const int D1D,
const int Q1D,
const bool symmetric,
const int NE,
const Array<double> &bo,
const Array<double> &bc,
const Array<double> &go,
const Array<double> &gc,
const Vector &pa_data,
Vector &diag)
{
constexpr static int VDIM = 3;
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
@@ -2273,16 +2273,16 @@ void PACurlCurlAssembleDiagonal3D(const int D1D,
}
template<int MAX_D1D = HCURL_MAX_D1D, int MAX_Q1D = HCURL_MAX_Q1D>
void SmemPACurlCurlAssembleDiagonal3D(const int D1D,
const int Q1D,
const bool symmetric,
const int NE,
const Array<double> &bo,
const Array<double> &bc,
const Array<double> &go,
const Array<double> &gc,
const Vector &pa_data,
Vector &diag)
static void SmemPACurlCurlAssembleDiagonal3D(const int D1D,
const int Q1D,
const bool symmetric,
const int NE,
const Array<double> &bo,
const Array<double> &bc,
const Array<double> &go,
const Array<double> &gc,
const Vector &pa_data,
Vector &diag)
{
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
MFEM_VERIFY(Q1D <= MAX_Q1D, "Error: Q1D > MAX_Q1D");
@@ -2955,18 +2955,18 @@ void MixedVectorCurlIntegrator::AssemblePA(const FiniteElementSpace &trial_fes,
// Apply to x corresponding to DOF's in H(curl) (trial), whose curl is
// integrated against H(curl) test functions corresponding to y.
template<int MAX_D1D = HCURL_MAX_D1D, int MAX_Q1D = HCURL_MAX_Q1D>
void PAHcurlL2Apply3D(const int D1D,
const int Q1D,
const int coeffDim,
const int NE,
const Array<double> &bo,
const Array<double> &bc,
const Array<double> &bot,
const Array<double> &bct,
const Array<double> &gc,
const Vector &pa_data,
const Vector &x,
Vector &y)
static void PAHcurlL2Apply3D(const int D1D,
const int Q1D,
const int coeffDim,
const int NE,
const Array<double> &bo,
const Array<double> &bc,
const Array<double> &bot,
const Array<double> &bct,
const Array<double> &gc,
const Vector &pa_data,
const Vector &x,
Vector &y)
{
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
MFEM_VERIFY(Q1D <= MAX_Q1D, "Error: Q1D > MAX_Q1D");
@@ -3297,16 +3297,16 @@ void PAHcurlL2Apply3D(const int D1D,
// Apply to x corresponding to DOF's in H(curl) (trial), whose curl is
// integrated against H(curl) test functions corresponding to y.
template<int MAX_D1D = HCURL_MAX_D1D, int MAX_Q1D = HCURL_MAX_Q1D>
void SmemPAHcurlL2Apply3D(const int D1D,
const int Q1D,
const int coeffDim,
const int NE,
const Array<double> &bo,
const Array<double> &bc,
const Array<double> &gc,
const Vector &pa_data,
const Vector &x,
Vector &y)
static void SmemPAHcurlL2Apply3D(const int D1D,
const int Q1D,
const int coeffDim,
const int NE,
const Array<double> &bo,
const Array<double> &bc,
const Array<double> &gc,
const Vector &pa_data,
const Vector &x,
Vector &y)
{
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
MFEM_VERIFY(Q1D <= MAX_Q1D, "Error: Q1D > MAX_Q1D");
@@ -3585,18 +3585,18 @@ void SmemPAHcurlL2Apply3D(const int D1D,
// Apply to x corresponding to DOF's in H(curl) (trial), whose curl is
// integrated against H(div) test functions corresponding to y.
template<int MAX_D1D = HCURL_MAX_D1D, int MAX_Q1D = HCURL_MAX_Q1D>
void PAHcurlHdivApply3D(const int D1D,
const int D1Dtest,
const int Q1D,
const int NE,
const Array<double> &bo,
const Array<double> &bc,
const Array<double> &bot,
const Array<double> &bct,
const Array<double> &gc,
const Vector &pa_data,
const Vector &x,
Vector &y)
static void PAHcurlHdivApply3D(const int D1D,
const int D1Dtest,
const int Q1D,
const int NE,
const Array<double> &bo,
const Array<double> &bc,
const Array<double> &bot,
const Array<double> &bct,
const Array<double> &gc,
const Vector &pa_data,
const Vector &x,
Vector &y)
{
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
MFEM_VERIFY(Q1D <= MAX_Q1D, "Error: Q1D > MAX_Q1D");
@@ -4071,18 +4071,18 @@ void MixedVectorWeakCurlIntegrator::AssemblePA(const FiniteElementSpace
// Apply to x corresponding to DOF's in H(curl) (trial), integrated against curl
// of H(curl) test functions corresponding to y.
template<int MAX_D1D = HCURL_MAX_D1D, int MAX_Q1D = HCURL_MAX_Q1D>
void PAHcurlL2Apply3DTranspose(const int D1D,
const int Q1D,
const int coeffDim,
const int NE,
const Array<double> &bo,
const Array<double> &bc,
const Array<double> &bot,
const Array<double> &bct,
const Array<double> &gct,
const Vector &pa_data,
const Vector &x,
Vector &y)
static void PAHcurlL2Apply3DTranspose(const int D1D,
const int Q1D,
const int coeffDim,
const int NE,
const Array<double> &bo,
const Array<double> &bc,
const Array<double> &bot,
const Array<double> &bct,
const Array<double> &gct,
const Vector &pa_data,
const Vector &x,
Vector &y)
{
// See PAHcurlL2Apply3D for comments.
@@ -4413,16 +4413,16 @@ void PAHcurlL2Apply3DTranspose(const int D1D,
}
template<int MAX_D1D = HCURL_MAX_D1D, int MAX_Q1D = HCURL_MAX_Q1D>
void SmemPAHcurlL2Apply3DTranspose(const int D1D,
const int Q1D,
const int coeffDim,
const int NE,
const Array<double> &bo,
const Array<double> &bc,
const Array<double> &gc,
const Vector &pa_data,
const Vector &x,
Vector &y)
static void SmemPAHcurlL2Apply3DTranspose(const int D1D,
const int Q1D,
const int coeffDim,
const int NE,
const Array<double> &bo,
const Array<double> &bc,
const Array<double> &gc,
const Vector &pa_data,
const Vector &x,
Vector &y)
{
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
MFEM_VERIFY(Q1D <= MAX_Q1D, "Error: Q1D > MAX_Q1D");
@@ -4675,13 +4675,13 @@ void MixedVectorWeakCurlIntegrator::AddMultPA(const Vector &x, Vector &y) const
// Apply to x corresponding to DOFs in H^1 (domain) the (topological) gradient
// to get a dof in H(curl) (range). You can think of the range as the "test" space
// and the domain as the "trial" space, but there's no integration.
void PAHcurlApplyGradient2D(const int c_dofs1D,
const int o_dofs1D,
const int NE,
const Array<double> &B_,
const Array<double> &G_,
const Vector &x_,
Vector &y_)
static void PAHcurlApplyGradient2D(const int c_dofs1D,
const int o_dofs1D,
const int NE,
const Array<double> &B_,
const Array<double> &G_,
const Vector &x_,
Vector &y_)
{
auto B = Reshape(B_.Read(), c_dofs1D, c_dofs1D);
auto G = Reshape(G_.Read(), o_dofs1D, c_dofs1D);
@@ -4753,12 +4753,12 @@ void PAHcurlApplyGradient2D(const int c_dofs1D,
}
// Specialization of PAHcurlApplyGradient2D to the case where B is identity
void PAHcurlApplyGradient2DBId(const int c_dofs1D,
const int o_dofs1D,
const int NE,
const Array<double> &G_,
const Vector &x_,
Vector &y_)
static void PAHcurlApplyGradient2DBId(const int c_dofs1D,
const int o_dofs1D,
const int NE,
const Array<double> &G_,
const Vector &x_,
Vector &y_)
{
auto G = Reshape(G_.Read(), o_dofs1D, c_dofs1D);
@@ -4822,7 +4822,7 @@ void PAHcurlApplyGradient2DBId(const int c_dofs1D,
});
}
void PAHcurlApplyGradientTranspose2D(
static void PAHcurlApplyGradientTranspose2D(
const int c_dofs1D, const int o_dofs1D, const int NE,
const Array<double> &B_, const Array<double> &G_,
const Vector &x_, Vector &y_)
@@ -4898,7 +4898,7 @@ void PAHcurlApplyGradientTranspose2D(
// Specialization of PAHcurlApplyGradientTranspose2D to the case where
// B is identity
void PAHcurlApplyGradientTranspose2DBId(
static void PAHcurlApplyGradientTranspose2DBId(
const int c_dofs1D, const int o_dofs1D, const int NE,
const Array<double> &G_,
const Vector &x_, Vector &y_)
@@ -4965,13 +4965,13 @@ void PAHcurlApplyGradientTranspose2DBId(
});
}
void PAHcurlApplyGradient3D(const int c_dofs1D,
const int o_dofs1D,
const int NE,
const Array<double> &B_,
const Array<double> &G_,
const Vector &x_,
Vector &y_)
static void PAHcurlApplyGradient3D(const int c_dofs1D,
const int o_dofs1D,
const int NE,
const Array<double> &B_,
const Array<double> &G_,
const Vector &x_,
Vector &y_)
{
auto B = Reshape(B_.Read(), c_dofs1D, c_dofs1D);
auto G = Reshape(G_.Read(), o_dofs1D, c_dofs1D);
@@ -5154,12 +5154,12 @@ void PAHcurlApplyGradient3D(const int c_dofs1D,
}
// Specialization of PAHcurlApplyGradient3D to the case where
void PAHcurlApplyGradient3DBId(const int c_dofs1D,
const int o_dofs1D,
const int NE,
const Array<double> &G_,
const Vector &x_,
Vector &y_)
static void PAHcurlApplyGradient3DBId(const int c_dofs1D,
const int o_dofs1D,
const int NE,
const Array<double> &G_,
const Vector &x_,
Vector &y_)
{
auto G = Reshape(G_.Read(), o_dofs1D, c_dofs1D);
@@ -5322,7 +5322,7 @@ void PAHcurlApplyGradient3DBId(const int c_dofs1D,
});
}
void PAHcurlApplyGradientTranspose3D(
static void PAHcurlApplyGradientTranspose3D(
const int c_dofs1D, const int o_dofs1D, const int NE,
const Array<double> &B_, const Array<double> &G_,
const Vector &x_, Vector &y_)
@@ -5507,7 +5507,7 @@ void PAHcurlApplyGradientTranspose3D(
}
// Specialization of PAHcurlApplyGradientTranspose3D to the case where
void PAHcurlApplyGradientTranspose3DBId(
static void PAHcurlApplyGradientTranspose3DBId(
const int c_dofs1D, const int o_dofs1D, const int NE,
const Array<double> &G_,
const Vector &x_, Vector &y_)
@@ -5789,14 +5789,14 @@ void GradientInterpolator::AddMultTransposePA(const Vector &x, Vector &y) const
}
}
void PAHcurlVecH1IdentityApply3D(const int c_dofs1D,
const int o_dofs1D,
const int NE,
const Array<double> &Bclosed,
const Array<double> &Bopen,
const Vector &pa_data,
const Vector &x_,
Vector &y_)
static void PAHcurlVecH1IdentityApply3D(const int c_dofs1D,
const int o_dofs1D,
const int NE,
const Array<double> &Bclosed,
const Array<double> &Bopen,
const Vector &pa_data,
const Vector &x_,
Vector &y_)
{
auto Bc = Reshape(Bclosed.Read(), c_dofs1D, c_dofs1D);
auto Bo = Reshape(Bopen.Read(), o_dofs1D, c_dofs1D);
@@ -6002,14 +6002,14 @@ void PAHcurlVecH1IdentityApply3D(const int c_dofs1D,
});
}
void PAHcurlVecH1IdentityApplyTranspose3D(const int c_dofs1D,
const int o_dofs1D,
const int NE,
const Array<double> &Bclosed,
const Array<double> &Bopen,
const Vector &pa_data,
const Vector &x_,
Vector &y_)
static void PAHcurlVecH1IdentityApplyTranspose3D(const int c_dofs1D,
const int o_dofs1D,
const int NE,
const Array<double> &Bclosed,
const Array<double> &Bopen,
const Vector &pa_data,
const Vector &x_,
Vector &y_)
{
auto Bc = Reshape(Bclosed.Read(), c_dofs1D, c_dofs1D);
auto Bo = Reshape(Bopen.Read(), o_dofs1D, c_dofs1D);
@@ -6228,14 +6228,14 @@ void PAHcurlVecH1IdentityApplyTranspose3D(const int c_dofs1D,
});
}
void PAHcurlVecH1IdentityApply2D(const int c_dofs1D,
const int o_dofs1D,
const int NE,
const Array<double> &Bclosed,
const Array<double> &Bopen,
const Vector &pa_data,
const Vector &x_,
Vector &y_)
static void PAHcurlVecH1IdentityApply2D(const int c_dofs1D,
const int o_dofs1D,
const int NE,
const Array<double> &Bclosed,
const Array<double> &Bopen,
const Vector &pa_data,
const Vector &x_,
Vector &y_)
{
auto Bc = Reshape(Bclosed.Read(), c_dofs1D, c_dofs1D);
auto Bo = Reshape(Bopen.Read(), o_dofs1D, c_dofs1D);
@@ -6327,14 +6327,14 @@ void PAHcurlVecH1IdentityApply2D(const int c_dofs1D,
});
}
void PAHcurlVecH1IdentityApplyTranspose2D(const int c_dofs1D,
const int o_dofs1D,
const int NE,
const Array<double> &Bclosed,
const Array<double> &Bopen,
const Vector &pa_data,
const Vector &x_,
Vector &y_)
static void PAHcurlVecH1IdentityApplyTranspose2D(const int c_dofs1D,
const int o_dofs1D,
const int NE,
const Array<double> &Bclosed,
const Array<double> &Bopen,
const Vector &pa_data,
const Vector &x_,
Vector &y_)
{
auto Bc = Reshape(Bclosed.Read(), c_dofs1D, c_dofs1D);
auto Bo = Reshape(Bopen.Read(), o_dofs1D, c_dofs1D);
+116 -116
View File
@@ -539,12 +539,12 @@ void PAHdivMassApply3D(const int D1D,
// PA H(div) div-div assemble 2D kernel
// NOTE: this is identical to PACurlCurlSetup3D
void PADivDivSetup2D(const int Q1D,
const int NE,
const Array<double> &w,
const Vector &j,
Vector &coeff_,
Vector &op)
static void PADivDivSetup2D(const int Q1D,
const int NE,
const Array<double> &w,
const Vector &j,
Vector &coeff_,
Vector &op)
{
const int NQ = Q1D*Q1D;
auto W = w.Read();
@@ -565,12 +565,12 @@ void PADivDivSetup2D(const int Q1D,
});
}
void PADivDivSetup3D(const int Q1D,
const int NE,
const Array<double> &w,
const Vector &j,
Vector &coeff_,
Vector &op)
static void PADivDivSetup3D(const int Q1D,
const int NE,
const Array<double> &w,
const Vector &j,
Vector &coeff_,
Vector &op)
{
const int NQ = Q1D*Q1D*Q1D;
auto W = w.Read();
@@ -599,16 +599,16 @@ void PADivDivSetup3D(const int Q1D,
});
}
void PADivDivApply2D(const int D1D,
const int Q1D,
const int NE,
const Array<double> &Bo_,
const Array<double> &Gc_,
const Array<double> &Bot_,
const Array<double> &Gct_,
const Vector &op_,
const Vector &x_,
Vector &y_)
static void PADivDivApply2D(const int D1D,
const int Q1D,
const int NE,
const Array<double> &Bo_,
const Array<double> &Gc_,
const Array<double> &Bot_,
const Array<double> &Gct_,
const Vector &op_,
const Vector &x_,
Vector &y_)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = HDIV_MAX_D1D;
@@ -718,16 +718,16 @@ void PADivDivApply2D(const int D1D,
}); // end of element loop
}
void PADivDivApply3D(const int D1D,
const int Q1D,
const int NE,
const Array<double> &Bo_,
const Array<double> &Gc_,
const Array<double> &Bot_,
const Array<double> &Gct_,
const Vector &op_,
const Vector &x_,
Vector &y_)
static void PADivDivApply3D(const int D1D,
const int Q1D,
const int NE,
const Array<double> &Bo_,
const Array<double> &Gc_,
const Array<double> &Bot_,
const Array<double> &Gct_,
const Vector &op_,
const Vector &x_,
Vector &y_)
{
MFEM_VERIFY(D1D <= HDIV_MAX_D1D, "Error: D1D > HDIV_MAX_D1D");
MFEM_VERIFY(Q1D <= HDIV_MAX_Q1D, "Error: Q1D > HDIV_MAX_Q1D");
@@ -967,13 +967,13 @@ void DivDivIntegrator::AddMultPA(const Vector &x, Vector &y) const
}
}
void PADivDivAssembleDiagonal2D(const int D1D,
const int Q1D,
const int NE,
const Array<double> &Bo_,
const Array<double> &Gc_,
const Vector &op_,
Vector &diag_)
static void PADivDivAssembleDiagonal2D(const int D1D,
const int Q1D,
const int NE,
const Array<double> &Bo_,
const Array<double> &Gc_,
const Vector &op_,
Vector &diag_)
{
constexpr static int VDIM = 2;
constexpr static int MAX_Q1D = HDIV_MAX_Q1D;
@@ -1023,13 +1023,13 @@ void PADivDivAssembleDiagonal2D(const int D1D,
});
}
void PADivDivAssembleDiagonal3D(const int D1D,
const int Q1D,
const int NE,
const Array<double> &Bo_,
const Array<double> &Gc_,
const Vector &op_,
Vector &diag_)
static void PADivDivAssembleDiagonal3D(const int D1D,
const int Q1D,
const int NE,
const Array<double> &Bo_,
const Array<double> &Gc_,
const Vector &op_,
Vector &diag_)
{
MFEM_VERIFY(D1D <= HDIV_MAX_D1D, "Error: D1D > HDIV_MAX_D1D");
MFEM_VERIFY(Q1D <= HDIV_MAX_Q1D, "Error: Q1D > HDIV_MAX_Q1D");
@@ -1104,11 +1104,11 @@ void DivDivIntegrator::AssembleDiagonalPA(Vector& diag)
}
// PA H(div)-L2 (div u, p) assemble 2D kernel
void PADivL2Setup2D(const int Q1D,
const int NE,
const Array<double> &w,
Vector &coeff_,
Vector &op)
static void PADivL2Setup2D(const int Q1D,
const int NE,
const Array<double> &w,
Vector &coeff_,
Vector &op)
{
const int NQ = Q1D*Q1D;
auto W = w.Read();
@@ -1123,11 +1123,11 @@ void PADivL2Setup2D(const int Q1D,
});
}
void PADivL2Setup3D(const int Q1D,
const int NE,
const Array<double> &w,
Vector &coeff_,
Vector &op)
static void PADivL2Setup3D(const int Q1D,
const int NE,
const Array<double> &w,
Vector &coeff_,
Vector &op)
{
const int NQ = Q1D*Q1D*Q1D;
auto W = w.Read();
@@ -1225,16 +1225,16 @@ VectorFEDivergenceIntegrator::AssemblePA(const FiniteElementSpace &trial_fes,
// Apply to x corresponding to DOF's in H(div) (trial), whose divergence is
// integrated against L_2 test functions corresponding to y.
void PAHdivL2Apply3D(const int D1D,
const int Q1D,
const int L2D1D,
const int NE,
const Array<double> &Bo_,
const Array<double> &Gc_,
const Array<double> &L2Bot_,
const Vector &op_,
const Vector &x_,
Vector &y_)
static void PAHdivL2Apply3D(const int D1D,
const int Q1D,
const int L2D1D,
const int NE,
const Array<double> &Bo_,
const Array<double> &Gc_,
const Array<double> &L2Bot_,
const Vector &op_,
const Vector &x_,
Vector &y_)
{
MFEM_VERIFY(D1D <= HDIV_MAX_D1D, "Error: D1D > HDIV_MAX_D1D");
MFEM_VERIFY(Q1D <= HDIV_MAX_Q1D, "Error: Q1D > HDIV_MAX_Q1D");
@@ -1388,16 +1388,16 @@ void PAHdivL2Apply3D(const int D1D,
// Apply to x corresponding to DOF's in H(div) (trial), whose divergence is
// integrated against L_2 test functions corresponding to y.
void PAHdivL2Apply2D(const int D1D,
const int Q1D,
const int L2D1D,
const int NE,
const Array<double> &Bo_,
const Array<double> &Gc_,
const Array<double> &L2Bot_,
const Vector &op_,
const Vector &x_,
Vector &y_)
static void PAHdivL2Apply2D(const int D1D,
const int Q1D,
const int L2D1D,
const int NE,
const Array<double> &Bo_,
const Array<double> &Gc_,
const Array<double> &L2Bot_,
const Vector &op_,
const Vector &x_,
Vector &y_)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = HDIV_MAX_D1D;
@@ -1494,16 +1494,16 @@ void PAHdivL2Apply2D(const int D1D,
}); // end of element loop
}
void PAHdivL2ApplyTranspose3D(const int D1D,
const int Q1D,
const int L2D1D,
const int NE,
const Array<double> &L2Bo_,
const Array<double> &Gct_,
const Array<double> &Bot_,
const Vector &op_,
const Vector &x_,
Vector &y_)
static void PAHdivL2ApplyTranspose3D(const int D1D,
const int Q1D,
const int L2D1D,
const int NE,
const Array<double> &L2Bo_,
const Array<double> &Gct_,
const Array<double> &Bot_,
const Vector &op_,
const Vector &x_,
Vector &y_)
{
MFEM_VERIFY(D1D <= HDIV_MAX_D1D, "Error: D1D > HDIV_MAX_D1D");
MFEM_VERIFY(Q1D <= HDIV_MAX_Q1D, "Error: Q1D > HDIV_MAX_Q1D");
@@ -1656,16 +1656,16 @@ void PAHdivL2ApplyTranspose3D(const int D1D,
}); // end of element loop
}
void PAHdivL2ApplyTranspose2D(const int D1D,
const int Q1D,
const int L2D1D,
const int NE,
const Array<double> &L2Bo_,
const Array<double> &Gct_,
const Array<double> &Bot_,
const Vector &op_,
const Vector &x_,
Vector &y_)
static void PAHdivL2ApplyTranspose2D(const int D1D,
const int Q1D,
const int L2D1D,
const int NE,
const Array<double> &L2Bo_,
const Array<double> &Gct_,
const Array<double> &Bot_,
const Vector &op_,
const Vector &x_,
Vector &y_)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = HDIV_MAX_D1D;
@@ -1791,16 +1791,16 @@ void VectorFEDivergenceIntegrator::AddMultTransposePA(const Vector &x,
}
}
void PAHdivL2AssembleDiagonal_ADAt_3D(const int D1D,
const int Q1D,
const int L2D1D,
const int NE,
const Array<double> &L2Bo_,
const Array<double> &Gct_,
const Array<double> &Bot_,
const Vector &op_,
const Vector &D_,
Vector &diag_)
static void PAHdivL2AssembleDiagonal_ADAt_3D(const int D1D,
const int Q1D,
const int L2D1D,
const int NE,
const Array<double> &L2Bo_,
const Array<double> &Gct_,
const Array<double> &Bot_,
const Vector &op_,
const Vector &D_,
Vector &diag_)
{
MFEM_VERIFY(D1D <= HDIV_MAX_D1D, "Error: D1D > HDIV_MAX_D1D");
MFEM_VERIFY(Q1D <= HDIV_MAX_Q1D, "Error: Q1D > HDIV_MAX_Q1D");
@@ -1916,16 +1916,16 @@ void PAHdivL2AssembleDiagonal_ADAt_3D(const int D1D,
}); // end of element loop
}
void PAHdivL2AssembleDiagonal_ADAt_2D(const int D1D,
const int Q1D,
const int L2D1D,
const int NE,
const Array<double> &L2Bo_,
const Array<double> &Gct_,
const Array<double> &Bot_,
const Vector &op_,
const Vector &D_,
Vector &diag_)
static void PAHdivL2AssembleDiagonal_ADAt_2D(const int D1D,
const int Q1D,
const int L2D1D,
const int NE,
const Array<double> &L2Bo_,
const Array<double> &Gct_,
const Array<double> &Bot_,
const Vector &op_,
const Vector &D_,
Vector &diag_)
{
constexpr static int VDIM = 2;
+21 -21
View File
@@ -17,13 +17,13 @@ namespace mfem
{
template<int T_D1D = 0, int T_Q1D = 0>
void EAMassAssemble1D(const int NE,
const Array<double> &basis,
const Vector &padata,
Vector &eadata,
const bool add,
const int d1d = 0,
const int q1d = 0)
static void EAMassAssemble1D(const int NE,
const Array<double> &basis,
const Vector &padata,
Vector &eadata,
const bool add,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -67,13 +67,13 @@ void EAMassAssemble1D(const int NE,
}
template<int T_D1D = 0, int T_Q1D = 0>
void EAMassAssemble2D(const int NE,
const Array<double> &basis,
const Vector &padata,
Vector &eadata,
const bool add,
const int d1d = 0,
const int q1d = 0)
static void EAMassAssemble2D(const int NE,
const Array<double> &basis,
const Vector &padata,
Vector &eadata,
const bool add,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -139,13 +139,13 @@ void EAMassAssemble2D(const int NE,
}
template<int T_D1D = 0, int T_Q1D = 0>
void EAMassAssemble3D(const int NE,
const Array<double> &basis,
const Vector &padata,
Vector &eadata,
const bool add,
const int d1d = 0,
const int q1d = 0)
static void EAMassAssemble3D(const int NE,
const Array<double> &basis,
const Vector &padata,
Vector &eadata,
const bool add,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
+58 -56
View File
@@ -155,12 +155,12 @@ void MassIntegrator::AssemblePA(const FiniteElementSpace &fes)
}
template<int T_D1D = 0, int T_Q1D = 0>
void PAMassAssembleDiagonal2D(const int NE,
const Array<double> &b,
const Vector &d,
Vector &y,
const int d1d = 0,
const int q1d = 0)
static void PAMassAssembleDiagonal2D(const int NE,
const Array<double> &b,
const Vector &d,
Vector &y,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -201,12 +201,12 @@ void PAMassAssembleDiagonal2D(const int NE,
}
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0>
void SmemPAMassAssembleDiagonal2D(const int NE,
const Array<double> &b_,
const Vector &d_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
static void SmemPAMassAssembleDiagonal2D(const int NE,
const Array<double> &b_,
const Vector &d_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -267,12 +267,12 @@ void SmemPAMassAssembleDiagonal2D(const int NE,
}
template<int T_D1D = 0, int T_Q1D = 0>
void PAMassAssembleDiagonal3D(const int NE,
const Array<double> &b,
const Vector &d,
Vector &y,
const int d1d = 0,
const int q1d = 0)
static void PAMassAssembleDiagonal3D(const int NE,
const Array<double> &b,
const Vector &d,
Vector &y,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -336,12 +336,12 @@ void PAMassAssembleDiagonal3D(const int NE,
}
template<int T_D1D = 0, int T_Q1D = 0>
void SmemPAMassAssembleDiagonal3D(const int NE,
const Array<double> &b_,
const Vector &d_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
static void SmemPAMassAssembleDiagonal3D(const int NE,
const Array<double> &b_,
const Vector &d_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -569,14 +569,14 @@ static void OccaPAMassApply3D(const int D1D,
#endif // MFEM_USE_OCCA
template<int T_D1D = 0, int T_Q1D = 0>
void PAMassApply2D(const int NE,
const Array<double> &b_,
const Array<double> &bt_,
const Vector &d_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
static void PAMassApply2D(const int NE,
const Array<double> &b_,
const Array<double> &bt_,
const Vector &d_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -661,14 +661,14 @@ void PAMassApply2D(const int NE,
}
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0>
void SmemPAMassApply2D(const int NE,
const Array<double> &b_,
const Array<double> &bt_,
const Vector &d_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
static void SmemPAMassApply2D(const int NE,
const Array<double> &b_,
const Array<double> &bt_,
const Vector &d_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
{
MFEM_CONTRACT_VAR(bt_);
const int D1D = T_D1D ? T_D1D : d1d;
@@ -784,14 +784,14 @@ void SmemPAMassApply2D(const int NE,
}
template<int T_D1D = 0, int T_Q1D = 0>
void PAMassApply3D(const int NE,
const Array<double> &b_,
const Array<double> &bt_,
const Vector &d_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
static void PAMassApply3D(const int NE,
const Array<double> &b_,
const Array<double> &bt_,
const Vector &d_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -925,14 +925,14 @@ void PAMassApply3D(const int NE,
}
template<int T_D1D = 0, int T_Q1D = 0>
void SmemPAMassApply3D(const int NE,
const Array<double> &b_,
const Array<double> &bt_,
const Vector &d_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
static void SmemPAMassApply3D(const int NE,
const Array<double> &b_,
const Array<double> &bt_,
const Vector &d_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
{
MFEM_CONTRACT_VAR(bt_);
const int D1D = T_D1D ? T_D1D : d1d;
@@ -1203,8 +1203,10 @@ static void PAMassApply(const int dim,
{
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);
+28 -28
View File
@@ -22,12 +22,12 @@ namespace mfem
// PA Vector Diffusion Integrator
// PA Diffusion Assemble 2D kernel
void PAVectorDiffusionSetup2D(const int Q1D,
const int NE,
const Array<double> &w,
const Vector &j,
const Vector &c,
Vector &op)
static void PAVectorDiffusionSetup2D(const int Q1D,
const int NE,
const Array<double> &w,
const Vector &j,
const Vector &c,
Vector &op)
{
const int NQ = Q1D*Q1D;
auto W = w.Read();
@@ -59,12 +59,12 @@ void PAVectorDiffusionSetup2D(const int Q1D,
}
// PA Diffusion Assemble 3D kernel
void PAVectorDiffusionSetup3D(const int Q1D,
const int NE,
const Array<double> &w,
const Vector &j,
const Vector &c,
Vector &op)
static void PAVectorDiffusionSetup3D(const int Q1D,
const int NE,
const Array<double> &w,
const Vector &j,
const Vector &c,
Vector &op)
{
const int NQ = Q1D*Q1D*Q1D;
auto W = w.Read();
@@ -251,7 +251,7 @@ void VectorDiffusionIntegrator::AssemblePA(const FiniteElementSpace &fes)
}
// PA Diffusion Apply 2D kernel
template<int T_D1D = 0, int T_Q1D = 0, int T_VDIM = 0>
template<int T_D1D = 0, int T_Q1D = 0, int T_VDIM = 0> static
void PAVectorDiffusionApply2D(const int NE,
const Array<double> &b,
const Array<double> &g,
@@ -374,7 +374,7 @@ void PAVectorDiffusionApply2D(const int NE,
// PA Diffusion Apply 3D kernel
template<const int T_D1D = 0,
const int T_Q1D = 0>
const int T_Q1D = 0> static
void PAVectorDiffusionApply3D(const int NE,
const Array<double> &b,
const Array<double> &g,
@@ -606,13 +606,13 @@ void VectorDiffusionIntegrator::AddMultPA(const Vector &x, Vector &y) const
}
template<int T_D1D = 0, int T_Q1D = 0>
void PAVectorDiffusionDiagonal2D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Vector &d,
Vector &y,
const int d1d = 0,
const int q1d = 0)
static void PAVectorDiffusionDiagonal2D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Vector &d,
Vector &y,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -673,13 +673,13 @@ void PAVectorDiffusionDiagonal2D(const int NE,
}
template<int T_D1D = 0, int T_Q1D = 0>
void PAVectorDiffusionDiagonal3D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Vector &d,
Vector &y,
const int d1d = 0,
const int q1d = 0)
static void PAVectorDiffusionDiagonal3D(const int NE,
const Array<double> &b,
const Array<double> &g,
const Vector &d,
Vector &y,
const int d1d = 0,
const int q1d = 0)
{
constexpr int DIM = 3;
const int D1D = T_D1D ? T_D1D : d1d;
+30 -30
View File
@@ -104,14 +104,14 @@ void VectorMassIntegrator::AssemblePA(const FiniteElementSpace &fes)
template<const int T_D1D = 0,
const int T_Q1D = 0>
void PAVectorMassApply2D(const int NE,
const Array<double> &B_,
const Array<double> &Bt_,
const Vector &op_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
static void PAVectorMassApply2D(const int NE,
const Array<double> &B_,
const Array<double> &Bt_,
const Vector &op_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -201,14 +201,14 @@ void PAVectorMassApply2D(const int NE,
template<const int T_D1D = 0,
const int T_Q1D = 0>
void PAVectorMassApply3D(const int NE,
const Array<double> &B_,
const Array<double> &Bt_,
const Vector &op_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
static void PAVectorMassApply3D(const int NE,
const Array<double> &B_,
const Array<double> &Bt_,
const Vector &op_,
const Vector &x_,
Vector &y_,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -379,13 +379,13 @@ void VectorMassIntegrator::AddMultPA(const Vector &x, Vector &y) const
}
template<const int T_D1D = 0, const int T_Q1D = 0>
void PAVectorMassAssembleDiagonal2D(const int NE,
const Array<double> &B_,
const Array<double> &Bt_,
const Vector &op_,
Vector &diag_,
const int d1d = 0,
const int q1d = 0)
static void PAVectorMassAssembleDiagonal2D(const int NE,
const Array<double> &B_,
const Array<double> &Bt_,
const Vector &op_,
Vector &diag_,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -431,13 +431,13 @@ void PAVectorMassAssembleDiagonal2D(const int NE,
}
template<const int T_D1D = 0, const int T_Q1D = 0>
void PAVectorMassAssembleDiagonal3D(const int NE,
const Array<double> &B_,
const Array<double> &Bt_,
const Vector &op_,
Vector &diag_,
const int d1d = 0,
const int q1d = 0)
static void PAVectorMassAssembleDiagonal3D(const int NE,
const Array<double> &B_,
const Array<double> &Bt_,
const Vector &op_,
Vector &diag_,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
+46 -46
View File
@@ -178,10 +178,10 @@ int CeedATPMGElemRestriction(int order,
{
left_in_edof = i*P1d + 0;
right_in_edof = i*P1d + (P1d - 1);
left_in_ldof = in_elem_dof[left_in_edof*in_layout[0]
+ e*in_layout[2]] + rounding_guard;
right_in_ldof = in_elem_dof[right_in_edof*in_layout[0]
+ e*in_layout[2]] + rounding_guard;
left_in_ldof = in_elem_dof[left_in_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
right_in_ldof = in_elem_dof[right_in_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
coarse_i = coarse_1d_edof(i, P1d, coarse_P1d);
coarse_j = (left_in_ldof < right_in_ldof) ?
coarse_1d_edof(j, P1d, coarse_P1d) : reverse_coarse_1d_edof(j, P1d, coarse_P1d);
@@ -190,10 +190,10 @@ int CeedATPMGElemRestriction(int order,
{
left_in_edof = 0*P1d + j;
right_in_edof = (P1d - 1)*P1d + j;
left_in_ldof = in_elem_dof[left_in_edof*in_layout[0]
+ e*in_layout[2]] + rounding_guard;
right_in_ldof = in_elem_dof[right_in_edof*in_layout[0]
+ e*in_layout[2]] + rounding_guard;
left_in_ldof = in_elem_dof[left_in_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
right_in_ldof = in_elem_dof[right_in_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
coarse_i = (left_in_ldof < right_in_ldof) ?
coarse_1d_edof(i, P1d, coarse_P1d) : reverse_coarse_1d_edof(i, P1d, coarse_P1d);
coarse_j = coarse_1d_edof(j, P1d, coarse_P1d);
@@ -234,8 +234,8 @@ int CeedATPMGElemRestriction(int order,
// Determine topology; is this edof on the outside of the element
// in the i, j, or k direction?
int in_edof = i*P1d*P1d + j*P1d + k;
int in_ldof = in_elem_dof[in_edof*in_layout[0] +
e*in_layout[2]] + rounding_guard;
int in_ldof = in_elem_dof[in_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
bool i_edge = (i == 0 || i == P1d - 1);
bool j_edge = (j == 0 || j == P1d - 1);
bool k_edge = (k == 0 || k == P1d - 1);
@@ -265,10 +265,10 @@ int CeedATPMGElemRestriction(int order,
{
left_in_edof = 0*P1d*P1d + j*P1d + k;
right_in_edof = (P1d - 1)*P1d*P1d + j*P1d + k;
left_in_ldof = in_elem_dof[left_in_edof*in_layout[0] +
e*in_layout[2]] + rounding_guard;
right_in_ldof = in_elem_dof[right_in_edof*in_layout[0] +
e*in_layout[2]] + rounding_guard;
left_in_ldof = in_elem_dof[left_in_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
right_in_ldof = in_elem_dof[right_in_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
coarse_i = (left_in_ldof < right_in_ldof) ?
coarse_1d_edof(i, P1d, coarse_P1d) : reverse_coarse_1d_edof(i, P1d, coarse_P1d);
coarse_j = coarse_1d_edof(j, P1d, coarse_P1d);
@@ -278,10 +278,10 @@ int CeedATPMGElemRestriction(int order,
{
left_in_edof = i*P1d*P1d + 0*P1d + k;
right_in_edof = i*P1d*P1d + (P1d - 1)*P1d + k;
left_in_ldof = in_elem_dof[left_in_edof*in_layout[0] +
e*in_layout[2]] + rounding_guard;
right_in_ldof = in_elem_dof[right_in_edof*in_layout[0] +
e*in_layout[2]] + rounding_guard;
left_in_ldof = in_elem_dof[left_in_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
right_in_ldof = in_elem_dof[right_in_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
coarse_i = coarse_1d_edof(i, P1d, coarse_P1d);
coarse_j = (left_in_ldof < right_in_ldof) ?
coarse_1d_edof(j, P1d, coarse_P1d) : reverse_coarse_1d_edof(j, P1d, coarse_P1d);
@@ -296,10 +296,10 @@ int CeedATPMGElemRestriction(int order,
}
left_in_edof = i*P1d*P1d + j*P1d + 0;
right_in_edof = i*P1d*P1d + j*P1d + (P1d - 1);
left_in_ldof = in_elem_dof[left_in_edof*in_layout[0] +
e*in_layout[2]] + rounding_guard;
right_in_ldof = in_elem_dof[right_in_edof*in_layout[0] +
e*in_layout[2]] + rounding_guard;
left_in_ldof = in_elem_dof[left_in_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
right_in_ldof = in_elem_dof[right_in_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
coarse_i = coarse_1d_edof(i, P1d, coarse_P1d);
coarse_j = coarse_1d_edof(j, P1d, coarse_P1d);
coarse_k = (left_in_ldof < right_in_ldof) ?
@@ -323,14 +323,14 @@ int CeedATPMGElemRestriction(int order,
bottom_right_edof = i*P1d*P1d + 0*P1d + (P1d - 1);
top_right_edof = i*P1d*P1d + (P1d - 1)*P1d + (P1d - 1);
top_left_edof = i*P1d*P1d + (P1d - 1)*P1d + 0;
bottom_left_ldof = in_elem_dof[bottom_left_edof*in_layout[0] +
e*in_layout[2]] + rounding_guard;
bottom_right_ldof = in_elem_dof[bottom_right_edof*in_layout[0] +
e*in_layout[2]] + rounding_guard;
top_right_ldof = in_elem_dof[top_right_edof*in_layout[0] +
e*in_layout[2]] + rounding_guard;
top_left_ldof = in_elem_dof[top_left_edof*in_layout[0] +
e*in_layout[2]] + rounding_guard;
bottom_left_ldof = in_elem_dof[bottom_left_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
bottom_right_ldof = in_elem_dof[bottom_right_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
top_right_ldof = in_elem_dof[top_right_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
top_left_ldof = in_elem_dof[top_left_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
int m = min4(bottom_left_ldof, bottom_right_ldof, top_right_ldof,
top_left_ldof);
coarse_i = coarse_1d_edof(i, P1d, coarse_P1d);
@@ -361,14 +361,14 @@ int CeedATPMGElemRestriction(int order,
bottom_right_edof = 0*P1d*P1d + j*P1d + (P1d - 1);
top_right_edof = (P1d - 1)*P1d*P1d + j*P1d + (P1d - 1);
top_left_edof = (P1d - 1)*P1d*P1d + j*P1d + 0;
bottom_left_ldof = in_elem_dof[bottom_left_edof*in_layout[0] +
e*in_layout[2]] + rounding_guard;
bottom_right_ldof = in_elem_dof[bottom_right_edof*in_layout[0] +
e*in_layout[2]] + rounding_guard;
top_right_ldof = in_elem_dof[top_right_edof*in_layout[0] +
e*in_layout[2]] + rounding_guard;
top_left_ldof = in_elem_dof[top_left_edof*in_layout[0] +
e*in_layout[2]] + rounding_guard;
bottom_left_ldof = in_elem_dof[bottom_left_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
bottom_right_ldof = in_elem_dof[bottom_right_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
top_right_ldof = in_elem_dof[top_right_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
top_left_ldof = in_elem_dof[top_left_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
int m = min4(bottom_left_ldof, bottom_right_ldof, top_right_ldof,
top_left_ldof);
coarse_j = coarse_1d_edof(j, P1d, coarse_P1d);
@@ -404,14 +404,14 @@ int CeedATPMGElemRestriction(int order,
bottom_right_edof = 0*P1d*P1d + (P1d - 1)*P1d + k;
top_right_edof = (P1d - 1)*P1d*P1d + (P1d - 1)*P1d + k;
top_left_edof = (P1d - 1)*P1d*P1d + 0*P1d + k;
bottom_left_ldof = in_elem_dof[bottom_left_edof*in_layout[0] +
e*in_layout[2]] + rounding_guard;
bottom_right_ldof = in_elem_dof[bottom_right_edof*in_layout[0] +
e*in_layout[2]] + rounding_guard;
top_right_ldof = in_elem_dof[top_right_edof*in_layout[0] +
e*in_layout[2]] + rounding_guard;
top_left_ldof = in_elem_dof[top_left_edof*in_layout[0] +
e*in_layout[2]] + rounding_guard;
bottom_left_ldof = in_elem_dof[bottom_left_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
bottom_right_ldof = in_elem_dof[bottom_right_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
top_right_ldof = in_elem_dof[top_right_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
top_left_ldof = in_elem_dof[top_left_edof*in_layout[0]+e*in_layout[2]]
+ rounding_guard;
int m = min4(bottom_left_ldof, bottom_right_ldof,
top_right_ldof, top_left_ldof);
coarse_k = coarse_1d_edof(k, P1d, coarse_P1d);
+7 -3
View File
@@ -186,14 +186,18 @@ static void InitTensorBasis(const mfem::FiniteElementSpace &fes,
const int ndofs = maps.ndof;
const int nqpts = maps.nqpt;
mfem::Vector qX(nqpts), qW(nqpts);
const mfem::IntegrationRule &ir1d =
IntRules.Get(Geometry::SEGMENT, ir.GetOrder());
// The x-coordinates of the first `nqpts` points of the integration rule are
// the points of the corresponding 1D rule. We also scale the weights
// accordingly.
double w_sum = 0.0;
for (int i = 0; i < nqpts; i++)
{
const mfem::IntegrationPoint &ip = ir1d.IntPoint(i);
const mfem::IntegrationPoint &ip = ir.IntPoint(i);
qX(i) = ip.x;
qW(i) = ip.weight;
w_sum += ip.weight;
}
qW *= 1.0/w_sum;
CeedBasisCreateTensorH1(ceed, mesh->Dimension(), fes.GetVDim(), ndofs,
nqpts, maps.Bt.GetData(),
maps.Gt.GetData(), qX.GetData(),
+191
View File
@@ -52,6 +52,13 @@ double GridFunctionCoefficient::Eval (ElementTransformation &T,
return GridF -> GetValue (T, ip, Component);
}
void TransformedCoefficient::SetTime(double t)
{
if (Q1) { Q1->SetTime(t); }
if (Q2) { Q2->SetTime(t); }
this->Coefficient::SetTime(t);
}
double TransformedCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip)
{
@@ -66,6 +73,12 @@ double TransformedCoefficient::Eval(ElementTransformation &T,
}
}
void DeltaCoefficient::SetTime(double t)
{
if (weight) { weight->SetTime(t); }
this->Coefficient::SetTime(t);
}
void DeltaCoefficient::SetDeltaCenter(const Vector& vcenter)
{
MFEM_VERIFY(vcenter.Size() <= 3,
@@ -87,6 +100,12 @@ double DeltaCoefficient::EvalDelta(ElementTransformation &T,
return weight ? weight->Eval(T, ip, GetTime())*w : w;
}
void RestrictedCoefficient::SetTime(double t)
{
if (c) { c->SetTime(t); }
this->Coefficient::SetTime(t);
}
void VectorCoefficient::Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationRule &ir)
{
@@ -134,6 +153,15 @@ VectorArrayCoefficient::VectorArrayCoefficient (int dim)
}
}
void VectorArrayCoefficient::SetTime(double t)
{
for (int i = 0; i < vdim; i++)
{
if (Coeff[i]) { Coeff[i]->SetTime(t); }
}
this->VectorCoefficient::SetTime(t);
}
void VectorArrayCoefficient::Set(int i, Coefficient *c, bool own)
{
if (ownCoeff[i]) { delete Coeff[i]; }
@@ -247,6 +275,12 @@ double DivergenceGridFunctionCoefficient::Eval(ElementTransformation &T,
return GridFunc->GetDivergence(T);
}
void VectorDeltaCoefficient::SetTime(double t)
{
d.SetTime(t);
this->VectorCoefficient::SetTime(t);
}
void VectorDeltaCoefficient::SetDirection(const Vector &d_)
{
dir = d_;
@@ -261,6 +295,12 @@ void VectorDeltaCoefficient::EvalDelta(
V *= d.EvalDelta(T, ip);
}
void VectorRestrictedCoefficient::SetTime(double t)
{
if (c) { c->SetTime(t); }
this->VectorCoefficient::SetTime(t);
}
void VectorRestrictedCoefficient::Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip)
{
@@ -291,6 +331,12 @@ void VectorRestrictedCoefficient::Eval(
}
}
void MatrixFunctionCoefficient::SetTime(double t)
{
if (Q) { Q->SetTime(t); }
this->MatrixCoefficient::SetTime(t);
}
void MatrixFunctionCoefficient::Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip)
{
@@ -371,6 +417,12 @@ void MatrixFunctionCoefficient::EvalSymmetric(Vector &K,
}
}
void SymmetricMatrixFunctionCoefficient::SetTime(double t)
{
if (Q) { Q->SetTime(t); }
this->SymmetricMatrixCoefficient::SetTime(t);
}
void SymmetricMatrixFunctionCoefficient::Eval(DenseSymmetricMatrix &K,
ElementTransformation &T,
const IntegrationPoint &ip)
@@ -413,6 +465,15 @@ MatrixArrayCoefficient::MatrixArrayCoefficient (int dim)
}
}
void MatrixArrayCoefficient::SetTime(double t)
{
for (int i=0; i < height*width; i++)
{
if (Coeff[i]) { Coeff[i]->SetTime(t); }
}
this->MatrixCoefficient::SetTime(t);
}
void MatrixArrayCoefficient::Set(int i, int j, Coefficient * c, bool own)
{
if (ownCoeff[i*width+j]) { delete Coeff[i*width+j]; }
@@ -431,6 +492,7 @@ MatrixArrayCoefficient::~MatrixArrayCoefficient ()
void MatrixArrayCoefficient::Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip)
{
K.SetSize(height, width);
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
@@ -440,6 +502,12 @@ void MatrixArrayCoefficient::Eval(DenseMatrix &K, ElementTransformation &T,
}
}
void MatrixRestrictedCoefficient::SetTime(double t)
{
if (c) { c->SetTime(t); }
this->MatrixCoefficient::SetTime(t);
}
void MatrixRestrictedCoefficient::Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip)
{
@@ -455,6 +523,33 @@ void MatrixRestrictedCoefficient::Eval(DenseMatrix &K, ElementTransformation &T,
}
}
void SumCoefficient::SetTime(double t)
{
if (a) { a->SetTime(t); }
if (b) { b->SetTime(t); }
this->Coefficient::SetTime(t);
}
void ProductCoefficient::SetTime(double t)
{
if (a) { a->SetTime(t); }
if (b) { b->SetTime(t); }
this->Coefficient::SetTime(t);
}
void RatioCoefficient::SetTime(double t)
{
if (a) { a->SetTime(t); }
if (b) { b->SetTime(t); }
this->Coefficient::SetTime(t);
}
void PowerCoefficient::SetTime(double t)
{
if (a) { a->SetTime(t); }
this->Coefficient::SetTime(t);
}
InnerProductCoefficient::InnerProductCoefficient(VectorCoefficient &A,
VectorCoefficient &B)
: a(&A), b(&B)
@@ -464,6 +559,13 @@ InnerProductCoefficient::InnerProductCoefficient(VectorCoefficient &A,
"Arguments have incompatible dimensions.");
}
void InnerProductCoefficient::SetTime(double t)
{
if (a) { a->SetTime(t); }
if (b) { b->SetTime(t); }
this->Coefficient::SetTime(t);
}
double InnerProductCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip)
{
@@ -481,6 +583,13 @@ VectorRotProductCoefficient::VectorRotProductCoefficient(VectorCoefficient &A,
"Arguments must have dimension equal to two.");
}
void VectorRotProductCoefficient::SetTime(double t)
{
if (a) { a->SetTime(t); }
if (b) { b->SetTime(t); }
this->Coefficient::SetTime(t);
}
double VectorRotProductCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip)
{
@@ -497,6 +606,12 @@ DeterminantCoefficient::DeterminantCoefficient(MatrixCoefficient &A)
"Argument must be a square matrix.");
}
void DeterminantCoefficient::SetTime(double t)
{
if (a) { a->SetTime(t); }
this->Coefficient::SetTime(t);
}
double DeterminantCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip)
{
@@ -545,6 +660,15 @@ VectorSumCoefficient::VectorSumCoefficient(VectorCoefficient &A_,
"Arguments must have the same dimension.");
}
void VectorSumCoefficient::SetTime(double t)
{
if (ACoef) { ACoef->SetTime(t); }
if (BCoef) { BCoef->SetTime(t); }
if (alphaCoef) { alphaCoef->SetTime(t); }
if (betaCoef) { betaCoef->SetTime(t); }
this->VectorCoefficient::SetTime(t);
}
void VectorSumCoefficient::Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip)
{
@@ -568,6 +692,13 @@ ScalarVectorProductCoefficient::ScalarVectorProductCoefficient(
: VectorCoefficient(B.GetVDim()), aConst(0.0), a(&A), b(&B)
{}
void ScalarVectorProductCoefficient::SetTime(double t)
{
if (a) { a->SetTime(t); }
if (b) { b->SetTime(t); }
this->VectorCoefficient::SetTime(t);
}
void ScalarVectorProductCoefficient::Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip)
{
@@ -581,6 +712,12 @@ NormalizedVectorCoefficient::NormalizedVectorCoefficient(VectorCoefficient &A,
: VectorCoefficient(A.GetVDim()), a(&A), tol(tol_)
{}
void NormalizedVectorCoefficient::SetTime(double t)
{
if (a) { a->SetTime(t); }
this->VectorCoefficient::SetTime(t);
}
void NormalizedVectorCoefficient::Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip)
{
@@ -599,6 +736,13 @@ VectorCrossProductCoefficient::VectorCrossProductCoefficient(
"Arguments must have dimension equal to three.");
}
void VectorCrossProductCoefficient::SetTime(double t)
{
if (a) { a->SetTime(t); }
if (b) { b->SetTime(t); }
this->VectorCoefficient::SetTime(t);
}
void VectorCrossProductCoefficient::Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip)
{
@@ -620,6 +764,13 @@ MatrixVectorProductCoefficient::MatrixVectorProductCoefficient(
"Arguments have incompatible dimensions.");
}
void MatrixVectorProductCoefficient::SetTime(double t)
{
if (a) { a->SetTime(t); }
if (b) { b->SetTime(t); }
this->VectorCoefficient::SetTime(t);
}
void MatrixVectorProductCoefficient::Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip)
{
@@ -649,6 +800,13 @@ MatrixSumCoefficient::MatrixSumCoefficient(MatrixCoefficient &A,
"Arguments must have the same dimensions.");
}
void MatrixSumCoefficient::SetTime(double t)
{
if (a) { a->SetTime(t); }
if (b) { b->SetTime(t); }
this->MatrixCoefficient::SetTime(t);
}
void MatrixSumCoefficient::Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip)
{
@@ -670,6 +828,13 @@ ScalarMatrixProductCoefficient::ScalarMatrixProductCoefficient(
: MatrixCoefficient(B.GetHeight(), B.GetWidth()), aConst(0.0), a(&A), b(&B)
{}
void ScalarMatrixProductCoefficient::SetTime(double t)
{
if (a) { a->SetTime(t); }
if (b) { b->SetTime(t); }
this->MatrixCoefficient::SetTime(t);
}
void ScalarMatrixProductCoefficient::Eval(DenseMatrix &M,
ElementTransformation &T,
const IntegrationPoint &ip)
@@ -683,6 +848,12 @@ TransposeMatrixCoefficient::TransposeMatrixCoefficient(MatrixCoefficient &A)
: MatrixCoefficient(A.GetWidth(), A.GetHeight()), a(&A)
{}
void TransposeMatrixCoefficient::SetTime(double t)
{
if (a) { a->SetTime(t); }
this->MatrixCoefficient::SetTime(t);
}
void TransposeMatrixCoefficient::Eval(DenseMatrix &M,
ElementTransformation &T,
const IntegrationPoint &ip)
@@ -699,6 +870,12 @@ InverseMatrixCoefficient::InverseMatrixCoefficient(MatrixCoefficient &A)
"Argument must be a square matrix.");
}
void InverseMatrixCoefficient::SetTime(double t)
{
if (a) { a->SetTime(t); }
this->MatrixCoefficient::SetTime(t);
}
void InverseMatrixCoefficient::Eval(DenseMatrix &M,
ElementTransformation &T,
const IntegrationPoint &ip)
@@ -713,6 +890,13 @@ OuterProductCoefficient::OuterProductCoefficient(VectorCoefficient &A,
va(A.GetVDim()), vb(B.GetVDim())
{}
void OuterProductCoefficient::SetTime(double t)
{
if (a) { a->SetTime(t); }
if (b) { b->SetTime(t); }
this->MatrixCoefficient::SetTime(t);
}
void OuterProductCoefficient::Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip)
{
@@ -739,6 +923,13 @@ CrossCrossCoefficient::CrossCrossCoefficient(Coefficient &A,
vk(K.GetVDim())
{}
void CrossCrossCoefficient::SetTime(double t)
{
if (a) { a->SetTime(t); }
if (k) { k->SetTime(t); }
this->MatrixCoefficient::SetTime(t);
}
void CrossCrossCoefficient::Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip)
{
+88 -4
View File
@@ -45,7 +45,7 @@ public:
Coefficient() { time = 0.; }
/// Set the time for time dependent coefficients
void SetTime(double t) { time = t; }
virtual void SetTime(double t) { time = t; }
/// Get the time for time dependent coefficients
double GetTime() { return time; }
@@ -217,6 +217,9 @@ public:
double (*F)(double,double))
: Q1(q1), Q2(q2), Transform2(F) { Transform1 = 0; }
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Evaluate the coefficient at @a ip.
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip);
};
@@ -269,6 +272,9 @@ public:
weight = NULL; sdim = 3; tdf = NULL;
}
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Set the center location of the delta function.
void SetDeltaCenter(const Vector& center);
@@ -333,6 +339,9 @@ public:
RestrictedCoefficient(Coefficient &c_, Array<int> &attr)
{ c = &c_; attr.Copy(active_attr); }
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Evaluate the coefficient at @a ip.
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip)
{ return active_attr[T.Attribute-1] ? c->Eval(T, ip, GetTime()) : 0.0; }
@@ -350,7 +359,7 @@ public:
VectorCoefficient(int vd) { vdim = vd; time = 0.; }
/// Set the time for time dependent coefficients
void SetTime(double t) { time = t; }
virtual void SetTime(double t) { time = t; }
/// Get the time for time dependent coefficients
double GetTime() { return time; }
@@ -456,6 +465,9 @@ public:
still need to be added with Set(). */
explicit VectorArrayCoefficient(int dim);
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Returns i'th coefficient.
Coefficient* GetCoeff(int i) { return Coeff[i]; }
@@ -632,6 +644,9 @@ public:
double s)
: VectorCoefficient(dir_.Size()), dir(dir_), d(x,y,z,s) { }
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Replace the associated DeltaCoefficient with a new DeltaCoefficient.
/** The new DeltaCoefficient cannot have a specified weight Coefficient, i.e.
DeltaCoefficient::Weight() should return NULL. */
@@ -677,6 +692,9 @@ public:
: VectorCoefficient(vc.GetVDim())
{ c = &vc; attr.Copy(active_attr); }
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Evaluate the vector coefficient at @a ip.
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
@@ -708,7 +726,7 @@ public:
height(h), width(w), time(0.), symmetric(symm) { }
/// Set the time for time dependent coefficients
void SetTime(double t) { time = t; }
virtual void SetTime(double t) { time = t; }
/// Get the time for time dependent coefficients
double GetTime() { return time; }
@@ -817,6 +835,9 @@ public:
: MatrixCoefficient(dim), TDFunction(std::move(TDF)), Q(q)
{ }
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Evaluate the matrix coefficient at @a ip.
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip);
@@ -844,6 +865,9 @@ public:
actual coefficients still need to be added with Set(). */
explicit MatrixArrayCoefficient (int dim);
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Get the coefficient located at (i,j) in the matrix.
Coefficient* GetCoeff (int i, int j) { return Coeff[i*width+j]; }
@@ -881,6 +905,9 @@ public:
: MatrixCoefficient(mc.GetHeight(), mc.GetWidth())
{ c = &mc; attr.Copy(active_attr); }
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Evaluate the matrix coefficient at @a ip.
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip);
@@ -911,6 +938,9 @@ public:
double alpha_ = 1.0, double beta_ = 1.0)
: aConst(0.0), a(&A), b(&B), alpha(alpha_), beta(beta_) { }
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Reset the first term in the linear combination as a constant
void SetAConst(double A) { a = NULL; aConst = A; }
/// Return the first term in the linear combination
@@ -959,7 +989,7 @@ public:
{ dim = dimension; time = 0.; }
/// Set the time for time dependent coefficients
void SetTime(double t) { time = t; }
virtual void SetTime(double t) { time = t; }
/// Get the time for time dependent coefficients
double GetTime() { return time; }
@@ -1037,6 +1067,9 @@ public:
: SymmetricMatrixCoefficient(dim), TDFunction(std::move(TDF)), Q(q)
{ }
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Evaluate the matrix coefficient at @a ip.
virtual void Eval(DenseSymmetricMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip);
@@ -1063,6 +1096,9 @@ public:
ProductCoefficient(Coefficient &A, Coefficient &B)
: aConst(0.0), a(&A), b(&B) { }
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Reset the first term in the product as a constant
void SetAConst(double A) { a = NULL; aConst = A; }
/// Return the first term in the product
@@ -1108,6 +1144,9 @@ public:
RatioCoefficient(Coefficient &A, double B)
: aConst(0.0), bConst(B), a(&A), b(NULL) { }
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Reset the numerator in the ratio as a constant
void SetAConst(double A) { a = NULL; aConst = A; }
/// Return the numerator of the ratio
@@ -1151,6 +1190,9 @@ public:
PowerCoefficient(Coefficient &A, double p_)
: a(&A), p(p_) { }
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Reset the base coefficient
void SetACoef(Coefficient &A) { a = &A; }
/// Return the base coefficient
@@ -1181,6 +1223,9 @@ public:
/// Construct with the two vector coefficients. Result is \f$ A \cdot B \f$.
InnerProductCoefficient(VectorCoefficient &A, VectorCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Reset the first vector in the inner product
void SetACoef(VectorCoefficient &A) { a = &A; }
/// Return the first vector coefficient in the inner product
@@ -1210,6 +1255,9 @@ public:
/// Constructor with two vector coefficients. Result is \f$ A_x B_y - A_y * B_x; \f$.
VectorRotProductCoefficient(VectorCoefficient &A, VectorCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Reset the first vector in the product
void SetACoef(VectorCoefficient &A) { a = &A; }
/// Return the first vector of the product
@@ -1237,6 +1285,9 @@ public:
/// Construct with the matrix.
DeterminantCoefficient(MatrixCoefficient &A);
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Reset the matrix coefficient
void SetACoef(MatrixCoefficient &A) { a = &A; }
/// Return the matrix coefficient
@@ -1280,6 +1331,9 @@ public:
VectorSumCoefficient(VectorCoefficient &A_, VectorCoefficient &B_,
Coefficient &alpha_, Coefficient &beta_);
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Reset the first vector coefficient
void SetACoef(VectorCoefficient &A) { ACoef = &A; }
/// Return the first vector coefficient
@@ -1341,6 +1395,9 @@ public:
/// Constructor with two coefficients. Result is A * B.
ScalarVectorProductCoefficient(Coefficient &A, VectorCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Reset the scalar factor as a constant
void SetAConst(double A) { a = NULL; aConst = A; }
/// Return the scalar factor
@@ -1379,6 +1436,9 @@ public:
*/
NormalizedVectorCoefficient(VectorCoefficient &A, double tol = 1e-6);
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Reset the vector coefficient
void SetACoef(VectorCoefficient &A) { a = &A; }
/// Return the vector coefficient
@@ -1404,6 +1464,9 @@ public:
/// Construct with the two coefficients. Result is A x B.
VectorCrossProductCoefficient(VectorCoefficient &A, VectorCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Reset the first term in the product
void SetACoef(VectorCoefficient &A) { a = &A; }
/// Return the first term in the product
@@ -1435,6 +1498,9 @@ public:
/// Constructor with two coefficients. Result is A*B.
MatrixVectorProductCoefficient(MatrixCoefficient &A, VectorCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Reset the matrix coefficient
void SetACoef(MatrixCoefficient &A) { a = &A; }
/// Return the matrix coefficient
@@ -1487,6 +1553,9 @@ public:
MatrixSumCoefficient(MatrixCoefficient &A, MatrixCoefficient &B,
double alpha_ = 1.0, double beta_ = 1.0);
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Reset the first matrix coefficient
void SetACoef(MatrixCoefficient &A) { a = &A; }
/// Return the first matrix coefficient
@@ -1528,6 +1597,9 @@ public:
/// Constructor with two coefficients. Result is A*B.
ScalarMatrixProductCoefficient(Coefficient &A, MatrixCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Reset the scalar factor as a constant
void SetAConst(double A) { a = NULL; aConst = A; }
/// Return the scalar factor
@@ -1558,6 +1630,9 @@ public:
/// Construct with the matrix coefficient. Result is \f$ A^T \f$.
TransposeMatrixCoefficient(MatrixCoefficient &A);
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Reset the matrix coefficient
void SetACoef(MatrixCoefficient &A) { a = &A; }
/// Return the matrix coefficient
@@ -1578,6 +1653,9 @@ public:
/// Construct with the matrix coefficient. Result is \f$ A^{-1} \f$.
InverseMatrixCoefficient(MatrixCoefficient &A);
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Reset the matrix coefficient
void SetACoef(MatrixCoefficient &A) { a = &A; }
/// Return the matrix coefficient
@@ -1602,6 +1680,9 @@ public:
/// Construct with two vector coefficients. Result is \f$ A B^T \f$.
OuterProductCoefficient(VectorCoefficient &A, VectorCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Reset the first vector in the outer product
void SetACoef(VectorCoefficient &A) { a = &A; }
/// Return the first vector coefficient in the outer product
@@ -1637,6 +1718,9 @@ public:
CrossCrossCoefficient(double A, VectorCoefficient &K);
CrossCrossCoefficient(Coefficient &A, VectorCoefficient &K);
/// Set the time for internally stored coefficients
void SetTime(double t);
/// Reset the scalar factor as a constant
void SetAConst(double A) { a = NULL; aConst = A; }
/// Return the scalar factor
+34
View File
@@ -195,6 +195,15 @@ ComplexLinearForm::AddDomainIntegrator(LinearFormIntegrator *lfi_real,
if ( lfi_imag ) { lfi->AddDomainIntegrator(lfi_imag); }
}
void
ComplexLinearForm::AddDomainIntegrator(LinearFormIntegrator *lfi_real,
LinearFormIntegrator *lfi_imag,
Array<int> &elem_attr_marker)
{
if ( lfi_real ) { lfr->AddDomainIntegrator(lfi_real, elem_attr_marker); }
if ( lfi_imag ) { lfi->AddDomainIntegrator(lfi_imag, elem_attr_marker); }
}
void
ComplexLinearForm::AddBoundaryIntegrator(LinearFormIntegrator *lfi_real,
LinearFormIntegrator *lfi_imag)
@@ -317,6 +326,14 @@ void SesquilinearForm::AddDomainIntegrator(BilinearFormIntegrator *bfi_real,
if (bfi_imag) { blfi->AddDomainIntegrator(bfi_imag); }
}
void SesquilinearForm::AddDomainIntegrator(BilinearFormIntegrator *bfi_real,
BilinearFormIntegrator *bfi_imag,
Array<int> & elem_marker)
{
if (bfi_real) { blfr->AddDomainIntegrator(bfi_real, elem_marker); }
if (bfi_imag) { blfi->AddDomainIntegrator(bfi_imag, elem_marker); }
}
void
SesquilinearForm::AddBoundaryIntegrator(BilinearFormIntegrator *bfi_real,
BilinearFormIntegrator *bfi_imag)
@@ -879,6 +896,15 @@ ParComplexLinearForm::AddDomainIntegrator(LinearFormIntegrator *lfi_real,
if ( lfi_imag ) { plfi->AddDomainIntegrator(lfi_imag); }
}
void
ParComplexLinearForm::AddDomainIntegrator(LinearFormIntegrator *lfi_real,
LinearFormIntegrator *lfi_imag,
Array<int> &elem_attr_marker)
{
if ( lfi_real ) { plfr->AddDomainIntegrator(lfi_real, elem_attr_marker); }
if ( lfi_imag ) { plfi->AddDomainIntegrator(lfi_imag, elem_attr_marker); }
}
void
ParComplexLinearForm::AddBoundaryIntegrator(LinearFormIntegrator *lfi_real,
LinearFormIntegrator *lfi_imag)
@@ -1040,6 +1066,14 @@ void ParSesquilinearForm::AddDomainIntegrator(BilinearFormIntegrator *bfi_real,
if (bfi_imag) { pblfi->AddDomainIntegrator(bfi_imag); }
}
void ParSesquilinearForm::AddDomainIntegrator(BilinearFormIntegrator *bfi_real,
BilinearFormIntegrator *bfi_imag,
Array<int> & elem_marker)
{
if (bfi_real) { pblfr->AddDomainIntegrator(bfi_real, elem_marker); }
if (bfi_imag) { pblfi->AddDomainIntegrator(bfi_imag, elem_marker); }
}
void
ParSesquilinearForm::AddBoundaryIntegrator(BilinearFormIntegrator *bfi_real,
BilinearFormIntegrator *bfi_imag)
+20
View File
@@ -128,6 +128,11 @@ public:
void AddDomainIntegrator(LinearFormIntegrator *lfi_real,
LinearFormIntegrator *lfi_imag);
/// Adds new Domain Integrator, restricted to the given attributes.
void AddDomainIntegrator(LinearFormIntegrator *lfi_real,
LinearFormIntegrator *lfi_imag,
Array<int> &elem_attr_marker);
/// Adds new Boundary Integrator.
void AddBoundaryIntegrator(LinearFormIntegrator *lfi_real,
LinearFormIntegrator *lfi_imag);
@@ -260,6 +265,11 @@ public:
void AddDomainIntegrator(BilinearFormIntegrator *bfi_real,
BilinearFormIntegrator *bfi_imag);
/// Adds new Domain Integrator, restricted to the given attributes.
void AddDomainIntegrator(BilinearFormIntegrator *bfi_real,
BilinearFormIntegrator *bfi_imag,
Array<int> &elem_marker);
/// Adds new Boundary Integrator.
void AddBoundaryIntegrator(BilinearFormIntegrator *bfi_real,
BilinearFormIntegrator *bfi_imag);
@@ -464,6 +474,11 @@ public:
void AddDomainIntegrator(LinearFormIntegrator *lfi_real,
LinearFormIntegrator *lfi_imag);
/// Adds new Domain Integrator, restricted to specific attributes.
void AddDomainIntegrator(LinearFormIntegrator *lfi_real,
LinearFormIntegrator *lfi_imag,
Array<int> &elem_attr_marker);
/// Adds new Boundary Integrator.
void AddBoundaryIntegrator(LinearFormIntegrator *lfi_real,
LinearFormIntegrator *lfi_imag);
@@ -598,6 +613,11 @@ public:
void AddDomainIntegrator(BilinearFormIntegrator *bfi_real,
BilinearFormIntegrator *bfi_imag);
/// Adds new Domain Integrator, restricted to specific attributes.
void AddDomainIntegrator(BilinearFormIntegrator *bfi_real,
BilinearFormIntegrator *bfi_imag,
Array<int> &elem_marker);
/// Adds new Boundary Integrator.
void AddBoundaryIntegrator(BilinearFormIntegrator *bfi_real,
BilinearFormIntegrator *bfi_imag);
+79 -1
View File
@@ -645,7 +645,8 @@ ConduitDataCollection::MeshToBlueprintMesh(Mesh *mesh,
Node &n_mesh,
const std::string &coordset_name,
const std::string &main_topology_name,
const std::string &boundary_topology_name)
const std::string &boundary_topology_name,
const std::string &main_adjset_name)
{
int dim = mesh->SpaceDimension();
@@ -815,6 +816,83 @@ ConduitDataCollection::MeshToBlueprintMesh(Mesh *mesh,
bndry_att_vals[i] = mesh->GetBdrAttribute(i);
}
}
////////////////////////////////////////////
// Setup adjsets
////////////////////////////////////////////
#ifdef MFEM_USE_MPI
ParMesh *pmesh = dynamic_cast<ParMesh*>(mesh);
if (pmesh)
{
////////////////////////////////////////////
// Setup main adjset
////////////////////////////////////////////
Node &n_adjset = n_mesh["adjsets"][main_adjset_name];
n_adjset["association"] = "vertex";
n_adjset["topology"] = main_topology_name;
n_adjset["groups"].set(DataType::object());
const GroupTopology &pmesh_gtopo = pmesh->gtopo;
const int local_rank = pmesh->GetMyRank();
const int num_groups = pmesh_gtopo.NGroups();
// NOTE: skip the first group since its the local-only group
for (int i = 1; i < num_groups; i++)
{
const int num_group_nbrs = pmesh_gtopo.GetGroupSize(i);
const int *group_nbrs = pmesh_gtopo.GetGroup(i);
const int num_group_verts = pmesh->GroupNVertices(i);
// NOTE: 'neighbor' values are local to this processor, but Blueprint
// expects global domain identifiers, so we collapse this layer of
// indirection
Array<int> group_ranks(num_group_nbrs);
std::string group_name = "group";
{
for (int j = 0; j < num_group_nbrs; j++)
{
group_ranks[j] = pmesh_gtopo.GetNeighborRank(group_nbrs[j]);
}
group_ranks.Sort();
for (int j = 0; j < num_group_nbrs; j++)
{
group_name += "_" + std::to_string(group_ranks[j]);
}
// NOTE: Blueprint only wants remote ranks in its neighbor list,
// so we remove the local rank after the canonicalized Blueprint
// group name is formed
group_ranks.DeleteFirst(local_rank);
}
Node &n_group = n_adjset["groups"][group_name];
n_group["neighbors"].set(group_ranks.GetData(), group_ranks.Size());
n_group["values"].set(DataType::c_int(num_group_verts));
int_array group_vals = n_group["values"].value();
for (int j = 0; j < num_group_verts; j++)
{
group_vals[j] = pmesh->GroupVertex(i, j);
}
}
// NOTE: We don't create an adjset for face neighbor data because
// these faces aren't listed in the 'boundary_topology_name' topology
// (this topology only covers the faces between 'main_topology_name'
// elements and void). To include a face neighbor data adjset, this
// function would need to export a topology with either (1) all faces
// in the mesh topology or (2) all boundary faces, including neighbors.
////////////////////////////////////////////
// Setup distributed state
////////////////////////////////////////////
Node &n_domid = n_mesh["state/domain_id"];
n_domid.set(local_rank);
}
#endif
}
//---------------------------------------------------------------------------//
+2 -1
View File
@@ -166,7 +166,8 @@ public:
conduit::Node &out,
const std::string &coordset_name = "coords",
const std::string &main_topology_name = "main",
const std::string &boundary_topology_name = "boundary");
const std::string &boundary_topology_name = "boundary",
const std::string &main_adjset_name = "main_adjset");
/// Describes a MFEM grid function using the mesh blueprint
/** Sets up passed conduit::Node out to describe the given grid function
+31 -15
View File
@@ -482,7 +482,7 @@ void VisItDataCollection::SaveRootFile()
std::string root_name = prefix_path + name + "_" +
to_padded_string(cycle, pad_digits_cycle) +
".mfem_root";
std::ofstream root_file(root_name.c_str());
std::ofstream root_file(root_name);
root_file << GetVisItRootString();
if (!root_file)
{
@@ -548,7 +548,7 @@ void VisItDataCollection::Load(int cycle_)
void VisItDataCollection::LoadVisItRootFile(const std::string& root_name)
{
std::ifstream root_file(root_name.c_str());
std::ifstream root_file(root_name);
std::stringstream buffer;
buffer << root_file.rdbuf();
if (!buffer)
@@ -853,6 +853,7 @@ void ParaViewDataCollection::Save()
std::string dpath=GenerateCollectionPath();
std::string pvdname=dpath+"/"+GeneratePVDFileName();
bool write_header = true;
std::ifstream pvd_in;
if (restart_mode && (pvd_in.open(pvdname,std::ios::binary),pvd_in.good()))
{
@@ -879,20 +880,34 @@ void ParaViewDataCollection::Save()
pos_end = pvd_in.tellg();
}
}
// Since pvd_in is opened in binary mode, count will store the number
// of bytes from the beginning of the file until the desired insertion
// point (in text mode on Windows this is not the case).
size_t count = pos_end - pos_begin;
std::vector<char> buf(count);
pvd_in.clear();
pvd_in.seekg(pos_begin);
pvd_in.read(buf.data(), count);
pvd_in.close();
pvd_stream.open(pvdname.c_str(),std::ios::out);
pvd_stream.write(buf.data(), count);
if (count != 0)
{
write_header = false;
std::vector<char> buf(count);
// Read the contents of the PVD file, from the beginning to the
// insertion point.
pvd_in.clear();
pvd_in.seekg(pos_begin);
pvd_in.read(buf.data(), count);
pvd_in.close();
// Open the PVD file in truncate mode to delete the previous
// contents. Open in binary mode to write the data buffer without
// converting \r\n to \r\r\n on Windows.
pvd_stream.open(pvdname,std::ios::out|std::ios::trunc|std::ios::binary);
pvd_stream.write(buf.data(), count);
// Close and reopen the file in text mode, appending to the end.
pvd_stream.close();
pvd_stream.open(pvdname,std::ios::in|std::ios::out|std::ios::ate);
}
}
else
if (write_header)
{
// initialize new pvd file
pvd_stream.open(pvdname.c_str(),std::ios::out);
// initialize the file
// Initialize new pvd file.
pvd_stream.open(pvdname,std::ios::out|std::ios::trunc);
pvd_stream << "<?xml version=\"1.0\"?>\n";
pvd_stream << "<VTKFile type=\"Collection\" version=\"0.1\"";
pvd_stream << " byte_order=\"" << VTKByteOrder() << "\">\n";
@@ -904,7 +919,7 @@ void ParaViewDataCollection::Save()
{
std::string fname = GenerateCollectionPath()+"/"+GenerateVTUPath()+"/"
+GenerateVTUFileName();
std::fstream out(fname.c_str(), std::ios::out);
std::fstream out(fname, std::ios::out);
out.precision(precision);
SaveDataVTU(out,levels_of_detail);
out.close();
@@ -915,7 +930,7 @@ void ParaViewDataCollection::Save()
{
std::string fname = GenerateCollectionPath()+"/"+GeneratePVTUPath()+"/"
+GeneratePVTUFileName();
std::fstream out(fname.c_str(), std::ios::out);
std::fstream out(fname, std::ios::out);
out << "<?xml version=\"1.0\"?>\n";
out << "<VTKFile type=\"PUnstructuredGrid\"";
@@ -973,6 +988,7 @@ void ParaViewDataCollection::Save()
pvd_stream << "<DataSet timestep=\"" << GetTime(); // GetCycle();
pvd_stream << "\" group=\"\" part=\"" << 0 << "\" file=\"";
pvd_stream << fname << "\"/>\n";
pvd_stream.flush();
std::fstream::pos_type pos = pvd_stream.tellp();
pvd_stream << "</Collection>\n";
pvd_stream << "</VTKFile>" << std::endl;
+6 -14650
View File
File diff suppressed because it is too large Load Diff
+9 -3694
View File
File diff suppressed because it is too large Load Diff
+2503
View File
File diff suppressed because it is too large Load Diff
+1245
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1043
View File
File diff suppressed because it is too large Load Diff
+153
View File
@@ -0,0 +1,153 @@
// Copyright (c) 2010-2021, 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_FE_H1
#define MFEM_FE_H1
#include "fe_base.hpp"
namespace mfem
{
/// Arbitrary order H1 elements in 1D
class H1_SegmentElement : public NodalTensorFiniteElement
{
private:
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_x, dshape_x, d2shape_x;
#endif
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;
};
/// Arbitrary order H1 elements in 2D on a square
class H1_QuadrilateralElement : public NodalTensorFiniteElement
{
private:
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_x, shape_y, dshape_x, dshape_y, d2shape_x, d2shape_y;
#endif
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;
};
/// Arbitrary order H1 elements in 3D on a cube
class H1_HexahedronElement : public NodalTensorFiniteElement
{
private:
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_x, shape_y, shape_z, dshape_x, dshape_y, dshape_z,
d2shape_x, d2shape_y, d2shape_z;
#endif
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;
};
/// Arbitrary order H1 elements in 2D on a triangle
class H1_TriangleElement : public NodalFiniteElement
{
private:
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_x, shape_y, shape_l, dshape_x, dshape_y, dshape_l, u;
mutable Vector ddshape_x, ddshape_y, ddshape_l;
mutable DenseMatrix du, ddu;
#endif
DenseMatrixInverse Ti;
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;
};
/// Arbitrary order H1 elements in 3D on a tetrahedron
class H1_TetrahedronElement : public NodalFiniteElement
{
private:
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_x, shape_y, shape_z, shape_l;
mutable Vector dshape_x, dshape_y, dshape_z, dshape_l, u;
mutable Vector ddshape_x, ddshape_y, ddshape_z, ddshape_l;
mutable DenseMatrix du, ddu;
#endif
DenseMatrixInverse Ti;
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;
};
/// Arbitrary order H1 elements in 3D on a wedge
class H1_WedgeElement : public NodalFiniteElement
{
private:
#ifndef MFEM_THREAD_SAFE
mutable Vector t_shape, s_shape;
mutable DenseMatrix t_dshape, s_dshape;
#endif
Array<int> t_dof, s_dof;
H1_TriangleElement TriangleFE;
H1_SegmentElement SegmentFE;
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;
};
} // namespace mfem
#endif
+694
View File
@@ -0,0 +1,694 @@
// Copyright (c) 2010-2021, 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.
// L2 Finite Element classes
#include "fe_l2.hpp"
#include "fe_h1.hpp"
namespace mfem
{
using namespace std;
L2_SegmentElement::L2_SegmentElement(const int p, const int btype)
: NodalTensorFiniteElement(1, p, VerifyOpen(btype), L2_DOF_MAP)
{
const double *op = poly1d.OpenPoints(p, btype);
#ifndef MFEM_THREAD_SAFE
shape_x.SetSize(p + 1);
dshape_x.SetDataAndSize(NULL, p + 1);
#endif
for (int i = 0; i <= p; i++)
{
Nodes.IntPoint(i).x = op[i];
}
}
void L2_SegmentElement::CalcShape(const IntegrationPoint &ip,
Vector &shape) const
{
basis1d.Eval(ip.x, shape);
}
void L2_SegmentElement::CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const
{
#ifdef MFEM_THREAD_SAFE
Vector shape_x(dof), dshape_x(dshape.Data(), dof);
#else
dshape_x.SetData(dshape.Data());
#endif
basis1d.Eval(ip.x, shape_x, dshape_x);
}
void L2_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
{
const int p = order;
const double *op = poly1d.OpenPoints(p, b_type);
switch (vertex)
{
case 0:
for (int i = 0; i <= p; i++)
{
dofs(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
}
break;
case 1:
for (int i = 0; i <= p; i++)
{
dofs(i) = poly1d.CalcDelta(p,op[i]);
}
break;
}
}
L2_QuadrilateralElement::L2_QuadrilateralElement(const int p, const int btype)
: NodalTensorFiniteElement(2, p, VerifyOpen(btype), L2_DOF_MAP)
{
const double *op = poly1d.OpenPoints(p, b_type);
#ifndef MFEM_THREAD_SAFE
shape_x.SetSize(p + 1);
shape_y.SetSize(p + 1);
dshape_x.SetSize(p + 1);
dshape_y.SetSize(p + 1);
#endif
for (int o = 0, j = 0; j <= p; j++)
for (int i = 0; i <= p; i++)
{
Nodes.IntPoint(o++).Set2(op[i], op[j]);
}
}
void L2_QuadrilateralElement::CalcShape(const IntegrationPoint &ip,
Vector &shape) const
{
const int p = order;
#ifdef MFEM_THREAD_SAFE
Vector shape_x(p+1), shape_y(p+1);
#endif
basis1d.Eval(ip.x, shape_x);
basis1d.Eval(ip.y, shape_y);
for (int o = 0, j = 0; j <= p; j++)
for (int i = 0; i <= p; i++)
{
shape(o++) = shape_x(i)*shape_y(j);
}
}
void L2_QuadrilateralElement::CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const
{
const int p = order;
#ifdef MFEM_THREAD_SAFE
Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
#endif
basis1d.Eval(ip.x, shape_x, dshape_x);
basis1d.Eval(ip.y, shape_y, dshape_y);
for (int o = 0, j = 0; j <= p; j++)
for (int i = 0; i <= p; i++)
{
dshape(o,0) = dshape_x(i)* shape_y(j);
dshape(o,1) = shape_x(i)*dshape_y(j); o++;
}
}
void L2_QuadrilateralElement::ProjectDelta(int vertex, Vector &dofs) const
{
const int p = order;
const double *op = poly1d.OpenPoints(p, b_type);
#ifdef MFEM_THREAD_SAFE
Vector shape_x(p+1), shape_y(p+1);
#endif
for (int i = 0; i <= p; i++)
{
shape_x(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
shape_y(i) = poly1d.CalcDelta(p,op[i]);
}
switch (vertex)
{
case 0:
for (int o = 0, j = 0; j <= p; j++)
for (int i = 0; i <= p; i++)
{
dofs[o++] = shape_x(i)*shape_x(j);
}
break;
case 1:
for (int o = 0, j = 0; j <= p; j++)
for (int i = 0; i <= p; i++)
{
dofs[o++] = shape_y(i)*shape_x(j);
}
break;
case 2:
for (int o = 0, j = 0; j <= p; j++)
for (int i = 0; i <= p; i++)
{
dofs[o++] = shape_y(i)*shape_y(j);
}
break;
case 3:
for (int o = 0, j = 0; j <= p; j++)
for (int i = 0; i <= p; i++)
{
dofs[o++] = shape_x(i)*shape_y(j);
}
break;
}
}
L2_HexahedronElement::L2_HexahedronElement(const int p, const int btype)
: NodalTensorFiniteElement(3, p, VerifyOpen(btype), L2_DOF_MAP)
{
const double *op = poly1d.OpenPoints(p, btype);
#ifndef MFEM_THREAD_SAFE
shape_x.SetSize(p + 1);
shape_y.SetSize(p + 1);
shape_z.SetSize(p + 1);
dshape_x.SetSize(p + 1);
dshape_y.SetSize(p + 1);
dshape_z.SetSize(p + 1);
#endif
for (int o = 0, k = 0; k <= p; k++)
for (int j = 0; j <= p; j++)
for (int i = 0; i <= p; i++)
{
Nodes.IntPoint(o++).Set3(op[i], op[j], op[k]);
}
}
void L2_HexahedronElement::CalcShape(const IntegrationPoint &ip,
Vector &shape) const
{
const int p = order;
#ifdef MFEM_THREAD_SAFE
Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
#endif
basis1d.Eval(ip.x, shape_x);
basis1d.Eval(ip.y, shape_y);
basis1d.Eval(ip.z, shape_z);
for (int o = 0, k = 0; k <= p; k++)
for (int j = 0; j <= p; j++)
for (int i = 0; i <= p; i++)
{
shape(o++) = shape_x(i)*shape_y(j)*shape_z(k);
}
}
void L2_HexahedronElement::CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const
{
const int p = order;
#ifdef MFEM_THREAD_SAFE
Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
#endif
basis1d.Eval(ip.x, shape_x, dshape_x);
basis1d.Eval(ip.y, shape_y, dshape_y);
basis1d.Eval(ip.z, shape_z, dshape_z);
for (int o = 0, k = 0; k <= p; k++)
for (int j = 0; j <= p; j++)
for (int i = 0; i <= p; i++)
{
dshape(o,0) = dshape_x(i)* shape_y(j)* shape_z(k);
dshape(o,1) = shape_x(i)*dshape_y(j)* shape_z(k);
dshape(o,2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
}
}
void L2_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
{
const int p = order;
const double *op = poly1d.OpenPoints(p, b_type);
#ifdef MFEM_THREAD_SAFE
Vector shape_x(p+1), shape_y(p+1);
#endif
for (int i = 0; i <= p; i++)
{
shape_x(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
shape_y(i) = poly1d.CalcDelta(p,op[i]);
}
switch (vertex)
{
case 0:
for (int o = 0, k = 0; k <= p; k++)
for (int j = 0; j <= p; j++)
for (int i = 0; i <= p; i++)
{
dofs[o++] = shape_x(i)*shape_x(j)*shape_x(k);
}
break;
case 1:
for (int o = 0, k = 0; k <= p; k++)
for (int j = 0; j <= p; j++)
for (int i = 0; i <= p; i++)
{
dofs[o++] = shape_y(i)*shape_x(j)*shape_x(k);
}
break;
case 2:
for (int o = 0, k = 0; k <= p; k++)
for (int j = 0; j <= p; j++)
for (int i = 0; i <= p; i++)
{
dofs[o++] = shape_y(i)*shape_y(j)*shape_x(k);
}
break;
case 3:
for (int o = 0, k = 0; k <= p; k++)
for (int j = 0; j <= p; j++)
for (int i = 0; i <= p; i++)
{
dofs[o++] = shape_x(i)*shape_y(j)*shape_x(k);
}
break;
case 4:
for (int o = 0, k = 0; k <= p; k++)
for (int j = 0; j <= p; j++)
for (int i = 0; i <= p; i++)
{
dofs[o++] = shape_x(i)*shape_x(j)*shape_y(k);
}
break;
case 5:
for (int o = 0, k = 0; k <= p; k++)
for (int j = 0; j <= p; j++)
for (int i = 0; i <= p; i++)
{
dofs[o++] = shape_y(i)*shape_x(j)*shape_y(k);
}
break;
case 6:
for (int o = 0, k = 0; k <= p; k++)
for (int j = 0; j <= p; j++)
for (int i = 0; i <= p; i++)
{
dofs[o++] = shape_y(i)*shape_y(j)*shape_y(k);
}
break;
case 7:
for (int o = 0, k = 0; k <= p; k++)
for (int j = 0; j <= p; j++)
for (int i = 0; i <= p; i++)
{
dofs[o++] = shape_x(i)*shape_y(j)*shape_y(k);
}
break;
}
}
L2_TriangleElement::L2_TriangleElement(const int p, const int btype)
: NodalFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
FunctionSpace::Pk)
{
const double *op = poly1d.OpenPoints(p, VerifyOpen(btype));
#ifndef MFEM_THREAD_SAFE
shape_x.SetSize(p + 1);
shape_y.SetSize(p + 1);
shape_l.SetSize(p + 1);
dshape_x.SetSize(p + 1);
dshape_y.SetSize(p + 1);
dshape_l.SetSize(p + 1);
u.SetSize(dof);
du.SetSize(dof, dim);
#else
Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
#endif
for (int o = 0, j = 0; j <= p; j++)
for (int i = 0; i + j <= p; i++)
{
double w = op[i] + op[j] + op[p-i-j];
Nodes.IntPoint(o++).Set2(op[i]/w, op[j]/w);
}
DenseMatrix T(dof);
for (int k = 0; k < dof; k++)
{
IntegrationPoint &ip = Nodes.IntPoint(k);
poly1d.CalcBasis(p, ip.x, shape_x);
poly1d.CalcBasis(p, ip.y, shape_y);
poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
for (int o = 0, j = 0; j <= p; j++)
for (int i = 0; i + j <= p; i++)
{
T(o++, k) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
}
}
Ti.Factor(T);
// mfem::out << "L2_TriangleElement(" << p << ") : "; Ti.TestInversion();
}
void L2_TriangleElement::CalcShape(const IntegrationPoint &ip,
Vector &shape) const
{
const int p = order;
#ifdef MFEM_THREAD_SAFE
Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1), u(dof);
#endif
poly1d.CalcBasis(p, ip.x, shape_x);
poly1d.CalcBasis(p, ip.y, shape_y);
poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
for (int o = 0, j = 0; j <= p; j++)
for (int i = 0; i + j <= p; i++)
{
u(o++) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
}
Ti.Mult(u, shape);
}
void L2_TriangleElement::CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const
{
const int p = order;
#ifdef MFEM_THREAD_SAFE
Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
DenseMatrix du(dof, dim);
#endif
poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
for (int o = 0, j = 0; j <= p; j++)
for (int i = 0; i + j <= p; i++)
{
int k = p - i - j;
du(o,0) = ((dshape_x(i)* shape_l(k)) -
( shape_x(i)*dshape_l(k)))*shape_y(j);
du(o,1) = ((dshape_y(j)* shape_l(k)) -
( shape_y(j)*dshape_l(k)))*shape_x(i);
o++;
}
Ti.Mult(du, dshape);
}
void L2_TriangleElement::ProjectDelta(int vertex, Vector &dofs) const
{
switch (vertex)
{
case 0:
for (int i = 0; i < dof; i++)
{
const IntegrationPoint &ip = Nodes.IntPoint(i);
dofs[i] = pow(1.0 - ip.x - ip.y, order);
}
break;
case 1:
for (int i = 0; i < dof; i++)
{
const IntegrationPoint &ip = Nodes.IntPoint(i);
dofs[i] = pow(ip.x, order);
}
break;
case 2:
for (int i = 0; i < dof; i++)
{
const IntegrationPoint &ip = Nodes.IntPoint(i);
dofs[i] = pow(ip.y, order);
}
break;
}
}
L2_TetrahedronElement::L2_TetrahedronElement(const int p, const int btype)
: NodalFiniteElement(3, Geometry::TETRAHEDRON, ((p + 1)*(p + 2)*(p + 3))/6,
p, FunctionSpace::Pk)
{
const double *op = poly1d.OpenPoints(p, VerifyNodal(VerifyOpen(btype)));
#ifndef MFEM_THREAD_SAFE
shape_x.SetSize(p + 1);
shape_y.SetSize(p + 1);
shape_z.SetSize(p + 1);
shape_l.SetSize(p + 1);
dshape_x.SetSize(p + 1);
dshape_y.SetSize(p + 1);
dshape_z.SetSize(p + 1);
dshape_l.SetSize(p + 1);
u.SetSize(dof);
du.SetSize(dof, dim);
#else
Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
#endif
for (int o = 0, k = 0; k <= p; k++)
for (int j = 0; j + k <= p; j++)
for (int i = 0; i + j + k <= p; i++)
{
double w = op[i] + op[j] + op[k] + op[p-i-j-k];
Nodes.IntPoint(o++).Set3(op[i]/w, op[j]/w, op[k]/w);
}
DenseMatrix T(dof);
for (int m = 0; m < dof; m++)
{
IntegrationPoint &ip = Nodes.IntPoint(m);
poly1d.CalcBasis(p, ip.x, shape_x);
poly1d.CalcBasis(p, ip.y, shape_y);
poly1d.CalcBasis(p, ip.z, shape_z);
poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
for (int o = 0, k = 0; k <= p; k++)
for (int j = 0; j + k <= p; j++)
for (int i = 0; i + j + k <= p; i++)
{
T(o++, m) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
}
}
Ti.Factor(T);
// mfem::out << "L2_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
}
void L2_TetrahedronElement::CalcShape(const IntegrationPoint &ip,
Vector &shape) const
{
const int p = order;
#ifdef MFEM_THREAD_SAFE
Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
Vector u(dof);
#endif
poly1d.CalcBasis(p, ip.x, shape_x);
poly1d.CalcBasis(p, ip.y, shape_y);
poly1d.CalcBasis(p, ip.z, shape_z);
poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
for (int o = 0, k = 0; k <= p; k++)
for (int j = 0; j + k <= p; j++)
for (int i = 0; i + j + k <= p; i++)
{
u(o++) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
}
Ti.Mult(u, shape);
}
void L2_TetrahedronElement::CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const
{
const int p = order;
#ifdef MFEM_THREAD_SAFE
Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
DenseMatrix du(dof, dim);
#endif
poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
for (int o = 0, k = 0; k <= p; k++)
for (int j = 0; j + k <= p; j++)
for (int i = 0; i + j + k <= p; i++)
{
int l = p - i - j - k;
du(o,0) = ((dshape_x(i)* shape_l(l)) -
( shape_x(i)*dshape_l(l)))*shape_y(j)*shape_z(k);
du(o,1) = ((dshape_y(j)* shape_l(l)) -
( shape_y(j)*dshape_l(l)))*shape_x(i)*shape_z(k);
du(o,2) = ((dshape_z(k)* shape_l(l)) -
( shape_z(k)*dshape_l(l)))*shape_x(i)*shape_y(j);
o++;
}
Ti.Mult(du, dshape);
}
void L2_TetrahedronElement::ProjectDelta(int vertex, Vector &dofs) const
{
switch (vertex)
{
case 0:
for (int i = 0; i < dof; i++)
{
const IntegrationPoint &ip = Nodes.IntPoint(i);
dofs[i] = pow(1.0 - ip.x - ip.y - ip.z, order);
}
break;
case 1:
for (int i = 0; i < dof; i++)
{
const IntegrationPoint &ip = Nodes.IntPoint(i);
dofs[i] = pow(ip.x, order);
}
break;
case 2:
for (int i = 0; i < dof; i++)
{
const IntegrationPoint &ip = Nodes.IntPoint(i);
dofs[i] = pow(ip.y, order);
}
break;
case 3:
for (int i = 0; i < dof; i++)
{
const IntegrationPoint &ip = Nodes.IntPoint(i);
dofs[i] = pow(ip.z, order);
}
break;
}
}
L2_WedgeElement::L2_WedgeElement(const int p, const int btype)
: NodalFiniteElement(3, Geometry::PRISM, ((p + 1)*(p + 1)*(p + 2))/2,
p, FunctionSpace::Qk),
TriangleFE(p, btype),
SegmentFE(p, btype)
{
#ifndef MFEM_THREAD_SAFE
t_shape.SetSize(TriangleFE.GetDof());
s_shape.SetSize(SegmentFE.GetDof());
t_dshape.SetSize(TriangleFE.GetDof(), 2);
s_dshape.SetSize(SegmentFE.GetDof(), 1);
#endif
t_dof.SetSize(dof);
s_dof.SetSize(dof);
// Interior DoFs
int m=0;
for (int k=0; k<=p; k++)
{
int l=0;
for (int j=0; j<=p; j++)
{
for (int i=0; i<=j; i++)
{
t_dof[m] = l;
s_dof[m] = k;
l++; m++;
}
}
}
// Define Nodes
const IntegrationRule & t_Nodes = TriangleFE.GetNodes();
const IntegrationRule & s_Nodes = SegmentFE.GetNodes();
for (int i=0; i<dof; i++)
{
Nodes.IntPoint(i).x = t_Nodes.IntPoint(t_dof[i]).x;
Nodes.IntPoint(i).y = t_Nodes.IntPoint(t_dof[i]).y;
Nodes.IntPoint(i).z = s_Nodes.IntPoint(s_dof[i]).x;
}
}
void L2_WedgeElement::CalcShape(const IntegrationPoint &ip,
Vector &shape) const
{
#ifdef MFEM_THREAD_SAFE
Vector t_shape(TriangleFE.GetDof());
Vector s_shape(SegmentFE.GetDof());
#endif
IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
TriangleFE.CalcShape(ip, t_shape);
SegmentFE.CalcShape(ipz, s_shape);
for (int i=0; i<dof; i++)
{
shape[i] = t_shape[t_dof[i]] * s_shape[s_dof[i]];
}
}
void L2_WedgeElement::CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const
{
#ifdef MFEM_THREAD_SAFE
Vector t_shape(TriangleFE.GetDof());
DenseMatrix t_dshape(TriangleFE.GetDof(), 2);
Vector s_shape(SegmentFE.GetDof());
DenseMatrix s_dshape(SegmentFE.GetDof(), 1);
#endif
IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
TriangleFE.CalcShape(ip, t_shape);
TriangleFE.CalcDShape(ip, t_dshape);
SegmentFE.CalcShape(ipz, s_shape);
SegmentFE.CalcDShape(ipz, s_dshape);
for (int i=0; i<dof; i++)
{
dshape(i, 0) = t_dshape(t_dof[i],0) * s_shape[s_dof[i]];
dshape(i, 1) = t_dshape(t_dof[i],1) * s_shape[s_dof[i]];
dshape(i, 2) = t_shape[t_dof[i]] * s_dshape(s_dof[i],0);
}
}
}
+151
View File
@@ -0,0 +1,151 @@
// Copyright (c) 2010-2021, 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_FE_L2
#define MFEM_FE_L2
#include "fe_base.hpp"
namespace mfem
{
/// Arbitrary order L2 elements in 1D on a segment
class L2_SegmentElement : public NodalTensorFiniteElement
{
private:
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_x, dshape_x;
#endif
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;
};
/// Arbitrary order L2 elements in 2D on a square
class L2_QuadrilateralElement : public NodalTensorFiniteElement
{
private:
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_x, shape_y, dshape_x, dshape_y;
#endif
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
{ ProjectCurl_2D(fe, Trans, curl); }
};
/// Arbitrary order L2 elements in 3D on a cube
class L2_HexahedronElement : public NodalTensorFiniteElement
{
private:
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_x, shape_y, shape_z, dshape_x, dshape_y, dshape_z;
#endif
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;
};
/// Arbitrary order L2 elements in 2D on a triangle
class L2_TriangleElement : public NodalFiniteElement
{
private:
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_x, shape_y, shape_l, dshape_x, dshape_y, dshape_l, u;
mutable DenseMatrix du;
#endif
DenseMatrixInverse Ti;
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
{ ProjectCurl_2D(fe, Trans, curl); }
};
/// Arbitrary order L2 elements in 3D on a tetrahedron
class L2_TetrahedronElement : public NodalFiniteElement
{
private:
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_x, shape_y, shape_z, shape_l;
mutable Vector dshape_x, dshape_y, dshape_z, dshape_l, u;
mutable DenseMatrix du;
#endif
DenseMatrixInverse Ti;
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;
};
/// Arbitrary order L2 elements in 3D on a wedge
class L2_WedgeElement : public NodalFiniteElement
{
private:
#ifndef MFEM_THREAD_SAFE
mutable Vector t_shape, s_shape;
mutable DenseMatrix t_dshape, s_dshape;
#endif
Array<int> t_dof, s_dof;
L2_TriangleElement TriangleFE;
L2_SegmentElement SegmentFE;
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;
};
} // namespace mfem
#endif
+1219
View File
File diff suppressed because it is too large Load Diff
+326
View File
@@ -0,0 +1,326 @@
// Copyright (c) 2010-2021, 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_FE_ND
#define MFEM_FE_ND
#include "fe_base.hpp"
namespace mfem
{
/// Arbitrary order Nedelec elements in 3D on a cube
class ND_HexahedronElement : public VectorTensorFiniteElement
{
static const double tk[18];
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_cx, shape_ox, shape_cy, shape_oy, shape_cz, shape_oz;
mutable Vector dshape_cx, dshape_cy, dshape_cz;
#endif
Array<int> dof2tk;
const double *cp;
public:
/** @brief Construct the ND_HexahedronElement of order @a p and closed and
open BasisType @a cb_type and @a ob_type */
ND_HexahedronElement(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
{ CalcVShape_ND(Trans, shape); }
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
{
if (obasis1d.IsIntegratedType()) { ProjectIntegrated(vc, Trans, dofs); }
else { Project_ND(tk, dof2tk, vc, Trans, dofs); }
}
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ Project_ND(tk, dof2tk, fe, Trans, I); }
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
{ ProjectCurl_ND(tk, dof2tk, fe, Trans, curl); }
protected:
void ProjectIntegrated(VectorCoefficient &vc,
ElementTransformation &Trans,
Vector &dofs) const;
};
/// Arbitrary order Nedelec elements in 2D on a square
class ND_QuadrilateralElement : public VectorTensorFiniteElement
{
static const double tk[8];
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_cx, shape_ox, shape_cy, shape_oy;
mutable Vector dshape_cx, dshape_cy;
#endif
Array<int> dof2tk;
const double *cp;
public:
/** @brief Construct the ND_QuadrilateralElement of order @a p and closed and
open BasisType @a cb_type and @a ob_type */
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
{ CalcVShape_ND(Trans, shape); }
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
{
if (obasis1d.IsIntegratedType()) { ProjectIntegrated(vc, Trans, dofs); }
else { Project_ND(tk, dof2tk, vc, Trans, dofs); }
}
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ Project_ND(tk, dof2tk, fe, Trans, I); }
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
protected:
void ProjectIntegrated(VectorCoefficient &vc,
ElementTransformation &Trans,
Vector &dofs) const;
};
/// Arbitrary order Nedelec elements in 3D on a tetrahedron
class ND_TetrahedronElement : public VectorFiniteElement
{
static const double tk[18], c;
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_x, shape_y, shape_z, shape_l;
mutable Vector dshape_x, dshape_y, dshape_z, dshape_l;
mutable DenseMatrix u;
#endif
Array<int> dof2tk;
DenseMatrixInverse Ti;
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
{ CalcVShape_ND(Trans, shape); }
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ Project_ND(tk, dof2tk, fe, Trans, I); }
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
{ ProjectCurl_ND(tk, dof2tk, fe, Trans, curl); }
};
/// Arbitrary order Nedelec elements in 2D on a triangle
class ND_TriangleElement : public VectorFiniteElement
{
static const double tk[8], c;
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_x, shape_y, shape_l;
mutable Vector dshape_x, dshape_y, dshape_l;
mutable DenseMatrix u;
mutable Vector curlu;
#endif
Array<int> dof2tk;
DenseMatrixInverse Ti;
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
{ CalcVShape_ND(Trans, shape); }
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ Project_ND(tk, dof2tk, fe, Trans, I); }
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
};
/// Arbitrary order Nedelec elements in 1D on a segment
class ND_SegmentElement : public VectorTensorFiniteElement
{
static const double tk[1];
Array<int> dof2tk;
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
{ obasis1d.Eval(ip.x, shape); }
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
{ CalcVShape_ND(Trans, shape); }
// virtual void CalcCurlShape(const IntegrationPoint &ip,
// DenseMatrix &curl_shape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ Project_ND(tk, dof2tk, fe, Trans, I); }
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
};
} // namespace mfem
#endif
+405
View File
@@ -0,0 +1,405 @@
// Copyright (c) 2010-2021, 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.
// H1 Finite Element classes utilizing the Bernstein basis
#include "fe_nurbs.hpp"
#include "../../mesh/nurbs.hpp"
namespace mfem
{
using namespace std;
void NURBS1DFiniteElement::SetOrder() const
{
order = kv[0]->GetOrder();
dof = order + 1;
weights.SetSize(dof);
shape_x.SetSize(dof);
}
void NURBS1DFiniteElement::CalcShape(const IntegrationPoint &ip,
Vector &shape) const
{
kv[0]->CalcShape(shape, ijk[0], ip.x);
double sum = 0.0;
for (int i = 0; i <= order; i++)
{
sum += (shape(i) *= weights(i));
}
shape /= sum;
}
void NURBS1DFiniteElement::CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const
{
Vector grad(dshape.Data(), dof);
kv[0]->CalcShape (shape_x, ijk[0], ip.x);
kv[0]->CalcDShape(grad, ijk[0], ip.x);
double sum = 0.0, dsum = 0.0;
for (int i = 0; i <= order; i++)
{
sum += (shape_x(i) *= weights(i));
dsum += ( grad(i) *= weights(i));
}
sum = 1.0/sum;
add(sum, grad, -dsum*sum*sum, shape_x, grad);
}
void NURBS1DFiniteElement::CalcHessian (const IntegrationPoint &ip,
DenseMatrix &hessian) const
{
Vector grad(dof);
Vector hess(hessian.Data(), dof);
kv[0]->CalcShape (shape_x, ijk[0], ip.x);
kv[0]->CalcDShape(grad, ijk[0], ip.x);
kv[0]->CalcD2Shape(hess, ijk[0], ip.x);
double sum = 0.0, dsum = 0.0, d2sum = 0.0;
for (int i = 0; i <= order; i++)
{
sum += (shape_x(i) *= weights(i));
dsum += ( grad(i) *= weights(i));
d2sum += ( hess(i) *= weights(i));
}
sum = 1.0/sum;
add(sum, hess, -2*dsum*sum*sum, grad, hess);
add(1.0, hess, (-d2sum + 2*dsum*dsum*sum)*sum*sum, shape_x, hess);
}
void NURBS2DFiniteElement::SetOrder() const
{
orders[0] = kv[0]->GetOrder();
orders[1] = kv[1]->GetOrder();
shape_x.SetSize(orders[0]+1);
shape_y.SetSize(orders[1]+1);
dshape_x.SetSize(orders[0]+1);
dshape_y.SetSize(orders[1]+1);
d2shape_x.SetSize(orders[0]+1);
d2shape_y.SetSize(orders[1]+1);
order = max(orders[0], orders[1]);
dof = (orders[0] + 1)*(orders[1] + 1);
u.SetSize(dof);
du.SetSize(dof);
weights.SetSize(dof);
}
void NURBS2DFiniteElement::CalcShape(const IntegrationPoint &ip,
Vector &shape) const
{
kv[0]->CalcShape(shape_x, ijk[0], ip.x);
kv[1]->CalcShape(shape_y, ijk[1], ip.y);
double sum = 0.0;
for (int o = 0, j = 0; j <= orders[1]; j++)
{
const double sy = shape_y(j);
for (int i = 0; i <= orders[0]; i++, o++)
{
sum += ( shape(o) = shape_x(i)*sy*weights(o) );
}
}
shape /= sum;
}
void NURBS2DFiniteElement::CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const
{
double sum, dsum[2];
kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
sum = dsum[0] = dsum[1] = 0.0;
for (int o = 0, j = 0; j <= orders[1]; j++)
{
const double sy = shape_y(j), dsy = dshape_y(j);
for (int i = 0; i <= orders[0]; i++, o++)
{
sum += ( u(o) = shape_x(i)*sy*weights(o) );
dsum[0] += ( dshape(o,0) = dshape_x(i)*sy *weights(o) );
dsum[1] += ( dshape(o,1) = shape_x(i)*dsy*weights(o) );
}
}
sum = 1.0/sum;
dsum[0] *= sum*sum;
dsum[1] *= sum*sum;
for (int o = 0; o < dof; o++)
{
dshape(o,0) = dshape(o,0)*sum - u(o)*dsum[0];
dshape(o,1) = dshape(o,1)*sum - u(o)*dsum[1];
}
}
void NURBS2DFiniteElement::CalcHessian (const IntegrationPoint &ip,
DenseMatrix &hessian) const
{
double sum, dsum[2], d2sum[3];
kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
kv[0]->CalcD2Shape(d2shape_x, ijk[0], ip.x);
kv[1]->CalcD2Shape(d2shape_y, ijk[1], ip.y);
sum = dsum[0] = dsum[1] = 0.0;
d2sum[0] = d2sum[1] = d2sum[2] = 0.0;
for (int o = 0, j = 0; j <= orders[1]; j++)
{
const double sy = shape_y(j), dsy = dshape_y(j), d2sy = d2shape_y(j);
for (int i = 0; i <= orders[0]; i++, o++)
{
const double sx = shape_x(i), dsx = dshape_x(i), d2sx = d2shape_x(i);
sum += ( u(o) = sx*sy*weights(o) );
dsum[0] += ( du(o,0) = dsx*sy*weights(o) );
dsum[1] += ( du(o,1) = sx*dsy*weights(o) );
d2sum[0] += ( hessian(o,0) = d2sx*sy*weights(o) );
d2sum[1] += ( hessian(o,1) = dsx*dsy*weights(o) );
d2sum[2] += ( hessian(o,2) = sx*d2sy*weights(o) );
}
}
sum = 1.0/sum;
dsum[0] *= sum;
dsum[1] *= sum;
d2sum[0] *= sum;
d2sum[1] *= sum;
d2sum[2] *= sum;
for (int o = 0; o < dof; o++)
{
hessian(o,0) = hessian(o,0)*sum
- 2*du(o,0)*sum*dsum[0]
+ u[o]*sum*(2*dsum[0]*dsum[0] - d2sum[0]);
hessian(o,1) = hessian(o,1)*sum
- du(o,0)*sum*dsum[1]
- du(o,1)*sum*dsum[0]
+ u[o]*sum*(2*dsum[0]*dsum[1] - d2sum[1]);
hessian(o,2) = hessian(o,2)*sum
- 2*du(o,1)*sum*dsum[1]
+ u[o]*sum*(2*dsum[1]*dsum[1] - d2sum[2]);
}
}
void NURBS3DFiniteElement::SetOrder() const
{
orders[0] = kv[0]->GetOrder();
orders[1] = kv[1]->GetOrder();
orders[2] = kv[2]->GetOrder();
shape_x.SetSize(orders[0]+1);
shape_y.SetSize(orders[1]+1);
shape_z.SetSize(orders[2]+1);
dshape_x.SetSize(orders[0]+1);
dshape_y.SetSize(orders[1]+1);
dshape_z.SetSize(orders[2]+1);
d2shape_x.SetSize(orders[0]+1);
d2shape_y.SetSize(orders[1]+1);
d2shape_z.SetSize(orders[2]+1);
order = max(max(orders[0], orders[1]), orders[2]);
dof = (orders[0] + 1)*(orders[1] + 1)*(orders[2] + 1);
u.SetSize(dof);
du.SetSize(dof);
weights.SetSize(dof);
}
void NURBS3DFiniteElement::CalcShape(const IntegrationPoint &ip,
Vector &shape) const
{
kv[0]->CalcShape(shape_x, ijk[0], ip.x);
kv[1]->CalcShape(shape_y, ijk[1], ip.y);
kv[2]->CalcShape(shape_z, ijk[2], ip.z);
double sum = 0.0;
for (int o = 0, k = 0; k <= orders[2]; k++)
{
const double sz = shape_z(k);
for (int j = 0; j <= orders[1]; j++)
{
const double sy_sz = shape_y(j)*sz;
for (int i = 0; i <= orders[0]; i++, o++)
{
sum += ( shape(o) = shape_x(i)*sy_sz*weights(o) );
}
}
}
shape /= sum;
}
void NURBS3DFiniteElement::CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const
{
double sum, dsum[3];
kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
kv[2]->CalcShape ( shape_z, ijk[2], ip.z);
kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
kv[2]->CalcDShape(dshape_z, ijk[2], ip.z);
sum = dsum[0] = dsum[1] = dsum[2] = 0.0;
for (int o = 0, k = 0; k <= orders[2]; k++)
{
const double sz = shape_z(k), dsz = dshape_z(k);
for (int j = 0; j <= orders[1]; j++)
{
const double sy_sz = shape_y(j)* sz;
const double dsy_sz = dshape_y(j)* sz;
const double sy_dsz = shape_y(j)*dsz;
for (int i = 0; i <= orders[0]; i++, o++)
{
sum += ( u(o) = shape_x(i)*sy_sz*weights(o) );
dsum[0] += ( dshape(o,0) = dshape_x(i)* sy_sz *weights(o) );
dsum[1] += ( dshape(o,1) = shape_x(i)*dsy_sz *weights(o) );
dsum[2] += ( dshape(o,2) = shape_x(i)* sy_dsz*weights(o) );
}
}
}
sum = 1.0/sum;
dsum[0] *= sum*sum;
dsum[1] *= sum*sum;
dsum[2] *= sum*sum;
for (int o = 0; o < dof; o++)
{
dshape(o,0) = dshape(o,0)*sum - u(o)*dsum[0];
dshape(o,1) = dshape(o,1)*sum - u(o)*dsum[1];
dshape(o,2) = dshape(o,2)*sum - u(o)*dsum[2];
}
}
void NURBS3DFiniteElement::CalcHessian (const IntegrationPoint &ip,
DenseMatrix &hessian) const
{
double sum, dsum[3], d2sum[6];
kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
kv[2]->CalcShape ( shape_z, ijk[2], ip.z);
kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
kv[2]->CalcDShape(dshape_z, ijk[2], ip.z);
kv[0]->CalcD2Shape(d2shape_x, ijk[0], ip.x);
kv[1]->CalcD2Shape(d2shape_y, ijk[1], ip.y);
kv[2]->CalcD2Shape(d2shape_z, ijk[2], ip.z);
sum = dsum[0] = dsum[1] = dsum[2] = 0.0;
d2sum[0] = d2sum[1] = d2sum[2] = d2sum[3] = d2sum[4] = d2sum[5] = 0.0;
for (int o = 0, k = 0; k <= orders[2]; k++)
{
const double sz = shape_z(k), dsz = dshape_z(k), d2sz = d2shape_z(k);
for (int j = 0; j <= orders[1]; j++)
{
const double sy = shape_y(j), dsy = dshape_y(j), d2sy = d2shape_y(j);
for (int i = 0; i <= orders[0]; i++, o++)
{
const double sx = shape_x(i), dsx = dshape_x(i), d2sx = d2shape_x(i);
sum += ( u(o) = sx*sy*sz*weights(o) );
dsum[0] += ( du(o,0) = dsx*sy*sz*weights(o) );
dsum[1] += ( du(o,1) = sx*dsy*sz*weights(o) );
dsum[2] += ( du(o,2) = sx*sy*dsz*weights(o) );
d2sum[0] += ( hessian(o,0) = d2sx*sy*sz*weights(o) );
d2sum[1] += ( hessian(o,1) = dsx*dsy*sz*weights(o) );
d2sum[2] += ( hessian(o,2) = dsx*sy*dsz*weights(o) );
d2sum[3] += ( hessian(o,3) = sx*dsy*dsz*weights(o) );
d2sum[4] += ( hessian(o,4) = sx*sy*d2sz*weights(o) );
d2sum[5] += ( hessian(o,5) = sx*d2sy*sz*weights(o) );
}
}
}
sum = 1.0/sum;
dsum[0] *= sum;
dsum[1] *= sum;
dsum[2] *= sum;
d2sum[0] *= sum;
d2sum[1] *= sum;
d2sum[2] *= sum;
d2sum[3] *= sum;
d2sum[4] *= sum;
d2sum[5] *= sum;
for (int o = 0; o < dof; o++)
{
hessian(o,0) = hessian(o,0)*sum
- 2*du(o,0)*sum*dsum[0]
+ u[o]*sum*(2*dsum[0]*dsum[0] - d2sum[0]);
hessian(o,1) = hessian(o,1)*sum
- du(o,0)*sum*dsum[1]
- du(o,1)*sum*dsum[0]
+ u[o]*sum*(2*dsum[0]*dsum[1] - d2sum[1]);
hessian(o,2) = hessian(o,2)*sum
- du(o,0)*sum*dsum[2]
- du(o,2)*sum*dsum[0]
+ u[o]*sum*(2*dsum[0]*dsum[2] - d2sum[2]);
hessian(o,3) = hessian(o,3)*sum
- du(o,1)*sum*dsum[2]
- du(o,2)*sum*dsum[1]
+ u[o]*sum*(2*dsum[1]*dsum[2] - d2sum[3]);
hessian(o,4) = hessian(o,4)*sum
- 2*du(o,2)*sum*dsum[2]
+ u[o]*sum*(2*dsum[2]*dsum[2] - d2sum[4]);
hessian(o,5) = hessian(o,5)*sum
- 2*du(o,1)*sum*dsum[1]
+ u[o]*sum*(2*dsum[1]*dsum[1] - d2sum[5]);
}
}
}
+153
View File
@@ -0,0 +1,153 @@
// Copyright (c) 2010-2021, 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_FE_NURBS
#define MFEM_FE_NURBS
#include "fe_base.hpp"
namespace mfem
{
class KnotVector;
/// An arbitrary order and dimension NURBS element
class NURBSFiniteElement : public ScalarFiniteElement
{
protected:
mutable Array <const KnotVector*> kv;
mutable const int *ijk;
mutable int patch, elem;
mutable Vector weights;
public:
/** @brief Construct NURBSFiniteElement with given
@param D Reference space dimension
@param G Geometry type (of type Geometry::Type)
@param Do Number of degrees of freedom in the FiniteElement
@param O Order/degree of the FiniteElement
@param F FunctionSpace type of the FiniteElement
*/
NURBSFiniteElement(int D, Geometry::Type G, int Do, int O, int F)
: ScalarFiniteElement(D, G, Do, O, F)
{
ijk = NULL;
patch = elem = -1;
kv.SetSize(dim);
weights.SetSize(dof);
weights = 1.0;
}
void Reset () const { patch = elem = -1; }
void SetIJK (const int *IJK) const { ijk = IJK; }
int GetPatch () const { return patch; }
void SetPatch (int p) const { patch = p; }
int GetElement () const { return elem; }
void SetElement (int e) const { elem = e; }
Array <const KnotVector*> &KnotVectors() const { return kv; }
Vector &Weights () const { return weights; }
/// Update the NURBSFiniteElement according to the currently set knot vectors
virtual void SetOrder () const { }
};
/// An arbitrary order 1D NURBS element on a segment
class NURBS1DFiniteElement : public NURBSFiniteElement
{
protected:
mutable Vector shape_x;
public:
/// Construct the NURBS1DFiniteElement of order @a p
NURBS1DFiniteElement(int p)
: NURBSFiniteElement(1, Geometry::SEGMENT, p + 1, p, FunctionSpace::Qk),
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;
};
/// An arbitrary order 2D NURBS element on a square
class NURBS2DFiniteElement : public NURBSFiniteElement
{
protected:
mutable Vector u, shape_x, shape_y, dshape_x, dshape_y, d2shape_x, d2shape_y;
mutable DenseMatrix du;
public:
/// Construct the NURBS2DFiniteElement of order @a p
NURBS2DFiniteElement(int p)
: NURBSFiniteElement(2, Geometry::SQUARE, (p + 1)*(p + 1), p,
FunctionSpace::Qk),
u(dof), shape_x(p + 1), shape_y(p + 1), dshape_x(p + 1),
dshape_y(p + 1), d2shape_x(p + 1), d2shape_y(p + 1), du(dof,2)
{ orders[0] = orders[1] = p; }
/// Construct the NURBS2DFiniteElement with x-order @a px and y-order @a py
NURBS2DFiniteElement(int px, int py)
: NURBSFiniteElement(2, Geometry::SQUARE, (px + 1)*(py + 1),
std::max(px, py), FunctionSpace::Qk),
u(dof), shape_x(px + 1), shape_y(py + 1), dshape_x(px + 1),
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;
};
/// An arbitrary order 3D NURBS element on a cube
class NURBS3DFiniteElement : public NURBSFiniteElement
{
protected:
mutable Vector u, shape_x, shape_y, shape_z;
mutable Vector dshape_x, dshape_y, dshape_z;
mutable Vector d2shape_x, d2shape_y, d2shape_z;
mutable DenseMatrix du;
public:
/// Construct the NURBS3DFiniteElement of order @a p
NURBS3DFiniteElement(int p)
: NURBSFiniteElement(3, Geometry::CUBE, (p + 1)*(p + 1)*(p + 1), p,
FunctionSpace::Qk),
u(dof), shape_x(p + 1), shape_y(p + 1), shape_z(p + 1),
dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1),
d2shape_x(p + 1), d2shape_y(p + 1), d2shape_z(p + 1), du(dof,3)
{ orders[0] = orders[1] = orders[2] = p; }
/// Construct the NURBS3DFiniteElement with x-order @a px and y-order @a py
/// and z-order @a pz
NURBS3DFiniteElement(int px, int py, int pz)
: NURBSFiniteElement(3, Geometry::CUBE, (px + 1)*(py + 1)*(pz + 1),
std::max(std::max(px,py),pz), FunctionSpace::Qk),
u(dof), shape_x(px + 1), shape_y(py + 1), shape_z(pz + 1),
dshape_x(px + 1), dshape_y(py + 1), dshape_z(pz + 1),
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;
};
} // namespace mfem
#endif
+1443
View File
File diff suppressed because it is too large Load Diff
+372
View File
@@ -0,0 +1,372 @@
// Copyright (c) 2010-2021, 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_FE_POS
#define MFEM_FE_POS
#include "fe_base.hpp"
namespace mfem
{
/** @brief Class for finite elements utilizing the
always positive Bernstein basis. */
class PositiveFiniteElement : public ScalarFiniteElement
{
public:
/** @brief Construct PositiveFiniteElement with given
@param D Reference space dimension
@param G Geometry type (of type Geometry::Type)
@param Do Number of degrees of freedom in the FiniteElement
@param O Order/degree of the FiniteElement
@param F FunctionSpace type of the FiniteElement
*/
PositiveFiniteElement(int D, Geometry::Type G, int Do, int O,
int F = FunctionSpace::Pk) :
ScalarFiniteElement(D, G, Do, O, F)
{ }
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
{ ScalarLocalInterpolation(Trans, I, *this); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ ScalarLocalRestriction(Trans, R, *this); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ 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;
virtual void Project (VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const;
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const;
};
class PositiveTensorFiniteElement : public PositiveFiniteElement,
public TensorBasisElement
{
public:
PositiveTensorFiniteElement(const int dims, const int p,
const DofMapType dmtype);
const DofToQuad &GetDofToQuad(const IntegrationRule &ir,
DofToQuad::Mode mode) const
{
return (mode == DofToQuad::FULL) ?
ScalarFiniteElement::GetDofToQuad(ir, mode) :
ScalarFiniteElement::GetTensorDofToQuad(*this, ir, mode);
}
};
/// A 2D positive bi-quadratic element on a square utilizing the 2nd order
/// Bernstein basis
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;
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
{ dofs = 0.; dofs(vertex) = 1.; }
};
/// A 1D quadratic positive element utilizing the 2nd order Bernstein basis
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;
};
/// Arbitrary order H1 elements in 1D utilizing the Bernstein basis
class H1Pos_SegmentElement : public PositiveTensorFiniteElement
{
private:
#ifndef MFEM_THREAD_SAFE
// This is to share scratch space between invocations, which helps speed
// things up, but with OpenMP, we need one copy per thread. Right now, we
// solve this by allocating this space within each function call every time
// we call it. Alternatively, we should do some sort thread private thing.
// Brunner, Jan 2014
mutable Vector shape_x, dshape_x;
#endif
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;
};
/// Arbitrary order H1 elements in 2D utilizing the Bernstein basis on a square
class H1Pos_QuadrilateralElement : public PositiveTensorFiniteElement
{
private:
#ifndef MFEM_THREAD_SAFE
// See comment in H1Pos_SegmentElement
mutable Vector shape_x, shape_y, dshape_x, dshape_y;
#endif
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;
};
/// Arbitrary order H1 elements in 3D utilizing the Bernstein basis on a cube
class H1Pos_HexahedronElement : public PositiveTensorFiniteElement
{
private:
#ifndef MFEM_THREAD_SAFE
// See comment in H1Pos_SegmentElement.
mutable Vector shape_x, shape_y, shape_z, dshape_x, dshape_y, dshape_z;
#endif
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;
};
/// Arbitrary order H1 elements in 2D utilizing the Bernstein basis on a triangle
class H1Pos_TriangleElement : public PositiveFiniteElement
{
protected:
#ifndef MFEM_THREAD_SAFE
mutable Vector m_shape, dshape_1d;
mutable DenseMatrix m_dshape;
#endif
Array<int> dof_map;
public:
/// Construct the H1Pos_TriangleElement of order @a p
H1Pos_TriangleElement(const int p);
// The size of shape is (p+1)(p+2)/2 (dof).
static void CalcShape(const int p, const double x, const double y,
double *shape);
// The size of dshape_1d is p+1; the size of dshape is (dof x dim).
static void CalcDShape(const int p, const double x, const double y,
double *dshape_1d, double *dshape);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
};
/// Arbitrary order H1 elements in 3D utilizing the Bernstein basis on a
/// tetrahedron
class H1Pos_TetrahedronElement : public PositiveFiniteElement
{
protected:
#ifndef MFEM_THREAD_SAFE
mutable Vector m_shape, dshape_1d;
mutable DenseMatrix m_dshape;
#endif
Array<int> dof_map;
public:
/// Construct the H1Pos_TetrahedronElement of order @a p
H1Pos_TetrahedronElement(const int p);
// The size of shape is (p+1)(p+2)(p+3)/6 (dof).
static void CalcShape(const int p, const double x, const double y,
const double z, double *shape);
// The size of dshape_1d is p+1; the size of dshape is (dof x dim).
static void CalcDShape(const int p, const double x, const double y,
const double z, double *dshape_1d, double *dshape);
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
};
/// Arbitrary order H1 elements in 3D utilizing the Bernstein basis on a wedge
class H1Pos_WedgeElement : public PositiveFiniteElement
{
protected:
#ifndef MFEM_THREAD_SAFE
mutable Vector t_shape, s_shape;
mutable DenseMatrix t_dshape, s_dshape;
#endif
Array<int> t_dof, s_dof;
H1Pos_TriangleElement TriangleFE;
H1Pos_SegmentElement SegmentFE;
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;
};
/// Arbitrary order L2 elements in 1D utilizing the Bernstein basis on a segment
class L2Pos_SegmentElement : public PositiveTensorFiniteElement
{
private:
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_x, dshape_x;
#endif
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;
};
/// Arbitrary order L2 elements in 2D utilizing the Bernstein basis on a square
class L2Pos_QuadrilateralElement : public PositiveTensorFiniteElement
{
private:
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_x, shape_y, dshape_x, dshape_y;
#endif
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;
};
/// Arbitrary order L2 elements in 3D utilizing the Bernstein basis on a cube
class L2Pos_HexahedronElement : public PositiveTensorFiniteElement
{
private:
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_x, shape_y, shape_z, dshape_x, dshape_y, dshape_z;
#endif
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;
};
/// Arbitrary order L2 elements in 2D utilizing the Bernstein basis on a triangle
class L2Pos_TriangleElement : public PositiveFiniteElement
{
private:
#ifndef MFEM_THREAD_SAFE
mutable Vector dshape_1d;
#endif
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;
};
/// Arbitrary order L2 elements in 3D utilizing the Bernstein basis on a
/// tetrahedron
class L2Pos_TetrahedronElement : public PositiveFiniteElement
{
private:
#ifndef MFEM_THREAD_SAFE
mutable Vector dshape_1d;
#endif
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;
};
/// Arbitrary order L2 elements in 3D utilizing the Bernstein basis on a wedge
class L2Pos_WedgeElement : public PositiveFiniteElement
{
protected:
#ifndef MFEM_THREAD_SAFE
mutable Vector t_shape, s_shape;
mutable DenseMatrix t_dshape, s_dshape;
#endif
Array<int> t_dof, s_dof;
L2Pos_TriangleElement TriangleFE;
L2Pos_SegmentElement SegmentFE;
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;
};
} // namespace mfem
#endif
+1020
View File
File diff suppressed because it is too large Load Diff
+268
View File
@@ -0,0 +1,268 @@
// Copyright (c) 2010-2021, 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_FE_RT
#define MFEM_FE_RT
#include "fe_base.hpp"
namespace mfem
{
/// Arbitrary order Raviart-Thomas elements in 2D on a square
class RT_QuadrilateralElement : public VectorTensorFiniteElement
{
private:
static const double nk[8];
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_cx, shape_ox, shape_cy, shape_oy;
mutable Vector dshape_cx, dshape_cy;
#endif
Array<int> dof2nk;
const double *cp;
public:
/** @brief Construct the RT_QuadrilateralElement of order @a p and closed and
open BasisType @a cb_type and @a ob_type */
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
{ CalcVShape_RT(Trans, shape); }
virtual void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_RT(*this, nk, dof2nk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ LocalRestriction_RT(nk, dof2nk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_RT(CheckVectorFE(fe), nk, dof2nk, Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
{
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
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
{ ProjectMatrixCoefficient_RT(nk, dof2nk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const
{ Project_RT(nk, dof2nk, fe, Trans, I); }
// Gradient + rotation = Curl: H1 -> H(div)
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
{ ProjectGrad_RT(nk, dof2nk, fe, Trans, grad); }
// Curl = Gradient + rotation: H1 -> H(div)
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
{ ProjectGrad_RT(nk, dof2nk, fe, Trans, curl); }
protected:
void ProjectIntegrated(VectorCoefficient &vc, ElementTransformation &Trans,
Vector &dofs) const;
};
/// Arbitrary order Raviart-Thomas elements in 3D on a cube
class RT_HexahedronElement : public VectorTensorFiniteElement
{
static const double nk[18];
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_cx, shape_ox, shape_cy, shape_oy, shape_cz, shape_oz;
mutable Vector dshape_cx, dshape_cy, dshape_cz;
#endif
Array<int> dof2nk;
const double *cp;
public:
/** @brief Construct the RT_HexahedronElement of order @a p and closed and
open BasisType @a cb_type and @a ob_type */
RT_HexahedronElement(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
{ CalcVShape_RT(Trans, shape); }
virtual void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_RT(*this, nk, dof2nk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ LocalRestriction_RT(nk, dof2nk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_RT(CheckVectorFE(fe), nk, dof2nk, Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
{
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
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
{ ProjectMatrixCoefficient_RT(nk, dof2nk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const
{ Project_RT(nk, dof2nk, fe, Trans, I); }
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
{ ProjectCurl_RT(nk, dof2nk, fe, Trans, curl); }
protected:
void ProjectIntegrated(VectorCoefficient &vc,
ElementTransformation &Trans,
Vector &dofs) const;
};
/// Arbitrary order Raviart-Thomas elements in 2D on a triangle
class RT_TriangleElement : public VectorFiniteElement
{
static const double nk[6], c;
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_x, shape_y, shape_l;
mutable Vector dshape_x, dshape_y, dshape_l;
mutable DenseMatrix u;
mutable Vector divu;
#endif
Array<int> dof2nk;
DenseMatrixInverse Ti;
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
{ CalcVShape_RT(Trans, shape); }
virtual void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_RT(*this, nk, dof2nk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ LocalRestriction_RT(nk, dof2nk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_RT(CheckVectorFE(fe), nk, dof2nk, Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
{ ProjectMatrixCoefficient_RT(nk, dof2nk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const
{ Project_RT(nk, dof2nk, fe, Trans, I); }
// Gradient + rotation = Curl: H1 -> H(div)
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
{ ProjectGrad_RT(nk, dof2nk, fe, Trans, grad); }
// Curl = Gradient + rotation: H1 -> H(div)
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
{ ProjectGrad_RT(nk, dof2nk, fe, Trans, curl); }
};
/// Arbitrary order Raviart-Thomas elements in 3D on a tetrahedron
class RT_TetrahedronElement : public VectorFiniteElement
{
static const double nk[12], c;
#ifndef MFEM_THREAD_SAFE
mutable Vector shape_x, shape_y, shape_z, shape_l;
mutable Vector dshape_x, dshape_y, dshape_z, dshape_l;
mutable DenseMatrix u;
mutable Vector divu;
#endif
Array<int> dof2nk;
DenseMatrixInverse Ti;
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
{ CalcVShape_RT(Trans, shape); }
virtual void CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_RT(*this, nk, dof2nk, Trans, I); }
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ LocalRestriction_RT(nk, dof2nk, Trans, R); }
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_RT(CheckVectorFE(fe), nk, dof2nk, Trans, I); }
using FiniteElement::Project;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
{ ProjectMatrixCoefficient_RT(nk, dof2nk, mc, T, dofs); }
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const
{ Project_RT(nk, dof2nk, fe, Trans, I); }
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
{ ProjectCurl_RT(nk, dof2nk, fe, Trans, curl); }
};
} // namespace mfem
#endif
+247
View File
@@ -0,0 +1,247 @@
// Copyright (c) 2010-2021, 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.
// Serendipity Finite Element classes
#include "fe_ser.hpp"
#include "fe_fixed_order.hpp"
namespace mfem
{
using namespace std;
H1Ser_QuadrilateralElement::H1Ser_QuadrilateralElement(const int p)
: ScalarFiniteElement(2, Geometry::SQUARE, (p*p + 3*p +6) / 2, p,
FunctionSpace::Qk)
{
// Store the dof_map of the associated TensorBasisElement, which will be used
// to create the serendipity dof map. Its size is larger than the size of
// the serendipity element.
TensorBasisElement tbeTemp =
TensorBasisElement(2, p, BasisType::GaussLobatto,
TensorBasisElement::DofMapType::Sr_DOF_MAP);
const Array<int> tp_dof_map = tbeTemp.GetDofMap();
const double *cp = poly1d.ClosedPoints(p, BasisType::GaussLobatto);
// Fixing the Nodes is exactly the same as the H1_QuadrilateralElement
// constructor except we only use those values of the associated tensor
// product dof_map that are <= the number of serendipity Dofs e.g. only DoFs
// 0-7 out of the 9 tensor product dofs (at quadratic order)
int o = 0;
for (int j = 0; j <= p; j++)
{
for (int i = 0; i <= p; i++)
{
if (tp_dof_map[o] < Nodes.Size())
{
Nodes.IntPoint(tp_dof_map[o]).x = cp[i];
Nodes.IntPoint(tp_dof_map[o]).y = cp[j];
}
o++;
}
}
}
void H1Ser_QuadrilateralElement::CalcShape(const IntegrationPoint &ip,
Vector &shape) const
{
int p = (this)->GetOrder();
double x = ip.x, y = ip.y;
Poly_1D::Basis edgeNodalBasis(poly1d.GetBasis(p, BasisType::GaussLobatto));
Vector nodalX(p+1);
Vector nodalY(p+1);
edgeNodalBasis.Eval(x, nodalX);
edgeNodalBasis.Eval(y, nodalY);
// First, fix edge-based shape functions. Use a nodal interpolant for edge
// points, weighted by the linear function that vanishes on opposite edge.
for (int i = 0; i < p-1; i++)
{
shape(4 + 0*(p-1) + i) = (nodalX(i+1))*(1.-y); // south edge 0->1
shape(4 + 1*(p-1) + i) = (nodalY(i+1))*x; // east edge 1->2
shape(4 + 3*(p-1) - i - 1) = (nodalX(i+1)) * y; // north edge 3->2
shape(4 + 4*(p-1) - i - 1) = (nodalY(i+1)) * (1. - x); // west edge 0->3
}
BiLinear2DFiniteElement bilinear = BiLinear2DFiniteElement();
Vector bilinearsAtIP(4);
bilinear.CalcShape(ip, bilinearsAtIP);
const double *edgePts(poly1d.ClosedPoints(p, BasisType::GaussLobatto));
// Next, set the shape function associated with vertex V, evaluated at (x,y)
// to be: bilinear function associated to V, evaluated at (x,y) - sum (shape
// function at edge point P, weighted by bilinear function for V evaluated at
// P) where the sum is taken only for points P on edges incident to V.
double vtx0fix =0;
double vtx1fix =0;
double vtx2fix =0;
double vtx3fix =0;
for (int i = 0; i<p-1; i++)
{
vtx0fix += (1-edgePts[i+1])*(shape(4 + i) +
shape(4 + 4*(p-1) - i - 1)); // bot+left edge
vtx1fix += (1-edgePts[i+1])*(shape(4 + 1*(p-1) + i) +
shape(4 + (p-2)-i)); // right+bot edge
vtx2fix += (1-edgePts[i+1])*(shape(4 + 2*(p-1) + i) +
shape(1 + 2*p-i)); // top+right edge
vtx3fix += (1-edgePts[i+1])*(shape(4 + 3*(p-1) + i) +
shape(3*p - i)); // left+top edge
}
shape(0) = bilinearsAtIP(0) - vtx0fix;
shape(1) = bilinearsAtIP(1) - vtx1fix;
shape(2) = bilinearsAtIP(2) - vtx2fix;
shape(3) = bilinearsAtIP(3) - vtx3fix;
// Interior basis functions appear starting at order p=4. These are non-nodal
// bubble functions.
if (p > 3)
{
double *legX = new double[p-1];
double *legY = new double[p-1];
Poly_1D *storeLegendre = new Poly_1D();
storeLegendre->CalcLegendre(p-2, x, legX);
storeLegendre->CalcLegendre(p-2, y, legY);
int interior_total = 0;
for (int j = 4; j < p + 1; j++)
{
for (int k = 0; k < j-3; k++)
{
shape(4 + 4*(p-1) + interior_total)
= legX[k] * legY[j-4-k] * x * (1. - x) * y * (1. - y);
interior_total++;
}
}
delete[] legX;
delete[] legY;
delete storeLegendre;
}
}
void H1Ser_QuadrilateralElement::CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const
{
int p = (this)->GetOrder();
double x = ip.x, y = ip.y;
Poly_1D::Basis edgeNodalBasis(poly1d.GetBasis(p, BasisType::GaussLobatto));
Vector nodalX(p+1);
Vector DnodalX(p+1);
Vector nodalY(p+1);
Vector DnodalY(p+1);
edgeNodalBasis.Eval(x, nodalX, DnodalX);
edgeNodalBasis.Eval(y, nodalY, DnodalY);
for (int i = 0; i < p-1; i++)
{
dshape(4 + 0*(p-1) + i,0) = DnodalX(i+1) * (1.-y);
dshape(4 + 0*(p-1) + i,1) = -nodalX(i+1);
dshape(4 + 1*(p-1) + i,0) = nodalY(i+1);
dshape(4 + 1*(p-1) + i,1) = DnodalY(i+1)*x;
dshape(4 + 3*(p-1) - i - 1,0) = DnodalX(i+1)*y;
dshape(4 + 3*(p-1) - i - 1,1) = nodalX(i+1);
dshape(4 + 4*(p-1) - i - 1,0) = -nodalY(i+1);
dshape(4 + 4*(p-1) - i - 1,1) = DnodalY(i+1) * (1.-x);
}
BiLinear2DFiniteElement bilinear = BiLinear2DFiniteElement();
DenseMatrix DbilinearsAtIP(4);
bilinear.CalcDShape(ip, DbilinearsAtIP);
const double *edgePts(poly1d.ClosedPoints(p, BasisType::GaussLobatto));
dshape(0,0) = DbilinearsAtIP(0,0);
dshape(0,1) = DbilinearsAtIP(0,1);
dshape(1,0) = DbilinearsAtIP(1,0);
dshape(1,1) = DbilinearsAtIP(1,1);
dshape(2,0) = DbilinearsAtIP(2,0);
dshape(2,1) = DbilinearsAtIP(2,1);
dshape(3,0) = DbilinearsAtIP(3,0);
dshape(3,1) = DbilinearsAtIP(3,1);
for (int i = 0; i<p-1; i++)
{
dshape(0,0) -= (1-edgePts[i+1])*(dshape(4 + 0*(p-1) + i, 0) +
dshape(4 + 4*(p-1) - i - 1,0));
dshape(0,1) -= (1-edgePts[i+1])*(dshape(4 + 0*(p-1) + i, 1) +
dshape(4 + 4*(p-1) - i - 1,1));
dshape(1,0) -= (1-edgePts[i+1])*(dshape(4 + 1*(p-1) + i, 0) +
dshape(4 + (p-2)-i, 0));
dshape(1,1) -= (1-edgePts[i+1])*(dshape(4 + 1*(p-1) + i, 1) +
dshape(4 + (p-2)-i, 1));
dshape(2,0) -= (1-edgePts[i+1])*(dshape(4 + 2*(p-1) + i, 0) +
dshape(1 + 2*p-i, 0));
dshape(2,1) -= (1-edgePts[i+1])*(dshape(4 + 2*(p-1) + i, 1) +
dshape(1 + 2*p-i, 1));
dshape(3,0) -= (1-edgePts[i+1])*(dshape(4 + 3*(p-1) + i, 0) +
dshape(3*p - i, 0));
dshape(3,1) -= (1-edgePts[i+1])*(dshape(4 + 3*(p-1) + i, 1) +
dshape(3*p - i, 1));
}
if (p > 3)
{
double *legX = new double[p-1];
double *legY = new double[p-1];
double *DlegX = new double[p-1];
double *DlegY = new double[p-1];
Poly_1D *storeLegendre = new Poly_1D();
storeLegendre->CalcLegendre(p-2, x, legX, DlegX);
storeLegendre->CalcLegendre(p-2, y, legY, DlegY);
int interior_total = 0;
for (int j = 4; j < p + 1; j++)
{
for (int k = 0; k < j-3; k++)
{
dshape(4 + 4*(p-1) + interior_total, 0) =
legY[j-4-k]*y*(1-y) * (DlegX[k]*x*(1-x) + legX[k]*(1-2*x));
dshape(4 + 4*(p-1) + interior_total, 1) =
legX[k]*x*(1-x) * (DlegY[j-4-k]*y*(1-y) + legY[j-4-k]*(1-2*y));
interior_total++;
}
}
delete[] legX;
delete[] legY;
delete[] DlegX;
delete[] DlegY;
delete storeLegendre;
}
}
void H1Ser_QuadrilateralElement::GetLocalInterpolation(ElementTransformation
&Trans,
DenseMatrix &I) const
{
// For p<=4, the basis is nodal; for p>4, the quad-interior functions are
// non-nodal.
if (order <= 4)
{
NodalLocalInterpolation(Trans, I, *this);
}
else
{
ScalarLocalInterpolation(Trans, I, *this);
}
}
}

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