Compare commits

...
Author SHA1 Message Date
Socratis Petrides bc39660801 minor bug 2023-05-31 11:00:58 -07:00
Frank Wang a72cd6b7a8 remove comments 2023-04-07 18:43:48 -07:00
Frank Wang bcc308b263 fixing bugs 2023-04-07 18:43:09 -07:00
nychiang 23b5e402e3 clean code 2023-04-04 16:40:28 -07:00
nychiang ee0dd42064 code style 2023-04-04 12:14:57 -07:00
nychiang 39a78ff3df IPOPT in mfem 2023-04-04 00:09:53 -07:00
Frank Wang 20460cafda add bc 2023-03-31 10:57:16 -07:00
Frank Wang 2f188e9fcf fix bug 2023-03-29 10:29:51 -07:00
Frank Wang e772d71ecb update 2023-03-24 21:43:41 -07:00
Frank Wang d9c4cad220 latest update 2023-03-21 12:35:20 -07:00
Frank Wang 0c572d4779 comment out nodepair for now 2023-03-16 13:44:16 -07:00
Frank Wang 4320ad2272 adding things needed for Jacobian computation 2023-03-16 13:42:17 -07:00
Dylan Copeland 5c09d2b4c9 Added computation of face reference coordinates, as well as the global vertex indices corresponding to the corners of the face. 2023-03-15 20:16:36 -07:00
Dylan Copeland 65e75e271b Enabling an example with points outside domain 1. 2023-03-15 17:35:55 -07:00
Frank Wang f8e5fe77e6 update contact 2023-03-12 19:07:25 -07:00
Frank Wang 4ff880f0cf remove binary 2023-03-10 11:04:44 -08:00
Frank Wang a1f57a6375 adding x field 2023-03-10 10:28:01 -08:00
Dylan Copeland 5ffb605333 Fixing contact example. 2023-03-08 18:52:04 -08:00
Frank Wang f8ea695e13 add contactcpp 2023-03-08 12:02:01 -08:00
Veselin Dobrev fe525828ab Merge pull request #3501 from mfem/task/2023_02_windows_macro_fixes
changes to enums to avoid windows macro conflicts
2023-03-08 11:22:57 -08:00
Tzanio Kolev a275e75549 Merge pull request #3427 from mfem/FindPointsGSLIB-update
Fix logic for points near but outside domain boundary
2023-03-07 12:45:23 -08:00
Veselin Dobrev 119451df1a Rename NO_ERROR_ to No_Error and REGISTERED_ to Registered 2023-03-06 16:26:45 -08:00
Veselin Dobrev c8801d0d27 Merge pull request #3515 from mfem/bugfix/generalize-addelemvec
Relax the assert requirement in AddElementVector
2023-03-04 20:24:48 -08:00
Ben Chung Yee ff993ffb1b Loosen assert in SetSubVector as well 2023-02-28 18:05:58 -08:00
Ben Chung Yee 69d96008ae Relax the assert requirement in AddElementVector
The implementation is fine if we just want the dofs.Size() entries of
elemvect, so we only need <= rather than ==

This is currently causing an issue in
ParLinearForm::AssembleSharedFaces, where the integrator returns an
elemvect of size 2x dofs, but we are only appending the local portion of
that vector.
2023-02-28 17:52:26 -08:00
Ketan Mittal 72b0bdbcef serial sample run 2023-02-28 11:50:12 -08:00
Mark L. Stowell ea5c466486 Merge pull request #3314 from mfem/sjg/dof-to-quad-dev
Non-tensor H(curl) and H(div) FiniteElement::GetDofToQuad
2023-02-24 16:27:35 -08:00
Mark L. Stowell 82bc4f058d Merge branch 'master' into sjg/dof-to-quad-dev 2023-02-24 14:34:18 -08:00
Tzanio Kolev c416dddeae Merge pull request #3253 from mfem/parGF-grad
GetGradient methods for face-neighbor elements.
2023-02-24 14:23:37 -08:00
Tzanio Kolev 7aa6e58d07 Merge branch 'master' into parGF-grad 2023-02-24 14:23:29 -08:00
Mark L. Stowell df01ea1554 Merge branch 'master' into sjg/dof-to-quad-dev 2023-02-24 13:43:25 -08:00
Mark L. Stowell 563b8d455a Merge pull request #3503 from mfem/fe-coll--fe-for-dim--fix
Fix an issue in `FiniteElementCollection::FiniteElementForDim`
2023-02-24 13:42:08 -08:00
Mark L. Stowell e28ed04f52 Merge branch 'master' into sjg/dof-to-quad-dev 2023-02-24 13:05:26 -08:00
Mark L. Stowell 1406569993 Merge branch 'master' into fe-coll--fe-for-dim--fix 2023-02-24 13:00:10 -08:00
Veselin Dobrev c5b77f1dca Merge pull request #3474 from mfem/mass-pa-geom
Use GeometricFactors::DETERMINANTS in PA mass integrator
2023-02-24 12:30:54 -08:00
Veselin Dobrev 220b22f33b Merge pull request #3462 from mfem/cmake-global-flag-fix
Cmake global flag fix
2023-02-23 09:41:33 -08:00
Tzanio Kolev 1789cb6d3f Merge pull request #3468 from mfem/origin/ms-fix
Bug fixes in GSLib and TMOP
2023-02-23 07:41:55 -08:00
Ketan Mittal d1689afc84 Merge branch 'master' of https://github.com/mfem/mfem into FindPointsGSLIB-update 2023-02-22 17:59:07 -08:00
Cyrus Harrison 023552d99f Merge branch 'master' into task/2023_02_windows_macro_fixes 2023-02-21 16:38:44 -08:00
Will Pazner 1f89a88844 Merge pull request #3363 from mfem/mesh-reflect
Mesh reflector miniapp
2023-02-21 14:38:00 -08:00
Will Pazner d3d3b6b1c5 Merge pull request #3452 from mfem/static_glvis_init
Avoid global initialization issues in (p)minimal-surface
2023-02-21 14:37:34 -08:00
Tzanio Kolev 5a0414146c Merge pull request #3275 from mfem/add_default_constructor
Add default constructor to ParFiniteElementSpaceHierarchy [add_default_constructor]
2023-02-21 13:51:11 -08:00
Tzanio Kolev e90514c51f Merge pull request #3458 from mfem/goto-dev
Change intersect algorithm to not use goto
2023-02-21 13:50:33 -08:00
Veselin Dobrev 715175844d Merge pull request #3412 from mfem/tmop-auto-gamma
TMOP - balancing of compound metrics
2023-02-21 12:46:27 -08:00
Veselin Dobrev af73e58ffc Fix an issue in FiniteElementCollection::FiniteElementForDim for
sub-classes that raise errors instead of returning NULL from
calls to FiniteElementForGeometry.
2023-02-21 12:27:59 -08:00
Mathias Rainer Schmidt 534194bb74 - removed comm_free() call from this PR. Should be investigated in future PR to resolve the corresponding memory leak. 2023-02-21 12:07:48 -08:00
Cyrus Harrison 13cccd6c66 style 2023-02-21 11:19:12 -08:00
Cyrus Harrison 06beca6d83 changes to enums to avoid windows macro conflicts 2023-02-21 10:59:20 -08:00
Will Pazner fb2b2f0067 Use GeometricFactors::DETERMINANTS in PA mass integrator 2023-02-17 13:57:15 -08:00
Mathias Rainer Schmidt 9484091bce - fixed memory corruption bug
- fixed parallel bug
- fixed memory leak
2023-02-16 11:19:41 -08:00
Hugh Carson 78706f96dc Further unwind the nested if branch 2023-02-15 13:25:19 -05:00
Dylan Copeland 92e11e48f8 Merge branch 'master' into mesh-reflect 2023-02-14 22:25:55 -08:00
Dylan Copeland 42102085ec Another attempt. 2023-02-14 21:30:51 -08:00
Dylan Copeland 4d95303bf3 Attempting to fix reflector serial test. 2023-02-14 21:01:04 -08:00
Ketan Mittal 1399f10675 change sample runs in miniapp 2023-02-14 13:13:30 -08:00
Frank Wang d4b6deeeb7 fix bugs 2023-02-14 12:26:03 -08:00
Ketan Mittal 93f7e778cd Merge branch 'FindPointsGSLIB-update' of https://github.com/mfem/mfem into FindPointsGSLIB-update 2023-02-14 11:54:24 -08:00
Ketan Mittal 8c62969dc7 disable FD+GSLIB+DiscreteAdaptivity 2023-02-14 11:53:09 -08:00
Vladimir Z Tomov 29ec82fcb9 changelog 2023-02-14 11:08:53 -08:00
Tzanio Kolev 1303b3e251 Merge branch 'master' into FindPointsGSLIB-update 2023-02-14 10:13:55 -08:00
Tzanio Kolev 93940754a3 Merge branch 'master' into add_default_constructor 2023-02-14 10:12:33 -08:00
Hugh Carson 69541be811 Change intersect algorithm to not use goto 2023-02-13 12:17:21 -05:00
Vladimir Z Tomov 5937a85546 small fix for sum=1. 2023-02-12 15:37:59 -08:00
Vladimir Z Tomov 5061dbd214 avoid possible div by zero 2023-02-10 17:55:26 -08:00
Dylan Copeland 7ded5aae7a FindFaceNeighbors now returns an Array instead of a set. 2023-02-10 10:21:14 -08:00
Tzanio Kolev e110cd4554 Merge branch 'master' into parGF-grad 2023-02-09 20:40:38 -08:00
Dylan Copeland e163306242 Documenting ownership of some tables. 2023-02-09 18:52:13 -08:00
Dylan Copeland 096c5f8db7 Fixed a memory leak. 2023-02-09 18:37:55 -08:00
Sebastian Grimberg 1b8e5e3717 Merge branch 'master' into sjg/dof-to-quad-dev 2023-02-09 14:32:44 -08:00
Tzanio Kolev 61b394409b Merge pull request #3440 from mfem/lor-space-fix
Support LOR transfer with smaller LOR spaces
2023-02-09 10:16:11 -08:00
Vladimir Z Tomov 1698c06900 gitignore 2023-02-08 09:25:43 -08:00
camierjs 48e3de797c Avoid global initialization issues in (p)minimal-surface 2023-02-08 08:58:20 -08:00
Dylan Copeland f7f20e8542 Add reflector to SEQ_MINIAPPS. 2023-02-07 20:59:47 -08:00
Dylan Copeland dd40e443c1 Merge branch 'master' of github.com:mfem/mfem into mesh-reflect 2023-02-07 20:59:09 -08:00
Vladimir Z Tomov 7ad3cd3509 autotest fix 2023-02-07 18:45:03 -08:00
Vladimir Z Tomov 371047e628 missing ifdef. 2023-02-07 18:21:37 -08:00
Vladimir Z Tomov fd4bf50a71 minor 2023-02-07 18:13:11 -08:00
Vladimir Z Tomov fa89fbfc71 minor 2023-02-07 18:09:57 -08:00
Vladimir Z Tomov 8805b1fd98 Removed the universal averaging stuff. 2023-02-07 17:42:10 -08:00
Vladimir Z Tomov 32d62a23a3 canceled 3d tmop-metric-magnitude for now. 2023-02-07 17:34:43 -08:00
Vladimir Z Tomov 35300fa1b6 Merge branch 'master' into tmop-auto-gamma 2023-02-07 17:14:28 -08:00
Veselin Dobrev d5f46a61bc Merge pull request #3411 from mfem/gitlab-ci-retry-push
Retry git push in autotest GitLab CI
2023-02-07 12:20:24 -08:00
Sebastian Grimberg 538ec0b33d Merge branch 'master' into sjg/dof-to-quad-dev 2023-02-07 12:06:22 -08:00
Will Pazner 2e8c7a1c07 Handle the case of empty local mesh 2023-02-07 10:02:02 -08:00
Frank Wang c33a8cebb4 using a simpler changwe 2023-02-06 10:19:04 -08:00
Tzanio Kolev 52162982a8 Merge pull request #2980 from mfem/gmsh-pyr-dev
Add support for pyramid elements in Gmsh meshes
2023-02-03 15:28:09 -08:00
Tzanio Kolev 69c52e55bd Merge pull request #3430 from mfem/nodes-doxygen
Improve Doxygen comments for Mesh::GetNodes and related functions
2023-02-03 15:27:21 -08:00
Tzanio Kolev 23b0fa7e3c Merge branch 'master' into gmsh-pyr-dev 2023-02-03 15:26:57 -08:00
Dylan Copeland 13504d6116 Merge branch 'master' of github.com:mfem/mfem into mesh-reflect 2023-02-03 15:02:51 -08:00
Dylan Copeland 9aa6b00053 Removed unused variable. Fixed the boundary element orientation. Added some documentation. 2023-02-03 14:58:29 -08:00
Will Pazner a059294d02 Merge pull request #3441 from mfem/missing-inline
Add missing `inline`
2023-02-03 13:44:56 -08:00
Will Pazner 2e8750410e Merge pull request #3364 from mfem/fix-hypreparvec-double-free
Fix double-free of HypreParVector after move with hypre+GPU
2023-02-03 13:43:46 -08:00
Will Pazner 33635307cf Merge pull request #3405 from mfem/final-rel-norm
Initial and relative final norm for IterativeSolvers.
2023-02-03 13:42:50 -08:00
Will Pazner 75b1906749 Merge branch 'master' into fix-hypreparvec-double-free 2023-02-03 12:59:55 -08:00
Veselin Dobrev 271c63fbee Merge pull request #3445 from mfem/update-setup-mpi-action
Update version of mpi4py/setup-mpi action
2023-02-03 12:35:10 -08:00
Veselin Dobrev ad37c6af78 Merge pull request #3357 from mfem/docs-get-trans
Documentation improvements for `GetTransformation()`
2023-02-02 18:56:52 -08:00
Will Pazner 64e61fdc3e Update version of mpi4py/setup-mpi action 2023-02-01 10:27:46 -08:00
Vladimir Z Tomov ce74176355 CGSolver norm<0 fix. 2023-01-31 10:40:51 -08:00
Tom Stitt 6acba0c1f0 add inline to avoid duplicate symbols (discovered with misconfigured compute-device spec) 2023-01-30 12:45:40 -08:00
Sebastian Grimberg caa1e2c7ae Update changelog 2023-01-30 08:59:29 -08:00
Tzanio Kolev e70e80da3f Merge pull request #3417 from mfem/pbilinearform-fix
Bugfix in `ParBilinearForm::TrueAddMult`
2023-01-30 08:30:00 -08:00
Tzanio Kolev 2c6d541745 Merge pull request #3285 from mfem/tmop-fix-301
Fix metric 301.
2023-01-30 08:29:20 -08:00
Vladimir Z Tomov a92e1600e3 3D perturbations. 2023-01-29 18:23:09 -08:00
Will Pazner f271e9d549 Allow construction of L2ProjectionGridTransfer::ForwardOperator even when the LOR space is small
Resolves issue #2429.
2023-01-28 16:28:11 -08:00
Tzanio Kolev 2f6eb8838f Merge pull request #3007 from mfem/bugfix/rwa/coarsen-L2-proj
Use local L2 projection for coarsening L2 spaces on non-conforming AMR meshes [bugfix/rwa/coarsen-L2-proj]
2023-01-27 14:30:06 -08:00
Veselin Dobrev cbfbe68651 Update and sort the list of tests in tests/unit/CMakeLists.txt 2023-01-26 15:03:39 -08:00
Vladimir Z Tomov 8358ce040b minor 2023-01-25 10:16:23 -08:00
Vladimir Z Tomov b4934a836c Tool for checking magnitudes. 2023-01-24 19:58:27 -08:00
Sebastian Grimberg 446eda52c7 Minor style cleanup looking for bug in next 2023-01-24 18:13:03 -08:00
Vladimir Z Tomov 0a3f8bdea5 Reviewer suggestions. 2023-01-24 11:53:44 -08:00
Sebastian Grimberg b62e11cd34 Merge branch 'master' into sjg/dof-to-quad-dev 2023-01-24 11:47:32 -08:00
Vladimir Z Tomov 61613ae1a5 Merge branch 'master' into tmop-fix-301 2023-01-24 11:44:07 -08:00
Will Pazner 4c9157bd30 Improve Doxygen comments for Mesh::GetNodes and related functions 2023-01-23 15:53:09 -08:00
Will PaznerandAdrien Bernede 21c3272e3f Use short-circuit && instead of if statement
Co-authored-by: Adrien Bernede <51493078+adrienbernede@users.noreply.github.com>
2023-01-23 08:50:55 -08:00
Tzanio Kolev 62c65660c8 Merge branch 'master' into gmsh-pyr-dev 2023-01-21 14:56:14 -08:00
Vladimir Z Tomov 16d20ff17f balancing based on universal perturbed element. 2023-01-20 13:00:51 -08:00
Robert W. Anderson d3a98b2f01 fix for deprecated operator 2023-01-19 12:30:40 -08:00
Robert W. Anderson 83dfc2bb49 replace Set with SetRow for better performance 2023-01-19 10:47:28 -08:00
Ketan Mittal 058590bb39 fix logic for points near but outside domain boundary 2023-01-19 09:54:49 -08:00
Will Pazner 349ddfd954 Merge pull request #3410 from mfem/mesh-explorer-datacollection-dev
Adding DataCollection output to mesh-explorer [mesh-explorer-datacollection-dev]
2023-01-18 13:47:38 -08:00
Frank Wang 6ac4a86a15 update 2023-01-14 22:31:53 -08:00
Frank Wang d729b1b9bf cmake cuda using target 2023-01-14 22:20:24 -08:00
Mark L. Stowell 3bb1f7921b Merge branch 'master' into mesh-explorer-datacollection-dev 2023-01-14 09:14:44 -05:00
Will Pazner 715c242f44 Bug fix 2023-01-13 21:40:05 -08:00
Will Pazner 01fde3cecb Make behavior of ParaViewDataCollection::SetCompression consistent with its Doxygen comment 2023-01-13 18:41:34 -08:00
Veselin Dobrev 6992c1daac In the mesh-explorer miniapp, use high-order ParaView export when
the mesh is high-order.

Tweak doxygen comments in class ParaViewDataCollection.

Fix a bug in ParaViewDataCollection::SetCompression -- it still
needs work, I think, so I left a FIXME comment there too.
2023-01-13 15:55:12 -08:00
Vladimir Z Tomov 95c2b08358 Reports the final imbalance of the combinations. 2023-01-13 13:14:10 -08:00
Vladimir Z Tomov 8bce1ab633 Reviewer suggestions. 2023-01-13 10:54:29 -08:00
Veselin Dobrev 479c15a336 Merge branch 'master' into fix-hypreparvec-double-free 2023-01-13 09:13:14 -08:00
Veselin Dobrev f858ed978d Make some move-assignment operators safe for self-assignment
See: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c65-make-move-assignment-safe-for-self-assignment
2023-01-12 17:06:26 -08:00
Veselin Dobrev aa6b8c24bb Cleaner implementation of move assignment for HypreParVector using
the Vector move assignment.

Small simplification in the Vector move assignment operator.
2023-01-12 16:04:59 -08:00
Veselin Dobrev 0905576515 Merge pull request #3403 from mfem/algoim_fix
Algoim configuration fix
2023-01-12 11:45:55 -08:00
Veselin Dobrev e401a26051 In ParBilinearForm::TrueAddMult, handle correctly the case when
the pointer 'pfes' has not changed but the object it points to
has changed, e.g. due to mesh refinement.
2023-01-12 10:28:06 -08:00
Veselin Dobrev 253eac37d2 A few small tweaks and fixes 2023-01-12 07:08:04 -08:00
Vladimir Z Tomov f282c0c2c5 General balancing of N metrics, moved it into the combo metric class. 2023-01-11 13:46:46 -08:00
Will Pazner 1922df6fd2 Simplify 2023-01-11 12:57:55 -08:00
Stowell, Mark L 05cf37c8c1 Adding CHANGELOG entry 2023-01-11 15:24:27 -05:00
Stowell, Mark L b561b07712 Changing default ParaViewDataCollection cycle index to zero 2023-01-11 15:07:20 -05:00
Will Pazner a87373710d Use git_try_to_push in quartz-baseline 2023-01-11 11:14:52 -08:00
Will Pazner 4ea2860257 Move delay after unsuccessful git push 2023-01-11 11:10:22 -08:00
Will Pazner d8ccf16b87 Add delay between git push retries 2023-01-11 10:59:36 -08:00
Will Pazner 64ccaa8941 Bug fix 2023-01-11 10:56:33 -08:00
Will Pazner 3937340ec3 Bug fix 2023-01-11 10:52:35 -08:00
Will Pazner c87fdf7e8b Retry git push in autotest GitLab CI 2023-01-11 10:16:06 -08:00
Stowell, Mark L 11b1d2a597 Removing extraneous setting (thanks @pazner!) 2023-01-11 12:05:43 -05:00
Stowell, Mark L ff6fed8ee9 Increased error handling in DataCollection option 2023-01-11 12:05:09 -05:00
Stowell, Mark L 3b98856717 Adding DataCollection output to mesh-explorer 2023-01-11 11:48:39 -05:00
Tzanio Kolev a598682d68 Merge pull request #3271 from Biswa96/cmake-mingw-install
Fix DLL install directory in mingw
2023-01-11 08:01:45 -08:00
Veselin Dobrev 3bc57ff6ba Merge pull request #3394 from mfem/coefficient-unneeded-using
Remove unneeded `using` statements in coefficient.hpp
2023-01-10 16:25:56 -08:00
Tzanio Kolev 5a6ef6e9e2 Merge branch 'master' into cmake-mingw-install 2023-01-10 14:26:28 -08:00
Veselin Dobrev a1849e45a3 Merge branch 'master' into coefficient-unneeded-using 2023-01-10 12:29:20 -08:00
Tzanio Kolev dec0dc4b4d Merge pull request #3402 from mfem/move-par-transfer-map
Add Array move constructor, make [Par]TransferMap movable
2023-01-10 12:12:07 -08:00
Sebastian Grimberg daa8b6b844 Add support for pyramid elements in Gmsh meshes 2023-01-10 10:43:23 -08:00
Sebastian Grimberg bc43f6fbf1 Merge branch 'master' into sjg/dof-to-quad-dev 2023-01-10 10:42:21 -08:00
Tzanio Kolev 2bf54066e9 Merge branch 'master' into move-par-transfer-map 2023-01-10 10:40:27 -08:00
Will Pazner 7aa756bebb Doxygen comments for IterativeSolver statistics 2023-01-10 10:28:54 -08:00
Mark L. Stowell 646715d66b Merge pull request #3075 from mfem/sjg/multigrid-mult-rhs
`Multigrid::Mult` with multiple RHS
2023-01-10 09:21:32 -05:00
Vladimir Z Tomov 84eb2bee18 minor 2023-01-09 22:47:37 -08:00
Boyan Lazarov 6c54854ddc Merge branch 'master' into algoim_fix 2023-01-09 21:48:53 -08:00
blaz c6922112d1 fix in findalgoim 2023-01-09 21:36:14 -08:00
Veselin Dobrev f64405b283 Merge branch 'master' into sjg/multigrid-mult-rhs 2023-01-09 12:16:28 -08:00
Vladimir Z Tomov d4eeee31b5 IterativeSolver::GetInitialNorm() and GetFinalRelNorm(). 2023-01-09 11:51:57 -08:00
Will Pazner 2ab6da3489 Remove unneeded static_cast 2023-01-08 20:07:36 -08:00
Will Pazner c5c7acd5cf Make TransferMap implicitly movable 2023-01-08 20:07:36 -08:00
Will Pazner eaaa541a16 Make ParTransferMap implicitly movable 2023-01-08 20:07:36 -08:00
Will Pazner 40a0fac667 Add move constructor to Array<T> 2023-01-08 20:07:34 -08:00
BL 4426e33e7e initial agloim fix 2023-01-08 17:50:34 -08:00
Will Pazner 8754571ef0 Infer root mesh type in GetRootParent 2023-01-08 17:25:39 -08:00
Tzanio Kolev f00eb000ed Merge pull request #3387 from mfem/submesh-surface-bdr-fix
Bugfix for surface submesh boundary elements from volume
2023-01-08 14:48:58 -08:00
Will Pazner cc79e6a1b9 Remove another using statement in coefficient.hpp 2023-01-05 14:59:53 -08:00
Tzanio Kolev 745504e4ab Merge pull request #3320 from mfem/FaceQuadratureSpace-bug-fix
Bug fix for non-conforming meshes.
2023-01-05 14:08:05 -08:00
Will Pazner 4e5b88054d Remove unneeded using statements in coefficient.hpp 2023-01-04 18:44:41 -08:00
Veselin Dobrev 576401f779 Merge pull request #3389 from mfem/fix-gnutls-shadow
Fix some shadow warnings
2023-01-03 19:43:45 -08:00
Vladimir Z Tomov bdb6e5a046 wip auto gamma in composite metrics 2023-01-03 14:06:21 -08:00
Veselin Dobrev 12dab69fe7 Merge branch 'master' into fix-gnutls-shadow 2023-01-03 12:42:21 -08:00
Will Pazner b210fb5398 Merge pull request #3362 from mfem/bugfix/kweiss/quad-face-ctor
Adds a QuadratureFunction constructor from external data
2023-01-03 12:33:22 -08:00
Veselin Dobrev f327a1f2fe Merge branch 'master' into fix-gnutls-shadow 2023-01-03 12:25:21 -08:00
Tzanio Kolev e81e3f7a55 Merge branch 'master' into bugfix/rwa/coarsen-L2-proj 2023-01-03 11:36:51 -08:00
Will Pazner 2d04785d2b Update CHANGELOG 2023-01-03 11:33:13 -08:00
Will Pazner 0364cab0f9 Merge remote-tracking branch 'origin/master' into FaceQuadratureSpace-bug-fix 2023-01-03 11:31:26 -08:00
Will Pazner b35eb5acd2 Merge remote-tracking branch 'origin/master' into bugfix/kweiss/quad-face-ctor 2023-01-03 11:17:25 -08:00
Tzanio Kolev eeece17619 Merge pull request #3293 from mfem/artv3/raja-launch-updates
RAJA launch API updates
2023-01-03 11:16:50 -08:00
Will Pazner 2905874bc0 Fix shadow warnings in ND and RT with MFEM_THREAD_SAFE 2022-12-29 14:53:35 -08:00
Will Pazner a8730f78fd Fix shadow warning when GNUTLS is enabled 2022-12-29 14:47:36 -08:00
Tzanio Kolev 70bcb774f2 Merge branch 'master' into bugfix/kweiss/quad-face-ctor 2022-12-28 11:06:34 -08:00
Tzanio Kolev 2b3b0ea1e7 Merge branch 'master' into FaceQuadratureSpace-bug-fix 2022-12-28 11:06:18 -08:00
Tzanio Kolev e53afac528 Merge branch 'master' into mesh-reflect 2022-12-28 11:05:15 -08:00
Tzanio Kolev fb21cca26e Merge branch 'master' into bugfix/rwa/coarsen-L2-proj 2022-12-28 11:03:05 -08:00
Tzanio Kolev f93da2f1b8 Merge branch 'master' into submesh-surface-bdr-fix 2022-12-28 10:17:41 -08:00
Tzanio Kolev e90e6e2b75 Merge pull request #3385 from mfem/gh-actions-homebrew-fix
Fix GitHub actions failure on MacOS
2022-12-28 10:17:17 -08:00
Veselin Dobrevand@tzanio fb3d72ce89 Add reviewer suggested comments
Co-authored-by: @tzanio
2022-12-28 10:08:50 -08:00
Will Pazner b9efa256b4 Add comment that QuadratureFunction constructor takes a host pointer 2022-12-27 15:08:03 -08:00
Tzanio Kolev 2e89831b1e Merge branch 'master' into gh-actions-homebrew-fix 2022-12-27 14:33:26 -08:00
Julian Andrej 3258e39120 bugfix for surface submesh boundary elements from volume 2022-12-27 13:49:31 -08:00
Veselin Dobrev ac1f88ee74 Merge pull request #3369 from mfem/feature/kweiss/caliper-dependencies
Adds support for optional caliper dependencies to build system
2022-12-25 19:21:05 -08:00
Veselin Dobrev 652e2ba386 GitHub actions: test MacOS fix 2022-12-24 16:15:52 -08:00
Veselin Dobrev 4756a9c405 Fix GitHub actions failure on MacOS 2022-12-24 15:39:40 -08:00
Tzanio KolevandYohann 72f17709e3 Update mesh/mesh.hpp
Co-authored-by: Yohann <dudouit1@llnl.gov>
2022-12-22 13:28:11 -08:00
Tzanio KolevandYohann 0aeb9b49b0 Update mesh/mesh.hpp
Co-authored-by: Yohann <dudouit1@llnl.gov>
2022-12-22 13:28:03 -08:00
Tzanio Kolev adf7a40c0a Merge branch 'master' into FaceQuadratureSpace-bug-fix 2022-12-22 13:25:39 -08:00
Kenneth Weiss 46f64bf75f Merge branch 'master' into feature/kweiss/caliper-dependencies 2022-12-21 10:58:53 -08:00
Kenneth Weiss 326a4177b4 Adds lib64 library paths for caliper, adiak and gotcha
Per PR suggestion.
2022-12-21 10:58:25 -08:00
Kenneth Weiss fcb9f6b4c2 Use find_package for adiak and gotcha dependencies in CMake build system
Per PR suggestion from Veselin.
2022-12-21 10:29:46 -08:00
Tzanio Kolev e16e2a916f Merge pull request #3373 from mfem/delete_noret
Modify Delete_ to not return a value
2022-12-19 15:24:44 -08:00
Tzanio Kolev c4f16f478b Merge pull request #3372 from mfem/enzyme_alloc
Add Enzyme info for allocation mechanisms
2022-12-19 15:23:33 -08:00
Tzanio Kolev bf8ec1a218 Merge pull request #3334 from mfem/bugfix/submesh-bdr-l2
Adding SubMesh support for discontinuous fields with vdim > 1
2022-12-17 19:17:24 -08:00
William S. Moses 973b42c57a Simplify 2022-12-16 17:19:02 -05:00
Veselin Dobrev 0ee0e55a92 Fix the Caliper tests defined in CMake 2022-12-15 18:33:42 -08:00
Tzanio Kolev 1f16c7a309 make style 2022-12-15 16:39:10 -08:00
William S. Moses ef42d3994a Add Enzyme info for allocation mechanisms 2022-12-15 18:07:34 -05:00
William S. Moses 0f75a95372 Modifiy Delete_ to not return a value 2022-12-15 18:06:16 -05:00
Dylan Copeland 91946fa48c Formatting 2022-12-15 12:22:07 -08:00
Dylan Copeland eadf460df5 Revert SEQ_MINIAPPS. 2022-12-15 11:21:07 -08:00
Dylan Copeland 726ffb93b0 CHANGELOG and a bug fix. 2022-12-15 10:56:26 -08:00
Sebastian Grimberg 7548778722 Rename Mult -> ArrayMult and similar to avoid partially overridden warnings 2022-12-14 18:14:38 -08:00
Dylan Copeland cffcc25cf1 Made GridFunction::GetVectorGradientHat public. Updated gitignore. 2022-12-14 18:13:55 -08:00
Kenneth Weiss 09331236d2 Adds support for optional caliper dependencies in cmake build system
If a user's caliper is built against `adiak` or `gotcha`, they can supply
`ADIAK_DIR` and/or `GOTCHA_DIR` config variables.
2022-12-14 12:18:52 -08:00
Kenneth Weiss be9f6a0d07 Adds support for optional caliper dependencies in make build system
If a user's caliper is built against `adiak` or `gotcha`, they can supply
`ADIAK_DIR` and/or `GOTCHA_DIR` config variables.
2022-12-14 12:18:42 -08:00
Dylan Copeland 2c1b05d448 Fixing default options. 2022-12-13 20:28:44 -08:00
Dylan Copeland 1d758dbc66 Fixing documentation. 2022-12-13 19:46:57 -08:00
Dylan Copeland 792184cf2c Fixing shadowed variable. 2022-12-13 19:33:14 -08:00
Dylan Copeland e4b71fde61 Moved FindFaceNeighbors to Mesh class. Added documentation. 2022-12-13 19:22:49 -08:00
Veselin Dobrev 4952b82c48 Restore CHANGELOG entries (deleted by mistake?)
Use C++14 when UMPIRE is enabled.

Fix and enhance FindUMPIRE.cmake.
2022-12-13 18:43:59 -08:00
Arturo Vargas e3b05bea8e update raja notes 2022-12-13 15:16:36 -08:00
Tzanio Kolev 831cd98243 Merge branch 'master' into sjg/multigrid-mult-rhs 2022-12-13 11:15:25 -08:00
Tom Stitt a1e4b59ed9 fix double-free of HypreParVector device memory after move when mfem is built with hypre+gpu; 2 Memories (different host pointer, same device pointer) will be registered, one will be freed when the object is destroyed and MemoryManager::Destroy will try to free the other. use Delete instead of Reset to make sure only one Memory is registered 2022-12-13 08:13:37 -08:00
Dylan Copeland 5982c7624d Adding missing include. 2022-12-12 21:35:59 -08:00
Kenneth Weiss d8a223bd56 Adds a QuadratureFunction constructor over an external data pointer
This was present in mfem@4.4, but missing in mfem@4.5.
The following call: `QuadratureFunction(qspace, qf_data, vdim);`
is equivalent to: `QuadratureFunction qf; qf.SetSpace(qspace, qf_data, vdim);`
2022-12-12 19:17:32 -08:00
Dylan Copeland 8462d81c7c Initial implementation of new reflector miniapp. 2022-12-12 16:22:21 -08:00
Stowell, Mark L 30fffb8cc6 Merge remote-tracking branch 'origin/master' into bugfix/submesh-bdr-l2 2022-12-12 14:46:43 -08:00
Stowell, Mark L b6c88d5b24 Hard coding dimension in unit test to avoid errors in Windows build 2022-12-12 11:59:46 -08:00
Tzanio Kolev 486c43a197 Merge branch 'master' into artv3/raja-launch-updates 2022-12-12 10:50:36 -08:00
Tzanio Kolev e6ba86462c Merge pull request #3349 from mfem/l2-integral-support
Adding support for map type INTEGRAL in GridFunction::GetNodalValues
2022-12-12 08:12:50 -08:00
Tzanio Kolev 26444a366d Merge pull request #3348 from mfem/cmake-strumpack-metis-fix
Fix CMake TPLs ordering issue
2022-12-12 08:12:24 -08:00
Tzanio Kolev 51a5982eb6 Merge branch 'master' into artv3/raja-launch-updates 2022-12-11 16:07:13 -08:00
Tzanio Kolev c5f51d0f12 Merge branch 'master' into bugfix/submesh-bdr-l2 2022-12-11 16:04:33 -08:00
Tzanio Kolev 59c2056226 Merge branch 'master' into sjg/multigrid-mult-rhs 2022-12-11 16:03:22 -08:00
Tzanio Kolev 05ed8c68cc Merge branch 'master' into cmake-strumpack-metis-fix 2022-12-11 16:03:10 -08:00
Tzanio Kolev 6f61468a93 Merge branch 'master' into l2-integral-support 2022-12-11 16:03:00 -08:00
Tzanio Kolev 881534e227 Merge pull request #3322 from mfem/tmop_exp_limiter
Exponential limiter integration [tmop_exp_limiter]
2022-12-11 16:02:15 -08:00
Tzanio Kolev 3155b5c7dc Merge pull request #3347 from mfem/fix-hip-compile
Fix hip compilation
2022-12-11 16:00:48 -08:00
Tzanio Kolev a2f529621c Merge pull request #3132 from mfem/ncmesh-pyramid-dev
NCMesh pyramid dev
2022-12-11 15:19:02 -08:00
Tzanio Kolev 3578622e42 Merge branch 'master' into ncmesh-pyramid-dev 2022-12-11 15:18:03 -08:00
Tzanio Kolev 371e625677 Updated CHANGELOG, other minor edits 2022-12-11 15:13:42 -08:00
Veselin Dobrev 9a7f764ac7 In the CMake build system, fixed broken build when NetCDF is
enabled and left some notes about future improvements.
2022-12-09 16:25:32 -08:00
Stowell, Mark L 58021339c0 Merge remote-tracking branch 'origin/master' into l2-integral-support
# Conflicts:
#	fem/gridfunc.cpp
2022-12-09 13:20:58 -08:00
Veselin Dobrev 640b86a094 Remove CMake version checks for versions older than the new
minimum required version, 3.8.

In defaults.mk, use C++14 when STRUMPACK is enabled, similar to CMake.
2022-12-09 10:52:45 -08:00
Stowell, Mark L 6ace118601 Merge remote-tracking branch 'origin/master' into sjg/multigrid-mult-rhs 2022-12-09 10:37:37 -08:00
Tzanio Kolev 449b3e3393 Merge branch 'master' into cmake-strumpack-metis-fix 2022-12-09 09:04:35 -08:00
Tzanio Kolev 7d2eddd603 Merge branch 'master' into fix-hip-compile 2022-12-09 09:00:45 -08:00
Tzanio Kolev 975c0f2eab Merge pull request #3343 from mfem/geom-factors-dox-update
Document that Get(Face)GeometricFactors might return stale data
2022-12-09 08:57:55 -08:00
Tzanio Kolev a3aa202f36 Merge pull request #3194 from mfem/vector-remove-implicit-conversion
Deprecate implicit conversion from `Vector` to `double *`
2022-12-09 08:54:29 -08:00
Tzanio Kolev cc8e2de479 Merge branch 'master' into cmake-strumpack-metis-fix 2022-12-09 08:45:50 -08:00
Sebastian Grimberg e2e1d6428e Make suggested changes for CMake builds: Bumps CMake version to 3.8 for correct CMAKE_CXX_STANDARD handling, corrects use of OpenMP flags for test builds. 2022-12-08 14:21:47 -08:00
Stowell, Mark L 44b3ed9b21 Merge remote-tracking branch 'origin/master' into bugfix/submesh-bdr-l2 2022-12-08 12:22:44 -08:00
Veselin Dobrev 7f7dc51c70 Merge branch 'master' into l2-integral-support 2022-12-08 10:29:59 -08:00
Stowell, Mark L 81e38c3f54 Removing soon to be deprecated casts 2022-12-08 09:42:33 -08:00
Veselin Dobrev 7799d447a3 Merge branch 'master' into artv3/raja-launch-updates 2022-12-08 06:17:36 -08:00
Veselin Dobrev 892352e9cd In FindRAJA.cmake, remove a workaround that is no longer needed
with RAJA v2022.10.3.

In the CMake build system, disable the 'hooke' miniapp when
HIP is enabled to avoid AMD HIP compiler crash (already done
in the GNU make build system).
2022-12-08 06:07:32 -08:00
Vladimir Z Tomov 6e7429a889 minor 2022-12-07 23:13:17 -08:00
Vladimir Z Tomov 949db3ccdb Corresponding edits for PMesh. 2022-12-07 23:09:31 -08:00
Vladimir Z Tomov cb1cf8dfe7 Improved / unified documentation for Mesh::Get*Transformation. 2022-12-07 23:04:09 -08:00
Tzanio Kolev 4cca442814 Merge branch 'master' into FaceQuadratureSpace-bug-fix 2022-12-07 15:08:24 -08:00
Tzanio Kolev 74700f5bc8 Merge branch 'master' into vector-remove-implicit-conversion 2022-12-07 15:06:58 -08:00
Tzanio Kolev 5b173dc044 Merge pull request #3352 from mfem/vector-random-seed-removal
Removing global random seed in vector
2022-12-07 15:05:49 -08:00
Arturo Vargas 941f930bae Merge branch 'master' into artv3/raja-launch-updates 2022-12-07 13:21:40 -08:00
Stowell, Mark L b04ce9e375 Removing GetRangeType etc from derived FE collection classes 2022-12-07 11:24:31 -08:00
Stowell, Mark L b43cf3b1fe Implementing GetRangeType etc in FiniteElementCollection base class 2022-12-07 11:24:01 -08:00
Stowell, Mark L 0b773a9f23 Adding FiniteElementCollection::FiniteElementForDim 2022-12-07 10:31:15 -08:00
Vladimir Z Tomov ae2f95d946 style. 2022-12-07 09:35:25 -08:00
Vladimir Z Tomov 4a4e135c1a Merge branch 'master' into tmop_exp_limiter 2022-12-07 09:28:50 -08:00
Sebastian Grimberg 496b0750ca Fix clang compiler warnings 2022-12-07 00:12:41 -08:00
Sebastian Grimberg e11b0cd409 Merge branch 'master' into sjg/dof-to-quad-dev 2022-12-06 20:59:55 -08:00
Sebastian Grimberg 1f6b128837 Merge branch 'master' into sjg/multigrid-mult-rhs 2022-12-06 20:59:48 -08:00
Tzanio Kolev a6c5b3b1e8 Merge branch 'master' into FaceQuadratureSpace-bug-fix 2022-12-06 17:41:52 -08:00
Veselin Dobrev 575547df7d Merge branch 'master' into cmake-strumpack-metis-fix 2022-12-06 17:04:23 -08:00
Veselin Dobrev 40b577d192 Merge pull request #3294 from mfem/doxygen-subdirs
Include several subdirectories in Doxygen docs
2022-12-06 16:40:28 -08:00
Will Pazner 41a2ada156 Bug fix 2022-12-06 14:56:11 -08:00
Will Pazner 1168f30492 Merge pull request #3355 from mfem/deprecate-get-face-geometry-type
Deprecate GetFaceGeometryType and GetFaceBaseGeometry
2022-12-06 14:06:27 -08:00
Will Pazner 50c238b1cf Add Doxygen comments to Mesh::GetFaceGeometry 2022-12-06 14:05:38 -08:00
Will Pazner 353d9b646e Move Mesh::GetFaceGeometryType implementation to header 2022-12-06 12:41:43 -08:00
Will Pazner 26073f789d Deprecate GetFaceGeometryType and GetFaceBaseGeometry
Now both of these functions call GetFaceGeometry.

GetFaceGeometry has been updated to handle ghost faces.
2022-12-06 12:21:12 -08:00
Tzanio Kolev c39459387a Merge branch 'master' into FaceQuadratureSpace-bug-fix 2022-12-06 12:03:20 -08:00
Will Pazner dcd8b0907f Merge remote-tracking branch 'origin/master' into vector-remove-implicit-conversion
# Conflicts:
#	CHANGELOG
#	fem/fe/fe_nd.cpp
#	fem/fe/fe_rt.cpp
2022-12-06 11:54:32 -08:00
Will Pazner 9e1c1ebc29 Merge pull request #3333 from mfem/vector-remove-implicit-conversion-tweaks
Various simplifications, tweaks, and fixes for PR #3194
2022-12-06 11:51:40 -08:00
Tzanio Kolev 615d13658e Merge branch 'master' into doxygen-subdirs 2022-12-06 11:32:02 -08:00
Tzanio Kolev 5ed071c026 Merge branch 'master' into geom-factors-dox-update 2022-12-06 11:24:07 -08:00
Tzanio Kolev db03d1e390 Merge branch 'master' into vector-random-seed-removal 2022-12-06 11:23:43 -08:00
Tzanio Kolev 7a24255cdb Merge branch 'master' into ncmesh-pyramid-dev 2022-12-06 10:28:44 -08:00
Tzanio Kolev f23b8135f5 Merge pull request #3287 from mfem/superlu-strumpack-cuda-fix
SuperLU_DIST and STRUMPACK with HYPRE+CUDA
2022-12-06 10:25:25 -08:00
Veselin Dobrev 84512a4733 [SQUASH MERGE] Fix GitHub CI failures with the new ubuntu-latest (#3351)
* Disable the test 'ubuntu-latest-cmake-opt-par-int32' which is
failing with 'ubuntu-latest' == 'ubuntu-22.04' to see if the
other tests pass.

* GH actions: update some action versions to fix warnings plus
some other tweaks

* GH actions: update more action versions to fix warnings

* GH actions: testing

* GH actions: testing

* GH actions: testing CMake fix

* GH actions: testing Doxygen fix
2022-12-06 10:20:12 -08:00
Tzanio Kolev 0c8a5d6530 Merge pull request #3353 from mfem/ceed-fix
Use renamed functions when libCEED version >= 0.10.2
2022-12-06 10:19:17 -08:00
Michael C Tyler Stees c1a78025ff Added missing parenthesis in limiting function and second derivative. 2022-12-06 09:06:18 -08:00
Veselin Dobrev 0eedd780f2 Merge branch 'master' into superlu-strumpack-cuda-fix 2022-12-05 15:24:12 -08:00
Aaron Fisher 21b7787aef Merge branch 'master' into ncmesh-pyramid-dev 2022-12-05 14:59:41 -08:00
Veselin Dobrev 44380ab02a Add calls to Mesh::NodesUpdated in both versions of Mesh::Transform 2022-12-05 02:30:45 -08:00
Veselin DobrevandsamuelpmishLLNL 8cdd2bb0c8 Doxygen tweak in Mesh::NodesUpdated
Co-authored-by: samuelpmishLLNL <61714427+samuelpmishLLNL@users.noreply.github.com>
2022-12-05 02:29:51 -08:00
Vladimir Z Tomov 8b5aa791e4 Added unit test for the expo limiting (failing, Mike will fix it). 2022-12-04 17:55:31 -08:00
Tzanio Kolev 70afda9c06 Merge pull request #3321 from mfem/rm-mesquite
Removed Mesquite support
2022-12-04 14:55:01 -08:00
Aaron Fisher 8bc44a8087 make style 2022-12-02 14:54:17 -08:00
Aaron Fisher ae93ec6887 Removed non-working anisotropic refinement of pyramids code. 2022-12-02 14:46:46 -08:00
Will Pazner caf638a3d3 Use renamed functions when libCEED version >= 0.10.2 2022-12-02 12:47:09 -08:00
Socratis Petrides aaec27a9ea removing global random seed in vector 2022-12-02 11:19:57 -08:00
Tzanio KolevandsamuelpmishLLNL 83dbeae7ab Update mesh/mesh.hpp
Co-authored-by: samuelpmishLLNL <61714427+samuelpmishLLNL@users.noreply.github.com>
2022-12-01 11:23:42 -08:00
Tzanio Kolev 3cd881e8b6 Merge branch 'master' into rm-mesquite 2022-12-01 11:20:50 -08:00
Veselin Dobrev 5b9dd0b42f Update doxygen docs based on reviewer feedback 2022-11-30 22:46:06 -08:00
Veselin Dobrevand@sebastiangrimberg 6947b3a639 In CMakeLists.txt, when removing duplicates from TPL_LIBRARIES,
keep the last occurrence instead of the first.

In the CMake function mfem_find_package, make sure the C++ standard
is used when calling check_cxx_source_compiles.

Fix a warning in STRUMPACKSolver::Mult.

Co-authored-by: @sebastiangrimberg
2022-11-30 18:34:12 -08:00
Stowell, Mark L 41a7679f19 Merge remote-tracking branch 'origin/master' into l2-integral-support 2022-11-30 10:46:25 -08:00
Stowell, Mark L 2b700c87d9 Improving doxygen comments 2022-11-30 10:33:45 -08:00
Stowell, Mark L 0d2f94be20 Exposing FiniteElement characteristics through FE_Collection 2022-11-30 10:18:19 -08:00
Michael C Tyler Stees 9c19c54114 Remove extra new line 2022-11-30 09:07:51 -08:00
Tzanio Kolev 8591e38a71 Merge pull request #3313 from mfem/sjg/dof-trans-cleanup
Fix minor copy-paste errors in DofTransformation
2022-11-30 08:02:32 -08:00
Tzanio Kolev acd46692a0 Merge pull request #3329 from mfem/bugfix/visit-dc-rfind
Bug fix for VisItDataCollection name parsing
2022-11-30 08:02:18 -08:00
Tzanio Kolev ca6588da7d Merge pull request #3305 from mfem/cmake-cuda-rdc-fix
Fix for CMake linking with TPLs built with CUDA relocatable device code (RDC)
2022-11-30 08:01:37 -08:00
Tzanio Kolev c60295e9c0 Merge pull request #3306 from mfem/cray-hip-gmake-support
Fix the building of the unit tests when using Cray HIP compilers
2022-11-30 08:01:04 -08:00
Stowell, Mark L a0bd50266c Adding support for map type INTEGRAL in GridFunction::GetNodalValues 2022-11-29 16:28:02 -08:00
Robert W. Anderson 5f74c1fa31 remove obsolete comment 2022-11-29 11:09:49 -08:00
Robert W. Anderson 5bb90b84e3 remove temp interactive testing files 2022-11-29 10:58:13 -08:00
Veselin Dobrev c2133437dd In CMakeLists.txt, move STRUMPACK before METIS in the list MFEM_TPLS 2022-11-28 21:13:55 -08:00
Tom Stitt 0c42f3751d fixes "no known conversion from 'int **' to 'void **'" compilation error during hip compilation 2022-11-28 16:49:22 -08:00
Tzanio Kolev 7830ee7877 Merge branch 'master' into bugfix/visit-dc-rfind 2022-11-28 14:32:19 -08:00
Tzanio Kolev 2196e61f4e Merge branch 'master' into rm-mesquite 2022-11-27 18:06:24 -08:00
Tzanio Kolev 42e979ebb6 Merge pull request #3337 from mfem/GradToCurl2D-fix
GradToCurl fix for vector and scalar valued curl.
2022-11-27 18:03:39 -08:00
Tzanio Kolev 5e0ffd933b Merge pull request #3268 from mfem/add-dist-solver
Fast distance solver
2022-11-27 18:02:56 -08:00
Tzanio Kolev 2d9850c642 Merge pull request #3278 from mfem/sjg/gslib-fix
Resolve compiler warnings in gslib.cpp
2022-11-27 18:01:51 -08:00
Tzanio Kolev 1301ed24fc Merge pull request #3290 from mfem/hipsparse-include-fix
Fix a warning with HIP >= 5.2.0
2022-11-27 18:01:21 -08:00
Veselin Dobrev 9b29c316e3 Update the doxygen docs of Mesh::GetGeometricFactors and
Mesh::GetFaceGeometricFactors to explicitly state that the
returned pointer to internal object may be invalidated by
some mesh operations.

Other small doxygen tweaks.
2022-11-26 19:46:03 -08:00
Vladimir Z Tomov cbdf014edf Reviewer comments. 2022-11-22 23:38:51 -08:00
Stowell, Mark L 7a277b6606 CHANGELOG entry 2022-11-22 14:03:04 -08:00
Stowell, Mark L 8976fe0284 Marking VisItDataCollection methods with "override" where appropriate 2022-11-22 13:49:08 -08:00
Arturo Vargas 41faa5428f add CAMP_LIB flag 2022-11-22 09:30:52 -08:00
Tzanio Kolev 1e17003af3 Merge pull request #3315 from mfem/fix-vismesh
Fixed `common::VisualizeMesh`
2022-11-22 08:57:46 -08:00
Socratis Petrides 818041228c fix MixedCurlIntegrator 2022-11-21 20:34:13 -08:00
Socratis Petrides cb5d670e01 revert changes in GradToCurl. Add new method for Vector-valued GradToCurl in 2D 2022-11-21 17:04:13 -08:00
Veselin Dobrev d7b1fb4880 CMake CUDA tweak 2022-11-20 22:14:28 -08:00
Veselin Dobrev 5578279386 In defaults.cmake, remove lines that are no longer needed 2022-11-20 20:20:27 -08:00
Veselin Dobrev 0a133cc3fa Update FindRAJA.cmake to use the exported RAJA CMake configs 2022-11-20 19:29:39 -08:00
Stowell, Mark L 8ef4bef094 Adding SubMesh support for discontinuous fields with vdim > 1 2022-11-20 14:12:58 -08:00
Veselin Dobrev 972a4c227e Various simplifications, tweaks, and fixes 2022-11-19 14:18:43 -08:00
Stowell, Mark L 6730ffeb6f Setting pad_digits_rank even in serial 2022-11-18 09:39:31 -08:00
Stowell, Mark L e33dd78845 Fixing pad digits calls in unit test 2022-11-17 15:58:41 -08:00
Stowell, Mark L 7b5b871eea Adding pad digits options to other DataCollection related tools 2022-11-17 15:25:47 -08:00
Stowell, Mark L d7b2c4a7b2 Declaring SetPadDigits* as virtual 2022-11-17 15:25:09 -08:00
Stowell, Mark L 77a745bd28 Modifying get-values to support arbitrary cycle number padding 2022-11-17 10:54:20 -08:00
Arturo Vargas 44f1c544fb Will need RAJA >= 2022.10.3 2022-11-17 10:20:53 -08:00
Arturo Vargas 67d95f4032 add -lcamp 2022-11-17 10:19:43 -08:00
Will Pazner 3027566eb5 Merge pull request #3327 from mfem/vector-distance-hostread
Add const Vector& overload for Distance
2022-11-16 10:45:47 -08:00
Stowell, Mark L a58aafb743 Search string from the end to extract data collection name 2022-11-16 10:35:28 -08:00
Tzanio Kolev b09cc38df9 Merge pull request #3288 from mfem/hiop-nvcc-warnings-fix
Fix nvcc warnings when HiOp integration is enabled
2022-11-16 10:27:42 -08:00
Will Pazner facf28e24c Add const Vector& overload for Distance 2022-11-16 09:52:23 -08:00
Vladimir Z Tomov 5913021d50 Removed dummy GridFunctions. 2022-11-15 23:59:41 -08:00
Tzanio Kolev 3fca8798f6 Merge pull request #3304 from mfem/fix-clang-warnings
Fix some clang 14 warnings
2022-11-15 16:20:41 -08:00
Tzanio Kolev 6a71b32f04 Merge pull request #3317 from mfem/hip-miniapps-build-fix
Fix two issues affecting the miniapps building with HIP enabled
2022-11-15 16:19:57 -08:00
Will Pazner 8ee9011b29 Merge pull request #3172 from mfem/yohann/sort+test
Add sorting of sparse matrix when assembled on device.
2022-11-14 09:37:30 -08:00
Michael C Tyler Stees 86530f1d5b Adding exponential limiter option in fem/tmop.hpp and partial assembly support. 2022-11-14 07:44:37 -08:00
Will Pazner b3a57feaae Use Device::IsEnabled and add explanation in ex1 and ex1p 2022-11-13 16:02:32 -08:00
Will Pazner fee80f9280 Revise comment for BilinearForm::EnableSparseMatrixSorting 2022-11-13 16:02:01 -08:00
Tzanio Kolev 49c8ff3a3b Small edit in CHANGELOG 2022-11-13 12:00:26 -08:00
Vladimir Z Tomov 2c7ecb75e2 Removed Mesquite. 2022-11-10 19:51:50 -08:00
Arturo Vargas 1d41202805 Bug fix for non-conforming meshes. 2022-11-10 17:34:10 -08:00
Robert W. Anderson 7797741733 make style 2022-11-10 09:59:03 -08:00
Veselin Dobrev 19105ba702 Fix two issues affecting the miniapps building with HIP enabled:
- the 'hooke' miniapp crashes the AMD HIP compiler, so for now
  we disabled it when building with HIP
- the building of the shared 'mfem-common' library was broken since
  the XLINKER make variable was left undefined with HIP enabled.
2022-11-10 00:15:09 -08:00
Robert W. Anderson 1030d3740f deactivate parallel stress test until exact projection is ready for positive basis 2022-11-09 21:40:47 -08:00
Robert W. Anderson 700a4aca47 revert projection to monotone version 2022-11-09 21:39:55 -08:00
Robert W. Anderson 1504729937 Merge branch 'master' into bugfix/rwa/coarsen-L2-proj 2022-11-09 19:23:44 -08:00
Tzanio Kolev 37b61aab9d Merge pull request #3303 from mfem/disconnected-mesh-fix
Fix partitioning error for disconnected meshes with METIS 5
2022-11-09 07:45:03 -08:00
Vladimir Z Tomov 725c2db36a Fixed common::VisualizeMesh(). 2022-11-08 23:29:49 -08:00
Sebastian Grimberg 3ac57bb15a Add missing tests for CMake builds 2022-11-08 21:27:04 -08:00
Sebastian Grimberg 5e2f3f9490 Refactor GetDofToQuad to support H(curl) and H(div) for non-tensor elements 2022-11-08 21:26:11 -08:00
Sebastian Grimberg aed2054149 Add some override specifiers for compile-time checking 2022-11-08 12:45:17 -08:00
Sebastian Grimberg 24ffcca5cd Merge branch 'master' into sjg/multigrid-mult-rhs 2022-11-08 12:44:50 -08:00
Sebastian Grimberg 646d73b980 Fix minor copy-paste errors in DofTransformation 2022-11-08 12:35:25 -08:00
Tzanio Kolev 55ccded864 Merge pull request #3307 from mfem/petsc-warning-fix
Fix PETSc 3.18.0 deprecation warning about MATTRANSPOSEMAT
2022-11-08 10:21:32 -08:00
Tzanio Kolev 4227521a52 Merge pull request #3309 from mfem/stefanozampini/fix-nonzeroguess-ksp
PetscLinearSolver: respect command line option for nonzero initial guess
2022-11-08 10:21:09 -08:00
Tzanio Kolev b9d166a4a4 Merge pull request #3302 from mfem/fix-doxygen-dgdiffusion
Fix Doxygen formatting for DGDiffusionIntegrator
2022-11-08 10:20:18 -08:00
Will Pazner 40c49ed992 Merge pull request #3297 from mfem/artv3/quadspacebase-init
Initalize order in quadrature space base class
2022-11-07 20:45:55 -08:00
Yohann Dudouit 6e70e2883b Set diagonal policy to DIAG_ONE when using Full assembly. 2022-11-07 12:32:53 -08:00
Yohann Dudouit affa9185bd Set the diagonal policy to DIAG_ONE in ex1 and ex1p. 2022-11-07 11:17:26 -08:00
Stefano Zampini c5c9a002c0 PetscLinearSolver: respect command line option for nonzero initial guess 2022-11-07 10:40:39 +03:00
Tzanio Kolev 0043dc833e Merge branch 'doxygen-subdirs' of github.com:mfem/mfem into doxygen-subdirs 2022-11-06 12:42:02 -08:00
Tzanio Kolev 14c43e1f98 Fix Doxygen comments 2022-11-06 12:40:56 -08:00
Veselin Dobrev 319d383af9 Fix PETSc 3.18.0 deprecation warning about MATTRANSPOSEMAT 2022-11-05 19:49:20 -07:00
Will Pazner 059cb2ce80 Remove unused variable in ParNCMesh::MemoryUsage 2022-11-05 13:47:19 -07:00
Will Pazner aa40b0b819 Suppress unused variable warning 2022-11-05 13:46:53 -07:00
Will Pazner d264a57850 Remove unused variable in Mesh::PrintVTU 2022-11-05 13:39:06 -07:00
Will Pazner 24825a5d26 Replace sprintf with snprintf 2022-11-05 13:38:42 -07:00
Veselin Dobrev 18e02de412 When partitioning a disconnected mesh with METIS 5, disable
the option for contiguous partitions which generates an error.
2022-11-04 23:45:47 -07:00
Will Pazner a1f2a79c3a Fix Doxygen formatting for DGDiffusionIntegrator 2022-11-04 12:18:52 -07:00
Will Pazner a6830a367a Merge remote-tracking branch 'origin/master' into yohann/sort+test 2022-11-04 09:55:29 -07:00
Veselin Dobrev 7176ad1ddd Add MFEM_USE_SUPERLU5 to the list of variables that will be
written to config.hpp and config.mk.

Also print MFEM_USE_SUPERLU5 when running 'make info'.
2022-11-04 01:40:32 -07:00
Julian Andrej cdc9408d27 more doxygen 2022-11-03 17:29:28 -07:00
Julian Andrej 322aa742d2 changed doxygen comment 2022-11-03 17:04:50 -07:00
Arturo Vargas 092180b3f7 Update qspace.cpp 2022-11-02 21:19:12 -07:00
Veselin Dobrev 65d28896cb Merge pull request #3281 from mfem/bugfix/qfunc_inline
Bug fix related to qfunction.cpp
2022-11-02 21:03:04 -07:00
Arturo Vargas 1fb13fe1a4 initalize order and size in quadrature space base 2022-11-02 16:39:14 -07:00
Veselin Dobrev 716d97e535 Ensure MUMPS and MKL CPardiso can use hypre matrices in GPU
memory by moving them temporarily to CPU memory.
2022-11-01 20:33:17 -07:00
Tzanio Kolev 9cd66faee6 Include several subdirectories in Doxygen docs 2022-11-01 19:10:28 -07:00
Arturo Vargas eec6f95561 make note of raja change in change log 2022-11-01 15:22:36 -07:00
Arturo Vargas 23fcd110f5 updates for raja launch 2022-11-01 15:21:30 -07:00
Veselin Dobrev f3c390fc1e To support building with HIP using the Cray compilers (which
need the -xhip flag) move the $(MFEM_FLAGS) argument (that
contains the -xhip flag) before the file(s) to be compiled.
2022-11-01 13:07:27 -07:00
Vladimir Z Tomov f4f6ab0f56 Merge branch 'master' into parGF-grad 2022-10-31 16:04:05 -07:00
Vladimir Z Tomov 2edddc5f9a Wrong #endif placement. 2022-10-31 16:01:36 -07:00
Vladimir Z Tomov b0048a2ccb Merge branch 'master' into add-dist-solver 2022-10-31 14:44:11 -07:00
Vladimir Z Tomov 90ef7e72ef Compilation error in the diffusion example due to the interface change. 2022-10-31 14:42:38 -07:00
Vladimir Z Tomov 9213f43286 Fixed failing tests. 2022-10-31 11:14:35 -07:00
Veselin Dobrev 7940fbea51 Add closing #endif forgotten in the previous commit 2022-10-30 16:57:56 -07:00
Veselin Dobrev 6c0d431f90 Fix a warning with HIP >= 5.2.0 to include <hipsparse/hipsparse.h>
instead of just <hisparse.h>
2022-10-30 16:44:11 -07:00
Veselin Dobrev a7501a08d6 Fix style 2022-10-29 21:01:34 -07:00
Veselin Dobrev d7e03640d9 Fix nvcc warnings when HiOp integration is enabled 2022-10-29 12:24:36 -07:00
Veselin Dobrev 87596eaa38 Ensure SuperLU_DIST and STRUMPACK can use hypre matrices in GPU
memory by moving them temporarily to CPU memory.
2022-10-29 08:22:30 -07:00
Vladimir Z Tomov 1759f79026 Bug in metric 301. Fix check-tmop-metric when Hessian is exact. 2022-10-28 19:05:18 -07:00
Robert Carson 6e9f62ca86 bug fix qfunction inline funcs in wrong file 2022-10-28 14:31:02 -04:00
Tzanio Kolev 2eb2061fb0 Merge pull request #3270 from mfem/mondrian-miniapp-fix
Fix bug in mondrian miniapp
2022-10-28 09:23:54 -07:00
Veselin Dobrev 297ee682d4 Fix a linking issue in the CMake build system when using newer
CMake versions (e.g. 3.18 and later) and linking with CUDA
libraries compiled with relocatable device code (rdc). Some
older versions of hypre were built with CUDA rdc (e.g. 2.22.x)
and the build with CMake 3.18 and hypre-2.22.x was failing.

This fix will probably be needed if we are linking with any
other TPLs built with CUDA rdc.
2022-10-27 15:17:00 -07:00
Sebastian Grimberg b1dec1eda0 Resolve compiler warnings in gslib.cpp 2022-10-27 13:16:50 -07:00
Hugh Carson 5be88369ce Add default constructor to ParFiniteElementSpaceHierarchy, and use default for FiniteElementSpaceHierarchy 2022-10-27 10:38:56 -04:00
Biswapriyo Nath 3afef10951 Fix DLL install directory in mingw
This installs DLL in 'bin' directory instead of 'lib' by default.
In mingw environment, all DLLs and EXEs are installed in 'bin'
and static & import libraries are installed in 'lib' directory.
This does not affect other environment because the 'RUNTIME'
and 'LIBRARY' targets are automatically set by cmake. See
https://cmake.org/cmake/help/latest/command/install.html
2022-10-26 08:05:33 +05:30
Sebastian Grimberg ab4bd64a5e Fix bug in mondrian miniapp 2022-10-25 16:29:49 -07:00
Vladimir Z Tomov ea9c2d2b8f style. 2022-10-24 19:05:11 -07:00
Vladimir Z Tomov b1383e0f80 Use OrthoSolver. 2022-10-24 18:19:11 -07:00
Vladimir Z Tomov b0573f4cec Updated to use IterativeSolver::PrintLevel. 2022-10-24 18:05:33 -07:00
Sebastian Grimberg 93536a8492 Merge branch 'master' into sjg/multigrid-mult-rhs 2022-10-24 17:53:03 -07:00
Vladimir Z Tomov 021532cebf 1d sample run, better eps value for gradient calculations. 2022-10-24 16:37:59 -07:00
Tzanio Kolev d84884d13c Merge pull request #3266 from mfem/new-dev-version-4.5.1
Update version numbers to 4.5.1 -- a new development version
2022-10-24 09:41:30 -07:00
Veselin Dobrev 6328e8b38c Update version numbers to 4.5.1 -- a new development version 2022-10-24 07:06:54 -07:00
Tzanio Kolev b7a4b61b5c Merge pull request #3199 from mfem/mfem-4.5-dev
Final changes for mfem-4.5
2022-10-22 15:33:35 -07:00
Tzanio Kolev 0a649ec155 mfem-4.5 release date is October 22, 2022 2022-10-22 15:10:18 -07:00
Vladimir Z Tomov 93d87c5a90 Added a simple normalization solver, error computations. 2022-10-21 17:08:56 -07:00
Tzanio Kolev c00eb3219e Merge branch 'mfem-4.5-dev' of github.com:mfem/mfem into mfem-4.5-dev 2022-10-21 16:58:01 -07:00
Tzanio Kolev eb08e9523d Finalized CHANGELOG for mfem-4.5 2022-10-21 16:57:53 -07:00
Veselin Dobrev 215d037a5a Fix a bug:
#elif MFEM_USE_HIP  -->  #elif defined(MFEM_USE_HIP)
2022-10-21 16:50:22 -07:00
Veselin Dobrev bf21800df8 In the CMake build system allow MFEM_MPIEXEC and MPIEXEC_NUMPROC_FLAG
to contain spaces, e.g. to allow -DMFEM_MPIEXEC="flux mini run".
2022-10-21 16:39:19 -07:00
Will Pazner 4a1fc607ce Fix bug when using IntegratedGLL basis in thread safe mode 2022-10-21 15:45:53 -07:00
Tzanio Kolev a2ffa0af29 More typos 2022-10-21 15:45:29 -07:00
Tzanio Kolev e7e8a67924 Revert a change from PR #3117 which caused double-free in Serac 2022-10-21 15:02:03 -07:00
Tzanio Kolev 19e40fa95f Typos 2022-10-21 15:00:47 -07:00
Tzanio Kolev 27d11e933f Merge branch 'master' into mfem-4.5-dev
Conflicts:
	CHANGELOG
2022-10-21 11:01:20 -07:00
Veselin Dobrev 762cbd9194 Use C++14 when SUNDIALS is enabled; needed for SUNDIALS >= 6.4.0 2022-10-21 10:56:02 -07:00
Veselin Dobrev 33a2dbac73 Merge pull request #3258 from mfem/quadfunc-projectGF-fix
Fix for autotest error in Remhos
2022-10-21 10:53:02 -07:00
Veselin Dobrev 8ca9061ce4 Merge pull request #3262 from mfem/hypre-commpkg-fix
check comm pkg
2022-10-21 10:51:36 -07:00
Tzanio Kolev 09fa91c42c Merge pull request #3257 from mfem/hypre-2-26-0-fixes
Some fixes for hypre v2.26.0
2022-10-21 10:48:21 -07:00
Veselin Dobrev b1dceed4c0 Fix the places for the EnsureMultTranspose calls in class
SparseMatrix.

Fix a warning in class KershawTransformation.
2022-10-21 05:34:37 -07:00
Tzanio Kolev fd6d3dcef4 Merge branch 'master' into mfem-4.5-dev
Conflicts:
	CHANGELOG
2022-10-20 19:14:11 -07:00
Vladimir Z Tomov 44f3fa8c48 Updated one more comment. 2022-10-20 17:03:13 -07:00
Vladimir Z Tomov 0a109e91cf Restored the old code, set the layout before computing FaceGeometricFactors. 2022-10-20 16:51:55 -07:00
Tzanio KolevandWill Pazner 8784555248 [SQUASH] Assembly levels for LinearForm (#3235)
* Assembly levels for LinearForm

* Typo

* Switched to Mesh::Update in methods like Mesh::SetNodes

* Update mesh/mesh.hpp

Co-authored-by: Will Pazner <11493037+pazner@users.noreply.github.com>

* Addressing Will's comments

* Update mesh/mesh.hpp

Co-authored-by: Will Pazner <11493037+pazner@users.noreply.github.com>

* Changes in linform-pa-fix after 10/14/22 meeting

* Update fem/linearform.hpp

Co-authored-by: Will Pazner <11493037+pazner@users.noreply.github.com>

* Update fem/linearform.hpp

Co-authored-by: Will Pazner <11493037+pazner@users.noreply.github.com>

* Some fixes from Will

* More fixes from Will

* Have LinearForm::Assemble check the value of fast_assembly

* Final reviewer comments for PR 3235

Co-authored-by: Will Pazner <11493037+pazner@users.noreply.github.com>
2022-10-20 16:50:47 -07:00
Veselin Dobrev f494da76f7 Merge branch 'master' into hypre-2-26-0-fixes
Resolved conflicts:
   CHANGELOG
2022-10-20 16:12:58 -07:00
Veselin Dobrev 1482864193 Remove the need to explicitly call EnsureMultTranspose in the
classes SparseMatrix and HypreParMatrix.

Added new methood HypreParMatrix::ResetTranspose.

Added some crarifying doxygen documentation.
2022-10-20 16:03:23 -07:00
Tzanio Kolev 9ae0f7a9a7 Merge pull request #3043 from mfem/gslib-node-ordering
Node ordering in GSLIBFindPoints and TMOP
2022-10-20 14:40:02 -07:00
Tzanio Kolev 0c6de1922c Merge pull request #3230 from mfem/tmopupdate-kershawtransform
Kershaw transformation
2022-10-20 14:39:05 -07:00
Veselin Dobrev 34448a8bb8 Merge pull request #3256 from mfem/supports-device-fix
Fix parallel hang in LinearForm::SupportsDevice
2022-10-20 13:11:49 -07:00
Yohann Dudouit 612a94aef7 Add EnableSparseMatrixSorting in ex1 and ex1p. 2022-10-20 09:47:05 -07:00
Veselin Dobrev ae7f17537c Fix warnings in HypreAMS::ResetAMSPrecond() for hypre >= 2.26.0 2022-10-20 08:48:48 -07:00
Veselin Dobrev 8b60ad5e7a Merge branch 'master' into mfem-4.5-dev 2022-10-20 08:39:59 -07:00
Socratis Petrides 905a856bd5 remove checks from constructors 2022-10-20 08:11:29 -07:00
Socratis Petrides d2106d86c3 check comm pkg 2022-10-19 19:22:12 -07:00
Tzanio Kolev 0504397b96 Merge pull request #3179 from mfem/stefanozampini/block-split
Exploit PETSc matrix block structure
2022-10-19 15:46:22 -07:00
Tzanio Kolev ec0f08bc2a Merge pull request #3096 from mfem/hypreams-mem-leak-fix
Fix memory leak found in HypreAMS when SetOperator is called multiple times [hypreams-mem-leak-fix]
2022-10-19 15:45:54 -07:00
Vladimir Z Tomov 975ec13e21 Fixes an error in the multi-field discrete target construction. 2022-10-19 12:23:58 -07:00
Vladimir Z Tomov 3d4ebdecb4 Merge branch 'master' into gslib-node-ordering 2022-10-19 11:54:53 -07:00
Ketan Mittal cd48e65827 restore relative path 2022-10-19 08:13:21 -07:00
Ketan Mittal 6650ae9bba Merge branch 'master' of https://github.com/mfem/mfem into tmopupdate-kershawtransform 2022-10-19 08:11:10 -07:00
Vladimir Z Tomov 1f3b58eab8 style. 2022-10-19 00:12:56 -07:00
Vladimir Z Tomov 00a2a38e8f Doxygen comment and extra ASSERT. 2022-10-19 00:09:33 -07:00
Vladimir Z Tomov 766d163a86 Created new interpolators in QuadratureFunction::ProjectGridFunction(). 2022-10-18 14:19:26 -07:00
Veselin Dobrev 5f81cb9d08 Tweak the script 'sample-runs.sh' to avoid early termination
when timing is enabled and a sample run line is ill formed.

Fix the sample runs in 'miniapps/solvers/block-solvers.cpp'.

Conflicts:
	miniapps/solvers/block-solvers.cpp
2022-10-18 14:06:17 -07:00
Tzanio 40e43e6ff3 Adjusted formatting of sample runs in miniapps/toys/life.cpp 2022-10-18 14:04:19 -07:00
Tzanio Kolev f111d240c4 Updated CHANGELOG 2022-10-18 13:58:34 -07:00
Tzanio Kolev 451939d7c8 Moved CHANGELOG entries to mfem-4.5 that were incorrectly under mfem-4.4 2022-10-18 13:47:43 -07:00
Veselin Dobrev b89de70dd1 A few small fixes for warnings and a command line argument. 2022-10-18 12:57:41 -07:00
Veselin Dobrev d7db3de9af Some fixes for hypre v2.26.0 2022-10-18 12:13:49 -07:00
Sebastian Grimberg a6bfdf3ed1 Fix parallel hang in LinearForm::SupportsDevice 2022-10-18 12:03:41 -07:00
Tzanio Kolev 64d4d39083 Typo 2022-10-17 12:19:07 -07:00
luz paz 9726992248 Fix typos
Found via `codespell -q 3 -L allright,ba,bu,childs,equil,esy,fo,fom,hda,localy,lod,mone,nd,ned,nnumber,numer,ot,pres,ro,seh,shat,solfes,strat,tbe,te,tthe,warmup`
2022-10-17 12:15:17 -07:00
Tzanio Kolev 67cac261e3 Merge branch 'master' into mfem-4.5-dev 2022-10-17 12:15:02 -07:00
Tzanio Kolev c644f3d174 Merge pull request #3233 from mfem/arm64-performance-flags
Change performance miniapps compiler flags for Apple M1
2022-10-14 18:35:18 -07:00
Vladimir Z Tomov ef6cadeaf2 style 2022-10-13 17:27:31 -07:00
Vladimir Z Tomov d8a9ce16cc cmakelist 2022-10-13 17:18:04 -07:00
Vladimir Z Tomov 2c4a5300d1 changelog. 2022-10-13 17:15:45 -07:00
Vladimir Z Tomov 9db0863ba9 GetGradients and GetVectorGraient on share faces. 2022-10-13 17:12:17 -07:00
Will Pazner a8fbe3aff4 Merge pull request #3146 from mfem/tmop-update3D
Update of the 3D tmop metrics
2022-10-13 09:30:58 -07:00
Will Pazner e0792c83cf Merge pull request #3170 from mfem/sundials-v6-dev
Support for SUNDIALS v6
2022-10-13 09:30:30 -07:00
Vladimir Z Tomov 2af7fe401e Unit test for GetGradient on shared faces. 2022-10-12 10:56:12 -07:00
Veselin Dobrev 1b535bdf6e Merge branch 'master' into sundials-v6-dev 2022-10-10 12:14:36 -07:00
Will Pazner 4772c94432 Merge pull request #3136 from mfem/gridfunc-gettruevec-fix
Modify GridFunction::GetTrueVector behavior to SetTrueVector if `t_vec` does not already exist
2022-10-10 11:18:00 -07:00
Will Pazner 62b3ef4041 Merge pull request #3243 from mfem/fix-get-mem-type
Fix a bug and a typo
2022-10-10 11:17:26 -07:00
Will Pazner cb4cfedbf8 Merge pull request #3240 from mfem/sjg/linearform-ext-marker-fix
Fix bug for markers in `LinearFormExtension::Assemble`
2022-10-10 11:16:46 -07:00
Will Pazner d7e1615f4c Revert test of memory leak in ex3p 2022-10-10 11:08:12 -07:00
Will Pazner 35ca1be13d Fix double setup of HypreADS when calling SetOperator more than once 2022-10-10 11:06:24 -07:00
Ketan MittalandChris Vogl 096f3143fb Get rid of relative path
Co-authored-by: Chris Vogl <vogl2@llnl.gov>
2022-10-07 15:05:18 -07:00
Will Pazner 0e8e2fb3c3 Fix arch flags for performance miniapp with gcc 2022-10-06 09:06:13 -07:00
Veselin Dobrev d6155a2259 Merge branch 'master' into sundials-v6-dev
Resolved conflicts:
   CHANGELOG
2022-10-06 01:24:02 -07:00
Veselin Dobrev 82dacf6441 In the GNU make build system, support SUNDIALS_DIR defined using
the @MFEM_DIR@ path substitution.
2022-10-06 01:09:12 -07:00
Veselin Dobrev 6caa552f0d Fix SUNDIALS + CUDA support when using SUNDIALS < v6 2022-10-06 00:44:05 -07:00
Ketan Mittal 771780350f fix sample run 2022-10-04 16:57:47 -07:00
Ketan Mittal 5265ab4959 Merge branch 'gslib-node-ordering' of https://github.com/mfem/mfem into gslib-node-ordering 2022-10-04 11:45:52 -07:00
Ketan Mittal 1ccd5c72c9 merge master and resolve conflict 2022-10-04 11:45:23 -07:00
Ketan Mittal 80f8ba8d6c fix merge conflict and bug 2022-10-03 22:37:39 -07:00
Ketan Mittal 498d4fe0a1 bug fix: EvalW of mu_58 2022-10-02 16:46:54 -07:00
Veselin Dobrev a7d760c24f In Memory<T>::GetMemoryType(), handle the case when h_ptr is
NULL and (flags & VALID_DEVICE) is true.

In CMakeLists.txt, fix a typo.
2022-09-30 18:22:03 -07:00
Sebastian Grimberg 5611e7b605 Address comment for empty attributes/bdr_attributes 2022-09-30 14:37:37 -04:00
Sebastian Grimberg 5e457c5b0e Fix bug for markers in LinearFormExtension::Assemble 2022-09-30 09:59:11 -04:00
Tzanio Kolev a97923ed62 Merge pull request #3143 from mfem/linear-form-ext-fixes
LinearFormExtension fixes
2022-09-29 11:10:32 -07:00
Tzanio Kolev 052e09e792 Merge branch 'master' into linear-form-ext-fixes 2022-09-29 11:10:18 -07:00
Tzanio Kolev e98d10d688 Updated CHANGELOG 2022-09-29 11:06:38 -07:00
Sebastian Grimberg 35b1d71507 Merge branch 'master' into sjg/multigrid-mult-rhs 2022-09-29 12:34:46 -04:00
Ketan Mittal 15e3f3f35b reviewer comments 2022-09-28 13:08:35 -07:00
Ketan Mittal 436c6b29d0 Merge branch 'master' of https://github.com/mfem/mfem into tmopupdate-kershawtransform 2022-09-28 08:16:06 -07:00
Ketan Mittal 1349842c5b minor 2022-09-28 08:15:57 -07:00
Vladimir Z Tomov 64dee7ba0b Minor 2022-09-27 17:40:51 -07:00
Mark L. Stowell 7d62e0f7e6 Merge pull request #3152 from mfem/additional-curl-integrators
Additional integrators
2022-09-27 17:37:18 -07:00
Will Pazner d54d2543eb Change performance ex1 compiler flags for Apple M1 2022-09-27 10:59:41 -07:00
Socratis Petrides 2bbe5fb8f4 Merge branch 'master' into additional-curl-integrators 2022-09-27 10:19:25 -07:00
Tzanio Kolev 4a069397a4 Merge pull request #3105 from mfem/yohann/dg-amr-opt
Optimize and benchmark nonconforming matrix-free DG.
2022-09-26 14:30:06 -07:00
Tzanio Kolev e95a608766 Merge pull request #3148 from mfem/ComplexDenseMatrix
Complex dense matrix
2022-09-26 14:29:40 -07:00
0ae7ae87e1 feature/tsuji1/constraints (#3117)
* Added build directly to gitignore

* First cut at mfem windows build

* Adding windows build files

* Fixed relative path issue

* Remove cmake rebuild from mfem project, fix filters issues with ms

* Response to Review, making sure it builds for different windows build types

* Windows build fixes

* Cleaning up the build fixes

* Fixing .gitignore for some of the newer packages

* Fixing code for MSVC Compiler in preperation for NVCC build

* Upgrade to latest VS2017

* commit after merge

* Tweeks

* Fix ordering of help options, protect agains not having SNLS in main code

* Fixed windows build

* more project files

* Move Eng_Matmodel under class form, remove some errors/warnings in RDG

* Response to review 5

* Fix accidentally deleted constructor

* Windows build fixes; further refactoring of .vcxproj files

* Added FindHDF5.cmake file to mfem

* Added time, time step, and cycle to conduit data collection

* Further compatibility fixes, Allowing non-chemical materials to use region inflow, updating documentation

* Fix merge

* Adding a preprocessor definition for hypre.

* Update mfem project

* Update project

* Fix typos in mfem project

* Update MFEM HYPRE version

* Split mfem projects

* Update projects

* Update projects

* Update projects

* More tweaks for windows  build

* Fix tribol and mfem build on windows

* Fix hypre and mfem projects

* Fix tribol project; add opac gitignore

* Update project for new mfem version

* Update mfem build to import umpire target so that camp can be found; add empty lapack include directory that is required if mfem config files are used

* Fix to mfem for new umpire

* Update Windows project files

* Undo changes to windows project files

* Update windows project files

* Fix all windows configurations for several libraries

* Fix CMake error in MFEM

* Adding functions to set another preconditioner, instead of BoomerAMG.
Adding EliminationGMRESSolver and PenaltyGMRESSolver to use GMRES
instead of CG.

* Adding some functions to get the number of iterations and residual norm
from Hypre solvers.

* Adding two lines to return the right residual and convergence information.

* Adding some functionality to choose the preconditioner for the SchurConstrainedHypreSolver.

* Vectorizing the penalty function, as we can have different penalty values
for each constraint equation.

* We should initialize a diagonal HypreParMatrix here, instead of trying
to do row scalings.

* Adding some functions to the Hypre solver classes to set parameters.

* Whoops, this function should be for logging.

* Make this a multiplication by a diagonal SparseMatrix.

* Memory fix for SuperLU solver. This passes the address sanitizer now.

* Update to VS2022 and Intel oneAPI (with some Intel Classic)

* Fixing the Windows build for MFEM.

* Applying the change to include directories to all builds.

* Fixing undefined references for MFEM.

* make style

* Fix copyright

* Fix hidden overload

* Fixing the hidden overload here.

* Some fixes to the Windows build, after adding the SuperLU_Dist option.

* Fix MFEM build

* Update .gitignore

* fix windows build issues

* Removing dead code, adding comments.

* Consistend FindHDF5.cmake (and don't mention ALE3D)

* Rename property sheets to more consistent pattern

* Moving some things around gitignore, moving the Win32 directory to config.
Changing the relative directory structure in the project files after moving
the directory.

* Adding a function to allow for parallel symbolic factorization.

* Editing the CHANGELOG and INSTALL files.

* Editorial updates

* Remove config/Win32 (will be maintained externally)

Co-authored-by: Jamie A. Bramwell <bramwell1@llnl.gov>
Co-authored-by: Albert L. Nichols, III <nichols5@llnl.gov>
Co-authored-by: Arlie Capps <capps2@llnl.gov>
Co-authored-by: Patrick Greene <greene30@llnl.gov>
Co-authored-by: Benjamin T. Liu <liu15@llnl.gov>
Co-authored-by: Alan Dayton <dayton8@llnl.gov>
Co-authored-by: Tzanio Kolev <tzanio@llnl.gov>
2022-09-26 14:29:17 -07:00
Ketan Mittal 66874e8860 add sample run with gslib adaptivity evaluator and mesh node ordering byVDIM 2022-09-26 13:45:35 -07:00
Vladimir Z Tomov 35db31402e minor 2022-09-26 12:54:32 -07:00
Vladimir Z Tomov 145539f4ab Simplified function parameters. All calls to these functions are internal,
we don't expect any issues.
2022-09-26 12:48:02 -07:00
Will Pazner 1f18293a2f Use clearer variable name 2022-09-26 10:50:30 -07:00
Will Pazner 6b38f5c46c Fix typos 2022-09-26 10:49:38 -07:00
Ketan Mittal cc09a3f428 fix CMakeLists 2022-09-22 19:34:49 -07:00
Ketan Mittal 5de599cef2 wordsmithing 2022-09-22 15:34:55 -07:00
Ketan Mittal 1e455ad4b0 add option to use Kershaw transformation in mesh-explorer 2022-09-22 15:27:15 -07:00
Ketan Mittal c17ea3b614 Merge branch 'master' of https://github.com/mfem/mfem into tmopupdate-kershawtransform 2022-09-22 11:14:56 -07:00
Ketan Mittal 0043957876 minor 2022-09-22 11:14:29 -07:00
Tzanio Kolev 23301d2223 Merge pull request #3133 from mfem/quadrature-coeff-lor
Support general coefficient types in batched LOR
2022-09-22 08:53:27 -07:00
Tzanio Kolev 9e6711d016 Merge pull request #3224 from mfem/boundary-lininteg-face-quadrature-space
Use FaceQuadratureSpace in device boundary linear forms
2022-09-22 08:53:17 -07:00
Chris Vogl 3a80ea1bde updated changelog with comments on encapsulation via removal of deprecated NVector functions 2022-09-21 14:00:51 -07:00
Chris Vogl f36aa1aece corrected SUNLinSolSPFGMR wrapper to use SPFGMR instead of SPGMR 2022-09-21 13:47:40 -07:00
Chris Vogl 4dd7becd3e removed unnecessary include in hypre.cpp 2022-09-21 13:45:59 -07:00
Chris Vogl 8ce6a04707 need default construct for dummy SundialsMemHelper when CUDA is not enabled 2022-09-21 13:45:39 -07:00
Tzanio Kolev e807d1ebd6 HTTP for the METIS webpage 2022-09-21 13:21:20 -07:00
Vladimir Z Tomov 3378b79a23 Moved check-tmop-metric to miniapps/tools. 2022-09-21 11:39:36 -07:00
Vladimir Z Tomov 5fe52fbddc changelog. 2022-09-21 11:25:52 -07:00
Vladimir Z Tomov a5da5734c2 Addded metric 360. 2022-09-21 11:22:54 -07:00
Tzanio Kolev 765918a611 Merge pull request #3178 from mfem/memory-movement-fixes
Improve memory movement in CheckFinite & DenseTensor(k)
2022-09-20 18:49:46 -07:00
Tzanio Kolev bc6996c885 HTTP for the METIS webpage 2022-09-20 17:37:32 -07:00
Tzanio Kolev b80755ab02 Merge branch 'master' into mfem-4.5-dev 2022-09-20 17:36:22 -07:00
Will Pazner 90257baa43 Merge remote-tracking branch 'origin/master' into linear-form-ext-fixes
# Conflicts:
#	fem/linearform.cpp
#	tests/unit/fem/test_linearform_ext.cpp
2022-09-20 12:05:39 -07:00
Will Pazner 0cd4f4456a Use FaceQuadratureSpace in device boundary linear forms 2022-09-20 10:47:17 -07:00
Ketan Mittal 2f077ea9a0 add kershaw transformation 2022-09-20 09:39:17 -06:00
Aaron Fisher bf287d6ae5 Fixed a comment. 2022-09-20 08:12:53 -07:00
Aaron Fisher 462842eea9 Merge branch 'master' into ncmesh-pyramid-dev 2022-09-20 08:11:01 -07:00
Tzanio Kolev 5cedebaa75 Merge pull request #3201 from mfem/ceed-mixedint-fix
Fix errors building with libCEED and hypre mixed int
2022-09-19 14:26:16 -07:00
Tzanio Kolev ae597b46a0 Mention mfem.org/building in INSTALL 2022-09-19 14:22:32 -07:00
Will Pazner 42c87f3baa Update CHANGELOG 2022-09-19 13:11:11 -07:00
Will Pazner 86e9298c5a Fix deprecation warnings in ParTransferMap 2022-09-19 12:21:07 -07:00
Will Pazner f0d7789836 Merge remote-tracking branch 'origin/master' into vector-remove-implicit-conversion 2022-09-19 12:02:56 -07:00
Will Pazner 883120f0e9 Fix deprecation warning when LAPACK is enabled 2022-09-19 11:59:36 -07:00
Socratis Petrides 1b79a1e12e Fix comment 2022-09-18 19:41:31 -07:00
Will Pazner 100caf5200 Support general coefficient types in batched LOR 2022-09-16 20:43:09 -07:00
Will Pazner 110f92a1d6 Merge pull request #3196 from mfem/metis-mirror
Use MFEM's METIS mirror instead of glaros.dtc.umn.edu
2022-09-16 20:41:54 -07:00
Socratis Petrides c9c50fadd3 adding missing comment 2022-09-16 20:25:07 -07:00
Socratis Petrides c72d37b764 minor 2022-09-16 20:01:37 -07:00
Socratis Petrides 542a8a6722 adding bounds checks 2022-09-16 19:53:16 -07:00
Socratis Petrides a6a7d2d5d7 adding block symmetric convention 2022-09-16 19:52:58 -07:00
Tzanio Kolev ede5bed103 Merge pull request #2920 from mfem/feature/submesh
SubMesh
2022-09-16 17:05:14 -07:00
Tzanio Kolev ba01aecddc Merge pull request #3066 from mfem/face-quadrature-space-coefficient
FaceQuadratureSpace
2022-09-16 16:59:28 -07:00
Socratis Petrides 28d9f4ba5b minor 2022-09-16 15:44:52 -07:00
Will Pazner e03a7fef41 Return ElementRestrictionOperator* from FiniteElementSpace::GetElementRestriction 2022-09-16 11:29:09 -07:00
Yohann aacc37c175 Revert change to google benchmark makefile. 2022-09-16 15:51:42 +02:00
Yohann d763963c24 Fix documentation. 2022-09-16 15:47:01 +02:00
Yohann 9ac1f3eec6 Rename SortSparseMatrix to EnableSparseMatrixSorting.
- Add a boolean parameter to enable/disable
- Also sort on CPU
2022-09-16 15:27:59 +02:00
Tom Stitt e046185ca7 switch to T* Memory version so we can set own=false
add const GetData
2022-09-15 13:35:18 -07:00
Tzanio Kolev c6bb7c2af9 Updates after the metis page came back up 2022-09-14 08:01:37 -06:00
Tzanio Kolev cea9fceb5c Merge pull request #3195 from mfem/hypreams-mem-leak-fix-tk
Suggested changes in PR 3096
2022-09-13 06:25:47 -07:00
Tzanio Kolev 2b9295db34 Copy *.mesh files in miniapps/multidomain for out-of-source builds 2022-09-13 07:13:53 -06:00
Yohann 7c9710b559 Use SortSparseMatrix in test_fa_determinism. 2022-09-12 18:24:58 +02:00
Yohann a747f49ec7 Remove unnecessary InPlace. 2022-09-12 18:22:17 +02:00
Yohann d31979c02e Add InPlace to methods doing "in place" computations. 2022-09-12 17:12:23 +02:00
Yohann 409e743bc4 Change sparse matrix sorting interface.
- Rename method to `SortSparseMatrix`.
- Default behavior is to not sort the sparse matrices.
- Improve documentation.
2022-09-12 15:57:36 +02:00
Yohann ccd01f2c58 Set ntrials to 2 in test_fa_determinism. 2022-09-12 15:49:25 +02:00
Tzanio Kolev c07bc1d90d Multidomain miniapp improvements 2022-09-11 17:29:33 -07:00
Tzanio Kolev 8daadc97d0 correct multidomain-hex.mesh location in tests/unit/mesh/test_psubmesh 2022-09-11 15:23:49 -07:00
Tzanio Kolev ee7c345081 minor 2022-09-11 14:50:18 -07:00
Tzanio Kolev 361c32362b Merge pull request #3126 from mfem/dg-mass-inv
Local PCG for DG mass inverse on GPU
2022-09-10 13:40:45 -07:00
Tzanio Kolev dfa9b7e85b Merge pull request #3177 from mfem/lor-vdim-ordering
Match ordering in LOR with vdim > 1
2022-09-10 13:38:14 -07:00
Will Pazner b171645d17 Merge pull request #3134 from luzpaz/typos
Fix various typos
2022-09-09 13:49:35 -07:00
Will Pazner 74a04838fa Merge remote-tracking branch 'origin/master' into typos 2022-09-09 09:57:48 -07:00
Will Pazner 62eda9466d Merge pull request #3127 from mfem/yohann/check-diag-poplicy
Check for consistent diagonal policy in `FABilinearFormExtension::EliminateBC`
2022-09-09 09:55:01 -07:00
Will Pazner 621081b3a8 Merge pull request #3183 from mfem/yohann/fix-markers
Bugfix in `linearform`
2022-09-09 09:54:08 -07:00
Tzanio Kolev 9bc9cdca17 Merge pull request #3144 from mfem/bdr-linear-form
Support boundary linear forms on device
2022-09-09 08:59:32 -07:00
Will Pazner e14b47e12f Fix errors building with libCEED and hypre mixed int 2022-09-08 21:06:36 -07:00
Veselin Dobrev b1a1c8cd17 Initial commit in v4.5 branch, mfem-4.5-dev 2022-09-08 13:45:22 -07:00
Tucker Babcock c45e6d12e6 make style 2022-09-08 16:42:31 -04:00
Tucker Babcock b2bb31ac8d modify ex3p so show the memory leak, and show that this fixes it. 2022-09-08 16:41:55 -04:00
Tucker Babcock 1fecc8d768 add option preserving memory leak fix, and use it if the hypre version allows 2022-09-08 16:41:07 -04:00
Will Pazner 0051469216 Update CHANGELOG 2022-09-07 15:43:33 -07:00
Ketan Mittal aa37d19f21 Merge branch 'master' of https://github.com/mfem/mfem into gslib-node-ordering 2022-09-07 15:30:11 -07:00
Ketan Mittal b50c494e8b grab fes_ordering from fes/pfes in AdaptivityEvaluator 2022-09-07 15:30:00 -07:00
Tzanio Kolev 26b4980060 Merge branch 'hypreams-mem-leak-fix' into hypreams-mem-leak-fix-tk 2022-09-07 14:59:56 -07:00
Tzanio Kolev 4f688f6c66 Merge branch 'master' into hypreams-mem-leak-fix-tk 2022-09-07 14:54:33 -07:00
Tzanio Kolev afe40bfb9f Merge branch 'master' into hypreams-mem-leak-fix 2022-09-07 14:53:42 -07:00
Tzanio Kolev 39a4b07641 Switch METIS homepage in vcpkg to their GH repo 2022-09-07 13:29:58 -07:00
Cody J. Balos 0142bb7c81 Address undef. behavior from 'recursive' init of singleton
According to the standard, recusrive initialization of a static
object is undefined. Some compilers handle it fine, but XL does not.

Also ensure that only one instance of Sundials class instantiated.
2022-09-07 12:00:03 -07:00
Tzanio Kolev 520790b25f Use MFEM's METIS mirror 2022-09-07 11:36:36 -07:00
Will Pazner 256ee6c1b5 Fix signed integer comparison 2022-09-07 11:29:12 -07:00
Will Pazner dc829768ad Fix issues handling boundary elements and faces in LinearFormExtension 2022-09-07 11:23:33 -07:00
Will Pazner ea2a9676c1 Use mesh face numbering for boundary element attributes in LinearFormExtension 2022-09-07 10:32:53 -07:00
Will Pazner 96e1b7d4a0 Make sure to accumulate boundary integrators in LinearFormExtension 2022-09-07 10:32:31 -07:00
Tzanio Kolev be8eaf6900 Merge pull request #3185 from mfem/cmake-lapack-blas-fix
Fix the link order of BLAS and LAPACK in CMake
2022-09-07 07:32:26 -07:00
Tzanio Kolev be2874c3e4 Suggested changes in PR 3096 2022-09-06 19:01:59 -07:00
Will Pazner e0d8ee2bcd Better host/device memory management in QuadratureFunction::GetValues 2022-09-06 17:00:08 -07:00
Socratis Petrides 59e8f98684 fic DivDiv unit test 2022-09-06 16:27:57 -07:00
Socratis Petrides c1ec08f5c0 addressing reviewer's comments 2022-09-06 15:55:17 -07:00
Socratis Petrides a2d5a9c350 fix documentation for MixedCurlIntegrator 2022-09-06 15:55:17 -07:00
Socratis Petrides bbab6f72a2 style 2022-09-06 15:55:17 -07:00
Socratis Petrides eadc1127cd forgotten test case name 2022-09-06 15:55:17 -07:00
Socratis Petrides 4c0893feef 3D curlintegrator unit tests 2022-09-06 15:55:17 -07:00
Socratis Petrides f2c013725f 2D curl unit tests 2022-09-06 15:55:17 -07:00
Socratis Petrides 80ff956840 ComputeCurl fix in densmat 2022-09-06 15:55:17 -07:00
Socratis Petrides 8b4546a758 fix assert 2022-09-06 15:55:17 -07:00
Socratis Petrides b959fdd961 remove empty lines 2022-09-06 15:55:17 -07:00
Socratis Petrides 4dee85fc93 fix sign in NormalTraceJump 2022-09-06 15:55:16 -07:00
Socratis Petrides cfc743e2e0 fix compiler issue 2022-09-06 15:55:16 -07:00
Socratis Petrides 8c70106578 AssembleElementMatrix2 for DivDivIntegrator 2022-09-06 15:55:16 -07:00
Socratis Petrides 8fc8bbcfea AssembleElementMatrix2 for CurlCurlIntegrator 2022-09-06 15:55:16 -07:00
Socratis Petrides af4798341f adding MixedCurlInitegrator 2022-09-06 15:55:16 -07:00
Will Pazner bfc871481f Remove implicit Vector conversions in tests, miniapps, examples 2022-09-06 13:20:56 -07:00
Will Pazner 5a455dd141 Deprecate Vector implicit conversion to double* 2022-09-06 13:05:38 -07:00
Socratis Petrides 0d71c27210 resolving conflicts with master 2022-09-05 12:15:57 -07:00
Socratis Petrides 7c7370fdc1 resolving conflicts with master 2022-09-05 11:37:22 -07:00
Tzanio Kolev 502d2f5dc7 Merge pull request #3149 from mfem/blockmatrix-util
BlockMatrix additional utilities
2022-09-03 20:47:01 -07:00
Tzanio Kolev 07048928a2 Merge pull request #3159 from mfem/white238/remove_unnecessary_ifs
Remove some now unnecessary if statement
2022-09-03 20:40:11 -07:00
Veselin Dobrev 5180b3f92e Revert changes in Mesh::GetLocalTriToTetTransformation() and
Mesh::GetLocalQuadToHexTransformation().

To address the issue seen when calling
Mesh::GetBdrElementAdjacentElement() followed by calling
Mesh::GetLocalFaceTransformation(), introduce a new method,
Mesh::GetBdrElementAdjacentElement2() that returns the orientation
of the face element w.r.t. the boundary element. This orientation
then produces the desired result when used with
Mesh::GetLocalFaceTransformation().
2022-09-02 18:57:43 -07:00
Will Pazner 39c4c47993 Support new QuadratureSpace in libCEED interface 2022-09-02 16:13:39 -07:00
Will Pazner 118a28aec4 Fix comment 2022-09-02 16:09:15 -07:00
Will PaznerandYohann Dudouit 89b71a2a52 Replace some MFEM_ASSERT with MFEM_VERIFY
Co-authored-by: Yohann Dudouit <dudouit1@llnl.gov>
2022-09-02 16:09:10 -07:00
Veselin Dobrev f7fcfe18f6 Update const-ness to match the new const result of the method
GroupCommunicator::GetGroupTopology().
2022-09-02 14:53:51 -07:00
Julian Andrej 4d43eb13eb remove const from returned object 2022-09-02 11:10:02 -07:00
Tzanio Kolev b3be2d347f Merge branch 'master' into feature/submesh 2022-09-01 14:49:56 -07:00
Tzanio Kolev 1fd1217962 Merge branch 'master' into white238/remove_unnecessary_ifs 2022-09-01 14:42:18 -07:00
Veselin Dobrev 2d4c32a19c In CMakeLists.txt, switch the order of BLAS and LAPACK in the
dependencies list to get correct link line order.
2022-09-01 14:10:06 -07:00
Yohann Dudouit c4f5897b20 Use Cu/Hip allocations to avoid int overflow with Memory interface. 2022-09-01 10:29:36 -07:00
Yohann Dudouit 03ce7c1d4a Set ntrials to 1. 2022-08-31 18:00:29 -07:00
Yohann Dudouit 7404fbbaf1 Replace DEVICE_MASK with ~CPU_MASK. 2022-08-31 17:59:16 -07:00
Yohann Dudouit 5a18775378 Merge branch 'yohann/sort+test' of https://github.com/mfem/mfem into yohann/sort+test 2022-08-31 17:21:07 -07:00
Yohann Dudouit f1a2fc2295 Factor out isSorted. 2022-08-31 17:21:03 -07:00
YohannandWill Pazner cff4473374 Update fem/bilinearform.hpp
Co-authored-by: Will Pazner <11493037+pazner@users.noreply.github.com>
2022-08-31 17:19:08 -07:00
Yohann Dudouit caa79bf801 feedback from @pazner 2022-08-31 17:17:18 -07:00
Yohann Dudouit a3392192f2 Remove whitespace... 2022-08-31 16:55:32 -07:00
Yohann Dudouit 93a7fc37e2 Avoid using non-const array accessor. 2022-08-31 16:49:53 -07:00
Stefano Zampini 04afec9eda remove unused variable 2022-08-31 10:49:11 +03:00
Stefano Zampini 589eefedfb Add block size support 2022-08-31 10:48:57 +03:00
Socratis Petrides ba5d2a6152 fix EliminateRowCols 2022-08-30 19:16:29 -07:00
Will PaznerandYohann 2dba5efb09 Fix typo in comment
Co-authored-by: Yohann <dudouit1@llnl.gov>
2022-08-30 10:30:59 -07:00
Will Pazner db5441c44c Fix bad resolution of merge conflict 2022-08-30 10:28:51 -07:00
Socratis Petrides 601df01c8f Merge branch 'master' into blockmatrix-util 2022-08-29 17:50:36 -07:00
Socratis Petrides 882ee134c2 Merge branch 'master' into ComplexDenseMatrix 2022-08-29 17:49:46 -07:00
Socratis Petrides 2b2c755405 reverting change in GradToCurl. To be handled by the CurlIntegrators PR 2022-08-29 17:48:10 -07:00
Chris Vogl 3adeb1d4f8 adding missed SUNContext variables to CUDA calls 2022-08-29 14:28:33 -07:00
Will Pazner 93fc7cf608 Match ordering in LOR with vdim > 1 2022-08-29 13:45:26 -07:00
Veselin Dobrev 4edfc95acc Merge pull request #3175 from mfem/tmop-MemLeakFix
Fix memory leak in TMOP metric
2022-08-29 13:10:31 -07:00
Tom Stitt 68473f6fca HostRead() instead of GetData() in CheckFinite
don't use non-const method from const operator()(k) so we can avoid unnecessary HostReadWrites
2022-08-29 12:58:20 -07:00
Ketan Mittal 17dbc28b51 fix memory leaks 2022-08-26 14:06:13 -07:00
Ketan Mittal 1298289bd4 update changelog 2022-08-25 17:31:10 -07:00
Ketan Mittal aecde778ed Merge branch 'master' of https://github.com/mfem/mfem into gridfunc-gettruevec-fix 2022-08-25 17:22:25 -07:00
Yohann Dudouit dabae076c5 Reactivate full assembly sample runs in ex1 and ex1p. 2022-08-25 13:36:46 -07:00
Yohann Dudouit a49b8a5a63 Merge branch 'master' into yohann/sort+test 2022-08-25 13:35:30 -07:00
Yohann Dudouit 3a62136a70 Remove SortRows from HypreParMatrix. 2022-08-25 13:25:20 -07:00
Yohann Dudouit 1fe908294d Add method to disable sparse matrix sorting on device. 2022-08-25 13:17:54 -07:00
Chris Vogl 42f9c6dbf4 Update linalg/sundials.cpp
add comment to preprocessor directive
2022-08-25 13:02:34 -07:00
Chris Vogl 672e477364 Update linalg/sundials.cpp
add comment to preprocessor directive
2022-08-25 13:02:25 -07:00
Chris Vogl 00f7b2bd02 applied astyle changes 2022-08-25 12:25:21 -07:00
Chris Vogl 1cd2ff2364 GitHub tests noted a mispelling 2022-08-25 12:22:45 -07:00
Chris Vogl 95c570b001 removed unused definition in hypre 2022-08-25 12:13:27 -07:00
Chris Vogl 4803dfa020 applied astyle changes 2022-08-25 12:04:57 -07:00
Chris Vogl 9b8d063584 added comments 2022-08-25 11:43:50 -07:00
Chris Vogl fa50d81410 used namespaces to help differentiate C and C++ functions 2022-08-25 11:11:08 -07:00
Yohann Dudouit 96f8aa4a89 Fix sorting of sparse matrices with hip. 2022-08-25 10:07:03 -07:00
Tzanio Kolev 5150ab71e9 Merge pull request #3161 from prathamgit/master
Minor change in output message in linalg/sparsemat.cpp
2022-08-25 09:21:24 -07:00
Chris Vogl 635e3de561 overloaded SUNDIALS >= v6 calls for backwards compatibility 2022-08-24 16:57:53 -07:00
Chris Vogl ff1e52c56a moved definition of SundialsMemHelper to sundials.hpp so the sunmemHelper can be added to the singleton Sundials class instead of being a global variable 2022-08-24 14:15:52 -07:00
Chris Vogl e03ff5825d removed definitions of removed deprecated functions 2022-08-24 10:27:17 -07:00
Chris Vogl 3adde968e4 removed deprecated Vector::ToNVector() 2022-08-24 10:25:57 -07:00
Chris Vogl 0bbeb2cf65 removed deprecated Vector::ToNVector()... user should instead use SundialsNVector(double*, int) 2022-08-24 10:24:53 -07:00
Chris Vogl 6b800d16f4 removed deprecated Vector(N_Vector)... user should instead us SundialsNvector(N_Vector) 2022-08-24 10:24:14 -07:00
Will Pazner 44663ed239 Clean up determinism test 2022-08-24 10:00:45 -07:00
Will Pazner 231ec7961d Add determinism test 2022-08-24 10:00:44 -07:00
Chris Vogl 0c77c3535a corrected SUNContext return code and shortened error message 2022-08-24 08:03:40 -07:00
Chris Vogl 7457eeea1a added call to Sundials::Init to all Sundials examples 2022-08-23 19:50:05 -07:00
Chris Vogl eff25a6b30 refactor deprecated calls to enum Butcher table values in Sundials examples 2022-08-23 19:46:37 -07:00
Chris Vogl 80fd02ffbf refactor of Sundials singleton to use static construction like Hypre singleton 2022-08-23 19:43:14 -07:00
Yohann Dudouit d7b5d07cce Create temporary cusparseMatDescr_t for sorting. 2022-08-23 17:37:46 -07:00
Yohann Dudouit 8029a5ace0 Use Arrays instead of Memory objects. 2022-08-23 17:37:14 -07:00
Yohann Dudouit 78ac894623 Use class methods to read and write. 2022-08-23 17:36:44 -07:00
Yohann Dudouit 6cd171ae05 Use Capacity instead of Size. 2022-08-23 17:33:30 -07:00
Tzanio Kolev 067afacfb4 Merge branch 'master' into yohann/dg-amr-opt 2022-08-23 17:25:44 -07:00
Tzanio Kolev f2b7d6f020 Merge branch 'master' into white238/remove_unnecessary_ifs 2022-08-23 17:21:45 -07:00
Chris Vogl 413d860ea6 added first draft of Sundials singleton for SUNContext and updated all calls into Sundials 2022-08-23 17:13:22 -07:00
Chris Vogl 73bbfda158 using enum types ARKODE_DIRKTableID and ARKODE_ERKTableID instead of int to avoid permissive errors 2022-08-23 17:12:42 -07:00
Veselin Dobrev 687f20e52c Merge pull request #3162 from mfem/lgtm-to-codeql
Replace LGTM static analysis with GitHub code scanning
2022-08-23 15:28:06 -07:00
Yohann Dudouit 9f035181c1 Update SortColumnIndices to be device aware. 2022-08-23 15:27:28 -07:00
Chris Vogl 88f5d5a0ca commented out deprecated ToNVector wrappers... will decide whether to support or not later 2022-08-23 15:18:35 -07:00
Tzanio Kolev 448851a07e Merge pull request #3039 from mfem/ComputeL2Errors
Compute l2 errors
2022-08-23 12:49:34 -07:00
Will Pazner 5352a2d910 Move host device kernel functions into internal namespace 2022-08-23 12:44:50 -07:00
Tzanio Kolev 0040a7bc0e Keep the log from upgrading Doxygen configuration 2022-08-23 12:37:01 -07:00
Yohann Dudouit 60de1d3102 Improve documentation. 2022-08-23 10:41:55 -07:00
Tzanio Kolev e3d9b0a649 Fixed wrong commit 2022-08-22 18:23:59 -07:00
Tzanio Kolev 2b15362ec5 Reverted to old version of doxygen configuration 2022-08-22 18:20:43 -07:00
Socratis Petrides 457c3ad80b review comments 2022-08-22 16:24:21 -07:00
Tzanio Kolev a44e27583c Addressed Veselin's comment 2022-08-22 15:59:24 -07:00
Tzanio Kolev 2c2d7161bc Switching to ubuntu/macos/windows-latest in GHA 2022-08-20 14:34:09 -07:00
Socratis Petrides c0fcb7680e fix unit test 2022-08-20 10:30:54 -07:00
Socratis Petrides 010327a950 fix unit test 2022-08-20 10:15:04 -07:00
Will Pazner cfb46e8db9 Exchange face neighbor data in ParMesh::GetNFbyType 2022-08-19 22:53:19 -07:00
Will Pazner a8b3dded79 Use variable coefficients in linear form extension unit tests 2022-08-19 21:48:49 -07:00
Will Pazner dca1206af6 Handle lexicographic permutation in boundary linear form extension 2022-08-19 21:46:30 -07:00
Tzanio Kolev 3c5cb60b6c Fixes for ubuntu-22.04 2022-08-19 19:13:27 -07:00
Tzanio Kolev afe229f744 Switch to ubuntu-22.04. Better Actions names. 2022-08-19 17:45:45 -07:00
Socratis Petrides 5819549ca4 Merge branch 'master' into blockmatrix-util 2022-08-19 17:12:59 -07:00
Socratis Petrides 5e540807cf Merge branch 'master' into ComplexDenseMatrix 2022-08-19 17:11:56 -07:00
Tzanio Kolev 662c97b7f1 Create codeql-analysis.yml 2022-08-19 16:52:45 -07:00
Will Pazner 59074421dc Merge remote-tracking branch 'origin/master' into dg-mass-inv 2022-08-19 16:29:02 -07:00
Will Pazner bba7bc2181 Merge remote-tracking branch 'origin/master' into linear-form-ext-fixes 2022-08-19 16:28:52 -07:00
Will Pazner 86911f0e26 Merge remote-tracking branch 'origin/master' into bdr-linear-form 2022-08-19 16:28:15 -07:00
Veselin Dobrev 641078645f Merge pull request #3155 from mfem/metis-vcpkg
Windows CI METIS workaround
2022-08-19 16:27:04 -07:00
Prathamesh Sirmalla @lab_pc 1f3d8a051c Minor change in output message in linalg/sparsemat.cpp 2022-08-19 15:38:25 -05:00
Will Pazner 3a85cae085 Change CRLF to LF line endings 2022-08-19 11:39:38 -07:00
Yohann Dudouit 2d135c4df5 Merge branch 'master' into yohann/dg-amr-opt 2022-08-19 10:47:31 -07:00
Tzanio Kolev 39fb7d6f0c Merge pull request #3151 from mfem/disable-fa-runs-ex1
Temporarily disable the FA sample runs in ex1/ex1p
2022-08-19 08:32:08 -07:00
Tzanio Kolev ee3216d8ff Merge pull request #3154 from mfem/lor-vdim
Support vdim in LOR solvers
2022-08-19 08:04:44 -07:00
Chris White f8ca9430da remove a now unnecessary if statement 2022-08-18 16:42:53 -07:00
Will Pazner f29f07ff87 Use custom metis vcpkg portfile 2022-08-18 16:41:21 -07:00
Will Pazner caff2c1ce3 Add DGMassInverse::Update 2022-08-18 15:03:28 -07:00
Tzanio Kolev 1db3de8fee Merge pull request #3145 from mfem/paraview-ascii-fix
Fix ParaView ASCII output
2022-08-17 11:31:43 -07:00
Tzanio Kolev 30abb73143 Minor 2022-08-17 11:30:01 -07:00
Will Pazner 5f3219cb06 Support vdim in LOR solvers 2022-08-17 10:06:18 -07:00
Veselin Dobrev da2b481c5b Temporarily disable the FA sample runs in ex1/ex1p due to
non-deterministic behavior.
2022-08-16 15:03:08 -07:00
Ketan Mittal 57f6f0d842 fix doxygen comments 2022-08-16 12:06:04 -07:00
Socratis Petrides 57aa5aaae8 remove unused variable 2022-08-16 11:58:10 -07:00
Socratis Petrides 1ab976992b style 2022-08-16 11:45:00 -07:00
Socratis Petrides ebf4d2e737 adding unit tests 2022-08-16 11:44:30 -07:00
Socratis Petrides 7917bc401f fix eliminaterowcols to work with general matrices 2022-08-16 11:44:03 -07:00
Vladimir Z Tomov 48152fdeac Merge branch 'master' into tmop-update3D 2022-08-16 11:11:26 -07:00
Socratis Petrides 639ca8f06a ParMult and ParAddMult 2022-08-16 09:50:33 -07:00
Socratis Petrides aef437100a Eliminate RowCols for blockmatrix 2022-08-16 09:48:26 -07:00
Socratis Petrides c0fff78f17 adding block operator types 2022-08-16 09:45:05 -07:00
Socratis Petrides e1e338fb86 return operator type 2022-08-16 09:43:27 -07:00
Julian Andrej e31e82cb0b Merge branch 'master' of github.com:mfem/mfem into feature/submesh 2022-08-16 09:40:19 -07:00
Julian Andrej 41e7162fbd review changes 2022-08-16 09:07:08 -07:00
Socratis Petrides 972243cfca Cmake fix 2022-08-15 20:50:04 -07:00
Socratis Petrides 63ba80fafe fixing shadow veriables 2022-08-15 18:20:53 -07:00
Socratis Petrides 0f582d0589 style 2022-08-15 17:48:32 -07:00
Socratis Petrides 5fd163b2db more comments edits 2022-08-15 17:44:48 -07:00
Socratis Petrides e6303f75ab comments edits 2022-08-15 17:44:31 -07:00
Socratis Petrides e008828901 forgotten comma 2022-08-15 16:56:23 -07:00
Socratis Petrides 2a3649970f additional vector util 2022-08-15 16:55:26 -07:00
Socratis Petrides a386076012 unit tests for complex_densemat 2022-08-15 16:55:12 -07:00
Socratis Petrides 3bc2c884e5 complex_densemat implementations 2022-08-15 16:54:37 -07:00
Socratis Petrides 4f24b51e06 complex dense mat signatures 2022-08-15 16:54:22 -07:00
Socratis Petrides 305466139f cmakelist 2022-08-15 16:53:57 -07:00
Socratis Petrides 3e4c755cd9 densmat additional utilities 2022-08-15 16:52:47 -07:00
Socratis Petrides 903e1cd5fb densmat additional util signatures 2022-08-15 16:52:34 -07:00
Vladimir Z Tomov 515e66f052 style 2022-08-15 14:15:08 -07:00
Vladimir Z Tomov 1e67aeff44 minor. 2022-08-13 17:10:56 -07:00
Vladimir Z Tomov be65b60cd7 added new metrics to miniapps. 2022-08-13 17:04:21 -07:00
Vladimir Z Tomov e6661b13df Added 347. 2022-08-13 16:49:16 -07:00
Vladimir Z Tomov 41f7a7f5a8 minor improvements. 2022-08-13 16:08:46 -07:00
Vladimir Z Tomov dc12bbaa80 Added 323. 2022-08-13 12:15:23 -07:00
Vladimir Z Tomov 80362ad10f minor 2022-08-12 16:43:02 -07:00
Vladimir Z Tomov dcd359e1f2 Added code that validates metric evaluation, and its derivatives.
Added metric 322.
2022-08-12 16:41:14 -07:00
Will Pazner c14899c149 Fix ParaView ASCII output (was going to mfem::out instead of file stream) 2022-08-12 12:04:25 -07:00
Will Pazner de6bd665c7 Don't request normals when not needed in BoundaryLFIntegrator 2022-08-12 11:27:51 -07:00
Will Pazner 106964e90c Rename J to DETJ in DomainLFIntegrator 2022-08-12 11:18:51 -07:00
Will Pazner 1914d41c74 Add unit test for BoundaryNormalLFIntegrator on device 2022-08-12 10:49:12 -07:00
Will Pazner 72e0c8da8a Support BoundaryNormalLFIntegrator on device 2022-08-12 10:49:12 -07:00
Will Pazner 44dd55eee0 Make VectorConstantCoefficient::GetVec const (const-correctness) 2022-08-12 10:49:12 -07:00
Will Pazner ce8493cb1f Assemble BoundaryLFIntegrator on device 2022-08-12 10:48:50 -07:00
Will Pazner f7829f2fd8 Support boundary linear form integrators in LinearFormExtension 2022-08-12 10:48:50 -07:00
Will Pazner 293de49b1d Add test for accumulation of integrators in LinearFormExtension 2022-08-12 10:45:39 -07:00
Will Pazner c77975fa74 Properly accumulate integrators in LinearFormExtension 2022-08-12 10:45:39 -07:00
Will Pazner a0629524bb Remove unneeded if 2022-08-12 10:45:39 -07:00
Will Pazner 88b53f434d Use DETERMINANTS instead of JACOBIANS in DomainLFIntegrator 2022-08-12 10:45:39 -07:00
Will Pazner 08df351c39 Add common abstract base class for ElementRestriction operators
Include AddMultTranspose virtual member function
2022-08-12 10:34:30 -07:00
Aaron Fisher 15680b2052 make style 2022-08-11 12:32:20 -07:00
Aaron Fisher 64737fad46 Merge branch 'ncmesh-pyramid-dev' of github.com:mfem/mfem into ncmesh-pyramid-dev 2022-08-11 10:19:29 -07:00
Aaron Fisher dd0b13ec5a Fixed the deref table after I reshuffled the elements. 2022-08-11 10:18:55 -07:00
Aaron Fisher 1b4480552c make style 2022-08-10 16:36:00 -07:00
Aaron Fisher 0e24a2840a Reordered the refined pyramid elements to put the tets at the end. 2022-08-10 16:33:22 -07:00
Aaron Fisher 3add57b2f1 Merge branch 'ncmesh-pyramid-dev' of github.com:mfem/mfem into ncmesh-pyramid-dev 2022-08-10 14:44:38 -07:00
Aaron Fisher e8df0436ef Fixed problems that unit testing uncovered. 2022-08-10 14:40:06 -07:00
Ketan Mittal 07ea7f867d merge with master and resolve conflicts 2022-08-09 11:17:14 -07:00
Ketan Mittal 1595ab60f3 modify GetTrueVector behavior to SetTrueVector if t_vec does not already exists 2022-08-08 16:46:00 -07:00
Sebastian Grimberg ef7806d1a0 Merge branch 'master' into sjg/multigrid-mult-rhs 2022-08-08 13:11:03 -07:00
Aaron Fisher 35afe5a468 make style 2022-08-05 19:36:09 -07:00
luz paz 476c855bd7 Fix various typos
Found via `codespell -q 3 -L allright,ba,equil,esy,fo,hda,lod,nd,ned,numer,ot,pres,ro,seh,shat,solfes,strat,tbe,te,warmup`
2022-08-05 20:50:51 -04:00
Aaron Fisher c8adac90f5 Added a unit test to make sure mesh volume is preserved on reference elements. 2022-08-05 16:27:30 -07:00
Aaron Fisher b3eaee247c Added pyramid support to ncmesh. 2022-08-05 15:44:25 -07:00
Will Pazner 80f963e77f Merge remote-tracking branch 'origin/master' into face-quadrature-space-coefficient
# Conflicts:
#	fem/fespace.hpp
2022-08-02 17:14:06 -07:00
Will Pazner 9593742ca7 QuadratureFunction comment improvements 2022-08-02 17:12:41 -07:00
Will Pazner 212dd03c80 Quadrature space documentation and interfaces fixes 2022-08-02 17:08:58 -07:00
Will Pazner f0f100b763 Add check for quadrature spaces that are invalid on mixed meshes 2022-08-02 17:08:43 -07:00
Yohann Dudouit 63599be6a6 Set diagonal policy in test_assembly_levels. 2022-08-02 13:04:10 -07:00
Yohann Dudouit e77d32c307 Replace HostRead with HostReadWrite. 2022-08-02 11:50:39 -07:00
Yohann Dudouit d0189bdf70 Add "host" reads in BilinearForm::EliminateVDofs 2022-08-01 18:07:13 -07:00
Yohann Dudouit eeff48cf5e Check that the diag policy is DIAG_ONE when FA. 2022-08-01 18:06:24 -07:00
Will Pazner b4a8e6218d Comments and clean up 2022-08-01 12:03:48 -07:00
Will Pazner 1233966f72 Fix some warnings in DGMassInverse 2022-08-01 10:47:16 -07:00
Will Pazner b93a8a6065 Only enable MFEM_UNROLL when defined(__CUDA_ARCH__) 2022-08-01 10:16:35 -07:00
Will Pazner 2eb06d7f3b Add unit test for DG mass inverse 2022-08-01 10:16:35 -07:00
Will Pazner 94eac27cbf Add local CG iteration for DG mass on device 2022-08-01 10:16:35 -07:00
Will Pazner 79ebe3395a Add overload for LoadX host device function 2022-08-01 09:18:33 -07:00
Sebastian Grimberg 7444aa5070 Merge branch 'master' into sjg/multigrid-mult-rhs 2022-08-01 08:59:34 -07:00
Sebastian Grimberg b15b188c44 Update const for Mult with multiple RHS 2022-08-01 08:59:06 -07:00
Will Pazner 4d80d2422d Factor out mass PA application into host device functions 2022-08-01 08:54:28 -07:00
Sebastian Grimberg 98ca552b74 Merge branch 'master' into sjg/multigrid-mult-rhs 2022-08-01 08:39:04 -07:00
Ketan Mittal 2d5e57a769 update interp miniapp to accommodate node ordering 2022-07-27 12:09:14 -07:00
Ketan Mittal cae54882f0 undo PrintAsSerial change in pmesh-optimizer from another branch 2022-07-27 11:32:16 -07:00
Tzanio Kolev 5299a2fed1 Merge branch 'master' into bugfix/rwa/coarsen-L2-proj 2022-07-27 08:39:10 -07:00
Vladimir Z Tomov d152dac87b Addedd metric 304. 2022-07-26 18:06:59 -07:00
Ketan Mittal 9e1fe38f85 minor changes and updated CHANGELOG 2022-07-26 15:11:42 -07:00
Yohann Dudouit c39b1a905b Call sorting on "local" matrices. 2022-07-26 12:06:18 -07:00
Yohann Dudouit fa62bc0bd1 Use hypre_CSRMatrixSortRow. 2022-07-26 11:52:31 -07:00
Ketan Mittal 939d07994c minor changes and resolve merge conflict 2022-07-25 12:06:07 -07:00
Sebastian Grimberg 9a2f3d5c73 Upgrades to Multigrid for multiple RHS 2022-07-14 15:52:25 -07:00
Sebastian Grimberg 4ffe3ef158 Fix shadowed names, abiguous cases, and make style 2022-07-14 15:52:25 -07:00
Sebastian Grimberg 89b7031a7a Add interface for multiple RHS solves
Also adds AddMult, AddMultTranspose as Operator methods for the ones that support it already.
2022-07-14 15:52:25 -07:00
Will Pazner f18bdee153 Add FaceQuadratureSpace::Save 2022-07-14 13:52:42 -07:00
Will Pazner dea1197142 Uncomment QuadratureFunction::Save implementation 2022-07-14 13:44:27 -07:00
Will Pazner 58c353b044 Fix shadowed variable 2022-07-14 13:24:21 -07:00
Will Pazner 2991036c44 Merge remote-tracking branch 'origin/master' into face-quadrature-space-coefficient
# Conflicts:
#	fem/bilininteg_vectorfe.cpp
#	tests/unit/fem/test_pa_coeff.cpp
2022-07-14 12:54:59 -07:00
Will Pazner f73005dee0 Use CoefficientVector in DGTraceIntegrator 2022-07-14 12:28:22 -07:00
Will Pazner bad9a95479 Support FaceQuadratureSpace in QuadratureFunction::ProjectGridFunction 2022-07-14 12:28:22 -07:00
Will Pazner 378abf1257 Permute indices to lexicographic when projecting to face QuadratureFunction 2022-07-14 12:28:22 -07:00
Will Pazner 3b954ebc3c Support FaceType in FaceQuadratureSpace 2022-07-14 12:28:22 -07:00
Will Pazner bfa7dd9a8c Add Q layout to FaceQuadratureInterpolator 2022-07-14 12:28:22 -07:00
Will Pazner ade168eb9b Add MakeRef to CoefficientVector 2022-07-14 12:28:22 -07:00
Will Pazner 173abd4126 Add GetMatrix to constant matrix coefficients 2022-07-14 07:57:43 -07:00
Will Pazner 65f75f558a Combine QuadratureFunction and FaceQuadratureFunction into one class 2022-07-13 17:31:14 -07:00
Yohann Dudouit 176df9e9b4 Even more early return for RAJA. 2022-07-13 16:12:14 -07:00
Yohann Dudouit 4415519d6f More early exit for RAJA. 2022-07-12 16:02:34 -07:00
Yohann Dudouit 9f35e0cb4f Add early return for RAJA. 2022-07-12 15:14:05 -07:00
Yohann Dudouit d0bf03c14b Remove dead code. 2022-07-11 14:20:06 -07:00
Yohann Dudouit 06ebbf33ac Minor fix: implicit cast. 2022-07-11 13:54:41 -07:00
Yohann fa198d3c5a Merge branch 'master' into yohann/dg-amr-opt 2022-07-11 13:49:59 -07:00
Yohann Dudouit 2a5ab19c5a Make private methods public for nvcc. 2022-07-11 12:41:15 -07:00
Yohann Dudouit f58cf9c2a9 Small edit to bench dg amr. 2022-07-11 12:35:28 -07:00
Yohann Dudouit 5bf8eb6a40 Fix const AddMultTranspose. 2022-07-11 12:32:27 -07:00
Yohann Dudouit d920c963ff Minor. 2022-07-11 12:05:04 -07:00
Yohann Dudouit 2be47e2a36 Fix face index. 2022-07-11 11:59:50 -07:00
Yohann Dudouit 4f7a819f40 Optimize ParNCH1FaceRestriction. 2022-07-11 11:51:46 -07:00
Yohann Dudouit 3bc6f7402e Propagate new algorithm to ParNCL2FaceRestriction. 2022-07-11 11:12:25 -07:00
Yohann Dudouit 1aa5a77567 Try to iterate only on nonconforming faces.
- Attempt to make interpolation from coarse to fine less expensive at low order.
2022-06-30 14:06:16 -07:00
Yohann Dudouit c35357d447 Overload AddMultTrasnpose to prevent memcpy. 2022-06-30 13:20:58 -07:00
Yohann Dudouit afa9394200 Try different algorithm for nc faces. 2022-06-30 10:45:20 -07:00
Yohann Dudouit 18894c1b48 Fix: finish mesh initialization before fes. 2022-06-29 18:00:32 -07:00
Tucker Babcock 81e2ebdf94 address shadow field error from CI 2022-06-29 18:56:41 -06:00
Yohann Dudouit 27cbbc2e53 Fix: change probability initialization. 2022-06-29 17:00:05 -07:00
Yohann Dudouit 6e94053e29 Add bench_dg_amr benchmark. 2022-06-29 16:16:35 -07:00
Yohann Dudouit 80b6914f03 Modify default makefile to include and link google benchmark properly. 2022-06-29 16:16:07 -07:00
Tucker Babcock 840eff1834 Fix memory leak found in HypreAMS when SetOperator is called multiple times. This occurs when using HypreAMS to precondition the linear system arising in a Newton solve. The fix is based on what has been used for HypreBoomerAMG. This source of the memory leak is that in HypreSolver::Setup the underlying solver's SetupFcn would be called, if setup_called was false. SetOperator sets setup_called to true, so HYPRE_AMSSetup would be called multiple times on the same underlying solver, creating a leak. I've introduced a new function ResetAMSPrecond that is called if SetOperator is called with a valid HypreParMatrix, that destroys the old AMS solver and creates a new one based on the old solver's settings/fields. This approach is based on HypreBoomerAMG's existing ResetAMGPrecond function. 2022-06-29 17:55:00 -04:00
Will Pazner 2487dd44be Use CoefficientVector in LinearFormExtension 2022-06-10 13:39:06 -07:00
Will Pazner 49de068515 Make sure to call T.SetIntPoint 2022-06-10 13:38:54 -07:00
Will Pazner 325f27176d Merge remote-tracking branch 'origin/master' into face-quadrature-space-coefficient
# Conflicts:
#	fem/bilininteg_convection_pa.cpp
#	fem/bilininteg_diffusion_pa.cpp
#	fem/bilininteg_mass_pa.cpp
#	fem/bilininteg_vecdiffusion.cpp
2022-06-10 13:19:19 -07:00
Will Pazner f686c25d82 Fix QuadratureFunction for rho in DGTraceIntegrator 2022-06-10 12:30:21 -07:00
Will Pazner 6932fa1da3 make style 2022-06-09 15:42:43 -07:00
Julian Andrej 876612ec3e typos 2022-06-09 09:33:42 -07:00
Julian Andrej 1e83375add rely on copy elision 2022-06-08 10:37:09 -07:00
Julian Andrej 481c94a0cc Merge github.com:mfem/mfem into feature/submesh 2022-06-08 08:43:01 -07:00
Julian AndrejandJamie Bramwell 0f189e339a Update mesh/submesh/submesh.hpp
Co-authored-by: Jamie Bramwell <bramwell1@llnl.gov>
2022-06-07 12:13:51 -07:00
Julian AndrejandJamie Bramwell 3a51fdde90 Update mesh/submesh/submesh.hpp
Co-authored-by: Jamie Bramwell <bramwell1@llnl.gov>
2022-06-07 12:13:43 -07:00
Julian AndrejandJamie Bramwell 8541caf480 Update mesh/submesh/submesh.hpp
Co-authored-by: Jamie Bramwell <bramwell1@llnl.gov>
2022-06-07 12:13:36 -07:00
Nabil Atallah 1054b851bc typo in variable name 2022-06-04 21:46:35 -07:00
Nabil Atallah c72d1d480a fixed style 2022-06-04 21:41:35 -07:00
Nabil Atallah eab6e008fd uncommented weighting in ComputeLpError 2022-06-04 21:41:05 -07:00
Nabil Atallah 702d7286a2 fixed code style 2022-06-04 21:36:10 -07:00
Nabil Atallah 42b18ab365 made the pointer to the elems input variable const 2022-06-04 17:29:54 -07:00
Nabil Atallah c547c31c9f fixed the scope of the ComputeL2Error call 2022-06-04 16:16:48 -07:00
Nabil Atallah 2aa3836fff comments 2022-06-03 13:51:14 -07:00
Nabil Atallah 09e9433254 the ComputeL2Error function with &exactCoef as input and instead used the ComputeLpError function to avoid code duplication 2022-06-03 06:18:21 -07:00
Ketan Mittal 3db15e80ff Merge branch 'master' of https://github.com/mfem/mfem into gslib-node-ordering 2022-05-31 09:51:05 -07:00
Julian Andrej 1474d485cd unused variable 2022-05-26 10:18:15 -07:00
Julian Andrej 4beefd72da omit false positive unused variable 2022-05-26 08:46:05 -07:00
Julian Andrej c0508267f6 shadowed variable 2022-05-26 08:20:11 -07:00
Ketan Mittal 31113f8eda doxygen 2022-05-25 15:33:23 -07:00
Julian Andrej cf083e8f4d fixes and unit tests for 2d 2022-05-25 13:51:55 -07:00
Julian Andrej c2b6c7d2e4 L2 2022-05-25 13:51:40 -07:00
Ketan Mittal 3d5b03d232 minor 2022-05-25 12:25:29 -07:00
Ketan Mittal b38d7f022c Merge branch 'master' of https://github.com/mfem/mfem into gslib-node-ordering 2022-05-25 11:52:53 -07:00
Nabil Atallah 699f0831ea fixed typo 2022-05-24 15:01:28 -07:00
Nabil Atallah e91641abd4 instead of declaring 'double err' as a variable, renamed it to 'err_ip; in gridfunc.cpp since 'err' is already declared as a global variable 2022-05-24 14:57:36 -07:00
Nabil Atallah 874cfcbe7c fixed some tabbing inconsistencies 2022-05-24 14:44:07 -07:00
Nabil Atallah 0e807fc154 conflicted files miniapps/shifted/makefile and fem/gridfunc.hpp 2022-05-24 14:25:31 -07:00
Nabil Atallah f3d850a0be removed commented functions 2022-05-24 13:59:22 -07:00
Robert W. Anderson 4e279ac6b4 fix typo 2022-05-24 13:40:37 -07:00
Nabil Atallah 9f3b533692 modified the ComputeL2Error by adding an element array so that the L2 error is only computed on those 2022-05-24 12:14:32 -07:00
Ketan Mittal ff2046df93 serial miniapp sample runs 2022-05-24 11:34:08 -07:00
Ketan Mittal b055cbd8b1 minor fixes and update miniapp sample runs 2022-05-24 11:32:56 -07:00
Julian Andrej 9a8f487dfe miniapp cleanup 2022-05-24 07:46:55 -07:00
Ketan Mittal 185fc95307 tmop miniapp 2022-05-23 13:21:29 -07:00
Ketan Mittal 2d732e4984 Merge branch 'pmesh-to-serial-mesh' of https://github.com/mfem/mfem into gslib-node-ordering 2022-05-23 13:16:03 -07:00
Ketan Mittal d3ee8c0449 style 2022-05-23 12:11:59 -07:00
Ketan Mittal bf76df9b9d miniapps 2022-05-23 12:11:47 -07:00
Ketan Mittal 228d33000b style 2022-05-23 11:45:11 -07:00
Ketan Mittal 7fe27cc8be fix tmop for node ordering 2022-05-23 11:43:29 -07:00
Ketan Mittal 9ceffa0645 make style 2022-05-20 17:33:33 -07:00
Ketan Mittal 7c2afd18c1 resolve conflict and update findpts example 2022-05-20 17:28:05 -07:00
Ketan Mittal d4c293d2eb initial commit 2022-05-20 14:33:33 -07:00
Robert W. Anderson 33e13e1234 fix for sum op case 2022-05-20 07:36:17 -07:00
Robert W. Anderson d177af97b3 test triangles 2022-05-19 22:18:04 -07:00
Robert W. Anderson a0dfd67635 update CHANGELOG 2022-05-19 22:17:37 -07:00
Robert W. Anderson bfb85c80b7 unit tests for tris and tets 2022-05-19 21:46:09 -07:00
Robert W. Anderson b68f43c223 support local L2 proj AMR coarsening on non-conforming tris and tets 2022-05-19 21:45:37 -07:00
Robert W. Anderson 649346bdce minimize diff 2022-05-19 20:28:40 -07:00
Robert W. Anderson d2bba7e1bb fuse DG and CG loops in parallel restriction assembly 2022-05-19 20:27:00 -07:00
Robert W. Anderson 999c1be8af fuse DG and CG loops for global restriction assembly 2022-05-19 19:23:16 -07:00
Robert W. Anderson 452209bb27 add AMR tag to coarsen tests 2022-05-19 19:22:53 -07:00
Julian Andrej 4e38e2d264 revert mistake 2022-05-19 17:41:38 -07:00
Robert W. Anderson 38c9ba0b19 clean up unused variable 2022-05-19 16:58:57 -07:00
Julian Andrej 5f3fdc281c documentation 2022-05-19 16:47:30 -07:00
Robert W. Anderson 7764aee799 fix MPI guard 2022-05-19 16:33:28 -07:00
Robert W. Anderson a9e0a32888 small cleanups and make style 2022-05-19 16:16:45 -07:00
Robert W. Anderson f52d05ff19 fix bug in AggregateError with min option 2022-05-19 16:14:38 -07:00
Robert W. Anderson ef2fb0dfd2 create loop for offdiag parts of discontinuous case in parallel coarsening matrix assembly 2022-05-19 16:12:44 -07:00
Robert W. Anderson a056c91c6a add unit tests that stress the correctness of parallel coarsen 2022-05-19 16:11:40 -07:00
Robert W. Anderson af8ec69446 make style 2022-05-19 14:15:30 -07:00
Robert W. Anderson 116d7b3990 stress test for parallel correctness 2022-05-19 14:05:17 -07:00
Robert W. Anderson 73a8e67efc make style 2022-05-19 11:56:50 -07:00
Robert W. Anderson 3e5d06aa51 temporary test code for developing parallel derefinement; tests will be captured persistently in test_derefine.cpp as we go and this will be removed at the end 2022-05-19 11:56:34 -07:00
Robert W. Anderson 1224c30c06 split parallel global assembly of the diagonal part of the derefinement matrix into continous and discontinuous cases, analogous to fespace.cpp; one processor case now works 2022-05-19 11:53:29 -07:00
Julian Andrej c7b8d3782c mesh directory 2022-05-19 10:12:25 -07:00
Julian Andrej 9623502afd header guard corrections 2022-05-19 09:50:40 -07:00
Julian Andrej d7e5c04159 gitignore 2022-05-19 08:40:32 -07:00
Julian Andrej 4b7cbacb28 move mesh file 2022-05-19 08:15:21 -07:00
Robert W. Anderson 534c0c5c3b fix up a shadowing/scope issue 2022-05-18 22:24:01 -07:00
Robert W. Anderson c2c32d8f4c merge master 2022-05-18 22:06:55 -07:00
Robert W. Anderson d9971e817f use order+1 test function, other cleanups 2022-05-18 22:01:27 -07:00
Robert W. Anderson 5e59345ee8 make style 2022-05-18 21:55:58 -07:00
Robert W. Anderson ab916272ed add tests for conservation and L2 optimality of projection for L2 FE spaces across compatible element types, basis types, orders, and dimensions 2022-05-18 21:55:29 -07:00
Robert W. Anderson 0384621463 make style 2022-05-18 21:51:52 -07:00
Robert W. Anderson 66959f111e add specialized L2 restriction from fine to coarse for discontinuous space elements 2022-05-18 21:51:20 -07:00
Robert W. Anderson 86332c87ee fix optimality test 2022-05-18 21:47:57 -07:00
Julian Andrej f2f82bd158 cmake lalalala 2022-05-18 15:33:56 -07:00
Julian Andrej 3b934147f6 par guard 2022-05-18 15:00:52 -07:00
Julian Andrej 5d28013f5d refactor 2022-05-18 14:41:28 -07:00
Tzanio Kolev 4fc819104b Merge branch 'master' into feature/submesh
Conflicts:
	makefile
2022-05-18 14:03:19 -07:00
Julian Andrej 4c2694a3dc add transfermap for serial submesh 2022-05-18 08:37:35 -07:00
Julian Andrej 44f25cb834 add nonconforming check 2022-05-18 08:35:48 -07:00
Nabil Atallah 9265b73024 added the sbm_aux.hpp file to the shifted miniapp makefile on line 55 2022-05-17 12:43:52 -07:00
Nabil Atallah 881dcb165c modified the ComputeL2Error by adding an element array so that the L2 error is only computed on those 2022-05-17 12:14:42 -07:00
Robert W. Anderson 2799bbe8f7 start building out test suite for coarsening GridFunctions 2022-05-17 11:05:00 -07:00
Robert W. Anderson aed21777fa perform conservation check and check for local optimality of coarse projection 2022-05-17 11:03:00 -07:00
Robert W. Anderson 0f86f7f249 revert the element restriction for nodal finite elements to the original method - this is needed for coarsening mesh nodes in the H1 space - still need to figure out how to handle L2 spaces with nodal elements 2022-05-17 11:01:57 -07:00
Robert W. Anderson 684270f526 split the assembling of the global refinement matrix into different methods for continuous (old method) and discontinuous (new method) spaces 2022-05-17 10:59:06 -07:00
Julian Andrej ccbd3e35b2 rename transfer map cache to avoid clash with serial version 2022-05-17 09:46:46 -07:00
Julian Andrej 52d358e29d added a transfer map cache 2022-05-17 09:41:58 -07:00
Robert W. Anderson ae566f467e temporary test code w/ visualization; will be removed before merging 2022-05-16 16:02:14 -07:00
Julian Andrej f14879f704 retry to get parallel right 2022-05-16 09:33:42 -07:00
Robert W. Anderson bd362b7612 compute coarse mass matrix and coarse-fine mass matrices separately over different domains of integration; use L2 projection matrices in NodalFiniteElement::GetLocalRestriction 2022-05-15 10:59:55 -07:00
Robert W. Anderson 995baf3b89 add isoparametric transform point matrix for 1D segments 2022-05-15 00:22:05 -07:00
Robert W. Anderson 949e866845 fixes for local L2 projection matrices for coarsening ScalarFiniteElements 2022-05-15 00:20:02 -07:00
Robert W. Anderson 47d8fd1622 when building global R matrix, each row will have multiple sets of entries, corresponding to multiple fine children; the mark and skip mechanism is not appropriate here 2022-05-15 00:11:31 -07:00
Julian Andrej bdc1a323a7 think harder about sorting 2022-04-25 15:48:35 -07:00
Julian Andrej f1ea61d5cc avoid querying non available face ids 2022-04-25 15:37:35 -07:00
Julian Andrej ca471f9421 Merge branch 'master' into feature/submesh 2022-04-25 12:37:24 -07:00
Julian Andrej 1e3ef26e5c added multidomain miniapp 2022-04-25 11:35:14 -07:00
Will Pazner acf9b51fe9 Prototype for FaceQuadratureSpace and FaceQuadratureFunction 2022-04-20 12:07:46 -07:00
Julian Andrej e1ae0fdf4f expand comment on dof order convenience function 2022-04-19 13:31:35 -07:00
Julian Andrej 87459f4240 direct transfer between two submeshes 2022-04-19 13:30:07 -07:00
Will Pazner 7d503a3dc9 Merge branch 'quadrature-function-coefficient' into face-quadrature-space-coefficient
# Conflicts:
#	fem/fespace.cpp
#	fem/fespace.hpp
#	fem/gridfunc.cpp
#	fem/gridfunc.hpp
2022-04-05 15:52:08 -07:00
Will Pazner 69c1822084 Add FaceQuadratureSpace and FaceQuadratureFunction
Also add base classes for QuadratureSpace and QuadratureFunction
2022-04-05 15:14:57 -07:00
Will Pazner 4e658ee85e Move QuadratureSpace and QuadratureFunction to their own files 2022-04-05 12:44:24 -07:00
Will Pazner 74c281cf97 Merge remote-tracking branch 'origin/master' into quadrature-function-coefficient
# Conflicts:
#	fem/bilininteg_diffusion_pa.cpp
#	fem/bilininteg_hcurl.cpp
#	fem/coefficient.hpp
2022-04-05 12:31:47 -07:00
Will Pazner fef477850e Merge remote-tracking branch 'origin/master' into quadrature-function-coefficient 2022-03-31 16:49:55 -07:00
Julian Andrej 2d515450f9 make GetVertexToVertexTable public 2022-03-30 12:45:56 -07:00
Julian Andrej 1637d1180b changelog 2022-03-30 08:27:26 -07:00
Julian Andrej bb17326582 submesh draft 2022-03-29 10:36:57 -07:00
Will Pazner 613c53d75a Use Coefficient::Project instead of Coefficient::Eval 2022-03-25 10:49:39 -07:00
Will Pazner 916af0e415 Add Coefficient::Eval(QuadratureFunction&)
With specializations for ConstantCoefficient and GridFunctionCoefficient.

Also add versions for VectorCoefficient and MatrixCoefficient.
2022-03-25 10:13:41 -07:00
Will Pazner 3ddf77d9d9 Fix virtual function partially overriden warning 2022-03-14 21:52:02 -07:00
Will Pazner 7a5446a74c Add QuadratureFunction::ProjectGridFunction 2022-03-14 21:30:27 -07:00
Will Pazner 339972daa0 Simplify CoefficientVector interface 2022-03-14 20:37:22 -07:00
Will Pazner 3ad5b4e517 Silence unused variable warning with MFEM_CONTRACT_VAR 2022-03-14 19:23:14 -07:00
Will Pazner 15b64f364e Use compressed CoefficientVector storage where supported 2022-03-14 19:12:25 -07:00
Will Pazner 463664a91d Optimize VectorQuadratureFunctionCoefficient in CoefficientVector 2022-03-14 19:12:25 -07:00
Will Pazner 6e6a0c8864 Add symmetric matrix storage to CoefficientVector 2022-03-14 17:31:36 -07:00
Will Pazner 79b7cb7032 Use CoefficientVector in the PA integrators 2022-03-14 17:31:07 -07:00
Will Pazner 4cfb23b3a7 Create CoefficientVector class
This class is for evaluating and storing coefficients (scalars, vectors,
matrices) at quadrature points defined by a QuadratureSpace. It centralizes
some memory savings and other optimizations that were previously performed by
each integrator.
2022-03-14 15:35:47 -07:00
Will Pazner be3a830a1b Project coefficients onto QuadratureFunctions 2022-03-14 15:35:47 -07:00
Will Pazner 2f5f3cdf01 Add DenseSymmetricMatrix::GetStoredSize 2022-03-14 15:35:47 -07:00
Will Pazner 965cb01072 PA unit tests: use fixed random seed 2022-03-14 15:35:47 -07:00
Will Pazner e84e70c3f3 Create a QuadratureSpace with an IntegrationRule 2022-03-14 11:57:47 -07:00
351 changed files with 26661 additions and 6783 deletions
+2 -3
View File
@@ -23,9 +23,8 @@ install:
- set MSMPI_LIB64=C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x64
- set MSMPI_INC=C:\Program Files (x86)\Microsoft SDKs\MPI\Include
# Install METIS, use a mirror because the original source server is not always
# up. Original url:
# http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/metis-5.1.0.tar.gz
# Install METIS, use MFEM's mirror because the original source server is often
# down and we don't support yet the new repo https://github.com/KarypisLab/METIS
- ps: Start-FileDownload 'https://mfem.github.io/tpls/metis-5.1.0.tar.gz'
- 7z x metis-5.1.0.tar.gz -so | 7z x -si -ttar > nul
- cd metis-5.1.0
+2 -2
View File
@@ -1,4 +1,4 @@
name: Build Deploy Container
name: "Docker"
on:
@@ -62,7 +62,7 @@ jobs:
- name: GHCR Login
if: (github.event_name != 'pull_request')
uses: docker/login-action@v1
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
+38 -45
View File
@@ -10,7 +10,7 @@
# CONTRIBUTING.md for details.
# In this CI section, we build different variants of mfem and run test on them.
name: builds-and-tests
name: "Tests"
# Github actions can use the default "GITHUB_TOKEN". By default, this token
# is set to have permissive access. However, this is not a good practice
@@ -47,17 +47,17 @@ jobs:
builds-and-tests:
strategy:
matrix:
os: [ubuntu-20.04, macos-10.15, windows-2022]
os: [ubuntu-latest, macos-latest, windows-latest]
target: [dbg, opt]
mpi: [seq, par]
build-system: [make, cmake]
hypre-target: [int32]
exclude:
- os: ubuntu-20.04
- os: ubuntu-latest
build-system: cmake
- os: macos-10.15
- os: macos-latest
build-system: cmake
- os: windows-2022
- os: windows-latest
build-system: make
# 'include' allows us to:
# - Add a variable to all jobs without creating a new matrix dimension.
@@ -72,15 +72,15 @@ jobs:
codecov: NO
- target: opt
codecov: YES
- os: windows-2022
- os: windows-latest
codecov: NO
- os: ubuntu-20.04
- os: ubuntu-latest
target: opt
codecov: NO
mpi: par
build-system: cmake
hypre-target: int32
- os: ubuntu-20.04
- os: ubuntu-latest
target: opt
codecov: NO
mpi: par
@@ -94,7 +94,7 @@ jobs:
# This external action allows to interrupt a workflow already running on
# the same branch to save resource
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.9.0
uses: styfle/cancel-workflow-action@0.11.0
with:
access_token: ${{ github.token }}
@@ -102,7 +102,7 @@ jobs:
# /home/runner/work/mfem/mfem/mfem
# Note: Done now to access "install-hypre" and "install-metis" actions.
- name: checkout mfem
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: ${{ env.MFEM_TOP_DIR }}
# Fetch the complete history for codecov to access commits ID
@@ -112,49 +112,49 @@ jobs:
# TODO: It would be nice to have only one step, e.g. with a dedicated
# action, but I (@adrienbernede) don't see how at the moment.
- name: get MPI (Linux)
if: matrix.mpi == 'par' && matrix.os == 'ubuntu-20.04'
if: matrix.mpi == 'par' && matrix.os == 'ubuntu-latest'
run: |
sudo apt-get install mpich libmpich-dev
export MAKE_CXX_FLAG="MPICXX=mpic++"
- name: get lcov (Linux)
if: matrix.codecov == 'YES' && matrix.os == 'ubuntu-20.04'
if: matrix.codecov == 'YES' && matrix.os == 'ubuntu-latest'
run: |
sudo apt-get install lcov
- name: Set up Homebrew
if: ( matrix.mpi == 'par' || matrix.codecov == 'YES' ) && matrix.os == 'macos-10.15'
uses: Homebrew/actions/setup-homebrew@c4aafe8c4620bf08883dd4679c374f11e73329d3
# Keep the following section in case we need it again in the future,
# see: https://github.com/mfem/mfem/pull/3385#discussion_r1058013032
# - name: Set up Homebrew
# if: ( matrix.mpi == 'par' || matrix.codecov == 'YES' ) && matrix.os == 'macos-latest'
# uses: Homebrew/actions/setup-homebrew@master
- name: get MPI (MacOS)
if: matrix.mpi == 'par' && matrix.os == 'macos-10.15'
if: matrix.mpi == 'par' && matrix.os == 'macos-latest'
run: |
export HOMEBREW_NO_INSTALL_CLEANUP=1
brew install openmpi
export MAKE_CXX_FLAG="MPICXX=mpic++"
- name: get MPI (MacOS)
if: matrix.codecov == 'YES' && matrix.os == 'macos-10.15'
- name: get lcov (MacOS)
if: matrix.codecov == 'YES' && matrix.os == 'macos-latest'
run: |
export HOMEBREW_NO_INSTALL_CLEANUP=1
brew install lcov
- name: get MPI (Windows)
if: matrix.mpi == 'par' && matrix.os == 'windows-2022'
uses: mpi4py/setup-mpi@v1.0.3
if: matrix.mpi == 'par' && matrix.os == 'windows-latest'
uses: mpi4py/setup-mpi@v1.1.4
# Get Hypre through cache, or build it.
# Install will only run on cache miss.
- name: cache hypre
id: hypre-cache
if: matrix.mpi == 'par'
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ${{ env.HYPRE_TOP_DIR }}
key: ${{ runner.os }}-build-${{ env.HYPRE_TOP_DIR }}-${{ matrix.hypre-target }}-v2.2
- name: get hypre
if: matrix.mpi == 'par' && steps.hypre-cache.outputs.cache-hit != 'true' && matrix.os != 'windows-2022'
if: matrix.mpi == 'par' && steps.hypre-cache.outputs.cache-hit != 'true' && matrix.os != 'windows-latest'
uses: mfem/github-actions/build-hypre@v2.2
with:
archive: ${{ env.HYPRE_ARCHIVE }}
@@ -163,7 +163,7 @@ jobs:
build-system: make
- name: get hypre (Windows)
if: matrix.mpi == 'par' && steps.hypre-cache.outputs.cache-hit != 'true' && matrix.os == 'windows-2022'
if: matrix.mpi == 'par' && steps.hypre-cache.outputs.cache-hit != 'true' && matrix.os == 'windows-latest'
uses: mfem/github-actions/build-hypre@v2.2
with:
archive: ${{ env.HYPRE_ARCHIVE }}
@@ -175,14 +175,14 @@ jobs:
# Install will only run on cache miss.
- name: cache metis
id: metis-cache
if: matrix.mpi == 'par' && matrix.os != 'windows-2022'
uses: actions/cache@v2
if: matrix.mpi == 'par' && matrix.os != 'windows-latest'
uses: actions/cache@v3
with:
path: ${{ env.METIS_TOP_DIR }}
key: ${{ runner.os }}-build-${{ env.METIS_TOP_DIR }}-v2.2
- name: install metis
if: matrix.mpi == 'par' && matrix.os != 'windows-2022' && steps.metis-cache.outputs.cache-hit != 'true'
if: matrix.mpi == 'par' && matrix.os != 'windows-latest' && steps.metis-cache.outputs.cache-hit != 'true'
uses: mfem/github-actions/build-metis@v2.2
with:
archive: ${{ env.METIS_ARCHIVE }}
@@ -190,26 +190,23 @@ jobs:
- name: cache vcpkg (Windows)
id: vcpkg-cache
if: matrix.os == 'windows-latest'
uses: actions/cache@v3
with:
path: vcpkg_cache
key: ${{ runner.os }}-${{ matrix.mpi }}-vcpkg-v1
- name: prepare binary cache location
if: matrix.os == 'windows-2022' && steps.vcpkg-cache.outputs.cache-hit != 'true'
- name: prepare vcpkg binary cache location (Windows)
if: matrix.os == 'windows-latest' && steps.vcpkg-cache.outputs.cache-hit != 'true'
run: |
mkdir -p vcpkg_cache
- name: install metis (Windows)
if: matrix.mpi == 'par' && matrix.os == 'windows-2022'
if: matrix.mpi == 'par' && matrix.os == 'windows-latest'
env:
VCPKG_DEFAULT_BINARY_CACHE: ${{ github.workspace }}/vcpkg_cache
run: |
$PortFile = 'C:\vcpkg\ports\metis\portfile.cmake'
$OriginalURL = 'http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/metis-${METIS_VERSION}.tar.gz'
$NewURL = 'https://github.com/mfem/tpls/raw/gh-pages/metis-5.1.0.tar.gz'
(Get-Content $PortFile).replace($OriginalURL, $NewURL) | Set-Content $PortFile
vcpkg install metis --triplet=x64-windows-static
vcpkg install metis-mfem --triplet=x64-windows-static --overlay-ports=${{ env.MFEM_TOP_DIR }}/config/vcpkg/ports
# MFEM build and test
- name: build
@@ -234,11 +231,7 @@ jobs:
run: |
cd ${{ env.MFEM_TOP_DIR }} && make check
- name: unit tests
if: matrix.build-system == 'make' && matrix.target == 'opt'
run: |
cd ${{ env.MFEM_TOP_DIR }} && make unittest
# Note: 'tests' include the unit tests
- name: tests
if: matrix.build-system == 'make' && matrix.target == 'opt'
run: |
@@ -251,8 +244,8 @@ jobs:
cd ${{ env.MFEM_TOP_DIR }} && cmake --build build --target check --config ${CTEST_CONFIG}
shell: bash
- name: cmake unit tests (Ubuntu 20.04)
if: matrix.build-system == 'cmake' && matrix.target == 'opt' && matrix.os == 'ubuntu-20.04'
- name: cmake unit tests (Ubuntu)
if: matrix.build-system == 'cmake' && matrix.target == 'opt' && matrix.os == 'ubuntu-latest'
run: |
CTEST_CONFIG="Release"
[[ ${{ matrix.target }} == 'dbg' ]] && CTEST_CONFIG="Debug"
@@ -260,7 +253,7 @@ jobs:
shell: bash
- name: cmake tests
if: matrix.build-system == 'cmake' && matrix.target == 'opt' && matrix.os != 'ubuntu-20.04'
if: matrix.build-system == 'cmake' && matrix.target == 'opt' && matrix.os != 'ubuntu-latest'
run: |
CTEST_CONFIG="Release"
cd ${{ env.MFEM_TOP_DIR }}/build && ctest --output-on-failure -C ${CTEST_CONFIG}
@@ -269,7 +262,7 @@ jobs:
# Code coverage (process and upload reports)
- name: codecov
if: matrix.codecov == 'YES'
uses: mfem/github-actions/upload-coverage@v2.0
uses: mfem/github-actions/upload-coverage@v2.2
with:
name: ${{ matrix.os }}-${{ matrix.build-system }}-${{ matrix.target }}-${{ matrix.mpi }}-${{ matrix.hypre-target }}
project_dir: ${{ env.MFEM_TOP_DIR }}
+70
View File
@@ -0,0 +1,70 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "Static Analysis"
on:
push:
branches: [ "master", "next"]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "master" ]
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'cpp' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
+6 -7
View File
@@ -9,7 +9,7 @@
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.
name: build-analysis
name: "Build Analysis"
permissions:
actions: write
@@ -31,27 +31,26 @@ env:
jobs:
gitignore:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.9.0
uses: styfle/cancel-workflow-action@0.11.0
with:
access_token: ${{ github.token }}
- name: checkout MFEM
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: mfem
- name: Get MPI (Linux)
run: |
sudo apt-get install mpich libmpich-dev
export MAKE_CXX_FLAG="MPICXX=mpic++"
- name: Cache Hypre Install
id: hypre-cache
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ${{ env.HYPRE_TOP_DIR }}
key: ${{ runner.os }}-build-${{ env.HYPRE_TOP_DIR }}-v2.2
@@ -66,7 +65,7 @@ jobs:
- name: Cache Metis Install
id: metis-cache
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ${{ env.METIS_TOP_DIR }}
key: ${{ runner.os }}-build-${{ env.METIS_TOP_DIR }}-v2.2
+16 -11
View File
@@ -9,7 +9,7 @@
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.
name: repo-check
name: "Checks"
permissions:
actions: write
@@ -28,18 +28,18 @@ on:
jobs:
file-headers-check:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
if: |
(github.event_name == 'push' ||
github.event.pull_request.head.repo.full_name != github.repository)
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.9.0
uses: styfle/cancel-workflow-action@0.11.0
with:
access_token: ${{ github.token }}
- name: checkout mfem
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: copyright check
id: copyright
@@ -78,35 +78,40 @@ jobs:
exit 1
code-style:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
if: |
(github.event_name == 'push' ||
github.event.pull_request.head.repo.full_name != github.repository)
steps:
- name: checkout mfem
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: get astyle
run: |
sudo apt-get install astyle=3.1-1ubuntu2
sudo apt-get install astyle
- name: style check
run: |
./config/githooks/pre-push --style
documentation:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
if: |
(github.event_name == 'push' ||
github.event.pull_request.head.repo.full_name != github.repository)
steps:
- name: checkout mfem
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: get doxygen and graphviz
run: |
sudo apt-get install doxygen graphviz
- name: update doxygen config file
run: |
cd doc
doxygen -u CodeDocumentation.conf.in
- name: build documentation
run: |
cd tests/scripts
@@ -118,10 +123,10 @@ jobs:
github.ref != 'refs/heads/master' &&
(github.event_name == 'push' ||
github.event.pull_request.head.repo.full_name != github.repository)
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
steps:
- name: checkout mfem
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0
+13
View File
@@ -131,6 +131,12 @@ examples/hiop/ex9-mesh.*
examples/hiop/ex9-init.*
examples/hiop/ex9-final.*
examples/ipopt/exContactBlockTL
examples/ipopt/exContactBlockTL.mesh
examples/ipopt/exContactBlockTL-mesh.*
examples/ipopt/exContactBlockTL-init.*
examples/ipopt/exContactBlockTL-final.*
examples/petsc/ex[1-69]p
examples/petsc/ex1[0-1]p
examples/petsc/mesh.*
@@ -203,6 +209,7 @@ miniapps/meshing/mesh-explorer
miniapps/meshing/shaper
miniapps/meshing/extruder
miniapps/meshing/trimmer
miniapps/meshing/reflector
miniapps/meshing/mesh-optimizer
miniapps/meshing/pmesh-optimizer
miniapps/meshing/minimal-surface
@@ -214,9 +221,12 @@ miniapps/meshing/toroid-*.mesh
miniapps/meshing/twist-*.mesh
miniapps/meshing/mesh-explorer.mesh
miniapps/meshing/partitioning.txt
miniapps/meshing/mesh-explorer-visit*
miniapps/meshing/mesh-explorer-paraview/
miniapps/meshing/shaper.mesh
miniapps/meshing/extruder.mesh
miniapps/meshing/trimmer.mesh
miniapps/meshing/reflected.mesh
miniapps/meshing/optimized*
miniapps/meshing/perturbed*
miniapps/meshing/polar-nc.mesh
@@ -275,6 +285,8 @@ miniapps/tools/load-dc
miniapps/tools/convert-dc
miniapps/tools/lor-transfer
miniapps/tools/get-values
miniapps/tools/check-tmop-metric
miniapps/tools/tmop-metric-magnitude
miniapps/toys/automata
miniapps/toys/life
@@ -307,6 +319,7 @@ miniapps/solvers/sol.*
miniapps/parelag/MultilevelHcurlHdivSolver
miniapps/parelag/*.mesh
miniapps/multidomain/multidomain
miniapps/hooke/hooke
# Unit test binary and outputs
+1 -1
View File
@@ -93,7 +93,7 @@ report_baseline:
git pull && \
git add ${rundir} && \
git commit -m "${msg}" && \
git push origin master
${CI_PROJECT_DIR}/.gitlab/scripts/git_try_to_push
else
for file in ${rundir}/*; do
echo "------------------------------"
+41
View File
@@ -0,0 +1,41 @@
#!/bin/bash
# Copyright (c) 2010-2022, 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.
# Try to push to the remote 5 times. If the push fails, and the local and remote
# have diverged, then pull from the remote to merge changes, and try pushing
# again. If some other failure happens
for i in {1..5}; do
git push origin master && exit 0
# Wait for 20 seconds in case someone else is pushing to the remote
# concurrently
sleep 20
# Fetch any updates from the remote
git remote update
# Get the latest commit on the local branch
LOCAL=$(git rev-parse @)
# Get the latest commit on the remote
REMOTE=$(git rev-parse @{u})
# Get the common ancestor
BASE=$(git merge-base @ @{u})
# Have the local and remote diverged?
if [[ $LOCAL != $REMOTE && $LOCAL != $BASE && $REMOTE != $BASE ]]; then
git pull
if [[ $? == 0 ]]; then
continue
else
exit 1 # Something else went wrong trying to pull
fi
fi
done
exit 1 # Did not succeed in 5 attempts
@@ -32,7 +32,7 @@ if [[ "$AUTOTEST_COMMIT" != "NO" ]]; then
git pull && \
git add ${rundir} && \
git commit -m "${msg}" && \
git push origin master
${CI_PROJECT_DIR}/.gitlab/scripts/git_try_to_push
else
for file in ${rundir}/*; do
echo "------------------------------"
@@ -29,7 +29,7 @@ if [[ "$AUTOTEST_COMMIT" != "NO" ]]; then
git pull && \
git add ${rundir} && \
git commit -m "${msg}" && \
git push origin master
${CI_PROJECT_DIR}/.gitlab/scripts/git_try_to_push
else
for file in ${rundir}/*; do
echo "------------------------------"
+152 -38
View File
@@ -8,31 +8,116 @@
https://mfem.org
Version 4.4.1 (development)
Version 4.5.1 (development)
===========================
- When using discontinuous (L2) spaces, use local (element-wise) L2 projection
as the coarsening operator for non-conforming AMR meshes.
Meshing improvements
--------------------
- Added support for pyramids in non-conforming meshes. Currently only isotropic
refinement is supported in this case.
- Updated logic in FindPointsGSLIB to ignore points found near (but outside) the
domain boundary.
- Added support for pyramids in Gmsh meshes.
- Fixed a bug in TMOP metric 301.
- Added an option to auto-balance compound TMOP metrics.
Discretization improvements
---------------------------
- TBD
Linear and nonlinear solvers
----------------------------
- Added a fast normalization-based distance solver, see the Distance miniapp
in the miniapps/shifted/ directory.
New and updated examples and miniapps
-------------------------------------
- Added a new meshing miniapp, reflector, which reflects a high-order or NURBS
hexahedral mesh about a plane.
- The mesh-explorer miniapp can now save mesh files in the VisIt or ParaView
formats using the corresponding DataCollection objects. See option 'D' in the
main menu.
Integrations, testing and documentation
---------------------------------------
- Removed the support for the Mesquite toolkit. We recommend using MFEM's TMOP
functionality instead for mesh optimization. See the mesh-optimizer miniapp.
- The following integrations have updated minimum version requirements:
* RAJA >= 2022.10.3
Miscellaneous
-------------
- VisItDataCollection now correctly handles collection names containing
underscores.
- VisItDataCollection::SetPadDigits() no longer alters the number of digits
used to represent the MPI rank because VisIt seems to require 6 digits.
This parameter can still be explicitly overridden with
VisItDataCollection::SetPadDigitsRank().
API changes
-----------
- The implicit cast methods of class Vector to 'double *' and 'const double *'
have been deprecated and generate deprecation warnings if used. They will be
removed in a future release.
- The methods Mesh::GetFaceBaseGeometry and Mesh::GetFaceGeometryType have been
deprecated, and Mesh::GetFaceGeometry (which provides identical functionality)
should be used instead.
Version 4.5, released on October 22, 2022
=========================================
Meshing improvements
--------------------
- Added new SubMesh and ParSubMesh classes that can be used to extract a subset
of a given Mesh. These classes have the same functionality as Mesh and ParMesh
and work with all existing MFEM interfaces like finite element spaces etc.
- Added a method, ParMesh::GetSerialMesh(), that reconstructs a partitioned
parallel mesh on a given single rank. Also, added ParMesh::PrintAsSerial(),
which saves the reconstructed serial mesh to a C++ stream on rank 0.
- Added more 3D TMOP metrics, as well as specialized metrics for mesh
untangling and worst-case quality improvement.
- Added a new method, Mesh::NodesUpdated, which should be called after the mesh
node coordinates have changed, e.g. after the mesh has moved. This is
necessary, for example, with device assembly of linear and bilinear forms.
- Added support for mixed meshes and pyramids in GSLIB-FindPoints.
Discretization improvements
---------------------------
- Added support for assembling low-order-refined matrices using a GPU-enabled
"batched" algorithm. The lor_solvers and plor_solvers now fully support GPU
acceleration.
- Added support for partial assembly and fully matrix-free operators on mixed
meshes (different element types and p-adaptivity) through libCEED, including
device acceleration, e.g. with NVIDIA and AMD GPUs. The p-adaptivity is
currently limited by MFEM capabilities, i.e. 2D serial meshes. All mixed
element topologies are supported in serial and parallel: segment, triangle,
square, tetrahedron, cube, prism, and pyramid.
- Added full assembly and device support for several LinearForm integrators:
* DomainLF: (f, v)
* VectorDomainLF: ((f1,...,fn), (v1,...,vn))
* DomainLFGrad: (f, grad(v))
* VectorDomainLFGrad: ((f1x,f1y,f1z,...,fnx,fny,fnz), grad(v1,...,vn))
The device assembly of linear forms has to be explicitly enabled by calling
LinearForm::UseFastAssembly(true), otherwise the legacy linear form assembly
is used by default.
- Added support for assembling low-order-refined matrices using a GPU-enabled
"batched" algorithm. The lor_solvers and plor_solvers now fully support GPU
acceleration with arbitrary user-supplied coefficients.
- Added a new class FaceQuadratureSpace that allows for the construction of
QuadratureFunctions on the interior or boundary faces of a mesh.
- Added a class CoefficientVector for efficient access of variable coefficient
values at quadrature points (in particular for GPU/device kernels).
- Added support for GridFunction::GetGradients() and
GriFunction::GetVectorGradient() on face-neighbor elements.
- Added WhiteGaussianNoiseDomainLFIntegrator: a LinearFormIntegrator class for
spatial Gaussian white noise.
@@ -40,8 +125,25 @@ Discretization improvements
- Added a new Zienkiewicz-Zhu patch recovery-based a posteriori error estimator.
See fem/estimators.hpp.
- Various fixes and improvements in LinearFormExtension.
Linear and nonlinear solvers
----------------------------
- Added a new class DGMassInverse that performs a local element-wise CG
iteration to solve systems involving the discontinuous Galerkin mass matrix,
including support for device/GPU acceleration.
- Added more flexibility to the constrained solver classes:
* PenaltyConstrainedSolver now allows for a vector of penalty parameters
(necessary for penalty contact)
* PenaltyConstrainedSolver and EliminationSolver can use GMRES or PCG
* All constraint solver classes can take a user-defined preconditioner
- Added functions to toggle additional options for the SuperLU_Dist and Hypre
preconditioners (ParaSails, Euclid, ILU).
- Added boundary elimination with device support for `SparseMatrix` and
`HypreParMatrix`.
New and updated examples and miniapps
-------------------------------------
@@ -51,12 +153,28 @@ New and updated examples and miniapps
automatic differentiation tools like a native dual number implementation or a
third party library such as Enzyme. See miniapps/elasticity for more details.
- Added example for body-fitted volumetric and shape integration using the
Algoim library in miniapps/shifted.
- Add a new example code, Example 33/33p, to demonstrate the solution of
spectral fractional PDEs with MFEM.
Integrations, testing and documentation
---------------------------------------
- Added a Dockerfile for a simple MFEM container, see config/docker/README.md.
More sophisticated developer containers are available in the new repo
https://github.com/mfem/containers.
- Added support for the LLVM-based automatic differentiation tool Enzyme, see
https://github.com/EnzymeAD/Enzyme. Build system flags and a convenience
header are provided. The functionality and interaction are demonstrated in a
new miniapp in miniapps/elasticity.
- Added support for partial assembly and fully matrix-free operators on mixed
meshes (different element types and p-adaptivity) through libCEED, including
device acceleration, e.g. with NVIDIA and AMD GPUs. The p-adaptivity is
currently limited to 2D serial meshes. All mixed element topologies are
supported in both serial and parallel.
- Added support for ParMoonolith, https://bitbucket.org/zulianp/par_moonolith,
which provides parallel non-conforming, non-matching, variational, volumetric
@@ -64,29 +182,40 @@ Integrations, testing and documentation
between arbitrarily distributed and unrelated finite element meshes in a
variationally consistent way.
- Added support for the LLVM-based automatic differentiation tool Enzyme, see
https://github.com/EnzymeAD/Enzyme. Build system flags and a convenience
header are provided. The functionality and interaction are demonstrated in a
new miniapp in miniapps/elasticity.
- Fully encapsulated SUNDIALS `N_Vector` object within the `SundialsNVector`
class by removing deprecated (e.g. `HypreParVector::ToNVector`) and
non-deprecated (e.g. `Vector::ToNVector`) functions in other classes.
- Added example for body-fitted volumetric and shape integration using the
Algoim library.
- New benchmark for the different assembly levels inspired by the CEED
Bake-Off Problems, see tests/benchmarks/bench_assembly_levels.cpp.
- Added Windows 2022 CI testing with GitHub actions.
Miscellaneous
-------------
- Various other simplifications, extensions, and bugfixes in the code.
- The method SparseMatrix::EnsureMultTranspose() is now automatically called
by the methods AddMultTranspose(), MultTranspose(), and AbsMultTranspose().
Added a method with the same name to class HypreParMatrix which is also called
automatically by the HypreParMatrix::MultTranspose() methods.
- Updated various MemoryUsage methods to return 'std::size_t' instead of 'long'
since the latter is 32-bit in Win64 builds.
- Added boundary elimination with device support for `SparseMatrix` and
`HypreParMatrix`.
- When using `AssemblyLevel::FULL`, `FABilinearFormExtension::FormSystemMatrix`
outputs an `OperatorHandle` containing a `SparseMatrix` in serial, and an
`HypreParMatrix` in parallel (instead of a `ConstrainedOperator`).
- Added TMOP metrics for mesh untangling and worst-case quality improvement.
- In various places in the library, replace the use of 'long' with 'long long'
to better support Win64 builds where 'long' is 32-bit and 'long long' is
64-bit. On Linux and MacOS, both types are typically 64-bit.
- The behavior of GridFunction::GetTrueVector() has been changed to not return
an empty true vector.
- Added support for ordering search points byVDIM in FindPointsGSLIB.
- Various other simplifications, extensions, and bugfixes in the code.
Version 4.4, released on March 21, 2022
=======================================
@@ -119,11 +248,6 @@ Meshing improvements
- Added a simpler interface to access mesh face information, see FaceInformation
and GetFaceInformation in the Mesh class.
- Added the method ParMesh::GetSerialMesh() that reconstructs a partitioned
parallel mesh on a given single rank. Also, added the method
ParMesh::PrintAsSerial() that saves the reconstructed serial mesh to a C++
stream on rank 0.
- 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.
@@ -213,9 +337,6 @@ Integrations, testing and documentation
- Switched from Artistic Style (astyle) version 2.05.1 to version 3.1 for code
formatting. See the "make style" target.
- New benchmark for the different assembly levels inspired by the CEED
Bake-Off Problems, see tests/benchmarks/bench_assembly_levels.cpp.
Miscellaneous
-------------
- Added a simple singleton class, Mpi, as a replacement for MPI_Session. New
@@ -226,13 +347,6 @@ Miscellaneous
- Fixed several MinGW build issues on Windows.
- In various places in the library, replace the use of 'long' with 'long long'
to better support Win64 builds where 'long' is 32-bit and 'long long' is
64-bit. On Linux and MacOS, both types are typically 64-bit.
- Update various "MemoryUsage" methods to return 'std::size_t' instead of 'long'
since the latter is 32-bit in Win64 builds.
- Added 'double' atomicAdd implementation for previous versions of CUDA.
- HypreParVector and Vector now support C++ move semantics, and the copy
+69 -47
View File
@@ -10,7 +10,9 @@
# CONTRIBUTING.md for details.
# The variable CMAKE_CXX_STANDARD and related were introduced in CMake v3.1
cmake_minimum_required(VERSION 3.1)
# Version 3.8 fixes the handling of CMAKE_CXX_STANDARD for try_compile.
# Version 3.8 or newer is required for direct CUDA support.
cmake_minimum_required(VERSION 3.8)
set(USER_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/config/user.cmake" CACHE PATH
"Path to optional user configuration file.")
@@ -51,7 +53,7 @@ project(mfem NONE)
# Current version of MFEM, see also `makefile`.
# mfem_VERSION = (string)
# MFEM_VERSION = (int) [automatically derived from mfem_VERSION]
set(${PROJECT_NAME}_VERSION 4.4.1)
set(${PROJECT_NAME}_VERSION 4.5.1)
# Prohibit in-source build
if (${PROJECT_SOURCE_DIR} STREQUAL ${PROJECT_BINARY_DIR})
@@ -66,8 +68,7 @@ set(XSDK_ENABLE_C OFF)
set(XSDK_ENABLE_Fortran OFF)
# Check if we need to enable C or Fortran.
if (CMAKE_VERSION VERSION_LESS 3.2 OR
MFEM_USE_CONDUIT OR
if (MFEM_USE_CONDUIT OR
MFEM_USE_SIDRE OR
MFEM_USE_PETSC)
# This seems to be needed by:
@@ -81,7 +82,13 @@ if (MFEM_USE_STRUMPACK)
# Just needed to find the MPI_Fortran libraries to link with
set(XSDK_ENABLE_Fortran ON)
endif()
if (MFEM_USE_GINKGO AND ("${CMAKE_CXX_STANDARD}" LESS "14"))
# SUNDIALS, STRUMPACK, Ginkgo, RAJA and Umpire require C++14:
if ((MFEM_USE_SUNDIALS OR
MFEM_USE_STRUMPACK OR
MFEM_USE_GINKGO OR
MFEM_USE_RAJA OR
MFEM_USE_UMPIRE) AND
("${CMAKE_CXX_STANDARD}" LESS "14"))
set(CMAKE_CXX_STANDARD 14)
endif()
@@ -99,17 +106,12 @@ if (MFEM_USE_CUDA)
if (MFEM_USE_HIP)
message(FATAL_ERROR " *** MFEM_USE_HIP cannot be combined with MFEM_USE_CUDA.")
endif()
# MFEM_USE_CUDA requires CMake 3.8 or newer (for direct CUDA support)
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
# Use ${CMAKE_CXX_COMPILER} as the cuda host compiler.
if (NOT CMAKE_CUDA_HOST_COMPILER)
set(CMAKE_CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER})
endif()
enable_language(CUDA)
set(CMAKE_CUDA_STANDARD 11)
if (MFEM_USE_GINKGO)
set(CMAKE_CUDA_STANDARD 14)
endif()
set(CMAKE_CUDA_STANDARD ${CMAKE_CXX_STANDARD})
set(CMAKE_CUDA_STANDARD_REQUIRED ON)
set(CMAKE_CUDA_EXTENSIONS OFF)
set(CUDA_FLAGS "--expt-extended-lambda")
@@ -132,12 +134,11 @@ if (MFEM_USE_CUDA)
set(CUDA_FLAGS "-ccbin=${CMAKE_CXX_COMPILER} ${CUDA_FLAGS}")
set(CMAKE_CUDA_HOST_LINK_LAUNCHER ${CMAKE_CXX_COMPILER})
endif()
set(CMAKE_CUDA_FLAGS "${CUDA_FLAGS}" CACHE STRING
"CUDA flags set for MFEM" FORCE)
set(CMAKE_CUDA_FLAGS ${CMAKE_CUDA_FLAGS} ${CUDA_FLAGS})
set(CUSPARSE_FOUND TRUE)
set(CUSPARSE_LIBRARIES "cusparse")
set(CUBLAS_FOUND TRUE)
set(CUSBLAS_LIBRARIES "cublas")
set(CUBLAS_LIBRARIES "cublas")
endif()
if (XSDK_ENABLE_C)
@@ -195,15 +196,35 @@ if (MFEM_USE_HIP)
find_package(HIPSPARSE REQUIRED)
endif()
# OpenMP
if (MFEM_USE_OPENMP OR MFEM_USE_LEGACY_OPENMP)
if (NOT MFEM_THREAD_SAFE AND MFEM_USE_LEGACY_OPENMP)
message(FATAL_ERROR " *** MFEM_USE_LEGACY_OPENMP requires MFEM_THREAD_SAFE=ON.")
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.
set(OPENMP_INCLUDE_DIRS ${OpenMP_CXX_INCLUDE_DIRS})
endif(APPLE)
if (OPENMP_FOUND)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
if (MFEM_USE_CUDA)
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler=${OpenMP_CXX_FLAGS}")
endif()
endif()
endif()
# MPI -> hypre; PETSc (optional)
if (MFEM_USE_MPI)
find_package(MPI REQUIRED)
set(MPI_CXX_INCLUDE_DIRS ${MPI_CXX_INCLUDE_PATH})
if (MFEM_MPIEXEC)
set(MPIEXEC ${MFEM_MPIEXEC})
string(REPLACE " " ";" MPIEXEC ${MFEM_MPIEXEC})
endif()
if (MFEM_MPIEXEC_NP)
set(MPIEXEC_NUMPROC_FLAG ${MFEM_MPIEXEC_NP})
string(REPLACE " " ";" MPIEXEC_NUMPROC_FLAG ${MFEM_MPIEXEC_NP})
endif()
# Parallel MFEM depends on hypre
find_package(HYPRE REQUIRED)
@@ -260,20 +281,6 @@ if (MFEM_USE_LAPACK)
find_package(LAPACK REQUIRED)
endif()
# OpenMP
if (MFEM_USE_OPENMP OR MFEM_USE_LEGACY_OPENMP)
if (NOT MFEM_THREAD_SAFE AND MFEM_USE_LEGACY_OPENMP)
message(FATAL_ERROR " *** MFEM_USE_LEGACY_OPENMP requires MFEM_THREAD_SAFE=ON.")
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.
set(OPENMP_INCLUDE_DIRS ${OpenMP_CXX_INCLUDE_DIRS})
endif(APPLE)
endif()
# SuiteSparse (before SUNDIALS which may depend on KLU)
if (MFEM_USE_SUITESPARSE)
find_package(SuiteSparse REQUIRED
@@ -292,11 +299,6 @@ if (MFEM_USE_SUNDIALS)
find_package(SUNDIALS REQUIRED ${SUNDIALS_COMPONENTS})
endif()
# Mesquite
if (MFEM_USE_MESQUITE)
find_package(Mesquite REQUIRED)
endif()
# SuperLU_DIST can only be enabled in parallel
if (MFEM_USE_SUPERLU)
if (MFEM_USE_MPI)
@@ -402,6 +404,15 @@ if (MFEM_USE_HIOP)
# find_package updates HIOP_FOUND, HIOP_INCLUDE_DIRS, HIOP_LIBRARIES
endif()
# IpOpt optimizer
if (MFEM_USE_IPOPT)
find_package(IPOPT REQUIRED)
message(
STATUS
"IPOPT_INCLUDE_DIRS=${IPOPT_INCLUDE_DIRS}, IPOPT_LIBRARIES=${IPOPT_LIBRARIES}, IPOPT_DIR=${IPOPT_DIR}")
# find_package updates IPOPT_FOUND, IPOPT_INCLUDE_DIRS, IPOPT_LIBRARIES
endif()
# CoDiPack package
if (MFEM_USE_CODIPACK)
find_package(CODIPACK REQUIRED)
@@ -477,14 +488,27 @@ if (NOT DEFINED MFEM_TIMER_TYPE)
endif()
endif()
# Without this, CMake 3.21.1 (and 3.20.2) run into CMake Errors like the following:
# CMake Error at config/cmake/modules/MfemCmakeUtilities.cmake:60 (add_library):
# Target "mfem" links to target "Threads::Threads" but the target was not
# found. Perhaps a find_package() call is missing for an IMPORTED target, or
# an ALIAS target is missing?
# Call Stack (most recent call first):
# CMakeLists.txt:474 (mfem_add_library)
#
# NOTE: We need to figure out which TPL library adds the dependency on
# "Threads::Threads" and call the next line only when that TPL library is
# enabled. -V. Dobrev
find_package(Threads REQUIRED)
# List all possible libraries in order of dependencies.
# [METIS < SuiteSparse]:
# 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 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
set(MFEM_TPLS OPENMP HYPRE LAPACK BLAS SuperLUDist STRUMPACK METIS SuiteSparse
SUNDIALS PETSC SLEPC MUMPS AXOM FMS CONDUIT Ginkgo GNUTLS GSLIB
NETCDF MPFR PUMI HIOP IPOPT POSIXCLOCKS MFEMBacktrace ZLIB OCCA CEED RAJA UMPIRE
ADIOS2 CUBLAS CUSPARSE MKL_CPARDISO AMGX CALIPER CODIPACK BENCHMARK PARELAG
MPI_CXX HIP HIPSPARSE MOONOLITH BLITZ ALGOIM ENZYME)
@@ -498,18 +522,12 @@ foreach(TPL IN LISTS MFEM_TPLS)
list(APPEND TPL_INCLUDE_DIRS ${${TPL}_INCLUDE_DIRS})
endif()
endforeach(TPL)
list(REVERSE TPL_LIBRARIES)
list(REMOVE_DUPLICATES TPL_LIBRARIES)
list(REVERSE TPL_LIBRARIES)
list(REMOVE_DUPLICATES TPL_INCLUDE_DIRS)
# message(STATUS "TPL_INCLUDE_DIRS = ${TPL_INCLUDE_DIRS}")
if (OPENMP_FOUND)
message(STATUS "MFEM: using package OpenMP")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
if (MFEM_USE_CUDA)
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler=${OpenMP_CXX_FLAGS}")
endif()
endif()
message(STATUS "MFEM build type: CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}")
message(STATUS "MFEM version: v${MFEM_VERSION_STRING}")
message(STATUS "MFEM git string: ${MFEM_GIT_STRING}")
@@ -688,6 +706,8 @@ add_subdirectory(doc)
message(STATUS "CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}")
set(INSTALL_INCLUDE_DIR include
CACHE PATH "Relative path for installing header files.")
set(INSTALL_BIN_DIR bin
CACHE PATH "Relative path for installing the binaries.")
set(INSTALL_LIB_DIR lib
CACHE PATH "Relative path for installing the library.")
# other options: "share/mfem/cmake", "lib/mfem/cmake"
@@ -706,7 +726,9 @@ set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME Development)
# Install the library
install(TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME_UC}Targets
DESTINATION ${INSTALL_LIB_DIR})
RUNTIME DESTINATION ${INSTALL_BIN_DIR}
LIBRARY DESTINATION ${INSTALL_LIB_DIR}
ARCHIVE DESTINATION ${INSTALL_LIB_DIR})
# Install the master headers
foreach(Header mfem.hpp mfem-performance.hpp)
+9 -2
View File
@@ -102,7 +102,9 @@ The MFEM source code has the following structure:
.
├── config
│ ├── cmake
── githooks
── docker
│ ├── githooks
│ └── vcpkg
├── data
├── doc
├── examples
@@ -110,7 +112,9 @@ The MFEM source code has the following structure:
│ ├── caliper
│ ├── ginkgo
│ ├── hiop
│ ├── ipopt
│ ├── jupyter
│ ├── moonolith
│ ├── petsc
│ ├── pumi
│ ├── sundials
@@ -118,13 +122,15 @@ The MFEM source code has the following structure:
├── fem
│ ├── ceed
│ ├── fe
│ ├── qinterp
│ ├── lor
│ ├── moonolith
│ ├── qinterp
│ └── tmop
├── general
├── linalg
│ └── simd
├── mesh
│ └── submesh
├── miniapps
│ ├── adjoint
│ ├── autodiff
@@ -134,6 +140,7 @@ The MFEM source code has the following structure:
│ ├── hooke
│ ├── meshing
│ ├── mtop
│ ├── multidomain
│ ├── navier
│ ├── nurbs
│ ├── parelag
+29 -22
View File
@@ -7,6 +7,10 @@
https://mfem.org
This file provides a detailed description of how to build and install the MFEM
library. For a simple build, see the step-by-step instructions on the website
at https://mfem.org/building.
The MFEM library has a serial and an MPI-based parallel version, which largely
share the same code base. The only prerequisite for building the serial version
of MFEM is a (modern) C++ compiler, such as g++. The parallel version of MFEM
@@ -16,7 +20,11 @@ requires an MPI C++ compiler, as well as the following external libraries:
https://github.com/hypre-space/hypre
- METIS (a family of multilevel partitioning algorithms)
http://glaros.dtc.umn.edu/gkhome/metis/metis/overview
https://github.com/mfem/tpls
Note: We recommend our mirror of metis-4.0.3/5.1.0 above because the METIS
webpage, http://glaros.dtc.umn.edu/gkhome/metis/metis/overview, is often down
and we don't support yet the new repo https://github.com/KarypisLab/METIS.
The hypre dependency can be downloaded as a tarball from GitHub or from the
project webpage https://www.llnl.gov/casc/hypre. For example, the 2.24.0 release
@@ -329,10 +337,6 @@ MFEM_USE_SUNDIALS = YES/NO
library. When enabled, this option uses the SUNDIALS_* library options,
see below.
MFEM_USE_MESQUITE = YES/NO
Enable MFEM functionality based on the Mesquite library. When enabled, this
option uses the MESQUITE_* library options, see below.
MFEM_USE_SUITESPARSE = YES/NO
Enable MFEM functionality based on the SuiteSparse library. Currently, this
option adds the classes UMFPackSolver and KLUSolver (both sparse serial
@@ -467,15 +471,18 @@ 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_IPOPT = YES/NO
Enable the usage of Ipopt in MFEM.
MFEM_USE_CODIPACK = YES/NO
Enable automatic differentiation using the CoDiPack library.
www.scicomp.uni-kl.de/codi/
MFEM_USE_ALGOIM = YES/NO
Enable the usage of Algoim - a collection of high-order accurate numerical
methods and C++ algorithms for working with implicitly-defined geometry and
level set methods. The Algoim library requires the Blitz++ library. The MFEM
provides interface to Algoim v1. Thus, to check out the specific state use:
Enable the usage of Algoim - a collection of high-order accurate numerical
methods and C++ algorithms for working with implicitly-defined geometry and
level set methods. The Algoim library requires the Blitz++ library. The MFEM
provides interface to Algoim v1. Thus, to check out the specific state use:
git checkout 9c9ca0ef094d8ab0390ed36367a1151b459bbe0a
https://algoim.github.io
@@ -550,7 +557,7 @@ MFEM_USE_FMS = YES/NO
Enables support for the FMS library which consists of the DataCollection
sub-class mfem::FMSDataCollection for I/O in FMS formats, see the header file
fem/fmsdatacollection.hpp. In addition, this option enables in-memory
convetion routines between FMS's FmsDataCollection structure and MFEM's
conversion routines between FMS's FmsDataCollection structure and MFEM's
DataCollection class, see the header file fem/fmsconvert.hpp.
MFEM_USE_PARELAG = YES/NO
@@ -597,7 +604,7 @@ The specific libraries and their options are:
- METIS, used when MFEM_USE_METIS = YES. If using METIS 5, set
MFEM_USE_METIS_5 = YES (default is to use METIS 4).
URL: http://glaros.dtc.umn.edu/gkhome/metis/metis/overview
URL: https://github.com/mfem/tpls (MFEM mirror, see above)
Options: METIS_OPT, METIS_LIB.
Versions: METIS 4.0.3 or 5.1.0.
@@ -628,11 +635,6 @@ The specific libraries and their options are:
Options: SUNDIALS_OPT, SUNDIALS_LIB.
Versions: SUNDIALS >= 5.0.0, SUNDIALS >= 5.4.0 for CUDA support.
- Mesquite (optional), used when MFEM_USE_MESQUITE = YES.
URL: http://trilinos.org/oldsite/packages/mesquite
Options: MESQUITE_OPT, MESQUITE_LIB.
The Mesquite support is deprecated and will be removed in the future.
- SuiteSparse (optional), used when MFEM_USE_SUITESPARSE = YES.
URL: http://faculty.cse.tamu.edu/davis/suitesparse.html
Options: SUITESPARSE_OPT, SUITESPARSE_LIB.
@@ -739,6 +741,11 @@ The specific libraries and their options are:
Options: HIOP_OPT, HIOP_LIB.
Versions: HIOP >= 0.4.6.
- Ipopt (optional), used when MFEM_USE_IPOPT = YES.
URL: https://github.com/coin-or/Ipopt
Options: IPOPT_OPT, IPOPT_LIB.
Versions: IPOPT >= 3.14
- CoDiPack (optional), used with MFEM_USE_CODIPACK = YES
URL: https://www.scicomp.uni-kl.de/codi/
Options: CODIPACK_OPT
@@ -754,12 +761,12 @@ The specific libraries and their options are:
Options: GSLIB_OPT, GSLIB_LIB.
Versions: GSLIB >= 1.0.7.
- ALGOIM (optional), used when MFE_USE_ALGOIM=YES. The library provides only
- ALGOIM (optional), used when MFEM_USE_ALGOIM=YES. The library provides only
headers so it just needs to be downloaded at the same level as MFEM. Download
the specific version we use as:
"git clone https://github.com/algoim/algoim.git;
git checkout 9c9ca0ef094d8ab0390ed36367a1151b459bbe0a"
ALGOIM depends on BLITZ and rhe library must be built prior to the MFEM build.
ALGOIM depends on BLITZ and the library must be built prior to the MFEM build.
Download v1.0.2, untar it at the same level as MFEM and create a symbolic link:
"ln -s blitz-1.0.2 blitz".
Build Blitz using CMake as:
@@ -794,10 +801,10 @@ The specific libraries and their options are:
Versions: libCEED >= 0.10.
- RAJA (optional), used when MFEM_USE_RAJA = YES.
Beginning with MFEM v4.3, only RAJA v0.14.0+ is supported.
Beginning with MFEM v4.5.1, only RAJA v2022.10.3+ is supported.
URL: https://github.com/LLNL/RAJA
Options: RAJA_DIR, RAJA_OPT, RAJA_LIB.
Versions: RAJA >= 0.14.0.
Versions: RAJA >= 2022.10.3.
- Moonolith (optional), use when MFEM_USE_MOONOLITH = YES.
URL: https://bitbucket.org/zulianp/par_moonolith
@@ -961,7 +968,6 @@ MFEM_USE_LEGACY_OPENMP
MFEM_USE_OPENMP
MFEM_USE_MEMALLOC
MFEM_TIMER_TYPE - Set automatically, can be overwritten.
MFEM_USE_MESQUITE
MFEM_USE_SUITESPARSE
MFEM_USE_SUPERLU
MFEM_USE_MUMPS
@@ -974,6 +980,7 @@ MFEM_USE_MPFR
MFEM_USE_ZLIB
MFEM_USE_PUMI
MFEM_USE_HIOP
MFEM_USE_IPOPT
MFEM_USE_CODIPACK
MFEM_USE_ADFORWARD
MFEM_USE_CUDA
@@ -1026,7 +1033,6 @@ The CMake build system adds auto-detection for the following packages/libraries:
- HYPRE
- METIS - The option MFEM_USE_METIS_5 is auto-detected.
- ParMETIS
- MESQUITE
- SuiteSparse
- SuperLUDist, STRUMPACK
- Ginkgo
@@ -1038,6 +1044,7 @@ The CMake build system adds auto-detection for the following packages/libraries:
- POSIXCLOCKS
- PUMI
- HIOP
- IPOPT
- CoDiPack
- OCCA
- RAJA
-4
View File
@@ -212,10 +212,6 @@ IF (DEFINED TPL_ENABLE_SUNDIALS)
SET(MFEM_USE_SUNDIALS ${TPL_ENABLE_SUNDIALS} CACHE BOOL "Enable SUNDIALS usage" FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_MESQUITE)
SET(MFEM_USE_MESQUITE ${TPL_ENABLE_MESQUITE} CACHE BOOL "Enable MESQUITE usage" FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_SUITESPARSE)
SET(MFEM_USE_SUITESPARSE ${TPL_ENABLE_SUITESPARSE} CACHE BOOL "Enable SuiteSparse usage" FORCE)
ENDIF()
+1 -1
View File
@@ -29,7 +29,6 @@ set(MFEM_USE_LEGACY_OPENMP @MFEM_USE_LEGACY_OPENMP@)
set(MFEM_USE_MEMALLOC @MFEM_USE_MEMALLOC@)
set(MFEM_TIMER_TYPE @MFEM_TIMER_TYPE@)
set(MFEM_USE_SUNDIALS @MFEM_USE_SUNDIALS@)
set(MFEM_USE_MESQUITE @MFEM_USE_MESQUITE@)
set(MFEM_USE_SUITESPARSE @MFEM_USE_SUITESPARSE@)
set(MFEM_USE_SUPERLU @MFEM_USE_SUPERLU@)
set(MFEM_USE_MUMPS @MFEM_USE_MUMPS@)
@@ -37,6 +36,7 @@ set(MFEM_USE_STRUMPACK @MFEM_USE_STRUMPACK@)
set(MFEM_USE_GINKGO @MFEM_USE_GINKGO@)
set(MFEM_USE_AMGX @MFEM_USE_AMGX@)
set(MFEM_USE_HIOP @MFEM_USE_HIOP@)
set(MFEM_USE_IPOPT @MFEM_USE_IPOPT@)
set(MFEM_USE_GNUTLS @MFEM_USE_GNUTLS@)
set(MFEM_USE_GSLIB @MFEM_USE_GSLIB@)
set(MFEM_USE_NETCDF @MFEM_USE_NETCDF@)
+3 -3
View File
@@ -77,9 +77,6 @@
// Internal MFEM option: enable group/batch allocation for some small objects.
#cmakedefine MFEM_USE_MEMALLOC
// Enable MFEM functionality based on the Mesquite library.
#cmakedefine MFEM_USE_MESQUITE
// Enable MFEM functionality based on the SuiteSparse library.
#cmakedefine MFEM_USE_SUITESPARSE
@@ -134,6 +131,9 @@
// Enable MFEM functionality based on the HiOp library
#cmakedefine MFEM_USE_HIOP
// Enable MFEM functionality based on the Ipopt library
#cmakedefine MFEM_USE_IPOPT
// Build the GPU/CUDA-enabled version of the MFEM library.
// Requires a CUDA compiler (nvcc).
#cmakedefine MFEM_USE_CUDA
+3 -3
View File
@@ -16,7 +16,7 @@
include(MfemCmakeUtilities)
mfem_find_package(Algoim ALGOIM ALGOIM_DIR
"include" "algoim_quad.hpp"
"include;src" "algoim_quad.hpp"
"" ""
"Paths to headers required by Algoim."
"Libraries required by Algoim.")
"Paths to headers required by Algoim."
"Libraries required by Algoim.")
+19 -4
View File
@@ -16,7 +16,22 @@
include(MfemCmakeUtilities)
mfem_find_package(Caliper CALIPER CALIPER_DIR
"include" "caliper/cali.h"
"lib" "caliper"
"Paths to headers required by Caliper."
"Libraries required by Caliper.")
"include" "caliper/cali.h"
"lib" "caliper"
"Paths to headers required by Caliper."
"Libraries required by Caliper.")
# Append adiak path/lib if the user provided ADIAK_DIR
if(ADIAK_DIR AND EXISTS ${ADIAK_DIR})
find_package(adiak NO_DEFAULT_PATH REQUIRED PATHS ${ADIAK_DIR}/lib/cmake/adiak ${ADIAK_DIR})
list(APPEND CALIPER_INCLUDE_DIRS ${adiak_INCLUDE_DIRS})
list(APPEND CALIPER_LIBRARIES ${adiak_LIBRARIES})
endif()
# Append gotcha path/lib if the user provided GOTCHA_DIR
if(GOTCHA_DIR AND EXISTS ${GOTCHA_DIR})
find_package(gotcha NO_DEFAULT_PATH REQUIRED PATHS ${GOTCHA_DIR}/lib/cmake/gotcha ${GOTCHA_DIR})
list(APPEND CALIPER_INCLUDE_DIRS ${gotcha_INCLUDE_DIRS})
list(APPEND CALIPER_LIBRARIES ${gotcha_LIBRARIES})
endif()
+1 -1
View File
@@ -19,7 +19,7 @@ if(EXISTS "${ENZYME_DIR}/ClangEnzyme-${ENZYME_VERSION}.so")
# Set ENZYME_FOUND
set(ENZYME_FOUND TRUE CACHE BOOL "ENZYME was found." FORCE)
# Set CXX flags to accomodate the Enzyme Clang plugin
# Set CXX flags to accommodate the Enzyme Clang plugin
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Xclang -load -Xclang ${ENZYME_DIR}/ClangEnzyme-${ENZYME_VERSION}.so -mllvm -enzyme-loose-types=1")
set(MFEM_USE_ENZYME YES)
else()
+70
View File
@@ -0,0 +1,70 @@
# Copyright (c) 2010-2022, 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:
# - HDF5_FOUND - If HDF5 was found
# - HDF5_LIBRARIES - The HDF5 libraries
# - HDF5_INCLUDE_DIRS - The HDF5 include directories
# NOTE: Using this FindHDF5.cmake instead of the CMake provided version may lead
# to issues with some TPL libraries that depend (or may depend) on HDF5.
# For this reason, we should consider removing this file, or at least
# making it use the CMake provided version by default and apply the logic
# below only when specifically requested by a user. -V. Dobrev
# First Check for HDF5_DIR
if(NOT HDF5_DIR)
message(FATAL_ERROR
"Could not find HDF5. HDF5 support needs explicit HDF5_DIR")
endif()
if (NOT HDF5_FIND_QUIETLY)
message(STATUS "Looking for HDF5 ...")
message(STATUS " in HDF5_DIR = ${HDF5_DIR}")
endif()
# Find includes
find_path( HDF5_INCLUDE_DIRS hdf5.h
PATHS ${HDF5_DIR}/include/
NO_DEFAULT_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_CMAKE_PATH
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
find_library( __HDF5_LIBRARY NAMES hdf5 libhdf5 libhdf5_D libhdf5_debug
PATHS ${HDF5_DIR}/lib
NO_DEFAULT_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_CMAKE_PATH
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
find_library( __HDF5_HL_LIBRARY NAMES hdf5_hl libhdf5_hl libhdf5_hl_D libhdf5_hl_debug
PATHS ${HDF5_DIR}/lib
NO_DEFAULT_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_CMAKE_PATH
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
set(HDF5_LIBRARIES ${__HDF5_HL_LIBRARY} ${__HDF5_LIBRARY})
include(FindPackageHandleStandardArgs)
# Handle the QUIETLY and REQUIRED arguments and set HDF5_FOUND to TRUE if all
# listed variables are TRUE
find_package_handle_standard_args(HDF5
" *** HDF5 not found. Please set HDF5_DIR."
HDF5_LIBRARIES
HDF5_INCLUDE_DIRS
__HDF5_LIBRARY
__HDF5_HL_LIBRARY)
@@ -9,12 +9,15 @@
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.
# Defines the following variables:
# - MESQUITE_FOUND
# - MESQUITE_LIBRARIES
# - MESQUITE_INCLUDE_DIRS
# Sets the following variables:
# - IPOPT_FOUND
# - IPOPT_INCLUDE_DIRS
# - IPOPT_LIBRARIES
include(MfemCmakeUtilities)
mfem_find_package(Mesquite MESQUITE MESQUITE_DIR
"include" "Mesquite_all_headers.hpp" "lib" "mesquite"
"Paths to headers required by Mesquite." "Libraries required by Mesquite.")
mfem_find_package(IPOPT IPOPT IPOPT_DIR
"include" "IpTNLP.hpp"
"lib" "ipopt"
"Paths to headers required by IPOPT."
"Libraries required by IPOPT.")
+8 -2
View File
@@ -17,18 +17,24 @@
include(MfemCmakeUtilities)
# FindHDF5.cmake uses HDF5_ROOT, so we "translate" from the MFEM convention
set(HDF5_ROOT ${HDF5_DIR} CACHE PATH "")
# (MFEM's FindHDF5.cmake does not need HDF5_ROOT)
# set(HDF5_ROOT ${HDF5_DIR} CACHE PATH "")
# We need to guard against the case where HDF5 was already found but without
# the HL extensions (in which case mfem_find_package will treat the package
# as already having been found), so we reset the variable to force FindHDF5.cmake
# to be called for a second time
set(HDF5_FOUND OFF)
enable_language(C) # FindHDF5.cmake uses the C compiler
mfem_find_package(NetCDF NETCDF NETCDF_DIR "include" netcdf.h "lib" netcdf
"Paths to headers required by NetCDF." "Libraries required by NetCDF.")
# The HL extension libraries are in a separate variable and must precede
# the "regular" hdf5 library, as hdf5_hl depends on hdf5
# The netcdf library will always be the first element of NETCDF_LIBRARIES
# and we need to insert after that library but before the hdf5 library, so
# position 1 is used
list(INSERT NETCDF_LIBRARIES 1 ${HDF5_C_LIBRARY_hdf5_hl})
# (MFEM's FindHDF5.cmake does not set HDF5_C_LIBRARY_hdf5_hl and the HL library
# is already added to NETCDF_LIBRARIES)
# list(INSERT NETCDF_LIBRARIES 1 ${HDF5_C_LIBRARY_hdf5_hl})
+21 -11
View File
@@ -14,17 +14,27 @@
# - RAJA_LIBRARIES
# - RAJA_INCLUDE_DIRS
include(MfemCmakeUtilities)
mfem_find_package(RAJA RAJA RAJA_DIR "include" "RAJA/RAJA.hpp" "lib" "RAJA"
"Paths to headers required by RAJA." "Libraries required by RAJA.")
if (NOT RAJA_CONFIG_CMAKE)
set(RAJA_CONFIG_CMAKE "${RAJA_DIR}/share/raja/cmake/raja-config.cmake")
if (RAJA_FOUND)
return()
endif()
if (EXISTS "${RAJA_CONFIG_CMAKE}")
include("${RAJA_CONFIG_CMAKE}")
if (ENABLE_CUDA AND NOT MFEM_USE_CUDA)
message(FATAL_ERROR
"RAJA is built with CUDA: MFEM_USE_CUDA=YES is required")
message(STATUS "Looking for RAJA ...")
if (RAJA_DIR)
message(STATUS " in RAJA_DIR = ${RAJA_DIR}")
find_package(RAJA CONFIG NO_DEFAULT_PATH PATHS "${RAJA_DIR}")
endif()
if (NOT RAJA_FOUND)
message(STATUS " in standard CMake locations")
find_package(RAJA CONFIG)
endif()
if (RAJA_FOUND)
set(RAJA_LIBRARIES "RAJA" CACHE STRING "RAJA imported target." FORCE)
set(RAJA_INCLUDE_DIRS "" CACHE STRING "RAJA include dirs (not used)" FORCE)
message(STATUS
"Found RAJA target: ${RAJA_LIBRARIES} (version: ${RAJA_VERSION})")
else()
set(msg STATUS)
if (RAJA_FIND_REQUIRED)
set(msg FATAL_ERROR)
endif()
message(${msg} "RAJA not found. Please set RAJA_DIR to the RAJA prefix.")
endif()
+20 -3
View File
@@ -14,6 +14,23 @@
# - UMPIRE_LIBRARIES
# - UMPIRE_INCLUDE_DIRS
include(MfemCmakeUtilities)
mfem_find_package(UMPIRE UMPIRE UMPIRE_DIR "include" "umpire/Umpire.hpp" "lib" "umpire"
"Paths to headers required by UMPIRE." "Libraries required by UMPIRE.")
if (NOT umpire_DIR AND UMPIRE_DIR)
set(umpire_DIR ${UMPIRE_DIR}/lib/cmake/umpire)
endif()
message(STATUS "Looking for UMPIRE ...")
message(STATUS " in UMPIRE_DIR = ${UMPIRE_DIR}")
message(STATUS " umpire_DIR = ${umpire_DIR}")
find_package(umpire CONFIG)
set(UMPIRE_FOUND ${umpire_FOUND})
set(UMPIRE_LIBRARIES "umpire")
if (UMPIRE_FOUND)
message(STATUS
"Found UMPIRE target: ${UMPIRE_LIBRARIES} (version: ${umpire_VERSION})")
else()
set(msg STATUS)
if (UMPIRE_FIND_REQUIRED)
set(msg FATAL_ERROR)
endif()
message(${msg}
"UMPIRE not found. Please set UMPIRE_DIR to the install prefix.")
endif()
+15 -36
View File
@@ -43,22 +43,18 @@ function(convert_filenames_to_full_paths NAMES)
set(${NAMES} ${tmp_names} PARENT_SCOPE)
endfunction()
# Wrapper for add_executable that calls the HIP wrapper if applicable
# Wrapper for add_executable
macro(mfem_add_executable NAME)
if (MFEM_USE_HIP)
add_executable(${NAME} ${ARGN})
else()
add_executable(${NAME} ${ARGN})
add_executable(${NAME} ${ARGN})
if (MFEM_USE_CUDA)
set_target_properties(${NAME} PROPERTIES
CUDA_RESOLVE_DEVICE_SYMBOLS ON)
endif()
endmacro()
# Wrapper for add_library that calls the HIP wrapper if applicable
# Wrapper for add_library
macro(mfem_add_library NAME)
if (MFEM_USE_HIP)
add_library(${NAME} ${ARGN})
else()
add_library(${NAME} ${ARGN})
endif()
add_library(${NAME} ${ARGN})
endmacro()
# Simple shortcut to add_custom_target() with option to add the target to the
@@ -166,27 +162,12 @@ macro(add_mfem_miniapp MFEM_EXE_NAME)
# Append the additional libraries and options
if (LIBRARIES_LIST)
if(CMAKE_VERSION VERSION_GREATER 2.8.11)
target_link_libraries(${MFEM_EXE_NAME} PRIVATE ${LIBRARIES_LIST})
else()
target_link_libraries(${MFEM_EXE_NAME} ${LIBRARIES_LIST})
endif()
target_link_libraries(${MFEM_EXE_NAME} PRIVATE ${LIBRARIES_LIST})
endif()
if (EXTRA_OPTIONS_LIST)
string(REPLACE ";" " " EXTRA_OPTIONS_STRING "${EXTRA_OPTIONS_LIST}")
message(STATUS "${MFEM_EXE_NAME}: add flags \"${EXTRA_OPTIONS_STRING}\"")
if(CMAKE_VERSION VERSION_GREATER 2.8.11)
target_compile_options(${MFEM_EXE_NAME} PRIVATE ${EXTRA_OPTIONS_LIST})
else()
get_target_property(THIS_COMPILE_FLAGS ${MFEM_EXE_NAME} COMPILE_FLAGS)
if (THIS_COMPILE_FLAGS)
set(THIS_COMPILE_FLAGS "${THIS_COMPILE_FLAGS} ${EXTRA_OPTIONS_STRING}")
else()
set(THIS_COMPILE_FLAGS "${EXTRA_OPTIONS_STRING}")
endif()
set_target_properties(${MFEM_EXE_NAME}
PROPERTIES COMPILE_FLAGS ${THIS_COMPILE_FLAGS})
endif()
target_compile_options(${MFEM_EXE_NAME} PRIVATE ${EXTRA_OPTIONS_LIST})
endif()
if (EXTRA_DEFINES_LIST)
target_compile_definitions(${MFEM_EXE_NAME} PRIVATE ${EXTRA_DEFINES_LIST})
@@ -195,17 +176,15 @@ macro(add_mfem_miniapp MFEM_EXE_NAME)
# Handle the MPI separately
if (MFEM_USE_MPI)
# Add MPI_CXX_LIBRARIES, in case this target does not link with mfem.
if(CMAKE_VERSION VERSION_GREATER 2.8.11)
target_link_libraries(${MFEM_EXE_NAME} PRIVATE ${MPI_CXX_LIBRARIES})
else()
target_link_libraries(${MFEM_EXE_NAME} ${MPI_CXX_LIBRARIES})
endif()
target_link_libraries(${MFEM_EXE_NAME} PRIVATE ${MPI_CXX_LIBRARIES})
if (MPI_CXX_INCLUDE_PATH)
target_include_directories(${MFEM_EXE_NAME} PRIVATE ${MPI_CXX_INCLUDE_PATH})
endif()
if (MPI_CXX_COMPILE_FLAGS)
target_compile_options(${MFEM_EXE_NAME} PRIVATE ${MPI_CXX_COMPILE_FLAGS})
separate_arguments(MPI_CXX_COMPILE_ARGS UNIX_COMMAND
"${MPI_CXX_COMPILE_FLAGS}")
target_compile_options(${MFEM_EXE_NAME} PRIVATE ${MPI_CXX_COMPILE_ARGS})
endif()
if (MPI_CXX_LINK_FLAGS)
@@ -886,11 +865,11 @@ function(mfem_export_mk_files)
set(CONFIG_MK_BOOL_VARS MFEM_USE_MPI MFEM_USE_METIS MFEM_USE_METIS_5
MFEM_DEBUG MFEM_USE_EXCEPTIONS MFEM_USE_ZLIB MFEM_USE_LIBUNWIND
MFEM_USE_LAPACK MFEM_THREAD_SAFE MFEM_USE_LEGACY_OPENMP MFEM_USE_OPENMP
MFEM_USE_MEMALLOC MFEM_USE_SUNDIALS MFEM_USE_MESQUITE MFEM_USE_SUITESPARSE
MFEM_USE_MEMALLOC MFEM_USE_SUNDIALS MFEM_USE_SUITESPARSE
MFEM_USE_SUPERLU MFEM_USE_SUPERLU5 MFEM_USE_MUMPS MFEM_USE_STRUMPACK
MFEM_USE_GINKGO MFEM_USE_AMGX MFEM_USE_GNUTLS MFEM_USE_NETCDF
MFEM_USE_PETSC MFEM_USE_SLEPC MFEM_USE_MPFR MFEM_USE_SIDRE MFEM_USE_FMS
MFEM_USE_CONDUIT MFEM_USE_PUMI MFEM_USE_HIOP MFEM_USE_GSLIB MFEM_USE_CUDA
MFEM_USE_CONDUIT MFEM_USE_PUMI MFEM_USE_HIOP MFEM_USE_IPOPT MFEM_USE_GSLIB MFEM_USE_CUDA
MFEM_USE_HIP MFEM_USE_RAJA MFEM_USE_OCCA MFEM_USE_CEED MFEM_USE_CALIPER
MFEM_USE_UMPIRE MFEM_USE_SIMD MFEM_USE_ADIOS2 MFEM_USE_MKL_CPARDISO
MFEM_USE_ADFORWARD MFEM_USE_CODIPACK MFEM_USE_BENCHMARK MFEM_USE_PARELAG
+2
View File
@@ -31,9 +31,11 @@
// Windows specific options
#ifdef _WIN32
#ifndef _USE_MATH_DEFINES
// Macro needed to get defines like M_PI from <cmath>. (Visual Studio C++ only?)
#define _USE_MATH_DEFINES
#endif
#endif
// On Cygwin the option -std=c++11 prevents the definition of M_PI. Defining
// the following macro allows us to get M_PI and some needed functions, e.g.
// posix_memalign(), strdup(), strerror_r().
+3 -3
View File
@@ -85,9 +85,6 @@
// Enable MFEM functionality based on the SUNDIALS libraries.
// #define MFEM_USE_SUNDIALS
// Enable MFEM functionality based on the Mesquite library.
// #define MFEM_USE_MESQUITE
// Enable MFEM functionality based on the SuiteSparse library.
// #define MFEM_USE_SUITESPARSE
@@ -144,6 +141,9 @@
// Enable MFEM functionality based on the HIOP library.
// #define MFEM_USE_HIOP
// Enable MFEM functionality based on the IPOPT library.
// #define MFEM_USE_IPOPT
// Enable MFEM functionality based on the GSLIB library
// #define MFEM_USE_GSLIB
+1 -1
View File
@@ -29,7 +29,6 @@ MFEM_USE_OPENMP = @MFEM_USE_OPENMP@
MFEM_USE_MEMALLOC = @MFEM_USE_MEMALLOC@
MFEM_TIMER_TYPE = @MFEM_TIMER_TYPE@
MFEM_USE_SUNDIALS = @MFEM_USE_SUNDIALS@
MFEM_USE_MESQUITE = @MFEM_USE_MESQUITE@
MFEM_USE_SUITESPARSE = @MFEM_USE_SUITESPARSE@
MFEM_USE_SUPERLU = @MFEM_USE_SUPERLU@
MFEM_USE_SUPERLU5 = @MFEM_USE_SUPERLU5@
@@ -47,6 +46,7 @@ MFEM_USE_FMS = @MFEM_USE_FMS@
MFEM_USE_CONDUIT = @MFEM_USE_CONDUIT@
MFEM_USE_PUMI = @MFEM_USE_PUMI@
MFEM_USE_HIOP = @MFEM_USE_HIOP@
MFEM_USE_IPOPT = @MFEM_USE_IPOPT@
MFEM_USE_GSLIB = @MFEM_USE_GSLIB@
MFEM_USE_CUDA = @MFEM_USE_CUDA@
MFEM_USE_HIP = @MFEM_USE_HIP@
+7 -10
View File
@@ -30,7 +30,6 @@ option(MFEM_USE_OPENMP "Enable the OpenMP backend" OFF)
option(MFEM_USE_LEGACY_OPENMP "Enable legacy OpenMP usage" OFF)
option(MFEM_USE_MEMALLOC "Enable the internal MEMALLOC option." ON)
option(MFEM_USE_SUNDIALS "Enable SUNDIALS usage" OFF)
option(MFEM_USE_MESQUITE "Enable MESQUITE usage" OFF)
option(MFEM_USE_SUITESPARSE "Enable SuiteSparse usage" OFF)
option(MFEM_USE_SUPERLU "Enable SuperLU_DIST usage" OFF)
option(MFEM_USE_SUPERLU5 "Use the old SuperLU_DIST 5.1 version" OFF)
@@ -49,6 +48,7 @@ option(MFEM_USE_FMS "Enable FMS usage" OFF)
option(MFEM_USE_CONDUIT "Enable Conduit usage" OFF)
option(MFEM_USE_PUMI "Enable PUMI" OFF)
option(MFEM_USE_HIOP "Enable HiOp" OFF)
option(MFEM_USE_IPOPT "Enable Ipopt" OFF)
option(MFEM_USE_CUDA "Enable CUDA" OFF)
option(MFEM_USE_HIP "Enable HIP" OFF)
option(MFEM_USE_OCCA "Enable OCCA" OFF)
@@ -124,9 +124,6 @@ set(SUNDIALS_DIR "${MFEM_DIR}/../sundials-5.0.0/instdir" CACHE PATH
# set(SUNDIALS_REQUIRED_PACKAGES "SuiteSparse/KLU/AMD/BTF/COLAMD/config"
# CACHE STRING "Additional packages required by SUNDIALS.")
set(MESQUITE_DIR "${MFEM_DIR}/../mesquite-2.99" CACHE PATH
"Path to the Mesquite library.")
set(SuiteSparse_DIR "${MFEM_DIR}/../SuiteSparse" CACHE PATH
"Path to the SuiteSparse library.")
set(SuiteSparse_REQUIRED_PACKAGES "BLAS" "METIS"
@@ -188,6 +185,7 @@ set(GNUTLS_DIR "" CACHE PATH "Path to the GnuTLS library.")
set(GSLIB_DIR "" CACHE PATH "Path to the GSLIB library.")
set(HDF5_DIR "/usr" CACHE PATH "Path to the HDF5 library.")
set(NETCDF_DIR "" CACHE PATH "Path to the NetCDF library.")
set(NetCDF_REQUIRED_PACKAGES "HDF5/C/HL" CACHE STRING
"Additional packages required by NetCDF.")
@@ -223,6 +221,10 @@ set(HIOP_DIR "${MFEM_DIR}/../hiop/install" CACHE STRING
"Directory where HiOp is installed")
set(HIOP_REQUIRED_PACKAGES "BLAS" "LAPACK" CACHE STRING
"Packages that HiOp depends on.")
set(IPOPT_DIR "${MFEM_DIR}/../ipopt/install" CACHE STRING
"Directory where IpOpt is installed")
set(IPOPT_REQUIRED_PACKAGES "BLAS" "LAPACK" CACHE STRING
"Packages that IpOpt depends on.")
set(MKL_CPARDISO_DIR "" CACHE STRING "MKL installation path.")
set(MKL_MPI_WRAPPER_LIB "mkl_blacs_mpich_lp64" CACHE STRING "MKL MPI wrapper library")
@@ -230,17 +232,12 @@ set(MKL_LIBRARY_DIR "" CACHE STRING "Custom library subdirectory")
set(OCCA_DIR "${MFEM_DIR}/../occa" CACHE PATH "Path to OCCA")
set(RAJA_DIR "${MFEM_DIR}/../raja" CACHE PATH "Path to RAJA")
# If RAJA is built with external CAMP:
# set(RAJA_REQUIRED_PACKAGES "camp"
# CACHE STRING "Packages that RAJA depends on.")
# set(camp_DIR "${MFEM_DIR}/../camp/lib/cmake/camp"
# CACHE PATH "Path to CAMP CMake files.")
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(BLITZ_DIR "${MFEM_DIR}/../blitz" CACHE PATH "Path to Blitz")
set(ALGOIM_DIR "${MFEM_DIR}/../algoim" CACHE PATH "Path to Algoim")
set(ALGOIM_REQUIRED_PACKAGES "BLITZ" CACHE STRING
set(Algoim_REQUIRED_PACKAGES "Blitz" CACHE STRING
"Packages that ALGOIM depends on.")
set(BENCHMARK_DIR "${MFEM_DIR}/../google-benchmark" CACHE PATH
+42 -16
View File
@@ -131,7 +131,6 @@ MFEM_USE_LEGACY_OPENMP = NO
MFEM_USE_MEMALLOC = YES
MFEM_TIMER_TYPE = $(if $(NOTMAC),2,4)
MFEM_USE_SUNDIALS = NO
MFEM_USE_MESQUITE = NO
MFEM_USE_SUITESPARSE = NO
MFEM_USE_SUPERLU = NO
MFEM_USE_SUPERLU5 = NO
@@ -149,6 +148,7 @@ MFEM_USE_FMS = NO
MFEM_USE_CONDUIT = NO
MFEM_USE_PUMI = NO
MFEM_USE_HIOP = NO
MFEM_USE_IPOPT = NO
MFEM_USE_GSLIB = NO
MFEM_USE_CUDA = NO
MFEM_USE_HIP = NO
@@ -179,7 +179,7 @@ ifeq ($(MFEM_USE_MPI)$(MFEM_USE_HIP),YESYES)
endif
# ROCM/HIP directory such that ROCM/HIP libraries like rocsparse and rocrand are
# found in $(HIP_DIR)/lib, usually as links. Typically, this directoory is of
# found in $(HIP_DIR)/lib, usually as links. Typically, this directory is of
# the form /opt/rocm-X.Y.Z which is called ROCM_PATH by hipconfig.
ifeq ($(MFEM_USE_HIP),YES)
HIP_DIR := $(patsubst %/,%,$(dir $(shell which $(HIP_CXX))))
@@ -251,12 +251,16 @@ POSIX_CLOCKS_LIB = -lrt
# SUNDIALS library configuration
# For sundials_nvecmpiplusx and nvecparallel remember to build with MPI_ENABLE=ON
# and modify cmake variables for hypre for sundials
SUNDIALS_DIR = @MFEM_DIR@/../sundials-5.0.0/instdir
SUNDIALS_OPT = -I$(SUNDIALS_DIR)/include
SUNDIALS_LIBDIR = $(wildcard $(SUNDIALS_DIR)/lib*)
SUNDIALS_LIB = $(XLINKER)-rpath,$(SUNDIALS_LIBDIR) -L$(SUNDIALS_LIBDIR)\
SUNDIALS_DIR = @MFEM_DIR@/../sundials-5.0.0/instdir
# SUNDIALS >= 6.4.0 requires C++14:
ifeq ($(MFEM_USE_SUNDIALS),YES)
BASE_FLAGS = -std=c++14
endif
SUNDIALS_OPT = -I$(SUNDIALS_DIR)/include
SUNDIALS_LIB = $(XLINKER)-rpath,$(SUNDIALS_DIR)/lib64\
$(XLINKER)-rpath,$(SUNDIALS_DIR)/lib\
-L$(SUNDIALS_DIR)/lib64 -L$(SUNDIALS_DIR)/lib\
-lsundials_arkode -lsundials_cvodes -lsundials_nvecserial -lsundials_kinsol
ifeq ($(MFEM_USE_MPI),YES)
SUNDIALS_LIB += -lsundials_nvecparallel -lsundials_nvecmpiplusx
endif
@@ -266,11 +270,6 @@ endif
# If SUNDIALS was built with KLU:
# MFEM_USE_SUITESPARSE = YES
# MESQUITE library configuration
MESQUITE_DIR = @MFEM_DIR@/../mesquite-2.99
MESQUITE_OPT = -I$(MESQUITE_DIR)/include
MESQUITE_LIB = -L$(MESQUITE_DIR)/lib -lmesquite
# SuiteSparse library configuration
LIB_RT = $(if $(NOTMAC),-lrt,)
SUITESPARSE_DIR = @MFEM_DIR@/../SuiteSparse
@@ -309,7 +308,7 @@ SCALAPACK_LIB = -L$(SCALAPACK_DIR)/lib -lscalapack $(LAPACK_LIB)
MPI_FORTRAN_LIB = -lmpifort
# OpenMPI:
# MPI_FORTRAN_LIB = -lmpi_mpifh
# Additional Fortan library:
# Additional Fortran library:
# MPI_FORTRAN_LIB += -lgfortran
# MUMPS library configuration
@@ -320,6 +319,9 @@ MUMPS_LIB = $(XLINKER)-rpath,$(MUMPS_DIR)/lib -L$(MUMPS_DIR)/lib -ldmumps\
# STRUMPACK library configuration
STRUMPACK_DIR = @MFEM_DIR@/../STRUMPACK-build
ifeq ($(MFEM_USE_STRUMPACK),YES)
BASE_FLAGS = -std=c++14
endif
STRUMPACK_OPT = -I$(STRUMPACK_DIR)/include $(SCOTCH_OPT)
# If STRUMPACK was build with OpenMP support, the following may be need:
# STRUMPACK_OPT += $(OPENMP_OPT)
@@ -446,6 +448,11 @@ HIOP_DIR = @MFEM_DIR@/../hiop/install
HIOP_OPT = -I$(HIOP_DIR)/include
HIOP_LIB = -L$(HIOP_DIR)/lib -lhiop $(LAPACK_LIB)
# IPOPT
IPOPT_DIR = @MFEM_DIR@/../ipopt/install
IPOPT_OPT = -I$(IPOPT_DIR)/include
IPOPT_LIB = -L$(IPOPT_DIR)/lib -lipopt $(LAPACK_LIB)
# CoDiPack
CODIPACK_DIR = @MFEM_DIR@/../CoDiPack
CODIPACK_OPT = -I$(CODIPACK_DIR)
@@ -472,7 +479,17 @@ OCCA_LIB = $(XLINKER)-rpath,$(OCCA_DIR)/lib -L$(OCCA_DIR)/lib -locca
# CALIPER library configuration
CALIPER_DIR = @MFEM_DIR@/../caliper
CALIPER_OPT = -I$(CALIPER_DIR)/include
CALIPER_LIB = $(XLINKER)-rpath,$(CALIPER_DIR)/lib64 -L$(CALIPER_DIR)/lib64 -lcaliper
CALIPER_LIB = $(XLINKER)-rpath,$(CALIPER_DIR)/lib64 $(XLINKER)-rpath,$(CALIPER_DIR)/lib -L$(CALIPER_DIR)/lib64 -L$(CALIPER_DIR)/lib -lcaliper
ifdef ADIAK_DIR
CALIPER_OPT += -I$(ADIAK_DIR)/include
CALIPER_LIB += $(XLINKER)-rpath,$(ADIAK_DIR)/lib64 $(XLINKER)-rpath,$(ADIAK_DIR)/lib -L$(ADIAK_DIR)/lib64 -L$(ADIAK_DIR)/lib -ladiak
endif
ifdef GOTCHA_DIR
CALIPER_OPT += -I$(GOTCHA_DIR)/include
CALIPER_LIB += $(XLINKER)-rpath,$(GOTCHA_DIR)/lib64 $(XLINKER)-rpath,$(GOTCHA_DIR)/lib -L$(GOTCHA_DIR)/lib64 -L$(GOTCHA_DIR)/lib -lgotcha
endif
# BLITZ library configuration
BLITZ_DIR = @MFEM_DIR@/../blitz
@@ -495,20 +512,29 @@ CEED_OPT = -I$(CEED_DIR)/include
CEED_LIB = $(XLINKER)-rpath,$(CEED_DIR)/lib -L$(CEED_DIR)/lib -lceed
# RAJA library configuration
ifeq ($(MFEM_USE_RAJA),YES)
BASE_FLAGS = -std=c++14
endif
RAJA_DIR = @MFEM_DIR@/../raja
RAJA_OPT = -I$(RAJA_DIR)/include
ifdef CUB_DIR
RAJA_OPT += -I$(CUB_DIR)
endif
CAMP_LIB = -lcamp
ifdef CAMP_DIR
RAJA_OPT += -I$(CAMP_DIR)/include
CAMP_LIB = $(XLINKER)-rpath,$(CAMP_DIR)/lib -L$(CAMP_DIR)/lib -lcamp
endif
RAJA_LIB = $(XLINKER)-rpath,$(RAJA_DIR)/lib -L$(RAJA_DIR)/lib -lRAJA
RAJA_LIB = $(XLINKER)-rpath,$(RAJA_DIR)/lib -L$(RAJA_DIR)/lib -lRAJA $(CAMP_LIB)
# UMPIRE library configuration
ifeq ($(MFEM_USE_UMPIRE),YES)
BASE_FLAGS = -std=c++14
endif
UMPIRE_DIR = @MFEM_DIR@/../umpire
UMPIRE_OPT = -I$(UMPIRE_DIR)/include $(if $(CAMP_DIR), -I$(CAMP_DIR)/include)
UMPIRE_LIB = -L$(UMPIRE_DIR)/lib -lumpire
UMPIRE_LIB = -L$(UMPIRE_DIR)/lib -lumpire $(CAMP_LIB)
# MKL CPardiso library configuration
MKL_CPARDISO_DIR ?=
+10 -3
View File
@@ -58,6 +58,10 @@ groups_serial=(
"HiOp examples:"
"examples/hiop"
"ex9.cpp"'
'"ipopt"
"IpOpt examples:"
"examples/ipopt"
"ex10.cpp"'
'"pumi"
"PUMI examples:"
"examples/pumi"
@@ -215,6 +219,10 @@ groups_all=(
"HiOp examples:"
"examples/hiop"
"ex9.cpp ex9p.cpp"'
'"ipopt"
"IpOpt examples:"
"examples/ipopt"
"ex10.cpp"'
'"pumi"
"PUMI examples:"
"examples/pumi"
@@ -554,15 +562,14 @@ function go()
local cmd_line="${1##+( )}"
cmd_line="${cmd_line%%+( )}"
shopt -u extglob
eval local cmd=(${cmd_line})
local res=""
echo $sep
echo "<${group}>" "${cmd_line}"
echo $sep
if [ "${timing}" == "yes" ]; then
timed_run "${cmd[@]}"
timed_run eval "${cmd_line}"
else
"${cmd[@]}"
eval "${cmd_line}"
fi
if [ "$?" -eq 0 ]; then
res="${green} OK ${none}"
@@ -0,0 +1,8 @@
--- a/CMakeLists.txt Wed Dec 21 18:24:22 2016
+++ b/CMakeLists.txt Wed Dec 21 18:24:26 2016
@@ -20,4 +20,4 @@
# Recursively look for CMakeLists.txt in subdirs.
add_subdirectory("include")
add_subdirectory("libmetis")
-add_subdirectory("programs")
+# add_subdirectory("programs")
@@ -0,0 +1,15 @@
--- a/CMakeLists.txt Sat Mar 30 17:24:45 2013
+++ b/CMakeLists.txt Wed Dec 21 18:23:43 2016
@@ -4,11 +4,7 @@
set(GKLIB_PATH "GKlib" CACHE PATH "path to GKlib")
set(SHARED FALSE CACHE BOOL "build a shared library")
-if(MSVC)
- set(METIS_INSTALL FALSE)
-else()
- set(METIS_INSTALL TRUE)
-endif()
+set(METIS_INSTALL TRUE)
# Configure libmetis library.
if(SHARED)
@@ -0,0 +1,34 @@
diff --git a/include/metis.h b/include/metis.h
index dc5406a..7732437 100644
--- a/include/metis.h
+++ b/include/metis.h
@@ -72,10 +72,14 @@ typedef __int64 int64_t;
#define PRId64 "I64d"
#define SCNd32 "ld"
#define SCNd64 "I64d"
+#ifdef _WIN32
+#include <stdint.h>
+#else
#define INT32_MIN ((int32_t)_I32_MIN)
#define INT32_MAX _I32_MAX
#define INT64_MIN ((int64_t)_I64_MIN)
#define INT64_MAX _I64_MAX
+#endif
#else
#include <inttypes.h>
#endif
diff --git a/GKlib/gk_arch.h b/GKlib/gk_arch.h
index 78b1431..7258763 100644
--- a/GKlib/gk_arch.h
+++ b/GKlib/gk_arch.h
@@ -32,8 +32,8 @@
#ifdef __MSC__
- #include "ms_stdint.h"
- #include "ms_inttypes.h"
+ #include <stdint.h>
+ #include <inttypes.h>
#include "ms_stat.h"
#else
#ifndef SUNOS
@@ -0,0 +1,11 @@
--- a/GKlib/gk_arch.h Wed Dec 21 18:34:18 2016
+++ b/GKlib/gk_arch.h Wed Dec 21 18:30:49 2016
@@ -58,7 +58,7 @@
#define PTRDIFF_MAX INT64_MAX
#endif
-#ifdef __MSC__
+#if defined(__MSC__) && (_MSC_VER < 1900)
/* MSC does not have rint() function */
#define rint(x) ((int)((x)+0.5))
@@ -0,0 +1,14 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e94f050..b9613a7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,8 @@
cmake_minimum_required(VERSION 2.8)
project(METIS)
-set(GKLIB_PATH "GKlib" CACHE PATH "path to GKlib")
+set(GKLIB_PATH "${CMAKE_SOURCE_DIR}/GKlib" CACHE PATH "path to GKlib")
+
set(SHARED FALSE CACHE BOOL "build a shared library")
set(METIS_INSTALL TRUE)
@@ -0,0 +1,11 @@
--- a/libmetis/metislib.h Sat Mar 30 17:24:45 2013
+++ b/libmetis/metislib.h Wed Dec 21 18:30:59 2016
@@ -31,7 +31,7 @@
#include <proto.h>
-#if defined(COMPILER_MSC)
+#if defined(COMPILER_MSC) && (_MSC_VER < 1900)
#if defined(rint)
#undef rint
#endif
@@ -0,0 +1,10 @@
--- a/libmetis/CMakeLists.txt Sat Mar 30 17:24:45 2013
+++ b/libmetis/CMakeLists.txt Wed Dec 21 17:41:37 2016
@@ -11,6 +11,6 @@
if(METIS_INSTALL)
install(TARGETS metis
LIBRARY DESTINATION lib
- RUNTIME DESTINATION lib
+ RUNTIME DESTINATION bin
ARCHIVE DESTINATION lib)
endif()
@@ -0,0 +1,44 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b9613a7..e43ffee 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -22,3 +22,23 @@ include_directories(include)
add_subdirectory("include")
add_subdirectory("libmetis")
# add_subdirectory("programs")
+
+if(METIS_INSTALL)
+ set(PRJ_NAME metis)
+ set(PRJ_VER 5.1.0)
+ install(EXPORT metisTargets
+ FILE ${PRJ_NAME}Targets.cmake
+ DESTINATION lib/cmake/${PRJ_NAME})
+ include(CMakePackageConfigHelpers)
+ write_basic_package_version_file(
+ ${CMAKE_CURRENT_BINARY_DIR}/${PRJ_NAME}ConfigVersion.cmake
+ VERSION ${PRJ_VER}
+ COMPATIBILITY SameMajorVersion)
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${PRJ_NAME}Config.cmake
+ "include(\${CMAKE_CURRENT_LIST_DIR}/${PRJ_NAME}Targets.cmake)")
+ install(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/${PRJ_NAME}ConfigVersion.cmake
+ ${CMAKE_CURRENT_BINARY_DIR}/${PRJ_NAME}Config.cmake
+ DESTINATION lib/cmake/${PRJ_NAME})
+endif()
+
diff --git a/libmetis/CMakeLists.txt b/libmetis/CMakeLists.txt
index 7a5fc74..5a68cf0 100644
--- a/libmetis/CMakeLists.txt
+++ b/libmetis/CMakeLists.txt
@@ -9,8 +9,9 @@ if(UNIX)
endif()
if(METIS_INSTALL)
- install(TARGETS metis
+ install(TARGETS metis EXPORT metisTargets
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
- ARCHIVE DESTINATION lib)
+ ARCHIVE DESTINATION lib
+ INCLUDES DESTINATION include)
endif()
@@ -0,0 +1,41 @@
vcpkg_check_linkage(ONLY_STATIC_LIBRARY)
set(OPTIONS -DSHARED=OFF)
set(METIS_VERSION 5.1.0)
vcpkg_download_distfile(ARCHIVE
URLS "https://github.com/mfem/tpls/raw/gh-pages/metis-${METIS_VERSION}.tar.gz"
FILENAME "metis-${METIS_VERSION}.tar.gz"
SHA512 deea47749d13bd06fbeaf98a53c6c0b61603ddc17a43dae81d72c8015576f6495fd83c11b0ef68d024879ed5415c14ebdbd87ce49c181bdac680573bea8bdb25
)
vcpkg_extract_source_archive_ex(
OUT_SOURCE_PATH SOURCE_PATH
ARCHIVE ${ARCHIVE}
REF ${METIS_VERSION}
PATCHES
enable-install.patch
disable-programs.patch
fix-runtime-install-destination.patch
fix-metis-vs14-math.patch
fix-gklib-vs14-math.patch
fix-linux-build-error.patch
install-metisConfig.patch
fix-INT_MIN_define.patch
)
vcpkg_configure_cmake(
SOURCE_PATH ${SOURCE_PATH}
PREFER_NINJA
OPTIONS ${OPTIONS}
)
vcpkg_install_cmake()
vcpkg_copy_pdbs()
vcpkg_fixup_cmake_targets(CONFIG_PATH lib/cmake/metis)
file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include)
# Handle copyright
file(COPY ${SOURCE_PATH}/LICENSE.txt DESTINATION ${CURRENT_PACKAGES_DIR}/share/metis)
file(INSTALL ${SOURCE_PATH}/LICENSE.txt DESTINATION ${CURRENT_PACKAGES_DIR}/share/${PORT} RENAME copyright)
+7
View File
@@ -0,0 +1,7 @@
{
"name": "metis-mfem",
"version-string": "5.1.0",
"port-version": 0,
"description": "Serial Graph Partitioning and Fill-reducing Matrix Ordering",
"homepage": "http://glaros.dtc.umn.edu/gkhome/metis/metis/overview"
}
+1 -1
View File
@@ -1,7 +1,7 @@
MFEM mesh v1.0
#
# MFEM Geomety Types (see mesh/geom.hpp):
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
+27 -8
View File
@@ -38,7 +38,7 @@ PROJECT_NAME = "MFEM"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = v4.4.1
PROJECT_NUMBER = v4.5.1
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -763,36 +763,55 @@ INPUT = @MFEM_SOURCE_DIR@/doc/CodeDocumentation.dox \
@MFEM_SOURCE_DIR@/config \
@MFEM_SOURCE_DIR@/general \
@MFEM_SOURCE_DIR@/linalg \
@MFEM_SOURCE_DIR@/linalg/simd \
@MFEM_SOURCE_DIR@/mesh \
@MFEM_SOURCE_DIR@/mesh/submesh \
@MFEM_SOURCE_DIR@/fem \
@MFEM_SOURCE_DIR@/fem/moonolith \
@MFEM_SOURCE_DIR@/fem/ceed \
@MFEM_SOURCE_DIR@/fem/ceed/integrators \
@MFEM_SOURCE_DIR@/fem/ceed/integrators/convection \
@MFEM_SOURCE_DIR@/fem/ceed/integrators/diffusion \
@MFEM_SOURCE_DIR@/fem/ceed/integrators/mass \
@MFEM_SOURCE_DIR@/fem/ceed/integrators/nlconvection \
@MFEM_SOURCE_DIR@/fem/ceed/interface \
@MFEM_SOURCE_DIR@/fem/ceed/solvers \
@MFEM_SOURCE_DIR@/fem/fe \
@MFEM_SOURCE_DIR@/fem/lor \
@MFEM_SOURCE_DIR@/fem/moonolith \
@MFEM_SOURCE_DIR@/fem/qinterp \
@MFEM_SOURCE_DIR@/fem/tmop \
@MFEM_SOURCE_DIR@/examples \
@MFEM_SOURCE_DIR@/examples/caliper \
@MFEM_SOURCE_DIR@/examples/amgx \
@MFEM_SOURCE_DIR@/examples/caliper \
@MFEM_SOURCE_DIR@/examples/ginkgo \
@MFEM_SOURCE_DIR@/examples/moonolith \
@MFEM_SOURCE_DIR@/examples/hiop \
@MFEM_SOURCE_DIR@/examples/ipopt \
@MFEM_SOURCE_DIR@/examples/moonolith \
@MFEM_SOURCE_DIR@/examples/petsc \
@MFEM_SOURCE_DIR@/examples/pumi \
@MFEM_SOURCE_DIR@/examples/sundials \
@MFEM_SOURCE_DIR@/examples/superlu \
@MFEM_SOURCE_DIR@/miniapps/adjoint \
@MFEM_SOURCE_DIR@/miniapps/autodiff \
@MFEM_SOURCE_DIR@/miniapps/common \
@MFEM_SOURCE_DIR@/miniapps/electromagnetics \
@MFEM_SOURCE_DIR@/miniapps/gslib \
@MFEM_SOURCE_DIR@/miniapps/hooke \
@MFEM_SOURCE_DIR@/miniapps/hooke/kernels \
@MFEM_SOURCE_DIR@/miniapps/hooke/materials \
@MFEM_SOURCE_DIR@/miniapps/hooke/operators \
@MFEM_SOURCE_DIR@/miniapps/hooke/preconditioners \
@MFEM_SOURCE_DIR@/miniapps/meshing \
@MFEM_SOURCE_DIR@/miniapps/mtop \
@MFEM_SOURCE_DIR@/miniapps/autodiff \
@MFEM_SOURCE_DIR@/miniapps/multidomain \
@MFEM_SOURCE_DIR@/miniapps/navier \
@MFEM_SOURCE_DIR@/miniapps/nurbs \
@MFEM_SOURCE_DIR@/miniapps/parelag \
@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/parelag
@MFEM_SOURCE_DIR@/miniapps/toys
# 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
@@ -2349,7 +2368,7 @@ PLANTUML_INCLUDE_PATH =
# Minimum value: 0, maximum value: 10000, default value: 50.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_GRAPH_MAX_NODES = 50
DOT_GRAPH_MAX_NODES = 100
# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
# generated by dot. A depth value of 3 means that only nodes reachable from the
+5
View File
@@ -178,6 +178,11 @@ if (MFEM_USE_HIOP)
add_subdirectory(hiop)
endif()
# Include the examples/ipopt directory if IpOpt is enabled
if (MFEM_USE_IPOPT)
add_subdirectory(ipopt)
endif()
# Include the examples/petsc directory if PETSc is enabled.
if (MFEM_USE_PETSC)
add_subdirectory(petsc)
+2 -2
View File
@@ -33,13 +33,13 @@ add_mfem_examples(CALIPER_EXE_SRCS ${PREFIX})
if (MFEM_ENABLE_TESTING)
foreach(SRC_FILE ${CALIPER_EXE_SRCS})
get_filename_component(SRC_FILENAME ${SRC_FILE} NAME)
string(REPLACE ".cpp" "" TEST_NAME ${SRC_FILENAME})
string(REPLACE ".cpp" "" TEST_NAME ${PREFIX}${SRC_FILENAME})
set(THIS_TEST_OPTIONS "-no-vis")
if (NOT (${TEST_NAME} MATCHES ".*p$"))
add_test(NAME ${TEST_NAME}_ser
COMMAND ${TEST_NAME} ${THIS_TEST_OPTIONS})
COMMAND $<TARGET_FILE:${TEST_NAME}> ${THIS_TEST_OPTIONS})
else()
add_test(NAME ${TEST_NAME}_np=${MFEM_MPI_NP}
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MFEM_MPI_NP}
+810
View File
@@ -0,0 +1,810 @@
// Contact example
//
// Compile with: make contact
//
// Sample runs: ./contact -m1 block1.mesh -m2 block2.mesh -at "5 6 7 8"
// Sample runs: ./contact -m1 block1_d.mesh -m2 block2_d.mesh -at "5 6 7 8"
#include "mfem.hpp"
#include <fstream>
#include <iostream>
#include "nodepair.hpp"
using namespace std;
using namespace mfem;
bool ifequalarray(const Array<int> a1, const Array<int> a2)
{
if (a1.Size()!=a2.Size())
{
return false;
}
for (int i=0; i<a1.Size(); i++)
{
if (a1[i] != a2[i])
{
return false;
}
}
return true;
}
void FindSurfaceToProject(Mesh& mesh, const int elem, int& cbdrface)
{
Array<int> attr;
attr.Append(2);
Array<int> faces;
Array<int> ori;
std::vector<Array<int> > facesVertices;
std::vector<int > faceid;
mesh.GetElementFaces(elem, faces, ori);
int face = -1;
for (int i=0; i<faces.Size(); i++)
{
face = faces[i];
Array<int> faceVert;
if (!mesh.FaceIsInterior(face)) // if on the boundary
{
mesh.GetFaceVertices(face, faceVert);
faceVert.Sort();
facesVertices.push_back(faceVert);
faceid.push_back(face);
}
}
int bdrface = facesVertices.size();
Array<int> bdryFaces;
// This shoulnd't need to be rebuilt
std::vector<Array<int> > bdryVerts;
for (int b=0; b<mesh.GetNBE(); ++b)
{
if (attr.FindSorted(mesh.GetBdrAttribute(b)) >= 0) // found the contact surface
{
bdryFaces.Append(b);
Array<int> vert;
mesh.GetBdrElementVertices(b, vert);
vert.Sort();
bdryVerts.push_back(vert);
}
}
int bdrvert = bdryVerts.size();
cbdrface = -1; // the face number of the contact surface element
int count_cbdrface = 0; // the number of matching surfaces, used for checks
for (int i=0; i<bdrface; i++)
{
for (int j=0; j<bdrvert; j++)
{
if (ifequalarray(facesVertices[i], bdryVerts[j]))
{
cbdrface = faceid[i];
count_cbdrface += 1;
}
}
}
MFEM_VERIFY(count_cbdrface == 1,"projection surface not found");
};
Vector GetNormalVector(Mesh & mesh, const int elem, const double *ref,
int & refFace, int & refNormal, bool & interior)
{
ElementTransformation *trans = mesh.GetElementTransformation(elem);
const int dim = mesh.Dimension();
const int spaceDim = trans->GetSpaceDim();
MFEM_VERIFY(spaceDim == 3, "");
Vector n(spaceDim);
IntegrationPoint ip;
ip.Set(ref, dim);
trans->SetIntPoint(&ip);
//CalcOrtho(trans->Jacobian(), n); // Works only for face transformations
const DenseMatrix jac = trans->Jacobian();
int dimNormal = -1;
int normalSide = -1;
const double tol = 1.0e-8;
for (int i=0; i<dim; ++i)
{
const double d0 = std::abs(ref[i]);
const double d1 = std::abs(ref[i] - 1.0);
const double d = std::min(d0, d1);
// TODO: this works only for hexahedral meshes!
if (d < tol)
{
MFEM_VERIFY(dimNormal == -1, "");
dimNormal = i;
if (d0 < tol)
{
normalSide = 0;
}
else
{
normalSide = 1;
}
}
}
// closest point on the boundary
if (dimNormal < 0 || normalSide < 0) // node is inside the element
{
interior = 1;
Vector n(3);
n = 0.0;
return n;
}
MFEM_VERIFY(dimNormal >= 0 && normalSide >= 0, "");
refNormal = dimNormal;
MFEM_VERIFY(dim == 3, "");
{
// Find the reference face
if (dimNormal == 0)
{
refFace = (normalSide == 1) ? 2 : 4;
}
else if (dimNormal == 1)
{
refFace = (normalSide == 1) ? 3 : 1;
}
else
{
refFace = (normalSide == 1) ? 5 : 0;
}
}
std::vector<Vector> tang(2);
int tangDir[2] = {-1, -1};
{
int t = 0;
for (int i=0; i<dim; ++i)
{
if (i != dimNormal)
{
tangDir[t] = i;
t++;
}
}
MFEM_VERIFY(t == 2, "");
}
for (int i=0; i<2; ++i)
{
tang[i].SetSize(3);
Vector tangRef(3);
tangRef = 0.0;
tangRef[tangDir[i]] = 1.0;
jac.Mult(tangRef, tang[i]);
}
Vector c(3); // Cross product
c[0] = (tang[0][1] * tang[1][2]) - (tang[0][2] * tang[1][1]);
c[1] = (tang[0][2] * tang[1][0]) - (tang[0][0] * tang[1][2]);
c[2] = (tang[0][0] * tang[1][1]) - (tang[0][1] * tang[1][0]);
c /= c.Norml2();
Vector nref(3);
nref = 0.0;
nref[dimNormal] = 1.0;
Vector ndir(3);
jac.Mult(nref, ndir);
ndir /= ndir.Norml2();
const double dp = ndir * c;
// TODO: eliminate c?
n = c;
if (dp < 0.0)
{
n *= -1.0;
}
interior = 0;
return n;
}
// WARNING: global variable, just for this little example.
std::array<std::array<int, 3>, 8> HEX_VERT =
{
{ {0,0,0},
{1,0,0},
{1,1,0},
{0,1,0},
{0,0,1},
{1,0,1},
{1,1,1},
{0,1,1}
}
};
int GetHexVertex(int cdim, int c, int fa, int fb, Vector & refCrd)
{
int ref[3];
ref[cdim] = c;
ref[cdim == 0 ? 1 : 0] = fa;
ref[cdim == 2 ? 1 : 2] = fb;
for (int i=0; i<3; ++i) { refCrd[i] = ref[i]; }
int refv = -1;
for (int i=0; i<8; ++i)
{
bool match = true;
for (int j=0; j<3; ++j)
{
if (ref[j] != HEX_VERT[i][j]) { match = false; }
}
if (match) { refv = i; }
}
MFEM_VERIFY(refv >= 0, "");
return refv;
}
// Coordinates in xyz are assumed to be ordered as [X, Y, Z]
// where X is the list of x-coordinates for all points and so on.
// conn: connectivity of the target surface elements
// xi: surface reference cooridnates for the cloest point, involves a linear transformation from [0,1] to [-1,1]
void FindPointsInMesh(Mesh & mesh, Vector const& xyz, Array<int>& conn,
Vector& xi)
{
const int dim = mesh.Dimension();
const int np = xyz.Size() / dim;
MFEM_VERIFY(np * dim == xyz.Size(), "");
mesh.EnsureNodes();
//FindPointsGSLIB finder(MPI_COMM_WORLD);
FindPointsGSLIB finder;
finder.SetDistanceToleranceForPointsFoundOnBoundary(0.5);
const double bb_t = 0.5;
finder.Setup(mesh, bb_t);
finder.FindPoints(xyz);
/// Return code for each point searched by FindPoints: inside element (0), on
/// element boundary (1), or not found (2).
Array<unsigned int> codes = finder.GetCode();
/// Return element number for each point found by FindPoints.
Array<unsigned int> elems = finder.GetElem();
/// Return reference coordinates for each point found by FindPoints.
Vector refcrd = finder.GetReferencePosition();
/// Return distance between the sought and the found point in physical space,
/// for each point found by FindPoints.
Vector dist = finder.GetDist();
MFEM_VERIFY(dist.Size() == np, "");
MFEM_VERIFY(refcrd.Size() == np * dim, "");
MFEM_VERIFY(elems.Size() == np, "");
MFEM_VERIFY(codes.Size() == np, "");
bool allfound = true;
for (auto code : codes)
if (code == 2) { allfound = false; }
MFEM_VERIFY(allfound, "A point was not found");
cout << "Maximum distance of projected points: " << dist.Max() << endl;
// extract information
for (int i=0; i<np; ++i)
{
/*cout << "Point " << i << ": (";
for (int j=0; j<dim; ++j)
{
cout << xyz[i + (j*np)];
if (j == dim-1) {cout << ")" << endl;}
else{cout << ", ";}
}*/
//cout << " element: " << elems[i] << endl;
//cout << " element " << elems[i] << " vertices:" << endl;
//Array<int> vert;
//mesh.GetElementVertices(elems[i], vert);
//for (auto v : vert)
//{
// cout << " " << v << endl;
//}
/*cout << " reference coordinates: (";
for (int j=0; j<dim; ++j)
{
cout << refcrd[(i*dim) + j];
if (j == dim-1)
{
cout << ")" << endl;
}
else
{
cout << ", ";
}
}*/
int refFace, refNormal, refNormalSide;
bool is_interior = -1;
Vector normal = GetNormalVector(mesh, elems[i], refcrd.GetData() + (i*dim),
refFace, refNormal, is_interior);
int phyFace;
if (is_interior)
{
phyFace = -1; // the id of the face that has the closest point
FindSurfaceToProject(mesh, elems[i], phyFace);
Array<int> cbdrVert;
mesh.GetFaceVertices(phyFace, cbdrVert);
Vector xs(dim);
xs[0] = xyz[i + 0*np];
xs[1] = xyz[i + 1*np];
xs[2] = xyz[i + 2*np];
Vector xi_tmp(dim-1);
// get nodes!
GridFunction *nodes = mesh.GetNodes();
DenseMatrix coords(4,3);
for (int i=0; i<4; i++)
{
for (int j=0; j<3; j++)
{
coords(i,j) = (*nodes)[cbdrVert[i]*3+j];
}
}
SlaveToMaster(coords, xs, xi_tmp);
for (int j=0; j<dim-1; ++j)
{
xi[i*(dim-1)+j] = xi_tmp[j];
}
// now get get the projection to the surface
}
else
{
Vector faceRefCrd(dim-1);
{
int fd = 0;
for (int j=0; j<dim; ++j)
{
if (j == refNormal)
{
refNormalSide = (refcrd[(i*dim) + j] > 0.5);
}
else
{
faceRefCrd[fd] = refcrd[(i*dim) + j];
fd++;
}
}
MFEM_VERIFY(fd == dim-1, "");
}
for (int j=0; j<dim-1; ++j)
{
xi[i*(dim-1)+j] = faceRefCrd[j]*2.0 - 1.0;
}
//cout << " face reference coordinates: (";
/*for (int j=0; j<dim-1; ++j)
{
cout << faceRefCrd[j];
if (j == dim-2){cout << ")" << endl;}
else{cout << ", ";}
}*/
}
//cout << " normal vector: ";
//normal.Print();
// ask, does this do anything?
/*
IntegrationPoint ip;
ip.Set(refcrd.GetData() + (i*dim), dim);
ElementTransformation *trans = mesh.GetElementTransformation(elems[i]);
Vector phys(trans->GetSpaceDim());
trans->Transform(ip, phys);
cout << " physical coordinates: ";
phys.Print();
*/
// Get the element face
Array<int> faces;
Array<int> ori;
int face;
if (is_interior)
{
face = phyFace;
}
else
{
mesh.GetElementFaces(elems[i], faces, ori);
face = faces[refFace];
}
Array<int> faceVert;
mesh.GetFaceVertices(face, faceVert);
//cout << " face " << face << " vertices:" << endl;
//for (auto v : faceVert){ cout << " " << v << endl;}
for (int p=0; p<4; p++)
{
conn[4*i+p] = faceVert[p];
}
/*
Vector ref(dim);
for (int p=0; p<2; ++p)
for (int q=0; q<2; ++q)
{
const int refv = GetHexVertex(refNormal, refNormalSide, p, q, ref);
cout << " face reference vertex (" << p << "," << q
<< ") is global vertex " << vert[refv] << endl;
{
// Sanity check
ip.Set(ref.GetData(), dim);
trans->Transform(ip, phys);
for (int j=0; j<dim; ++j)
{
phys[j] -= mesh.GetVertex(vert[refv])[j];
}
phys.Print();
cout<<vert[refv]<<endl;
cout<<mesh.GetVertex(vert[refv])[0]<<endl;
cout<<mesh.GetVertex(vert[refv])[1]<<endl;
cout<<mesh.GetVertex(vert[refv])[2]<<endl;
MFEM_VERIFY(phys.Norml2() < 1.0e-12, "Sanity check failed");
}
}*/
}
}
int main(int argc, char *argv[])
{
// 1. Parse command-line options.
const char *mesh_file1 = "block1.mesh";
const char *mesh_file2 = "block2.mesh";
Array<int> attr;
Array<int> m_attr;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file1, "-m1", "--mesh1",
"First mesh file to use.");
args.AddOption(&mesh_file2, "-m2", "--mesh2",
"Second mesh file to use.");
args.AddOption(&attr, "-at", "--attributes-surf",
"Attributes of boundary faces on contact surface for mesh 2.");
args.Parse();
if (!args.Good())
{
args.PrintUsage(cout);
return 1;
}
args.PrintOptions(cout);
Mesh mesh1(mesh_file1, 1, 1);
Mesh mesh2(mesh_file2, 1, 1);
{
char vishost[] = "localhost";
int visport = 19916;
socketstream mesh1a_sock(vishost, visport);
mesh1a_sock.precision(8);
mesh1a_sock << "mesh\n" << mesh1 << flush;
socketstream mesh2a_sock(vishost, visport);
mesh2a_sock.precision(8);
mesh2a_sock << "mesh\n" << mesh2 << flush;
}
const int dim = mesh1.Dimension();
MFEM_VERIFY(dim == mesh2.Dimension(), "");
// boundary attribute 2 is the potential contact surface of nodes
attr.Append(2);
// boundary attribute 2 is the potential contact surface for master surface
m_attr.Append(2);
// Define a finite element space on the mesh. Here we use vector finite
// elements, i.e. dim copies of a scalar finite element space. The vector
// dimension is specified by the last argument of the FiniteElementSpace
// constructor.
FiniteElementCollection *fec1;
FiniteElementSpace *fespace1;
fec1 = new H1_FECollection(1, dim);
fespace1 = new FiniteElementSpace(&mesh1, fec1, dim, Ordering::byVDIM);
cout << "Number of finite element unknowns for mesh1: "
<< fespace1->GetTrueVSize() << endl;
mesh1.SetNodalFESpace(fespace1);
GridFunction nodes0 = *mesh1.GetNodes(); // undeformed mesh1 nodal grid function
GridFunction *nodes1 = mesh1.GetNodes();
FiniteElementCollection *fec2 = new H1_FECollection(1, dim);
FiniteElementSpace *fespace2 = new FiniteElementSpace(&mesh2, fec2, dim,
Ordering::byVDIM);
cout << "Number of finite element unknowns for mesh2: "
<< fespace2->GetTrueVSize() << endl;
// degrees of freedom of both meshes
int ndof_1 = fespace1->GetTrueVSize();
int ndof_2 = fespace2->GetTrueVSize();
int ndofs = ndof_1 + ndof_2;
// number of nodes for each mesh
int nnd_1 = mesh1.GetNV();
int nnd_2 = mesh2.GetNV();
int nnd = nnd_1 + nnd_2;
// Determine the list of true (i.e. conforming) essential boundary dofs.
// In this example, the boundary conditions are defined by marking only
// boundary attribute 1 from the mesh as essential and converting it to a
// list of true dofs.
Array<int> ess_tdof_list1, ess_bdr1(mesh1.bdr_attributes.Max());
ess_bdr1 = 0;
//ess_bdr1[0] = 1;
// Not ready to be passed on yet
// fespace->GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
Array<int> ess_tdof_list2, ess_bdr2(mesh2.bdr_attributes.Max());
ess_bdr2 = 0;
//ess_bdr2[0] = 1;
// Define the displacement vector x as a finite element grid function
// corresponding to fespace. GridFunction is a derived class of Vector.
GridFunction x1(fespace1);
x1 = 0.0;
GridFunction x2(fespace2);
x2 = 0.0;
// Generate force
LinearForm *b1 = new LinearForm(fespace1);
b1->Assemble();
LinearForm *b2 = new LinearForm(fespace2);
b2->Assemble();
// Set up the bilinear form a(.,.) on the finite element space
// corresponding to the linear elasticity integrator with piece-wise
// constants coefficient lambda and mu.
Vector lambda1(mesh1.attributes.Max());
lambda1 = 57.6923076923;
PWConstCoefficient lambda1_func(lambda1);
Vector mu1(mesh1.attributes.Max());
mu1 = 38.4615384615;
PWConstCoefficient mu1_func(mu1);
BilinearForm *a1 = new BilinearForm(fespace1);
a1->AddDomainIntegrator(new ElasticityIntegrator(lambda1_func,mu1_func));
Vector lambda2(mesh2.attributes.Max());
lambda2 = 57.6923076923;
PWConstCoefficient lambda2_func(lambda2);
Vector mu2(mesh2.attributes.Max());
mu2 = 38.4615384615;
PWConstCoefficient mu2_func(mu2);
BilinearForm *a2 = new BilinearForm(fespace2);
a2->AddDomainIntegrator(new ElasticityIntegrator(lambda2_func,mu2_func));
a1->Assemble();
SparseMatrix A1;
Vector B1, X1;
a1->FormLinearSystem(ess_tdof_list1, x1, *b1, A1, X1, B1);
a2->Assemble();
SparseMatrix A2;
Vector B2, X2;
a2->FormLinearSystem(ess_tdof_list2, x2, *b2, A2, X2, B2);
// Combine elasticity operator for two meshes into one.
// Block Matrix
SparseMatrix K(ndofs,ndofs);
for (int i=0; i<A1.Height(); i++)
{
Array<int> col_tmp;
Vector v_tmp;
col_tmp = 0;
v_tmp = 0.0;
A1.GetRow(i, col_tmp, v_tmp);
K.SetRow(i, col_tmp, v_tmp);
}
for (int i=0; i<A2.Height(); i++)
{
Array<int> col_tmp;
Vector v_tmp;
col_tmp = 0;
v_tmp = 0.0;
A2.GetRow(i, col_tmp, v_tmp);
for (int j=0; j<col_tmp.Size(); j++)
{
col_tmp[j] += ndof_1;
}
K.SetRow(i+ndof_1, col_tmp, v_tmp); // mesh1 top left corner
}
// Construct node to segment contact constraint.
attr.Sort();
cout << "Boundary attributes for contact surface faces in mesh 2" << endl;
for (auto a : attr) { cout << a << endl; }
Array<int> bdryFaces2; // TODO: remove this?
std::set<int> bdryVerts2;
for (int b=0; b<mesh2.GetNBE(); ++b)
{
if (attr.FindSorted(mesh2.GetBdrAttribute(b)) >= 0)
{
bdryFaces2.Append(b);
Array<int> vert;
mesh2.GetBdrElementVertices(b, vert);
for (auto v : vert)
{
bdryVerts2.insert(v);
}
}
}
int npoints = bdryVerts2.size();
Array<int> s_conn(npoints); // connectivity of the second/slave mesh
Vector xyz(dim * npoints);
xyz = 0.0;
cout << "Boundary vertices for contact surface vertices in mesh 2" << endl;
// construct the nodal coordinates on mesh2 to be projected, including displacement
int count = 0;
for (auto v : bdryVerts2)
{
cout << v << ": " << mesh2.GetVertex(v)[0] << ", "
<< mesh2.GetVertex(v)[1] << ", "
<< mesh2.GetVertex(v)[2] << endl;
for (int i=0; i<dim; ++i)
{
xyz[count + (i * npoints)] = mesh2.GetVertex(v)[i] + x2[v*dim+i];
}
s_conn[count] = v + nnd_1; // dof1 is the master
count++;
}
MFEM_VERIFY(count == npoints, "");
// gap function
Vector g(npoints*dim);
g = -1.0;
// segment reference coordinates of the closest point
Vector m_xi(npoints*(dim-1));
m_xi = -1.0;
Vector xs(dim*npoints);
xs = 0.0;
for (int i=0; i<npoints; i++)
{
for (int j=0; j<dim; j++)
{
xs[i*dim+j] = xyz[i + (j*npoints)];
}
}
Array<int> m_conn(
npoints*4); // only works for linear elements that have 4 vertices!
DenseMatrix coordsm(npoints*4, dim);
// adding displacement to mesh1 using a fixed grid function from mesh1
x1 = 1e-4; // x1 order: [xyz xyz... xyz]
add(nodes0, x1, *nodes1);
FindPointsInMesh(mesh1, xyz, m_conn, m_xi);
for (int i=0; i<npoints; i++)
{
for (int j=0; j<4; j++)
{
for (int k=0; k<dim; k++)
{
coordsm(i*4+j,k) = mesh1.GetVertex(m_conn[i*4+j])[k]+x1[dim*m_conn[i*4+j]+k];
}
}
}
//coordsm.Print();
SparseMatrix M(nnd,ndofs);
std::vector<SparseMatrix> dM(nnd, SparseMatrix(ndofs,ndofs));
Assemble_Contact(nnd, npoints, ndofs, xs, m_xi, coordsm,
s_conn, m_conn, g, M, dM);
std::set<int> dirbdryv2;
for (int b=0; b<mesh2.GetNBE(); ++b)
{
if (mesh2.GetBdrAttribute(b) == 1)
{
Array<int> vert;
mesh2.GetBdrElementVertices(b, vert);
for (auto v : vert)
{
dirbdryv2.insert(v);
}
}
}
std::set<int> dirbdryv1;
for (int b=0; b<mesh1.GetNBE(); ++b)
{
if (mesh1.GetBdrAttribute(b) == 1)
{
Array<int> vert;
mesh1.GetBdrElementVertices(b, vert);
for (auto v : vert)
{
dirbdryv1.insert(v);
}
}
}
Array<int> Dirichlet_dof;
Array<double> Dirichlet_val;
for (auto v : dirbdryv2)
{
for (int i=0; i<dim; ++i)
{
Dirichlet_dof.Append(v*dim + i + ndof_1);
Dirichlet_val.Append(0.);
}
}
double delta = 0.1;
for (auto v : dirbdryv1)
{
Dirichlet_dof.Append(v*dim + 0);
Dirichlet_val.Append(delta);
Dirichlet_dof.Append(v*dim + 1);
Dirichlet_val.Append(0.);
Dirichlet_dof.Append(v*dim + 2);
Dirichlet_val.Append(0.);
}
{
char vishost[] = "localhost";
int visport = 19916;
socketstream mesh1_sock(vishost, visport);
mesh1_sock.precision(8);
mesh1_sock << "mesh\n" << mesh1 << flush;
socketstream mesh2_sock(vishost, visport);
mesh2_sock.precision(8);
mesh2_sock << "mesh\n" << mesh2 << flush;
}
//M.Print();
/*Vector eps(ndofs);
Vector sol(ndofs); sol = 0.;
for(int i=0;i<ndofs;i++) eps[i] = 1e-5 * i ;
for(int i=0;i<9;i++)
{
cout<<i<<endl;
dM[s_conn[i]].Mult(eps,sol);
sol.Print();
}
*/
return 0;
}
+8 -1
View File
@@ -192,7 +192,14 @@ int main(int argc, char *argv[])
// domain integrator.
BilinearForm a(&fespace);
if (pa) { a.SetAssemblyLevel(AssemblyLevel::PARTIAL); }
if (fa) { a.SetAssemblyLevel(AssemblyLevel::FULL); }
if (fa)
{
a.SetAssemblyLevel(AssemblyLevel::FULL);
// Sort the matrix column indices when running on GPU or with OpenMP (i.e.
// when Device::IsEnabled() returns true). This makes the results
// bit-for-bit deterministic at the cost of somewhat longer run time.
a.EnableSparseMatrixSorting(Device::IsEnabled());
}
a.AddDomainIntegrator(new DiffusionIntegrator(one));
// 10. Assemble the bilinear form and the corresponding linear system,
+8 -1
View File
@@ -219,7 +219,14 @@ int main(int argc, char *argv[])
// Diffusion domain integrator.
ParBilinearForm a(&fespace);
if (pa) { a.SetAssemblyLevel(AssemblyLevel::PARTIAL); }
if (fa) { a.SetAssemblyLevel(AssemblyLevel::FULL); }
if (fa)
{
a.SetAssemblyLevel(AssemblyLevel::FULL);
// Sort the matrix column indices when running on GPU or with OpenMP (i.e.
// when Device::IsEnabled() returns true). This makes the results
// bit-for-bit deterministic at the cost of somewhat longer run time.
a.EnableSparseMatrixSorting(Device::IsEnabled());
}
a.AddDomainIntegrator(new DiffusionIntegrator(one));
// 12. Assemble the parallel bilinear form and the corresponding linear
+1 -1
View File
@@ -195,7 +195,7 @@ int main(int argc, char *argv[])
Array<int> ess_tdof_list(0);
if (h1 && pmesh.bdr_attributes.Size())
{
// For a continuous basis the linear system must be modifed to enforce an
// For a continuous basis the linear system must be modified to enforce an
// essential (Dirichlet) boundary condition. In the DG case this is not
// necessary as the boundary condition will only be enforced weakly.
fespace.GetEssentialTrueDofs(dbc_bdr, ess_tdof_list);
-1
View File
@@ -197,7 +197,6 @@ int main(int argc, char *argv[])
SparseMatrix &M(mVarf->SpMat());
SparseMatrix &B(bVarf->SpMat());
B *= -1.;
B.EnsureMultTranspose();
Bt = new TransposeOperator(&B);
darcyOp.SetBlock(0,0, &M);
+60
View File
@@ -0,0 +1,60 @@
# Copyright (c) 2010-2022, 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.
set(IPOPT_EXAMPLES_SRCS)
list(APPEND IPOPT_EXAMPLES_SRCS exContactBlockTL.cpp)
# Include the source directory where mfem.hpp and mfem-performance.hpp are.
include_directories(BEFORE ${PROJECT_BINARY_DIR})
# Add "test_ipopt" target, see below.
add_custom_target(test_ipopt
${CMAKE_CTEST_COMMAND} -R ipopt USES_TERMINAL)
# Add one executable per cpp file, adding "ipopt_" as prefix. Sets
# "test_ipopt" as a target that depends on the given examples.
set(PFX ipopt_)
add_mfem_examples(IPOPT_EXAMPLES_SRCS ${PFX} "" test_ipopt)
# Testing.
# The IPOPT tests can be run separately using the target "test_ipopt"
# which builds the examples and runs:
# ctest -R ipopt
if (MFEM_ENABLE_TESTING)
# Command line options for the tests.
# Example 9:
set(EXCONTACTBTL_COMMON_OPTS -m ../../data/periodic-segment.mesh -p 0 -dt 0.005)
set(EXCONTACTBTL_TEST_OPTS ${EXCONTACTBTL_COMMON_OPTS} -r 2 )
# Add the tests: one test per source file.
foreach(SRC_FILE ${IPOPT_EXAMPLES_SRCS})
get_filename_component(SRC_FILENAME ${SRC_FILE} NAME)
string(REPLACE ".cpp" "" TEST_NAME ${SRC_FILENAME})
string(TOUPPER ${TEST_NAME} UP_TEST_NAME)
set(TEST_NAME ${PFX}${TEST_NAME})
set(THIS_TEST_OPTIONS "-no-vis")
list(APPEND THIS_TEST_OPTIONS ${${UP_TEST_NAME}_TEST_OPTS})
# message(STATUS "Test ${TEST_NAME} options: ${THIS_TEST_OPTIONS}")
if (NOT (${TEST_NAME} MATCHES ".*p$"))
add_test(NAME ${TEST_NAME}_ser
COMMAND ${TEST_NAME} ${THIS_TEST_OPTIONS})
else()
add_test(NAME ${TEST_NAME}_np=4
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} 4
${MPIEXEC_PREFLAGS}
$<TARGET_FILE:${TEST_NAME}> ${THIS_TEST_OPTIONS}
${MPIEXEC_POSTFLAGS})
endif()
endforeach()
endif()
+19
View File
@@ -0,0 +1,19 @@
Finite Element Discretization Library
__
_ __ ___ / _| ___ _ __ ___
| '_ ` _ \ | |_ / _ \| '_ ` _ \
| | | | | || _|| __/| | | | | |
|_| |_| |_||_| \___||_| |_| |_|
https://mfem.org
This directory contains modifications of the example codes that illustrate the
use of MFEM for solving nonlinear constrained optimization problems, including
features based on the IpOpt, a lightweight HPC solver for nonlinear optimization
problems.
To use the Ipopt features, make sure that MFEM is configured with the option
"MFEM_USE_IPOPT = YES", see the top-level INSTALL file for details.
We recommend comparing the original example codes with the corresponding files
in the current directory.
+103
View File
@@ -0,0 +1,103 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
#
dimension
3
elements
9
1 5 0 1 3 2 8 9 11 10
1 5 2 3 5 4 10 11 13 12
1 5 4 5 7 6 12 13 15 14
1 5 8 9 11 10 16 17 19 18
1 5 10 11 13 12 18 19 21 20
1 5 12 13 15 14 20 21 23 22
1 5 16 17 19 18 24 25 27 26
1 5 18 19 21 20 26 27 29 28
1 5 20 21 23 22 28 29 31 30
# 0 nothing
# 1 dirichlet bc
# 2 contact
boundary
30
0 3 1 0 2 3
0 3 3 2 4 5
0 3 5 4 6 7
0 3 24 25 27 26
0 3 26 27 29 28
0 3 28 29 31 30
1 3 2 0 8 10
1 3 4 2 10 12
1 3 6 4 12 14
1 3 10 8 16 18
1 3 12 10 18 20
1 3 14 12 20 22
1 3 18 16 24 26
1 3 20 18 26 28
1 3 22 20 28 30
2 3 1 3 11 9
2 3 3 5 13 11
2 3 5 7 15 13
2 3 9 11 19 17
2 3 11 13 21 19
2 3 13 15 23 21
2 3 17 19 27 25
2 3 19 21 29 27
2 3 21 23 31 29
0 3 8 0 1 9
0 3 16 8 9 17
0 3 24 16 17 25
0 3 6 14 15 7
0 3 14 22 23 15
0 3 22 30 31 23
vertices
32
3
-1.0000 0 0
0 0 0
-1.0000 0.3333 0
0 0.3333 0
-1.0000 0.6667 0
0 0.6667 0
-1.0000 1.0000 0
0 1.0000 0
-1.0000 0 0.3333
0 0 0.3333
-1.0000 0.3333 0.3333
0 0.3333 0.3333
-1.0000 0.6667 0.3333
0 0.6667 0.3333
-1.0000 1.0000 0.3333
0 1.0000 0.3333
-1.0000 0 0.6667
0 0 0.6667
-1.0000 0.3333 0.6667
0 0.3333 0.6667
-1.0000 0.6667 0.6667
0 0.6667 0.6667
-1.0000 1.0000 0.6667
0 1.0000 0.6667
-1.0000 0 1.0000
0 0 1.0000
-1.0000 0.3333 1.0000
0 0.3333 1.0000
-1.0000 0.6667 1.0000
0 0.6667 1.0000
-1.0000 1.0000 1.0000
0 1.0000 1.0000
+68
View File
@@ -0,0 +1,68 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
#
dimension
3
# 1 nothing
elements
4
1 5 0 1 3 2 6 7 9 8
1 5 2 3 5 4 8 9 11 10
1 5 6 7 9 8 12 13 15 14
1 5 8 9 11 10 14 15 17 16
# 0 nothing
# 1 dirichlet bc
# 2 contact
boundary
16
0 3 1 0 2 3
0 3 3 2 4 5
0 3 12 13 15 14
0 3 14 15 17 16
2 3 2 0 6 8
2 3 4 2 8 10
2 3 8 6 12 14
2 3 10 8 14 16
1 3 1 3 9 7
1 3 3 5 11 9
1 3 7 9 15 13
1 3 9 11 17 15
0 3 6 0 1 7
0 3 12 6 7 13
0 3 4 10 11 5
0 3 10 16 17 11
vertices
18
3
0 0.2464 0.2464
0.5071 0.2464 0.2464
0 0.5000 0.2464
0.5071 0.5000 0.2464
0 0.7536 0.2464
0.5071 0.7536 0.2464
0 0.2464 0.5000
0.5071 0.2464 0.5000
0 0.5000 0.5000
0.5071 0.5000 0.5000
0 0.7536 0.5000
0.5071 0.7536 0.5000
0 0.2464 0.7536
0.5071 0.2464 0.7536
0 0.5000 0.7536
0.5071 0.5000 0.7536
0 0.7536 0.7536
0.5071 0.7536 0.7536
+742
View File
@@ -0,0 +1,742 @@
// Contact example
//
// Compile with: make contact
//
// Sample runs: ./contact -m1 block1.mesh -m2 block2.mesh -at "5 6 7 8"
// Sample runs: ./contact -m1 block1_d.mesh -m2 block2_d.mesh -at "5 6 7 8"
#include "mfem.hpp"
#include <fstream>
#include <iostream>
#include "nodepair.hpp"
using namespace std;
using namespace mfem;
bool ifequalarray(const Array<int> a1, const Array<int> a2)
{
if (a1.Size()!=a2.Size())
{
return false;
}
for (int i=0; i<a1.Size(); i++)
{
if (a1[i] != a2[i])
{
return false;
}
}
return true;
}
void FindSurfaceToProject(Mesh& mesh, const int elem, int& cbdrface)
{
Array<int> attr;
attr.Append(2);
Array<int> faces;
Array<int> ori;
std::vector<Array<int> > facesVertices;
std::vector<int > faceid;
mesh.GetElementFaces(elem, faces, ori);
int face = -1;
for (int i=0; i<faces.Size(); i++)
{
face = faces[i];
Array<int> faceVert;
if (!mesh.FaceIsInterior(face)) // if on the boundary
{
mesh.GetFaceVertices(face, faceVert);
faceVert.Sort();
facesVertices.push_back(faceVert);
faceid.push_back(face);
}
}
int bdrface = facesVertices.size();
Array<int> bdryFaces;
// This shoulnd't need to be rebuilt
std::vector<Array<int> > bdryVerts;
for (int b=0; b<mesh.GetNBE(); ++b)
{
if (attr.FindSorted(mesh.GetBdrAttribute(b)) >= 0) // found the contact surface
{
bdryFaces.Append(b);
Array<int> vert;
mesh.GetBdrElementVertices(b, vert);
vert.Sort();
bdryVerts.push_back(vert);
}
}
int bdrvert = bdryVerts.size();
cbdrface = -1; // the face number of the contact surface element
int count_cbdrface = 0; // the number of matching surfaces, used for checks
for (int i=0; i<bdrface; i++)
{
for (int j=0; j<bdrvert; j++)
{
if (ifequalarray(facesVertices[i], bdryVerts[j]))
{
cbdrface = faceid[i];
count_cbdrface += 1;
}
}
}
MFEM_VERIFY(count_cbdrface == 1,"projection surface not found");
};
Vector GetNormalVector(Mesh & mesh, const int elem, const double *ref,
int & refFace, int & refNormal, bool & interior)
{
ElementTransformation *trans = mesh.GetElementTransformation(elem);
const int dim = mesh.Dimension();
const int spaceDim = trans->GetSpaceDim();
MFEM_VERIFY(spaceDim == 3, "");
Vector n(spaceDim);
IntegrationPoint ip;
ip.Set(ref, dim);
trans->SetIntPoint(&ip);
//CalcOrtho(trans->Jacobian(), n); // Works only for face transformations
const DenseMatrix jac = trans->Jacobian();
int dimNormal = -1;
int normalSide = -1;
const double tol = 1.0e-8;
for (int i=0; i<dim; ++i)
{
const double d0 = std::abs(ref[i]);
const double d1 = std::abs(ref[i] - 1.0);
const double d = std::min(d0, d1);
// TODO: this works only for hexahedral meshes!
if (d < tol)
{
MFEM_VERIFY(dimNormal == -1, "");
dimNormal = i;
if (d0 < tol)
{
normalSide = 0;
}
else
{
normalSide = 1;
}
}
}
// closest point on the boundary
if (dimNormal < 0 || normalSide < 0) // node is inside the element
{
interior = 1;
Vector n(3);
n = 0.0;
return n;
}
MFEM_VERIFY(dimNormal >= 0 && normalSide >= 0, "");
refNormal = dimNormal;
MFEM_VERIFY(dim == 3, "");
{
// Find the reference face
if (dimNormal == 0)
{
refFace = (normalSide == 1) ? 2 : 4;
}
else if (dimNormal == 1)
{
refFace = (normalSide == 1) ? 3 : 1;
}
else
{
refFace = (normalSide == 1) ? 5 : 0;
}
}
std::vector<Vector> tang(2);
int tangDir[2] = {-1, -1};
{
int t = 0;
for (int i=0; i<dim; ++i)
{
if (i != dimNormal)
{
tangDir[t] = i;
t++;
}
}
MFEM_VERIFY(t == 2, "");
}
for (int i=0; i<2; ++i)
{
tang[i].SetSize(3);
Vector tangRef(3);
tangRef = 0.0;
tangRef[tangDir[i]] = 1.0;
jac.Mult(tangRef, tang[i]);
}
Vector c(3); // Cross product
c[0] = (tang[0][1] * tang[1][2]) - (tang[0][2] * tang[1][1]);
c[1] = (tang[0][2] * tang[1][0]) - (tang[0][0] * tang[1][2]);
c[2] = (tang[0][0] * tang[1][1]) - (tang[0][1] * tang[1][0]);
c /= c.Norml2();
Vector nref(3);
nref = 0.0;
nref[dimNormal] = 1.0;
Vector ndir(3);
jac.Mult(nref, ndir);
ndir /= ndir.Norml2();
const double dp = ndir * c;
// TODO: eliminate c?
n = c;
if (dp < 0.0)
{
n *= -1.0;
}
interior = 0;
return n;
}
// WARNING: global variable, just for this little example.
std::array<std::array<int, 3>, 8> HEX_VERT =
{
{ {0,0,0},
{1,0,0},
{1,1,0},
{0,1,0},
{0,0,1},
{1,0,1},
{1,1,1},
{0,1,1}
}
};
int GetHexVertex(int cdim, int c, int fa, int fb, Vector & refCrd)
{
int ref[3];
ref[cdim] = c;
ref[cdim == 0 ? 1 : 0] = fa;
ref[cdim == 2 ? 1 : 2] = fb;
for (int i=0; i<3; ++i) { refCrd[i] = ref[i]; }
int refv = -1;
for (int i=0; i<8; ++i)
{
bool match = true;
for (int j=0; j<3; ++j)
{
if (ref[j] != HEX_VERT[i][j]) { match = false; }
}
if (match) { refv = i; }
}
MFEM_VERIFY(refv >= 0, "");
return refv;
}
// Coordinates in xyz are assumed to be ordered as [X, Y, Z]
// where X is the list of x-coordinates for all points and so on.
// conn: connectivity of the target surface elements
// xi: surface reference cooridnates for the cloest point, involves a linear transformation from [0,1] to [-1,1]
void FindPointsInMesh(Mesh & mesh, Vector const& xyz, Array<int>& conn,
Vector& xi)
{
const int dim = mesh.Dimension();
const int np = xyz.Size() / dim;
MFEM_VERIFY(np * dim == xyz.Size(), "");
mesh.EnsureNodes();
//FindPointsGSLIB finder(MPI_COMM_WORLD);
FindPointsGSLIB finder;
finder.SetDistanceToleranceForPointsFoundOnBoundary(0.5);
const double bb_t = 0.5;
finder.Setup(mesh, bb_t);
finder.FindPoints(xyz);
/// Return code for each point searched by FindPoints: inside element (0), on
/// element boundary (1), or not found (2).
Array<unsigned int> codes = finder.GetCode();
/// Return element number for each point found by FindPoints.
Array<unsigned int> elems = finder.GetElem();
/// Return reference coordinates for each point found by FindPoints.
Vector refcrd = finder.GetReferencePosition();
/// Return distance between the sought and the found point in physical space,
/// for each point found by FindPoints.
Vector dist = finder.GetDist();
MFEM_VERIFY(dist.Size() == np, "");
MFEM_VERIFY(refcrd.Size() == np * dim, "");
MFEM_VERIFY(elems.Size() == np, "");
MFEM_VERIFY(codes.Size() == np, "");
bool allfound = true;
for (auto code : codes)
if (code == 2) { allfound = false; }
MFEM_VERIFY(allfound, "A point was not found");
cout << "Maximum distance of projected points: " << dist.Max() << endl;
// extract information
for (int i=0; i<np; ++i)
{
cout << "Point " << i << ": (";
for (int j=0; j<dim; ++j)
{
cout << xyz[i + (j*np)];
if (j == dim-1) {cout << ")" << endl;}
else {cout << ", ";}
}
//cout << " element: " << elems[i] << endl;
//cout << " element " << elems[i] << " vertices:" << endl;
//Array<int> vert;
//mesh.GetElementVertices(elems[i], vert);
//for (auto v : vert)
//{
// cout << " " << v << endl;
//}
/*cout << " reference coordinates: (";
for (int j=0; j<dim; ++j)
{
cout << refcrd[(i*dim) + j];
if (j == dim-1)
{
cout << ")" << endl;
}
else
{
cout << ", ";
}
}*/
int refFace, refNormal, refNormalSide;
bool is_interior = -1;
Vector normal = GetNormalVector(mesh, elems[i], refcrd.GetData() + (i*dim),
refFace, refNormal, is_interior);
int phyFace;
if (is_interior)
{
phyFace = -1; // the id of the face that has the closest point
FindSurfaceToProject(mesh, elems[i], phyFace);
Array<int> cbdrVert;
mesh.GetFaceVertices(phyFace, cbdrVert);
Vector xs(dim);
xs[0] = xyz[i + 0*np];
xs[1] = xyz[i + 1*np];
xs[2] = xyz[i + 2*np];
Vector xi_tmp(dim-1);
// get nodes!
GridFunction *nodes = mesh.GetNodes();
DenseMatrix coords(4,3);
for (int i=0; i<4; i++)
{
for (int j=0; j<3; j++)
{
coords(i,j) = (*nodes)[cbdrVert[i]*3+j];
}
}
SlaveToMaster(coords, xs, xi_tmp);
for (int j=0; j<dim-1; ++j)
{
xi[i*(dim-1)+j] = xi_tmp[j];
}
// now get get the projection to the surface
}
else
{
Vector faceRefCrd(dim-1);
{
int fd = 0;
for (int j=0; j<dim; ++j)
{
if (j == refNormal)
{
refNormalSide = (refcrd[(i*dim) + j] > 0.5);
}
else
{
faceRefCrd[fd] = refcrd[(i*dim) + j];
fd++;
}
}
MFEM_VERIFY(fd == dim-1, "");
}
for (int j=0; j<dim-1; ++j)
{
xi[i*(dim-1)+j] = faceRefCrd[j]*2.0 - 1.0;
}
//cout << " face reference coordinates: (";
for (int j=0; j<dim-1; ++j)
{
cout << faceRefCrd[j];
if (j == dim-2) {cout << ")" << endl;}
else {cout << ", ";}
}
}
//cout << " normal vector: ";
//normal.Print();
// ask, does this do anything?
/*
IntegrationPoint ip;
ip.Set(refcrd.GetData() + (i*dim), dim);
ElementTransformation *trans = mesh.GetElementTransformation(elems[i]);
Vector phys(trans->GetSpaceDim());
trans->Transform(ip, phys);
cout << " physical coordinates: ";
phys.Print();
*/
// Get the element face
Array<int> faces;
Array<int> ori;
int face;
if (is_interior)
{
face = phyFace;
}
else
{
mesh.GetElementFaces(elems[i], faces, ori);
face = faces[refFace];
}
Array<int> faceVert;
mesh.GetFaceVertices(face, faceVert);
//cout << " face " << face << " vertices:" << endl;
//for (auto v : faceVert){ cout << " " << v << endl;}
for (int p=0; p<4; p++)
{
conn[4*i+p] = faceVert[p];
}
/*
Vector ref(dim);
for (int p=0; p<2; ++p)
for (int q=0; q<2; ++q)
{
const int refv = GetHexVertex(refNormal, refNormalSide, p, q, ref);
cout << " face reference vertex (" << p << "," << q
<< ") is global vertex " << vert[refv] << endl;
{
// Sanity check
ip.Set(ref.GetData(), dim);
trans->Transform(ip, phys);
for (int j=0; j<dim; ++j)
{
phys[j] -= mesh.GetVertex(vert[refv])[j];
}
phys.Print();
cout<<vert[refv]<<endl;
cout<<mesh.GetVertex(vert[refv])[0]<<endl;
cout<<mesh.GetVertex(vert[refv])[1]<<endl;
cout<<mesh.GetVertex(vert[refv])[2]<<endl;
MFEM_VERIFY(phys.Norml2() < 1.0e-12, "Sanity check failed");
}
}*/
}
}
int main(int argc, char *argv[])
{
// 1. Parse command-line options.
const char *mesh_file1 = "block1.mesh";
const char *mesh_file2 = "block2.mesh";
Array<int> attr;
Array<int> m_attr;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file1, "-m1", "--mesh1",
"First mesh file to use.");
args.AddOption(&mesh_file2, "-m2", "--mesh2",
"Second mesh file to use.");
args.AddOption(&attr, "-at", "--attributes-surf",
"Attributes of boundary faces on contact surface for mesh 2.");
args.Parse();
if (!args.Good())
{
args.PrintUsage(cout);
return 1;
}
args.PrintOptions(cout);
Mesh mesh1(mesh_file1, 1, 1);
Mesh mesh2(mesh_file2, 1, 1);
const int dim = mesh1.Dimension();
MFEM_VERIFY(dim == mesh2.Dimension(), "");
// boundary attribute 2 is the potential contact surface of nodes
attr.Append(2);
// boundary attribute 2 is the potential contact surface for master surface
m_attr.Append(2);
// Define a finite element space on the mesh. Here we use vector finite
// elements, i.e. dim copies of a scalar finite element space. The vector
// dimension is specified by the last argument of the FiniteElementSpace
// constructor.
FiniteElementCollection *fec1;
FiniteElementSpace *fespace1;
fec1 = new H1_FECollection(1, dim);
fespace1 = new FiniteElementSpace(&mesh1, fec1, dim, Ordering::byVDIM);
cout << "Number of finite element unknowns for mesh1: "
<< fespace1->GetTrueVSize() << endl;
mesh1.SetNodalFESpace(fespace1);
GridFunction nodes0 = *mesh1.GetNodes(); // undeformed mesh1 nodal grid function
GridFunction *nodes1 = mesh1.GetNodes();
FiniteElementCollection *fec2 = new H1_FECollection(1, dim);
FiniteElementSpace *fespace2 = new FiniteElementSpace(&mesh2, fec2, dim,
Ordering::byVDIM);
cout << "Number of finite element unknowns for mesh2: "
<< fespace2->GetTrueVSize() << endl;
// degrees of freedom of both meshes
int ndof_1 = fespace1->GetTrueVSize();
int ndof_2 = fespace2->GetTrueVSize();
int ndofs = ndof_1 + ndof_2;
// number of nodes for each mesh
int nnd_1 = mesh1.GetNV();
int nnd_2 = mesh2.GetNV();
int nnd = nnd_1 + nnd_2;
// Determine the list of true (i.e. conforming) essential boundary dofs.
// In this example, the boundary conditions are defined by marking only
// boundary attribute 1 from the mesh as essential and converting it to a
// list of true dofs.
Array<int> ess_tdof_list1, ess_bdr1(mesh1.bdr_attributes.Max());
cout<<mesh1.bdr_attributes.Max()<<endl;
ess_bdr1 = 0;
//ess_bdr1[0] = 1;
// Not ready to be passed on yet
// fespace->GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
Array<int> ess_tdof_list2, ess_bdr2(mesh2.bdr_attributes.Max());
ess_bdr2 = 0;
//ess_bdr2[0] = 1;
// Define the displacement vector x as a finite element grid function
// corresponding to fespace. GridFunction is a derived class of Vector.
GridFunction x1(fespace1);
x1 = 0.0;
GridFunction x2(fespace2);
x2 = 0.0;
// Generate force
LinearForm *b1 = new LinearForm(fespace1);
b1->Assemble();
LinearForm *b2 = new LinearForm(fespace2);
b2->Assemble();
// Set up the bilinear form a(.,.) on the finite element space
// corresponding to the linear elasticity integrator with piece-wise
// constants coefficient lambda and mu.
Vector lambda1(mesh1.attributes.Max());
lambda1 = 57.6923076923;
PWConstCoefficient lambda1_func(lambda1);
Vector mu1(mesh1.attributes.Max());
mu1 = 38.4615384615;
PWConstCoefficient mu1_func(mu1);
BilinearForm *a1 = new BilinearForm(fespace1);
a1->AddDomainIntegrator(new ElasticityIntegrator(lambda1_func,mu1_func));
Vector lambda2(mesh2.attributes.Max());
lambda2 = 57.6923076923;
PWConstCoefficient lambda2_func(lambda2);
Vector mu2(mesh2.attributes.Max());
mu2 = 38.4615384615;
PWConstCoefficient mu2_func(mu2);
BilinearForm *a2 = new BilinearForm(fespace2);
a2->AddDomainIntegrator(new ElasticityIntegrator(lambda2_func,mu2_func));
a1->Assemble();
SparseMatrix A1;
Vector B1, X1;
a1->FormLinearSystem(ess_tdof_list1, x1, *b1, A1, X1, B1);
a2->Assemble();
SparseMatrix A2;
Vector B2, X2;
a2->FormLinearSystem(ess_tdof_list2, x2, *b2, A2, X2, B2);
// Combine elasticity operator for two meshes into one.
// Block Matrix
SparseMatrix K(ndofs,ndofs);
for (int i=0; i<A1.Height(); i++)
{
Array<int> col_tmp;
Vector v_tmp;
col_tmp = 0;
v_tmp = 0.0;
A1.GetRow(i, col_tmp, v_tmp);
K.SetRow(i, col_tmp, v_tmp);
}
for (int i=0; i<A2.Height(); i++)
{
Array<int> col_tmp;
Vector v_tmp;
col_tmp = 0;
v_tmp = 0.0;
A2.GetRow(i, col_tmp, v_tmp);
for (int j=0; j<col_tmp.Size(); j++)
{
col_tmp[j] += ndof_1;
}
K.SetRow(i+ndof_1, col_tmp, v_tmp); // mesh1 top left corner
}
// Construct node to segment contact constraint.
attr.Sort();
cout << "Boundary attributes for contact surface faces in mesh 2" << endl;
for (auto a : attr)
{
cout << a << endl;
}
Array<int> bdryFaces2; // TODO: remove this?
std::set<int> bdryVerts2;
for (int b=0; b<mesh2.GetNBE(); ++b)
{
if (attr.FindSorted(mesh2.GetBdrAttribute(b)) >= 0)
{
bdryFaces2.Append(b);
Array<int> vert;
mesh2.GetBdrElementVertices(b, vert);
for (auto v : vert)
{
bdryVerts2.insert(v);
}
}
}
int npoints = bdryVerts2.size();
Array<int> s_conn(npoints); // connectivity of the second/slave mesh
Vector xyz(dim * npoints);
xyz = 0.0;
cout << "Boundary vertices for contact surface vertices in mesh 2" << endl;
// construct the nodal coordinates on mesh2 to be projected, including displacement
int count = 0;
for (auto v : bdryVerts2)
{
cout << v << ": " << mesh2.GetVertex(v)[0] << ", "
<< mesh2.GetVertex(v)[1] << ", "
<< mesh2.GetVertex(v)[2] << endl;
for (int i=0; i<dim; ++i)
{
xyz[count + (i * npoints)] = mesh2.GetVertex(v)[i] + x2[v*dim+i];
}
s_conn[count] = v + nnd_1; // dof1 is the master
count++;
}
MFEM_VERIFY(count == npoints, "");
// gap function
Vector g(npoints*dim);
g = -1.0;
// segment reference coordinates of the closest point
Vector m_xi(npoints*(dim-1));
m_xi = -1.0;
Vector xs(dim*npoints);
xs = 0.0;
for (int i=0; i<npoints; i++)
{
for (int j=0; j<dim; j++)
{
xs[i*dim+j] = xyz[i + (j*npoints)];
}
}
Array<int> m_conn(
npoints*4); // only works for linear elements that have 4 vertices!
DenseMatrix coordsm(npoints*4, dim);
// adding displacement to mesh1 using a fixed grid function from mesh1
x1 = 1e-4; // x1 order: [xyz xyz... xyz]
add(nodes0, x1, *nodes1);
FindPointsInMesh(mesh1, xyz, m_conn, m_xi);
for (int i=0; i<npoints; i++)
{
for (int j=0; j<4; j++)
{
for (int k=0; k<dim; k++)
{
coordsm(i*4+j,k) = mesh1.GetVertex(m_conn[i*4+j])[k]+x1[dim*m_conn[i*4+j]+k];
}
}
}
//coordsm.Print();
SparseMatrix M(nnd,ndofs);
std::vector<SparseMatrix> dM(nnd, SparseMatrix(ndofs,ndofs));
Assemble_Contact(nnd, npoints, ndofs, xs, m_xi, coordsm,
s_conn, m_conn, g, M, dM);
//M.Print();
/*Vector eps(ndofs);
Vector sol(ndofs); sol = 0.;
for(int i=0;i<ndofs;i++) eps[i] = 1e-5 * i ;
for(int i=0;i<9;i++)
{
cout<<i<<endl;
dM[s_conn[i]].Mult(eps,sol);
sol.Print();
}
*/
return 0;
}
File diff suppressed because it is too large Load Diff
+230
View File
@@ -0,0 +1,230 @@
// Contact example
//
// Compile with: make exContactBlockTL
//
// Sample runs: ./exContactBlockTL -m1 block1.mesh -m2 block2.mesh -at "5 6 7 8"
// Sample runs: ./exContactBlockTL -m1 block1_d.mesh -m2 block2_d.mesh -at "5 6 7 8"
#ifndef EXCONTACTBLOCKTL_HPP
#define EXCONTACTBLOCKTL_HPP
#include "mfem.hpp"
#include "IpTNLP.hpp"
using namespace std;
using namespace mfem;
using namespace Ipopt;
class ExContactBlockTL: public TNLP
{
public:
/** default constructor */
ExContactBlockTL(int argc, char *argv[]);
/** default destructor */
virtual ~ExContactBlockTL();
/**@name Overloaded from TNLP */
/** Method to return some info about the nlp */
virtual bool get_nlp_info(
Index& n,
Index& m,
Index& nnz_jac_g,
Index& nnz_h_lag,
IndexStyleEnum& index_style
);
/** Method to return the bounds for my problem */
virtual bool get_bounds_info(
Index n,
Number* x_l,
Number* x_u,
Index m,
Number* g_l,
Number* g_u
);
/** Method to return the starting point for the algorithm */
virtual bool get_starting_point(
Index n,
bool init_x,
Number* x,
bool init_z,
Number* z_L,
Number* z_U,
Index m,
bool init_lambda,
Number* lambda
);
/** Method to return the objective value */
virtual bool eval_f(
Index n,
const Number* x,
bool new_x,
Number& obj_value
);
/** Method to return the gradient of the objective */
virtual bool eval_grad_f(
Index n,
const Number* x,
bool new_x,
Number* grad_f
);
/** Method to return the constraint residuals */
virtual bool eval_g(
Index n,
const Number* x,
bool new_x,
Index m,
Number* cons
);
/** Method to return:
* 1) The structure of the Jacobian (if "values" is NULL)
* 2) The values of the Jacobian (if "values" is not NULL)
*/
virtual bool eval_jac_g(
Index n,
const Number* x,
bool new_x,
Index m,
Index nele_jac,
Index* iRow,
Index* jCol,
Number* values
);
/** Method to return:
* 1) The structure of the Hessian of the Lagrangian (if "values" is NULL)
* 2) The values of the Hessian of the Lagrangian (if "values" is not NULL)
*/
virtual bool eval_h(
Index n,
const Number* x,
bool new_x,
Number obj_factor,
Index m,
const Number* lambda,
bool new_lambda,
Index nele_hess,
Index* iRow,
Index* jCol,
Number* values
);
/** This method is called when the algorithm is complete so the TNLP can store/write the solution */
virtual void finalize_solution(
SolverReturn status,
Index n,
const Number* x,
const Number* z_L,
const Number* z_U,
Index m,
const Number* g,
const Number* lambda,
Number obj_value,
const IpoptData* ip_data,
IpoptCalculatedQuantities* ip_cq
);
private:
void update_g();
void update_jac();
void update_hess();
private:
/**@name Methods to block default compiler methods.
*
* The compiler automatically generates the following three methods.
* Since the default compiler implementation is generally not what
* you want (for all but the most simple classes), we usually
* put the declarations of these methods in the private section
* and never implement them. This prevents the compiler from
* implementing an incorrect "default" behavior without us
* knowing. (See Scott Meyers book, "Effective C++")
*/
ExContactBlockTL(
const ExContactBlockTL&
);
ExContactBlockTL& operator=(
const ExContactBlockTL&
);
Array<int> attr;
Array<int> m_attr;
Array<int> s_conn; // connectivity of the second/slave mesh
std::string mesh_file1;
std::string mesh_file2;
Mesh* mesh1;
Mesh* mesh2;
FiniteElementCollection* fec1;
FiniteElementCollection* fec2;
FiniteElementSpace* fespace1;
FiniteElementSpace* fespace2;
Array<int> ess_tdof_list1;
Array<int> ess_tdof_list2;
GridFunction nodes0;
GridFunction* nodes1;
GridFunction* nodes2;
GridFunction* x1;
GridFunction* x2;
LinearForm* b1;
LinearForm* b2;
PWConstCoefficient* lambda1_func;
PWConstCoefficient* lambda2_func;
PWConstCoefficient* mu1_func;
PWConstCoefficient* mu2_func;
BilinearForm* a1;
BilinearForm* a2;
mfem::Vector lambda1;
mfem::Vector lambda2;
mfem::Vector mu1;
mfem::Vector mu2;
mfem::Vector xyz;
std::set<int> bdryVerts2;
int dim;
// degrees of freedom of both meshes
int ndof_1;
int ndof_2;
int ndofs;
// number of nodes for each mesh
int nnd_1;
int nnd_2;
int nnd;
int npoints;
SparseMatrix A1;
mfem::Vector B1, X1;
SparseMatrix A2;
mfem::Vector B2, X2;
SparseMatrix* K;
mfem::Vector g;
mfem::Vector m_xi;
mfem::Vector xs;
Array<int> m_conn; // only works for linear elements that have 4 vertices!
DenseMatrix* coordsm;
SparseMatrix* M;
std::vector<SparseMatrix>* dM;
Array<int> Dirichlet_dof;
Array<double> Dirichlet_val;
public:
Mesh * GetMesh1() {return mesh1;}
Mesh * GetMesh2() {return mesh2;}
};
#endif
+68
View File
@@ -0,0 +1,68 @@
# Copyright (c) 2010-2022, 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.
# Use the MFEM build directory
MFEM_DIR ?= ../..
MFEM_BUILD_DIR ?= ../..
SRC = $(if $(MFEM_DIR:../..=),$(MFEM_DIR)/examples/ipopt/,)
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
# Use the MFEM install directory
# MFEM_INSTALL_DIR = ../../mfem
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
MFEM_LIB_FILE = mfem_is_not_built
-include $(CONFIG_MK)
SEQ_EXAMPLES = exContactBlockTL
EXAMPLES = $(SEQ_EXAMPLES)
.SUFFIXES:
.SUFFIXES: .o .cpp .mk
.PHONY: all clean clean-build clean-exec
# Remove built-in rule
%: %.cpp
# Replace the default implicit rule for *.cpp files
%: $(SRC)%.cpp $(MFEM_LIB_FILE) $(CONFIG_MK)
$(MFEM_CXX) $(MFEM_FLAGS) $< -o $@ $(MFEM_LIBS)
all: $(EXAMPLES)
ifeq ($(MFEM_USE_IPOPT),NO)
$(EXAMPLES):
$(error MFEM is not configured with IPOPT)
endif
MFEM_TESTS = EXAMPLES
include $(MFEM_TEST_MK)
# Testing: Parallel vs. serial runs
RUN_MPI = $(MFEM_MPIEXEC) $(MFEM_MPIEXEC_NP) $(MFEM_MPI_NP)
%-test-par: %
@$(call mfem-test,$<, $(RUN_MPI), Parallel example)
%-test-seq: %
@$(call mfem-test,$<,, Serial example)
# Testing: "test" target and mfem-test* variables are defined in config/test.mk
# Generate an error message if the MFEM library is not built and exit
$(MFEM_LIB_FILE):
$(error The MFEM library is not built)
clean: clean-build clean-exec
clean-build:
rm -f *.o *~ $(SEQ_EXAMPLES)
rm -rf *.dSYM *.TVD.*breakpoints
clean-exec:
@rm -f exContactBlockTL.mesh exContactBlockTL-mesh.* exContactBlockTL-init.* exContactBlockTL-final.* ExampleContactBlockTL*
+888
View File
@@ -0,0 +1,888 @@
using namespace std;
using namespace mfem;
void BasisEval(const Vector xi, Vector &N, DenseMatrix &dNdxi) // dNdxi is 2*4
{
N[0] = 0.25*(1-xi[0])*(1-xi[1]);
N[1] = 0.25*(1+xi[0])*(1-xi[1]);
N[2] = 0.25*(1+xi[0])*(1+xi[1]);
N[3] = 0.25*(1-xi[0])*(1+xi[1]);
dNdxi(0,0) = 0.25*(-1+xi[1]);
dNdxi(0,1) = 0.25*(1-xi[1]);
dNdxi(0,2) = 0.25*(1+xi[1]);
dNdxi(0,3) = 0.25*(-1-xi[1]);
dNdxi(1,0) = 0.25*(-1+xi[0]);
dNdxi(1,1) = 0.25*(-1-xi[0]);
dNdxi(1,2) = 0.25*(1+xi[0]);
dNdxi(1,3) = 0.25*(1-xi[0]);
}
void BasisEvalDerivs(const Vector xi, Vector& N, DenseMatrix& dNdxi,
DenseMatrix& dN2dxi)
{
N[0] = 0.25*(1-xi[0])*(1-xi[1]);
N[1] = 0.25*(1+xi[0])*(1-xi[1]);
N[2] = 0.25*(1+xi[0])*(1+xi[1]);
N[3] = 0.25*(1-xi[0])*(1+xi[1]);
dNdxi.SetSize(2,4); dNdxi = 0.0;
dN2dxi.SetSize(3,4);
dN2dxi = 0.0; // first row dxi2, second detadxi, third deta2
dNdxi(0,0) = 0.25*(-1+xi[1]); dNdxi(0,1) = 0.25*(1-xi[1]);
dNdxi(0,2) = 0.25*(1+xi[1]); dNdxi(0,3) = 0.25*(-1-xi[1]);
dNdxi(1,0) = 0.25*(-1+xi[0]); dNdxi(1,1) = 0.25*(-1-xi[0]);
dNdxi(1,2) = 0.25*(1+xi[0]); dNdxi(1,3) = 0.25*(1-xi[0]);
dN2dxi(1,0) = 0.25; dN2dxi(1,1) = -0.25; dN2dxi(1,2) = 0.25;
dN2dxi(1,3) = -0.25;
}
// returns the vector and matrix form of the shape functions and its derivative
void BasisVectorDerivs(const Vector xi, DenseMatrix& N, DenseMatrix& dNdxi,
DenseMatrix& ddNdxi)
{
N.SetSize(3,12); N = 0.0;
N(0,0) = 0.25*(1-xi[0])*(1-xi[1]); N(0,3) = 0.25*(1+xi[0])*(1-xi[1]);
N(0,6) = 0.25*(1+xi[0])*(1+xi[1]); N(0,9) = 0.25*(1-xi[0])*(1+xi[1]);
N(1,1) = 0.25*(1-xi[0])*(1-xi[1]); N(1,4) = 0.25*(1+xi[0])*(1-xi[1]);
N(1,7) = 0.25*(1+xi[0])*(1+xi[1]); N(1,10) = 0.25*(1-xi[0])*(1+xi[1]);
N(2,2) = 0.25*(1-xi[0])*(1-xi[1]); N(2,5) = 0.25*(1+xi[0])*(1-xi[1]);
N(2,8) = 0.25*(1+xi[0])*(1+xi[1]); N(2,11) = 0.25*(1-xi[0])*(1+xi[1]);
dNdxi.SetSize(3*2, 3*4); dNdxi = 0.0;
dNdxi(0,0) = 0.25*(-1+xi[1]); dNdxi(0,3) = 0.25*(1-xi[1]);
dNdxi(0,6) = 0.25*(1+xi[1]); dNdxi(0,9) = 0.25*(-1-xi[1]);
dNdxi(1,1) = 0.25*(-1+xi[1]); dNdxi(1,4) = 0.25*(1-xi[1]);
dNdxi(1,7) = 0.25*(1+xi[1]); dNdxi(1,10) = 0.25*(-1-xi[1]);
dNdxi(2,2) = 0.25*(-1+xi[1]); dNdxi(2,5) = 0.25*(1-xi[1]);
dNdxi(2,8) = 0.25*(1+xi[1]); dNdxi(2,11) = 0.25*(-1-xi[1]);
dNdxi(3,0) = 0.25*(-1+xi[0]); dNdxi(3,3) = 0.25*(-1-xi[0]);
dNdxi(3,6) = 0.25*(1+xi[0]); dNdxi(3,9) = 0.25*(1-xi[0]);
dNdxi(4,1) = 0.25*(-1+xi[0]); dNdxi(4,4) = 0.25*(-1-xi[0]);
dNdxi(4,7) = 0.25*(1+xi[0]); dNdxi(4,10) = 0.25*(1-xi[0]);
dNdxi(5,2) = 0.25*(-1+xi[0]); dNdxi(5,5) = 0.25*(-1-xi[0]);
dNdxi(5,8) = 0.25*(1+xi[0]); dNdxi(5,11) = 0.25*(1-xi[0]);
ddNdxi.SetSize(3*4, 3*4); ddNdxi = 0.0;
ddNdxi(3,0) = 0.25; ddNdxi(3,3) = -0.25;
ddNdxi(3,6) = 0.25; ddNdxi(3,9) = -0.25;
ddNdxi(4,1) = 0.25; ddNdxi(4,4) = -0.25;
ddNdxi(4,7) = 0.25; ddNdxi(4,10) = -0.25;
ddNdxi(5,2) = 0.25; ddNdxi(5,5) = -0.25;
ddNdxi(5,8) = 0.25; ddNdxi(5,11) = -0.25;
ddNdxi(6,0) = 0.25; ddNdxi(6,3) = -0.25;
ddNdxi(6,6) = 0.25; ddNdxi(6,9) = -0.25;
ddNdxi(7,1) = 0.25; ddNdxi(7,4) = -0.25;
ddNdxi(7,7) = 0.25; ddNdxi(7,10) = -0.25;
ddNdxi(8,2) = 0.25; ddNdxi(8,5) = -0.25;
ddNdxi(8,8) = 0.25; ddNdxi(8,11) = -0.25;
}
void cross(const Vector a, const Vector b, Vector& c)
{
assert(a.Size()==3);
c.SetSize(3);
c[0] = a[1]*b[2] - a[2]*b[1];
c[1] = -a[0]*b[2] + b[0]*a[2];
c[2] = a[0]*b[1] - a[1]*b[0];
}
// a outer b
void outer(const Vector a, const Vector b, DenseMatrix& c)
{
int m = a.Size();
int n = b.Size();
assert(c.Height()==m);
assert(c.Width() ==n);
for (int i=0; i<m; i++)
{
for (int j=0; j<n; j++)
{
c(i,j) = a[i]*b[j];
}
}
}
// dphidxi 2*4
// coords 4*3
void ComputeNormal(const DenseMatrix& dphidxi, const DenseMatrix& coords,
Vector& normal, double& nnorm)
{
DenseMatrix dxdxi(2,3);
Mult(dphidxi, coords, dxdxi);
Vector dxdxi1(3);
Vector dxdxi2(3);
dxdxi.GetRow(0,dxdxi1);
dxdxi.GetRow(1,dxdxi2);
cross(dxdxi1, dxdxi2, normal); // is there a cross product? no
// VectorCrossProductCoefficient::Eval has hard-coded cross product
nnorm = normal.Norml2( );
normal /= nnorm;
}
void SlaveToMaster(const DenseMatrix& m_coords, const Vector& s_x, Vector& xi)
{
bool converged = false;
bool pt_on_elem = false;
int dim = 3;
xi.SetSize(dim-1);
xi = 0.0;
double r = 1e10;
int max_iter = 15;
double off_el_xi = 1e-2;
double proj_newton_tol = 1e-13;
double proj_max_gap = 0.5;
Vector gap_v(dim);
// warm start from linear solution
for (int it=0; it<max_iter; it++)
{
//cout<<it<<endl;
Vector m_N(4);
m_N = 0.;
DenseMatrix m_dN(2,4);
m_dN = 0.;
DenseMatrix m_dN2(3,4);
m_dN2 = 0.;
BasisEvalDerivs(xi, m_N, m_dN, m_dN2);
Vector x_c(dim);
m_coords.MultTranspose(m_N, x_c);
gap_v = s_x;
gap_v -= x_c;
DenseMatrix m_dx(2,3);
m_dx = 0.;
Mult(m_dN, m_coords, m_dx);
Vector r(dim-1);
r = 0.0;
m_dx.Mult(gap_v, r);
if (r.Normlinf() < proj_newton_tol)
{
converged = true;
break;
}
DenseMatrix drdxi(dim-1,dim-1);
drdxi = 0.;
MultABt(m_dx, m_dx, drdxi); // m_dx * m_dx.T
drdxi *= -1.0;
DenseMatrix m_dx2(3,3); m_dx2 = 0.0;
Mult(m_dN2,m_coords, m_dx2);
//m_d2x = m_dN(:,:,2) * m_elem_coords(1:4,:); //m_dN(:,:,2) is 3*4
for (int d=0; d<3; d++)
{
DenseMatrix Mtemp(2,2); Mtemp = 0.0;
Mtemp(0,0) = m_dx2(0,d); Mtemp(0,1) = m_dx2(1,d);
Mtemp(1,0) = m_dx2(1,d); Mtemp(1,1) = m_dx2(2,d);
drdxi.Add(gap_v[d], Mtemp);
}
//cond_num = rcond(drdxi); condition number?
//drdxi.TestInversion();
DenseMatrixInverse drdxi_inv(drdxi);
Vector xi_tmp(dim-1);
drdxi_inv.Mult(r,xi_tmp);
xi -= xi_tmp;
}
if (!converged)
{
xi = 0.0;
}
off_el_xi += 1 ; // tolerance of offset of xi outside [-1,1]
//cout<<gap_v.Norml2()<<" " <<xi.Normlinf()<<endl;
if (gap_v.Norml2() < proj_max_gap && xi.Normlinf() <= off_el_xi)
{
pt_on_elem = true;
}
MFEM_VERIFY(pt_on_elem == true, "xi went out of bounds");
MFEM_VERIFY(converged == true, "projection didn't converge");
}
// m_coords is expected to be 4 * 3
void ComputeGapJacobian(const Vector x_s, const Vector xi,
const DenseMatrix m_coords,
double& gap, Vector& normal, Vector& dgdxm, Vector& dgdxs)
{
Vector m_N(4);
DenseMatrix m_dN(2,4);
DenseMatrix m_dN2(3,4);
BasisEvalDerivs(xi, m_N, m_dN, m_dN2);
Vector x_c(3);
m_coords.MultTranspose(m_N, x_c);
Vector gap_v(3); gap_v = 0.0;
gap_v = x_s;
gap_v -= x_c;
DenseMatrix m_dx(2,3);
Mult(m_dN, m_coords, m_dx);
double nnorm = 0;
ComputeNormal(m_dN, m_coords, normal, nnorm);
gap = gap_v * normal; // gap function value, dot product between vectors
//dr_dx = zeros(2,4,3); % nsegment, nodes in quad, ndim
DenseMatrix dr_dx_res1(4,3); dr_dx_res1 = 0.;
DenseMatrix dr_dx_res2(4,3); dr_dx_res2 = 0.;
Vector m_dxrow1(3);
m_dx.GetRow(0, m_dxrow1);
outer(m_N, m_dxrow1, dr_dx_res1);// 4*1 times 1*3
dr_dx_res1 *= -1.0;
Vector m_dxrow2(3);
m_dx.GetRow(1, m_dxrow2);
outer(m_N, m_dxrow2, dr_dx_res2);// 4*1 times 1*3
dr_dx_res2 *= -1.0;
Vector m_dNrow1(4); m_dN.GetRow(0, m_dNrow1);
Vector m_dNrow2(4); m_dN.GetRow(1, m_dNrow2);
DenseMatrix dr_dx_res1_tmp(4,3); dr_dx_res1_tmp = 0.;
DenseMatrix dr_dx_res2_tmp(4,3); dr_dx_res2_tmp = 0.;
outer(m_dNrow1, gap_v, dr_dx_res1_tmp);// 4*1 times 1*3
outer(m_dNrow2, gap_v, dr_dx_res2_tmp);// 4*1 times 1*3
dr_dx_res1 += dr_dx_res1_tmp; // outer product in vector?
dr_dx_res2 += dr_dx_res2_tmp;
DenseMatrix K_dxidx1(2,2); // 2*2
K_dxidx1 = 0.;
MultABt(m_dx, m_dx, K_dxidx1); // m_dx * m_dx.T
Vector v_dxidx2(4);
m_coords.Mult(gap_v, v_dxidx2); // m_coords * gap_v; // 4*3 * 3 = 4
DenseMatrix K_dxidx2(2,2); K_dxidx2 = 0.0;
Vector m_dN2row1(4); m_dN2.GetRow(0, m_dN2row1);
Vector m_dN2row2(4); m_dN2.GetRow(1, m_dN2row2);
Vector m_dN2row3(4); m_dN2.GetRow(2, m_dN2row3);
// how to get 2nd order? multidimensional matrix?
K_dxidx2(0,0) = m_dN2row1 * v_dxidx2; // how would 4*1 * 1*4 be computed?
K_dxidx2(0,1) = m_dN2row2 * v_dxidx2;
K_dxidx2(1,0) = m_dN2row2 * v_dxidx2;
K_dxidx2(1,1) = m_dN2row3 * v_dxidx2;
DenseMatrix K_dxidx(2,2);
K_dxidx -= K_dxidx1;
K_dxidx += K_dxidx2;
// resize the vectors and matrices
Vector dxidx(24); dxidx = 0.0;
Vector drdx_r(24); drdx_r = 0.0;
for (int i=0; i<4; i++)
{
for (int j=0; j<3; j++)
{
drdx_r[4*j+i] = dr_dx_res1(i,j);
drdx_r[4*j+i+12] = dr_dx_res2(i,j);
}
}
//drdx_r(1:4*3,1) = reshape(dr_dx_res(:,:,1),4*3,1);
//drdx_r(4*3+1:2*4*3,1) = reshape(dr_dx_res(:,:,2),4*3,1);
DenseMatrix drdx_K(24,24); drdx_K = 0.;
for (int i =0; i<12; i++)
{
drdx_K(i,i) = K_dxidx(0,0);
drdx_K(i,12+i) = K_dxidx(0,1);
drdx_K(12+i,i) = K_dxidx(1,0);
drdx_K(12+i,12+i) = K_dxidx(1,1);
}
DenseMatrixInverse drdxK_inv(drdx_K);
drdxK_inv.Mult(drdx_r,dxidx);
// LinearSolve (drdx_K,drdx_r, dxidx) ; //???
dxidx *= -1.0;
Vector drdxs_r(6);
drdxs_r[0] = m_dx(0,0); drdxs_r[1] = m_dx(0,1); drdxs_r[2] = m_dx(0,2);
drdxs_r[3] = m_dx(1,0); drdxs_r[4] = m_dx(1,1); drdxs_r[5] = m_dx(1,2);
DenseMatrix drdxs_K(6,6); drdxs_K = 0.;
for (int i=0; i<3; i++)
{
drdxs_K(i,i) = K_dxidx(0,0);
drdxs_K(i,3+i) = K_dxidx(0,1);
drdxs_K(i+3,i) = K_dxidx(1,0);
drdxs_K(i+3,i+3) = K_dxidx(1,1);
}
Vector dxidxs(6); dxidxs = 0.0;
DenseMatrixInverse drdxsK_inv(drdxs_K);
drdxsK_inv.Mult(drdxs_r,dxidxs);
dxidxs *= -1.0;
//dxidxs = -drdxs_K\drdxs_r;
//dxidx = reshape(dxidx, 4,3,2); dxidxs = reshape(dxidxs, 1,3,2);
dgdxm.SetSize(12); dgdxm = 0.;
DenseMatrix dgdxm_tmp(4,3);
outer(m_N, normal,dgdxm_tmp);
for (int i=0; i<4; i++)
{
for (int j=0; j<3; j++)
{
dgdxm[3*i+j] = -dgdxm_tmp(i,j);
}
}
//dxidx_M = -m_dN(1:2,:,1) * (m_coords(1:4,:)*normal'); % this turns out to be 0
dgdxs.SetSize(3);
dgdxs += normal;
//dgdxs = dgdxs + dxidx_M(1) * dxidxs(:,:,1) + dxidx_M(2) * dxidxs(:,:,2);
};
void ComputeGapHessian(const Vector x_s, const Vector xi,
const DenseMatrix m_coords,
DenseMatrix& dg2dx)
{
Vector m_N(4);
DenseMatrix m_dN(2,4);
DenseMatrix m_dN2(3,4);
BasisEvalDerivs(xi, m_N, m_dN, m_dN2);
int dim = 3;
int num_dofs1 = dim;
int num_dofs2 = 4*dim;
int num_dofs = num_dofs1 + num_dofs2;
dg2dx.SetSize(num_dofs,num_dofs); dg2dx = 0.0;
Vector x_c(3);
m_coords.MultTranspose(m_N,x_c);
Vector gap_v(3); gap_v = 0.0;
gap_v = x_s;
gap_v -= x_c;
DenseMatrix m_dx(2,3);
Mult(m_dN, m_coords, m_dx);
DenseMatrix m_dx2(3,3); m_dx2 = 0.0;
Mult(m_dN2,m_coords, m_dx2);
double nnorm = 0.0;
Vector normal(3); normal = 0.0;
ComputeNormal(m_dN, m_coords, normal, nnorm);
double gap = gap_v * normal; // gap function value, dot product between vectors
DenseMatrix M(2,2); M = 0.0;
MultABt(m_dx, m_dx, M);
DenseMatrix f(2, num_dofs2); f = 0.0;
for (int d=0; d<3; d++)
{
DenseMatrix Mtemp(2,2); Mtemp = 0.0;
Mtemp(0,0) = m_dx2(0,d); Mtemp(0,1) = m_dx2(1,d);
Mtemp(1,0) = m_dx2(1,d); Mtemp(1,1) = m_dx2(2,d);
M.Add(-gap_v[d], Mtemp);
Vector m_dxcol(2); m_dx.GetColumn(d, m_dxcol);
DenseMatrix ftmp(2,4);
outer(m_dxcol, m_N, ftmp);
ftmp *= -1;
ftmp.Add( gap_v[d], m_dN); // 2*4
for (int j=0; j<4; j++)
{
assert(d+3*j<num_dofs2);
f(0,d+j*3) = ftmp(0,j);
f(1,d+j*3) = ftmp(1,j);
}
}
//fprintf('hess dxidxm\n');
DenseMatrixInverse Minv(M);
DenseMatrix dxidxm(2,num_dofs2); dxidxm = 0.0;
Minv.Mult(f, dxidxm);
//LinearSolve??
//dxidxm = M\f;
DenseMatrix nde2(2,2); nde2 = 0.0;
DenseMatrix Nndx2(2,num_dofs2); Nndx2 = 0.0;
for (int d=0; d<3; d++)
{
DenseMatrix ndetmp(2,2); ndetmp = 0.0;
ndetmp(0,0) = normal(d)*m_dx2(0,d); ndetmp(0,1) = normal(d)*m_dx2(1,d);
ndetmp(1,0) = normal(d)*m_dx2(1,d); ndetmp(1,1) = normal(d)*m_dx2(2,d);
nde2 += ndetmp;
for (int j=0; j<4; j++)
{
assert(d+3*j<num_dofs2);
Nndx2(0,d+j*3) = normal[d]*m_dN(0,j);
Nndx2(1,d+j*3) = normal[d]*m_dN(1,j);
}
}
DenseMatrix Ndn(2,num_dofs2); Ndn = 0.0;
Ndn += Nndx2;
AddMult(nde2, dxidxm, Ndn);
DenseMatrix M2(2,2); M2 = 0.0;
MultABt(m_dx, m_dx, M2);
DenseMatrixInverse M2inv(M2);
DenseMatrix diag2(2,2); diag2(0,0) = 1.0; diag2(1,1) = 1.0;
DenseMatrix m_con(2,2); m_con = 0.0;
M2inv.Mult(diag2, m_con);
DenseMatrix dg2dxm(num_dofs2, num_dofs2); dg2dxm = 0.0;
DenseMatrix dg2dxm_tmp(num_dofs2,2); dg2dxm_tmp = 0.0;
MultAtB(Ndn, m_con, dg2dxm_tmp);
Mult(dg2dxm_tmp, Ndn, dg2dxm);
dg2dxm *= gap;
DenseMatrix dg2dxm_tmp2(num_dofs2,num_dofs2); dg2dxm_tmp2 = 0.0;
MultAtB(Nndx2, dxidxm, dg2dxm_tmp2);
dg2dxm.Add(-1.0, dg2dxm_tmp2);
dg2dxm_tmp = 0.0;
MultAtB(dxidxm, nde2, dg2dxm_tmp);
AddMult_a(-1.0, dg2dxm_tmp, dxidxm, dg2dxm);
dg2dxm_tmp2 = 0.0;
MultAtB(dxidxm, Nndx2, dg2dxm_tmp2);
dg2dxm.Add(-1.0, dg2dxm_tmp2);
Vector v_dxidx2(4);
m_coords.Mult(gap_v, v_dxidx2); // m_coords * gap_v; // 4*3 * 3 = 4
DenseMatrix K_dxidx2(2,2); K_dxidx2 = 0.0;
Vector m_dN2row1(4); m_dN2.GetRow(0, m_dN2row1);
Vector m_dN2row2(4); m_dN2.GetRow(1, m_dN2row2);
Vector m_dN2row3(4); m_dN2.GetRow(2, m_dN2row3);
K_dxidx2(0,0) = m_dN2row1 * v_dxidx2; // how would 4*1 * 1*4 be computed?
K_dxidx2(0,1) = m_dN2row2 * v_dxidx2;
K_dxidx2(1,0) = m_dN2row2 * v_dxidx2;
K_dxidx2(1,1) = m_dN2row3 * v_dxidx2;
DenseMatrix K_dxidx(2,2);
K_dxidx -= M2;
K_dxidx += K_dxidx2;
Vector drdxs_r(6);
drdxs_r[0] = m_dx(0,0); drdxs_r[1] = m_dx(0,1); drdxs_r[2] = m_dx(0,2);
drdxs_r[3] = m_dx(1,0); drdxs_r[4] = m_dx(1,1); drdxs_r[5] = m_dx(1,2);
DenseMatrix drdxs_K(6,6); drdxs_K = 0.;
for (int i=0; i<3; i++)
{
drdxs_K(i,i) = K_dxidx(0,0);
drdxs_K(i,3+i) = K_dxidx(0,1);
drdxs_K(i+3,i) = K_dxidx(1,0);
drdxs_K(i+3,i+3) = K_dxidx(1,1);
}
Vector dxidxs(6);
DenseMatrixInverse drdxsK_inv(drdxs_K);
drdxsK_inv.Mult(drdxs_r,dxidxs);
dxidxs *= -1.0;
//dxidxs = -drdxs_K\drdxs_r;
DenseMatrix dxidxs_m(2,3); dxidxs_m = 0.0;
dxidxs_m(0,0) = dxidxs[0]; dxidxs_m(0,1) = dxidxs[1]; dxidxs_m(0,2) = dxidxs[2];
dxidxs_m(1,0) = dxidxs[3]; dxidxs_m(1,1) = dxidxs[4]; dxidxs_m(1,2) = dxidxs[5];
DenseMatrix dtao1dxs(3,3); dtao1dxs = 0.0;
DenseMatrix dtao2dxs(3,3); dtao2dxs = 0.0;
Vector dxidxs_row1(3); dxidxs_row1 = 0.0; Vector dxidxs_row2(3);
dxidxs_row2 = 0.0;
Vector mdx2_row1(3); mdx2_row1 = 0.0; Vector mdx2_row2(3); mdx2_row2 = 0.0;
Vector mdx2_row3(3); mdx2_row3 = 0.0;
dxidxs_m.GetRow(0,dxidxs_row1);
dxidxs_m.GetRow(1,dxidxs_row2);
m_dx2.GetRow(0,mdx2_row1);
m_dx2.GetRow(1,mdx2_row2);
m_dx2.GetRow(2,mdx2_row3);
DenseMatrix dtaotmp(3,3); dtaotmp = 0.0;
outer(mdx2_row1, dxidxs_row1,dtaotmp);
dtao1dxs += dtaotmp; dtaotmp = 0.0;
outer(mdx2_row2, dxidxs_row1,dtaotmp);
dtao1dxs += dtaotmp; dtaotmp = 0.0;
outer(mdx2_row2, dxidxs_row2, dtaotmp);
dtao2dxs += dtaotmp; dtaotmp = 0.0;
outer(mdx2_row3, dxidxs_row2, dtaotmp);
dtao2dxs += dtaotmp; dtaotmp = 0.0;
DenseMatrix dtaodxs(3,3); dtaodxs = 0.0; //tao = tao1 cross tao2
for (int d=0; d<3; d++)
{
Vector dtao1dxs_tmp(3); dtao1dxs_tmp = 0.0;
dtao1dxs.GetColumn(d,dtao1dxs_tmp);
Vector m_dxrow(3); m_dx.GetRow(1, m_dxrow);
Vector dtaodxs_tmp(3); dtaodxs_tmp = 0.0;
cross(dtao1dxs_tmp, m_dxrow, dtaodxs_tmp);
Vector dtaodxs_tmp2(3); dtaodxs_tmp2 = 0.0;
m_dx.GetRow(0, m_dxrow);
dtao1dxs_tmp = 0.0; // reuse the same vector for dtao2
dtao2dxs.GetColumn(d,dtao1dxs_tmp);
cross(m_dxrow, dtao1dxs_tmp, dtaodxs_tmp2);
dtaodxs_tmp2 += dtaodxs_tmp;
dtaodxs.SetCol(d, dtaodxs_tmp2);
}
DenseMatrix dndxs(3,3); dndxs = 0.0; dndxs += dtaodxs; dndxs *= 1.0/nnorm;
DenseMatrix dndxs_tmp(3,3); dndxs_tmp = 0.0;
outer(normal, normal, dndxs_tmp);
AddMult_a(-1/nnorm, dndxs_tmp, dtaodxs, dndxs);
DenseMatrix dgvdxs(3,3); dgvdxs = 0.0;
MultAtB(m_dx, dxidxs_m, dgvdxs);
dgvdxs *= -1;
for (int d=0; d<3; d++)
{
dgvdxs(d,d) += 1.0;
}
//dxidxs: 2*3
DenseMatrix dg2dxs(3,3); dg2dxs = 0.0;
DenseMatrix dg2dxs_tmp(3,2); dg2dxs_tmp = 0.0;
MultAtB(dxidxs_m, nde2, dg2dxs_tmp);
AddMult_a(-1.0, dg2dxs_tmp, dxidxs_m, dg2dxs);
DenseMatrix dg2dxs_tmp2(3,3); dg2dxs_tmp2 = 0.0;
MultAtB(dgvdxs, dndxs, dg2dxs_tmp2);
dg2dxs += dg2dxs_tmp2;
dg2dxs_tmp2 = 0.0;
MultAtB(dndxs, dndxs_tmp, dg2dxs_tmp2);
AddMult(dg2dxs_tmp2, dgvdxs, dg2dxs);
DenseMatrix Ne(3,12), Be(6,12), dBe(12,12);
BasisVectorDerivs(xi, Ne, Be, dBe);
DenseMatrix dtao1dxm(3,12); dtao1dxm.CopyRows(Be, 0, 2);
DenseMatrix dtao2dxm(3,12); dtao2dxm.CopyRows(Be, 3, 5);
Vector m_coords_v(12);
for (int i=0; i<4; i++)
{
for (int j=0; j<3; j++)
{
m_coords_v[i*3+j] = m_coords(i,j);
}
}
for (int i=0; i<2; i++)
{
Vector dxidxm_tmp(num_dofs2); dxidxm_tmp = 0.0;
dxidxm.GetRow(i,dxidxm_tmp);
DenseMatrix dBe_tmp(3,12);
dBe_tmp.CopyRows(dBe,i*3,(i+1)*3-1);
DenseMatrix dtaodxm_tmp(12,12); dtaodxm_tmp = 0.0;
outer(m_coords_v, dxidxm_tmp, dtaodxm_tmp);
AddMult(dBe_tmp, dtaodxm_tmp, dtao1dxm);
//dtao1dxm += dBe(:,:,i)*reshape(m_coords(1:4,:)',12,1)*reshape(dxidxm(i,:),1,12); % 3*12
dBe_tmp = 0.0;
dBe_tmp.CopyRows(dBe,(i+2)*3,(i+3)*3-1);
AddMult(dBe_tmp, dtaodxm_tmp, dtao2dxm);
}
DenseMatrix dtaodxm(3,12); dtaodxm = 0.0;//tao = tao1 cross tao2
for (int d=0; d<12; d++)
{
Vector dtaodxm_tmp(3); dtaodxm_tmp = 0.0;
Vector dtaodxm_tmp2(3); dtaodxm_tmp2 = 0.0;
Vector tmp1(3); tmp1 = 0.0; dtao1dxm.GetColumn(d,tmp1);
Vector m_dxrow2(3); m_dx.GetRow(1, m_dxrow2);
Vector m_dxrow1(3); m_dx.GetRow(0, m_dxrow1);
Vector tmp2(3); tmp2 = 0.0; dtao2dxm.GetColumn(d,tmp2);
cross(tmp1, m_dxrow2, dtaodxm_tmp);
cross(m_dxrow1,tmp2, dtaodxm_tmp2);
dtaodxm_tmp += dtaodxm_tmp2;
dtaodxm.SetCol(d, dtaodxm_tmp);
}
DenseMatrix dndxm(3,12); dndxm = 0.0;
dndxm += dtaodxm;
dndxm *= 1.0/nnorm;
AddMult_a(-1/nnorm, dndxs_tmp, dtaodxm, dndxm); //dndxs_tmp = normal'*normal
DenseMatrix dgvdxm(3,12); dgvdxm = 0.0;
dgvdxm -= Ne;
for (int i=0; i<2; i++)
{
Vector dxidxm_tmp(num_dofs2); dxidxm_tmp = 0.0;
dxidxm.GetRow(i,dxidxm_tmp);
DenseMatrix Be_tmp(3,12);
Be_tmp.CopyRows(Be,i*3,(i+1)*3-1);
DenseMatrix dgvdxm_tmp(12,12); dgvdxm_tmp = 0.0;
outer(m_coords_v, dxidxm_tmp, dgvdxm_tmp);
AddMult_a(-1.0, Be_tmp, dgvdxm_tmp, dgvdxm);
}
DenseMatrix dg2dxsxm(3,12); dg2dxsxm = 0.0;
DenseMatrix dg2dxsxm_tmp(3,3); dg2dxsxm_tmp = 0.0;
MultAtB(dgvdxs, dndxm, dg2dxsxm);
MultAtB(dndxs, dndxs_tmp, dg2dxsxm_tmp);
AddMult(dg2dxsxm_tmp, dgvdxm, dg2dxsxm); // += dndxs'*normal'*normal*dgvdxm;
DenseMatrix dgvdxsxmn(3,12); dgvdxsxmn = 0.0;
DenseMatrix dgvdxsxmn_tmp(3,2); dgvdxsxmn_tmp = 0.0;
MultAtB(dxidxs_m, nde2, dgvdxsxmn_tmp); //dxidxs_m: 2*3
AddMult_a(-1.0, dgvdxsxmn_tmp, dxidxm, dgvdxsxmn);
for (int i =0; i<2; i++)
{
DenseMatrix Be_tmp(3,12);
Be_tmp.CopyRows(Be,i*3,(i+1)*3-1);
Vector dxidxs_row(3); dxidxs_row = 0.0; dxidxs_m.GetRow(i,dxidxs_row);
DenseMatrix dgvdxsxmn_tmp2(3,3); dgvdxsxmn_tmp2 = 0.0;
outer(dxidxs_row, normal, dgvdxsxmn_tmp2);
AddMult_a(-1.0, dgvdxsxmn_tmp2, Be_tmp, dgvdxsxmn);
}
dg2dxsxm += dgvdxsxmn;
DenseMatrix dg2dxmxs(12,3); dg2dxmxs = 0.0;
DenseMatrix dg2dxmxs_tmp(12,3); dg2dxmxs_tmp = 0.0;
MultAtB(dgvdxm, dndxs, dg2dxmxs);
MultAtB(dndxm, dndxs_tmp, dg2dxmxs_tmp);
AddMult(dg2dxmxs_tmp, dgvdxs, dg2dxmxs);
DenseMatrix dgvdxmxsn(12,3); dgvdxmxsn = 0.0;
DenseMatrix dgvdxmxsn_tmp(12,2); dgvdxmxsn_tmp = 0.0;
MultAtB(dxidxm, nde2, dgvdxmxsn_tmp);
dgvdxmxsn_tmp *= -1.0;
AddMult(dgvdxmxsn_tmp, dxidxs_m, dgvdxmxsn);
for (int i =0; i<2; i++)
{
DenseMatrix Be_tmp(3,12);
Be_tmp.CopyRows(Be,i*3,(i+1)*3-1);
Be_tmp.Transpose(); // Be is now 12*3
Vector dxidxs_row(3); dxidxs_row = 0.0; dxidxs_m.GetRow(i,dxidxs_row);
DenseMatrix dgvdxmxsn_tmp2(3,3); dgvdxmxsn_tmp2 = 0.0;
outer(normal, dxidxs_row, dgvdxmxsn_tmp2);
AddMult_a(-1.0, Be_tmp, dgvdxmxsn_tmp2, dgvdxmxsn);
}
dg2dxmxs += dgvdxmxsn;
dg2dx.CopyMN(dg2dxs, 0, 0);
dg2dx.CopyMN(dg2dxm, 3, 3);
dg2dx.CopyMN(dg2dxsxm, 0, 3);
dg2dx.CopyMN(dg2dxmxs, 3, 0);
};
void NodeSegConPairs(const Vector x1, const Vector xi2,
const DenseMatrix coords2,
double& node_g, Vector& node_dg, DenseMatrix& node_dg2)
{
double gap = 0.0;
Vector normal(3); normal = 0.0;
Vector dgdxm(12); dgdxm = 0.0;
Vector dgdxs(3); dgdxs = 0.0;
ComputeGapJacobian(x1, xi2, coords2, gap, normal, dgdxm, dgdxs);
node_g = gap;
node_dg.SetSize(12+3);
for (int i=0; i<3; i++) { node_dg[i] = dgdxs[i]; }
for (int i=0; i<12; i++) { node_dg[i+3] = dgdxm[i]; }
DenseMatrix dg2dx(15,15); dg2dx = 0.0;
DenseMatrix dgvdxmxsn(12,3); dgvdxmxsn = 0.0;
ComputeGapHessian(x1, xi2, coords2, dg2dx);
node_dg2.SetSize(15,15);
node_dg2 = dg2dx;
/*
if(obj.space1.conns{e1}(i)==150) % for debugging purpose
v1 = 1:3;
v2 = 1:12;
%v1 = ones(1,3)
%v2 = ones(1,12)
v2 = reshape(v2,4,3);
x1n1 = x1 + 0.01*v1;
coords2n1 = coords2 + 0.001*v2;
[xi2n1, gapv1, ~, ~] = SlaveToMaster(obj, coords2n1, x1n1);
[gapn1, n1,dgdxmn1, dgdxsn1] = ComputeGapJacobian(obj, x1n1, xi2n1, coords2n1);
x1n2 = x1 - 0.01*v1;
coords2n2 = coords2 - 0.001*v2;
[xi2n2, gapv2, ~, ~] = SlaveToMaster(obj, coords2n2, x1n2);
[gapn2, n2,dgdxmn2, dgdxsn2] = ComputeGapJacobian(obj, x1n2, xi2n2, coords2n2);
fprintf('fd\n');
%gapv1-gapv2
[dgdxsn1(:)',dgdxmn1(:)'] - [dgdxsn2(:)',dgdxmn2(:)']
%dgdxsn1-dgdxsn2
fprintf('code\n');
v2n = v2';
%dg2dx(1:3,1:3)*0.04*ones(3,1)
temp = zeros(12,3);
for i = 1:4
temp1 = dg2dx(3+(i-1)*3+1:3+i*3,1:3);
temp((i-1)*3+1:i*3,:) = temp1';
end
temp2 = zeros(3,12);
for i = 1:4
temp3 = dg2dx(1:3,3+(i-1)*3+1:3+i*3);
temp2(:,(i-1)*3+1:i*3) = temp3';
end
%dg2dx
%dg2dx(4:end,1:3) = temp;
%dg2dx(1:3,4:end) = temp2;
%dgvdxm * 0.002*v2n(:)
(dg2dx*[0.02*v1(:)',0.002*v2n(:)']')'
%dg2dx(4:end,1:3)
end*/
};
// coordsm : (npoints*4, 3) use what class?
// m_conn: (npoints*4)
void Assemble_Contact(const int m, const int npoints, const int ndofs,
const Vector x_s,
const Vector xi, const DenseMatrix coordsm, const Array<int> s_conn,
const Array<int> m_conn, Vector& g, SparseMatrix& M,
std::vector<SparseMatrix>& dM)
{
int n = ndofs;
int ndim = 3;
g.SetSize(m);
g = 0.0;
//SparseMatrix M(m, n); // M needs to be the correct size
//dM.resize(m); // needs to clear?
double g_tmp = 0.;
Vector dg(4*ndim+ndim);
dg = 0.;
DenseMatrix dg2(4*ndim+ndim,4*ndim+ndim);
dg2 = 0.;
for (int i=0; i<npoints; i++)
{
Vector x1(ndim);
x1[0] = x_s[i*ndim];
x1[1] = x_s[i*ndim+1];
x1[2] = x_s[i*ndim+2];
Vector xi2(ndim-1);
xi2[0] = xi[i*(ndim-1)];
xi2[1] = xi[i*(ndim-1)+1];
DenseMatrix coords2(4,3);
coords2.CopyRows(coordsm, i*4,(i+1)*4-1);
//how to get coords2?
dg = 0.0;
dg2 = 0.;
NodeSegConPairs(x1, xi2, coords2, g_tmp, dg, dg2);
//x1.Print();
//xi2.Print();
//coords2.Print();
g[s_conn[i]] = g_tmp; // should be unique
Array<int> m_conn_i(4);
m_conn.GetSubArray(4*i, 4, m_conn_i);
Array<int> node_conn(5);
node_conn[0] = s_conn[i];
for (int j=0; j<4; j++)
{
node_conn[j+1] = m_conn_i[j];
}
Array<int> M_i_tmp(1);
M_i_tmp[0] = s_conn[i];
//j_idx = (node_conn-1)*obj.disp_field.num_components +repmat((1:obj.disp_field.num_components)', 1, length(node_conn{i}));
Array<int> j_idx(5*ndim); j_idx = 0;
for (int j=0; j< 5; j++)
{
for (int k=0; k<ndim; k++)
{
j_idx[j*ndim+k] = node_conn[j]*ndim+k;
}
}
DenseMatrix M_v_tmp(1, ndim*(4+1)); // SetData now?
M_v_tmp.SetRow(0, dg);
M.AddSubMatrix(M_i_tmp, j_idx, M_v_tmp);
Array<int> dM_i(ndim*(4+1));
Array<int> dM_j(ndim*(4+1));
for (int j=0; j< ndim*(4+1); j++)
{
dM_i[j] = j_idx[j];
dM_j[j] = j_idx[j];
}
//dg2.Print();
//dM[s_conn[i]].Print();
dM[s_conn[i]].AddSubMatrix(dM_i,dM_j, dg2);
}
};
+3
View File
@@ -46,6 +46,9 @@ endif
ifeq ($(MFEM_USE_HIOP),YES)
SUBDIRS += hiop
endif
ifeq ($(MFEM_USE_IPOPT),YES)
SUBDIRS += ipopt
endif
ifeq ($(MFEM_USE_PETSC),YES)
SUBDIRS += petsc
endif
+888
View File
@@ -0,0 +1,888 @@
using namespace std;
using namespace mfem;
void BasisEval(const Vector xi, Vector &N, DenseMatrix &dNdxi) // dNdxi is 2*4
{
N[0] = 0.25*(1-xi[0])*(1-xi[1]);
N[1] = 0.25*(1+xi[0])*(1-xi[1]);
N[2] = 0.25*(1+xi[0])*(1+xi[1]);
N[3] = 0.25*(1-xi[0])*(1+xi[1]);
dNdxi(0,0) = 0.25*(-1+xi[1]);
dNdxi(0,1) = 0.25*(1-xi[1]);
dNdxi(0,2) = 0.25*(1+xi[1]);
dNdxi(0,3) = 0.25*(-1-xi[1]);
dNdxi(1,0) = 0.25*(-1+xi[0]);
dNdxi(1,1) = 0.25*(-1-xi[0]);
dNdxi(1,2) = 0.25*(1+xi[0]);
dNdxi(1,3) = 0.25*(1-xi[0]);
}
void BasisEvalDerivs(const Vector xi, Vector& N, DenseMatrix& dNdxi,
DenseMatrix& dN2dxi)
{
N[0] = 0.25*(1-xi[0])*(1-xi[1]);
N[1] = 0.25*(1+xi[0])*(1-xi[1]);
N[2] = 0.25*(1+xi[0])*(1+xi[1]);
N[3] = 0.25*(1-xi[0])*(1+xi[1]);
dNdxi.SetSize(2,4); dNdxi = 0.0;
dN2dxi.SetSize(3,4);
dN2dxi = 0.0; // first row dxi2, second detadxi, third deta2
dNdxi(0,0) = 0.25*(-1+xi[1]); dNdxi(0,1) = 0.25*(1-xi[1]);
dNdxi(0,2) = 0.25*(1+xi[1]); dNdxi(0,3) = 0.25*(-1-xi[1]);
dNdxi(1,0) = 0.25*(-1+xi[0]); dNdxi(1,1) = 0.25*(-1-xi[0]);
dNdxi(1,2) = 0.25*(1+xi[0]); dNdxi(1,3) = 0.25*(1-xi[0]);
dN2dxi(1,0) = 0.25; dN2dxi(1,1) = -0.25; dN2dxi(1,2) = 0.25;
dN2dxi(1,3) = -0.25;
}
// returns the vector and matrix form of the shape functions and its derivative
void BasisVectorDerivs(const Vector xi, DenseMatrix& N, DenseMatrix& dNdxi,
DenseMatrix& ddNdxi)
{
N.SetSize(3,12); N = 0.0;
N(0,0) = 0.25*(1-xi[0])*(1-xi[1]); N(0,3) = 0.25*(1+xi[0])*(1-xi[1]);
N(0,6) = 0.25*(1+xi[0])*(1+xi[1]); N(0,9) = 0.25*(1-xi[0])*(1+xi[1]);
N(1,1) = 0.25*(1-xi[0])*(1-xi[1]); N(1,4) = 0.25*(1+xi[0])*(1-xi[1]);
N(1,7) = 0.25*(1+xi[0])*(1+xi[1]); N(1,10) = 0.25*(1-xi[0])*(1+xi[1]);
N(2,2) = 0.25*(1-xi[0])*(1-xi[1]); N(2,5) = 0.25*(1+xi[0])*(1-xi[1]);
N(2,8) = 0.25*(1+xi[0])*(1+xi[1]); N(2,11) = 0.25*(1-xi[0])*(1+xi[1]);
dNdxi.SetSize(3*2, 3*4); dNdxi = 0.0;
dNdxi(0,0) = 0.25*(-1+xi[1]); dNdxi(0,3) = 0.25*(1-xi[1]);
dNdxi(0,6) = 0.25*(1+xi[1]); dNdxi(0,9) = 0.25*(-1-xi[1]);
dNdxi(1,1) = 0.25*(-1+xi[1]); dNdxi(1,4) = 0.25*(1-xi[1]);
dNdxi(1,7) = 0.25*(1+xi[1]); dNdxi(1,10) = 0.25*(-1-xi[1]);
dNdxi(2,2) = 0.25*(-1+xi[1]); dNdxi(2,5) = 0.25*(1-xi[1]);
dNdxi(2,8) = 0.25*(1+xi[1]); dNdxi(2,11) = 0.25*(-1-xi[1]);
dNdxi(3,0) = 0.25*(-1+xi[0]); dNdxi(3,3) = 0.25*(-1-xi[0]);
dNdxi(3,6) = 0.25*(1+xi[0]); dNdxi(3,9) = 0.25*(1-xi[0]);
dNdxi(4,1) = 0.25*(-1+xi[0]); dNdxi(4,4) = 0.25*(-1-xi[0]);
dNdxi(4,7) = 0.25*(1+xi[0]); dNdxi(4,10) = 0.25*(1-xi[0]);
dNdxi(5,2) = 0.25*(-1+xi[0]); dNdxi(5,5) = 0.25*(-1-xi[0]);
dNdxi(5,8) = 0.25*(1+xi[0]); dNdxi(5,11) = 0.25*(1-xi[0]);
ddNdxi.SetSize(3*4, 3*4); ddNdxi = 0.0;
ddNdxi(3,0) = 0.25; ddNdxi(3,3) = -0.25;
ddNdxi(3,6) = 0.25; ddNdxi(3,9) = -0.25;
ddNdxi(4,1) = 0.25; ddNdxi(4,4) = -0.25;
ddNdxi(4,7) = 0.25; ddNdxi(4,10) = -0.25;
ddNdxi(5,2) = 0.25; ddNdxi(5,5) = -0.25;
ddNdxi(5,8) = 0.25; ddNdxi(5,11) = -0.25;
ddNdxi(6,0) = 0.25; ddNdxi(6,3) = -0.25;
ddNdxi(6,6) = 0.25; ddNdxi(6,9) = -0.25;
ddNdxi(7,1) = 0.25; ddNdxi(7,4) = -0.25;
ddNdxi(7,7) = 0.25; ddNdxi(7,10) = -0.25;
ddNdxi(8,2) = 0.25; ddNdxi(8,5) = -0.25;
ddNdxi(8,8) = 0.25; ddNdxi(8,11) = -0.25;
}
void cross(const Vector a, const Vector b, Vector& c)
{
assert(a.Size()==3);
c.SetSize(3);
c[0] = a[1]*b[2] - a[2]*b[1];
c[1] = -a[0]*b[2] + b[0]*a[2];
c[2] = a[0]*b[1] - a[1]*b[0];
}
// a outer b
void outer(const Vector a, const Vector b, DenseMatrix& c)
{
int m = a.Size();
int n = b.Size();
assert(c.Height()==m);
assert(c.Width() ==n);
for (int i=0; i<m; i++)
{
for (int j=0; j<n; j++)
{
c(i,j) = a[i]*b[j];
}
}
}
// dphidxi 2*4
// coords 4*3
void ComputeNormal(const DenseMatrix& dphidxi, const DenseMatrix& coords,
Vector& normal, double& nnorm)
{
DenseMatrix dxdxi(2,3);
Mult(dphidxi, coords, dxdxi);
Vector dxdxi1(3);
Vector dxdxi2(3);
dxdxi.GetRow(0,dxdxi1);
dxdxi.GetRow(1,dxdxi2);
cross(dxdxi1, dxdxi2, normal); // is there a cross product? no
// VectorCrossProductCoefficient::Eval has hard-coded cross product
nnorm = normal.Norml2( );
normal /= nnorm;
}
void SlaveToMaster(const DenseMatrix& m_coords, const Vector& s_x, Vector& xi)
{
bool converged = false;
bool pt_on_elem = false;
int dim = 3;
xi.SetSize(dim-1);
xi = 0.0;
double r = 1e10;
int max_iter = 15;
double off_el_xi = 1e-2;
double proj_newton_tol = 1e-13;
double proj_max_gap = 0.5;
Vector gap_v(dim);
// warm start from linear solution
for (int it=0; it<max_iter; it++)
{
//cout<<it<<endl;
Vector m_N(4);
m_N = 0.;
DenseMatrix m_dN(2,4);
m_dN = 0.;
DenseMatrix m_dN2(3,4);
m_dN2 = 0.;
BasisEvalDerivs(xi, m_N, m_dN, m_dN2);
Vector x_c(dim);
m_coords.MultTranspose(m_N, x_c);
gap_v = s_x;
gap_v -= x_c;
DenseMatrix m_dx(2,3);
m_dx = 0.;
Mult(m_dN, m_coords, m_dx);
Vector r(dim-1);
r = 0.0;
m_dx.Mult(gap_v, r);
if (r.Normlinf() < proj_newton_tol)
{
converged = true;
break;
}
DenseMatrix drdxi(dim-1,dim-1);
drdxi = 0.;
MultABt(m_dx, m_dx, drdxi); // m_dx * m_dx.T
drdxi *= -1.0;
DenseMatrix m_dx2(3,3); m_dx2 = 0.0;
Mult(m_dN2,m_coords, m_dx2);
//m_d2x = m_dN(:,:,2) * m_elem_coords(1:4,:); //m_dN(:,:,2) is 3*4
for (int d=0; d<3; d++)
{
DenseMatrix Mtemp(2,2); Mtemp = 0.0;
Mtemp(0,0) = m_dx2(0,d); Mtemp(0,1) = m_dx2(1,d);
Mtemp(1,0) = m_dx2(1,d); Mtemp(1,1) = m_dx2(2,d);
drdxi.Add(gap_v[d], Mtemp);
}
//cond_num = rcond(drdxi); condition number?
//drdxi.TestInversion();
DenseMatrixInverse drdxi_inv(drdxi);
Vector xi_tmp(dim-1);
drdxi_inv.Mult(r,xi_tmp);
xi -= xi_tmp;
}
if (!converged)
{
xi = 0.0;
}
off_el_xi += 1 ; // tolerance of offset of xi outside [-1,1]
//cout<<gap_v.Norml2()<<" " <<xi.Normlinf()<<endl;
if (gap_v.Norml2() < proj_max_gap && xi.Normlinf() <= off_el_xi)
{
pt_on_elem = true;
}
MFEM_VERIFY(pt_on_elem == true, "xi went out of bounds");
MFEM_VERIFY(converged == true, "projection didn't converge");
}
// m_coords is expected to be 4 * 3
void ComputeGapJacobian(const Vector x_s, const Vector xi,
const DenseMatrix m_coords,
double& gap, Vector& normal, Vector& dgdxm, Vector& dgdxs)
{
Vector m_N(4);
DenseMatrix m_dN(2,4);
DenseMatrix m_dN2(3,4);
BasisEvalDerivs(xi, m_N, m_dN, m_dN2);
Vector x_c(3);
m_coords.MultTranspose(m_N, x_c);
Vector gap_v(3); gap_v = 0.0;
gap_v = x_s;
gap_v -= x_c;
DenseMatrix m_dx(2,3);
Mult(m_dN, m_coords, m_dx);
double nnorm = 0;
ComputeNormal(m_dN, m_coords, normal, nnorm);
gap = gap_v * normal; // gap function value, dot product between vectors
//dr_dx = zeros(2,4,3); % nsegment, nodes in quad, ndim
DenseMatrix dr_dx_res1(4,3); dr_dx_res1 = 0.;
DenseMatrix dr_dx_res2(4,3); dr_dx_res2 = 0.;
Vector m_dxrow1(3);
m_dx.GetRow(0, m_dxrow1);
outer(m_N, m_dxrow1, dr_dx_res1);// 4*1 times 1*3
dr_dx_res1 *= -1.0;
Vector m_dxrow2(3);
m_dx.GetRow(1, m_dxrow2);
outer(m_N, m_dxrow2, dr_dx_res2);// 4*1 times 1*3
dr_dx_res2 *= -1.0;
Vector m_dNrow1(4); m_dN.GetRow(0, m_dNrow1);
Vector m_dNrow2(4); m_dN.GetRow(1, m_dNrow2);
DenseMatrix dr_dx_res1_tmp(4,3); dr_dx_res1_tmp = 0.;
DenseMatrix dr_dx_res2_tmp(4,3); dr_dx_res2_tmp = 0.;
outer(m_dNrow1, gap_v, dr_dx_res1_tmp);// 4*1 times 1*3
outer(m_dNrow2, gap_v, dr_dx_res2_tmp);// 4*1 times 1*3
dr_dx_res1 += dr_dx_res1_tmp; // outer product in vector?
dr_dx_res2 += dr_dx_res2_tmp;
DenseMatrix K_dxidx1(2,2); // 2*2
K_dxidx1 = 0.;
MultABt(m_dx, m_dx, K_dxidx1); // m_dx * m_dx.T
Vector v_dxidx2(4);
m_coords.Mult(gap_v, v_dxidx2); // m_coords * gap_v; // 4*3 * 3 = 4
DenseMatrix K_dxidx2(2,2); K_dxidx2 = 0.0;
Vector m_dN2row1(4); m_dN2.GetRow(0, m_dN2row1);
Vector m_dN2row2(4); m_dN2.GetRow(1, m_dN2row2);
Vector m_dN2row3(4); m_dN2.GetRow(2, m_dN2row3);
// how to get 2nd order? multidimensional matrix?
K_dxidx2(0,0) = m_dN2row1 * v_dxidx2; // how would 4*1 * 1*4 be computed?
K_dxidx2(0,1) = m_dN2row2 * v_dxidx2;
K_dxidx2(1,0) = m_dN2row2 * v_dxidx2;
K_dxidx2(1,1) = m_dN2row3 * v_dxidx2;
DenseMatrix K_dxidx(2,2);
K_dxidx -= K_dxidx1;
K_dxidx += K_dxidx2;
// resize the vectors and matrices
Vector dxidx(24); dxidx = 0.0;
Vector drdx_r(24); drdx_r = 0.0;
for (int i=0; i<4; i++)
{
for (int j=0; j<3; j++)
{
drdx_r[4*j+i] = dr_dx_res1(i,j);
drdx_r[4*j+i+12] = dr_dx_res2(i,j);
}
}
//drdx_r(1:4*3,1) = reshape(dr_dx_res(:,:,1),4*3,1);
//drdx_r(4*3+1:2*4*3,1) = reshape(dr_dx_res(:,:,2),4*3,1);
DenseMatrix drdx_K(24,24); drdx_K = 0.;
for (int i =0; i<12; i++)
{
drdx_K(i,i) = K_dxidx(0,0);
drdx_K(i,12+i) = K_dxidx(0,1);
drdx_K(12+i,i) = K_dxidx(1,0);
drdx_K(12+i,12+i) = K_dxidx(1,1);
}
DenseMatrixInverse drdxK_inv(drdx_K);
drdxK_inv.Mult(drdx_r,dxidx);
// LinearSolve (drdx_K,drdx_r, dxidx) ; //???
dxidx *= -1.0;
Vector drdxs_r(6);
drdxs_r[0] = m_dx(0,0); drdxs_r[1] = m_dx(0,1); drdxs_r[2] = m_dx(0,2);
drdxs_r[3] = m_dx(1,0); drdxs_r[4] = m_dx(1,1); drdxs_r[5] = m_dx(1,2);
DenseMatrix drdxs_K(6,6); drdxs_K = 0.;
for (int i=0; i<3; i++)
{
drdxs_K(i,i) = K_dxidx(0,0);
drdxs_K(i,3+i) = K_dxidx(0,1);
drdxs_K(i+3,i) = K_dxidx(1,0);
drdxs_K(i+3,i+3) = K_dxidx(1,1);
}
Vector dxidxs(6); dxidxs = 0.0;
DenseMatrixInverse drdxsK_inv(drdxs_K);
drdxsK_inv.Mult(drdxs_r,dxidxs);
dxidxs *= -1.0;
//dxidxs = -drdxs_K\drdxs_r;
//dxidx = reshape(dxidx, 4,3,2); dxidxs = reshape(dxidxs, 1,3,2);
dgdxm.SetSize(12); dgdxm = 0.;
DenseMatrix dgdxm_tmp(4,3);
outer(m_N, normal,dgdxm_tmp);
for (int i=0; i<4; i++)
{
for (int j=0; j<3; j++)
{
dgdxm[3*i+j] = -dgdxm_tmp(i,j);
}
}
//dxidx_M = -m_dN(1:2,:,1) * (m_coords(1:4,:)*normal'); % this turns out to be 0
dgdxs.SetSize(3);
dgdxs += normal;
//dgdxs = dgdxs + dxidx_M(1) * dxidxs(:,:,1) + dxidx_M(2) * dxidxs(:,:,2);
};
void ComputeGapHessian(const Vector x_s, const Vector xi,
const DenseMatrix m_coords,
DenseMatrix& dg2dx)
{
Vector m_N(4);
DenseMatrix m_dN(2,4);
DenseMatrix m_dN2(3,4);
BasisEvalDerivs(xi, m_N, m_dN, m_dN2);
int dim = 3;
int num_dofs1 = dim;
int num_dofs2 = 4*dim;
int num_dofs = num_dofs1 + num_dofs2;
dg2dx.SetSize(num_dofs,num_dofs); dg2dx = 0.0;
Vector x_c(3);
m_coords.MultTranspose(m_N,x_c);
Vector gap_v(3); gap_v = 0.0;
gap_v = x_s;
gap_v -= x_c;
DenseMatrix m_dx(2,3);
Mult(m_dN, m_coords, m_dx);
DenseMatrix m_dx2(3,3); m_dx2 = 0.0;
Mult(m_dN2,m_coords, m_dx2);
double nnorm = 0.0;
Vector normal(3); normal = 0.0;
ComputeNormal(m_dN, m_coords, normal, nnorm);
double gap = gap_v * normal; // gap function value, dot product between vectors
DenseMatrix M(2,2); M = 0.0;
MultABt(m_dx, m_dx, M);
DenseMatrix f(2, num_dofs2); f = 0.0;
for (int d=0; d<3; d++)
{
DenseMatrix Mtemp(2,2); Mtemp = 0.0;
Mtemp(0,0) = m_dx2(0,d); Mtemp(0,1) = m_dx2(1,d);
Mtemp(1,0) = m_dx2(1,d); Mtemp(1,1) = m_dx2(2,d);
M.Add(-gap_v[d], Mtemp);
Vector m_dxcol(2); m_dx.GetColumn(d, m_dxcol);
DenseMatrix ftmp(2,4);
outer(m_dxcol, m_N, ftmp);
ftmp *= -1;
ftmp.Add( gap_v[d], m_dN); // 2*4
for (int j=0; j<4; j++)
{
assert(d+3*j<num_dofs2);
f(0,d+j*3) = ftmp(0,j);
f(1,d+j*3) = ftmp(1,j);
}
}
//fprintf('hess dxidxm\n');
DenseMatrixInverse Minv(M);
DenseMatrix dxidxm(2,num_dofs2); dxidxm = 0.0;
Minv.Mult(f, dxidxm);
//LinearSolve??
//dxidxm = M\f;
DenseMatrix nde2(2,2); nde2 = 0.0;
DenseMatrix Nndx2(2,num_dofs2); Nndx2 = 0.0;
for (int d=0; d<3; d++)
{
DenseMatrix ndetmp(2,2); ndetmp = 0.0;
ndetmp(0,0) = normal(d)*m_dx2(0,d); ndetmp(0,1) = normal(d)*m_dx2(1,d);
ndetmp(1,0) = normal(d)*m_dx2(1,d); ndetmp(1,1) = normal(d)*m_dx2(2,d);
nde2 += ndetmp;
for (int j=0; j<4; j++)
{
assert(d+3*j<num_dofs2);
Nndx2(0,d+j*3) = normal[d]*m_dN(0,j);
Nndx2(1,d+j*3) = normal[d]*m_dN(1,j);
}
}
DenseMatrix Ndn(2,num_dofs2); Ndn = 0.0;
Ndn += Nndx2;
AddMult(nde2, dxidxm, Ndn);
DenseMatrix M2(2,2); M2 = 0.0;
MultABt(m_dx, m_dx, M2);
DenseMatrixInverse M2inv(M2);
DenseMatrix diag2(2,2); diag2(0,0) = 1.0; diag2(1,1) = 1.0;
DenseMatrix m_con(2,2); m_con = 0.0;
M2inv.Mult(diag2, m_con);
DenseMatrix dg2dxm(num_dofs2, num_dofs2); dg2dxm = 0.0;
DenseMatrix dg2dxm_tmp(num_dofs2,2); dg2dxm_tmp = 0.0;
MultAtB(Ndn, m_con, dg2dxm_tmp);
Mult(dg2dxm_tmp, Ndn, dg2dxm);
dg2dxm *= gap;
DenseMatrix dg2dxm_tmp2(num_dofs2,num_dofs2); dg2dxm_tmp2 = 0.0;
MultAtB(Nndx2, dxidxm, dg2dxm_tmp2);
dg2dxm.Add(-1.0, dg2dxm_tmp2);
dg2dxm_tmp = 0.0;
MultAtB(dxidxm, nde2, dg2dxm_tmp);
AddMult_a(-1.0, dg2dxm_tmp, dxidxm, dg2dxm);
dg2dxm_tmp2 = 0.0;
MultAtB(dxidxm, Nndx2, dg2dxm_tmp2);
dg2dxm.Add(-1.0, dg2dxm_tmp2);
Vector v_dxidx2(4);
m_coords.Mult(gap_v, v_dxidx2); // m_coords * gap_v; // 4*3 * 3 = 4
DenseMatrix K_dxidx2(2,2); K_dxidx2 = 0.0;
Vector m_dN2row1(4); m_dN2.GetRow(0, m_dN2row1);
Vector m_dN2row2(4); m_dN2.GetRow(1, m_dN2row2);
Vector m_dN2row3(4); m_dN2.GetRow(2, m_dN2row3);
K_dxidx2(0,0) = m_dN2row1 * v_dxidx2; // how would 4*1 * 1*4 be computed?
K_dxidx2(0,1) = m_dN2row2 * v_dxidx2;
K_dxidx2(1,0) = m_dN2row2 * v_dxidx2;
K_dxidx2(1,1) = m_dN2row3 * v_dxidx2;
DenseMatrix K_dxidx(2,2);
K_dxidx -= M2;
K_dxidx += K_dxidx2;
Vector drdxs_r(6);
drdxs_r[0] = m_dx(0,0); drdxs_r[1] = m_dx(0,1); drdxs_r[2] = m_dx(0,2);
drdxs_r[3] = m_dx(1,0); drdxs_r[4] = m_dx(1,1); drdxs_r[5] = m_dx(1,2);
DenseMatrix drdxs_K(6,6); drdxs_K = 0.;
for (int i=0; i<3; i++)
{
drdxs_K(i,i) = K_dxidx(0,0);
drdxs_K(i,3+i) = K_dxidx(0,1);
drdxs_K(i+3,i) = K_dxidx(1,0);
drdxs_K(i+3,i+3) = K_dxidx(1,1);
}
Vector dxidxs(6);
DenseMatrixInverse drdxsK_inv(drdxs_K);
drdxsK_inv.Mult(drdxs_r,dxidxs);
dxidxs *= -1.0;
//dxidxs = -drdxs_K\drdxs_r;
DenseMatrix dxidxs_m(2,3); dxidxs_m = 0.0;
dxidxs_m(0,0) = dxidxs[0]; dxidxs_m(0,1) = dxidxs[1]; dxidxs_m(0,2) = dxidxs[2];
dxidxs_m(1,0) = dxidxs[3]; dxidxs_m(1,1) = dxidxs[4]; dxidxs_m(1,2) = dxidxs[5];
DenseMatrix dtao1dxs(3,3); dtao1dxs = 0.0;
DenseMatrix dtao2dxs(3,3); dtao2dxs = 0.0;
Vector dxidxs_row1(3); dxidxs_row1 = 0.0; Vector dxidxs_row2(3);
dxidxs_row2 = 0.0;
Vector mdx2_row1(3); mdx2_row1 = 0.0; Vector mdx2_row2(3); mdx2_row2 = 0.0;
Vector mdx2_row3(3); mdx2_row3 = 0.0;
dxidxs_m.GetRow(0,dxidxs_row1);
dxidxs_m.GetRow(1,dxidxs_row2);
m_dx2.GetRow(0,mdx2_row1);
m_dx2.GetRow(1,mdx2_row2);
m_dx2.GetRow(2,mdx2_row3);
DenseMatrix dtaotmp(3,3); dtaotmp = 0.0;
outer(mdx2_row1, dxidxs_row1,dtaotmp);
dtao1dxs += dtaotmp; dtaotmp = 0.0;
outer(mdx2_row2, dxidxs_row1,dtaotmp);
dtao1dxs += dtaotmp; dtaotmp = 0.0;
outer(mdx2_row2, dxidxs_row2, dtaotmp);
dtao2dxs += dtaotmp; dtaotmp = 0.0;
outer(mdx2_row3, dxidxs_row2, dtaotmp);
dtao2dxs += dtaotmp; dtaotmp = 0.0;
DenseMatrix dtaodxs(3,3); dtaodxs = 0.0; //tao = tao1 cross tao2
for (int d=0; d<3; d++)
{
Vector dtao1dxs_tmp(3); dtao1dxs_tmp = 0.0;
dtao1dxs.GetColumn(d,dtao1dxs_tmp);
Vector m_dxrow(3); m_dx.GetRow(1, m_dxrow);
Vector dtaodxs_tmp(3); dtaodxs_tmp = 0.0;
cross(dtao1dxs_tmp, m_dxrow, dtaodxs_tmp);
Vector dtaodxs_tmp2(3); dtaodxs_tmp2 = 0.0;
m_dx.GetRow(0, m_dxrow);
dtao1dxs_tmp = 0.0; // reuse the same vector for dtao2
dtao2dxs.GetColumn(d,dtao1dxs_tmp);
cross(m_dxrow, dtao1dxs_tmp, dtaodxs_tmp2);
dtaodxs_tmp2 += dtaodxs_tmp;
dtaodxs.SetCol(d, dtaodxs_tmp2);
}
DenseMatrix dndxs(3,3); dndxs = 0.0; dndxs += dtaodxs; dndxs *= 1.0/nnorm;
DenseMatrix dndxs_tmp(3,3); dndxs_tmp = 0.0;
outer(normal, normal, dndxs_tmp);
AddMult_a(-1/nnorm, dndxs_tmp, dtaodxs, dndxs);
DenseMatrix dgvdxs(3,3); dgvdxs = 0.0;
MultAtB(m_dx, dxidxs_m, dgvdxs);
dgvdxs *= -1;
for (int d=0; d<3; d++)
{
dgvdxs(d,d) += 1.0;
}
//dxidxs: 2*3
DenseMatrix dg2dxs(3,3); dg2dxs = 0.0;
DenseMatrix dg2dxs_tmp(3,2); dg2dxs_tmp = 0.0;
MultAtB(dxidxs_m, nde2, dg2dxs_tmp);
AddMult_a(-1.0, dg2dxs_tmp, dxidxs_m, dg2dxs);
DenseMatrix dg2dxs_tmp2(3,3); dg2dxs_tmp2 = 0.0;
MultAtB(dgvdxs, dndxs, dg2dxs_tmp2);
dg2dxs += dg2dxs_tmp2;
dg2dxs_tmp2 = 0.0;
MultAtB(dndxs, dndxs_tmp, dg2dxs_tmp2);
AddMult(dg2dxs_tmp2, dgvdxs, dg2dxs);
DenseMatrix Ne(3,12), Be(6,12), dBe(12,12);
BasisVectorDerivs(xi, Ne, Be, dBe);
DenseMatrix dtao1dxm(3,12); dtao1dxm.CopyRows(Be, 0, 2);
DenseMatrix dtao2dxm(3,12); dtao2dxm.CopyRows(Be, 3, 5);
Vector m_coords_v(12);
for (int i=0; i<4; i++)
{
for (int j=0; j<3; j++)
{
m_coords_v[i*3+j] = m_coords(i,j);
}
}
for (int i=0; i<2; i++)
{
Vector dxidxm_tmp(num_dofs2); dxidxm_tmp = 0.0;
dxidxm.GetRow(i,dxidxm_tmp);
DenseMatrix dBe_tmp(3,12);
dBe_tmp.CopyRows(dBe,i*3,(i+1)*3-1);
DenseMatrix dtaodxm_tmp(12,12); dtaodxm_tmp = 0.0;
outer(m_coords_v, dxidxm_tmp, dtaodxm_tmp);
AddMult(dBe_tmp, dtaodxm_tmp, dtao1dxm);
//dtao1dxm += dBe(:,:,i)*reshape(m_coords(1:4,:)',12,1)*reshape(dxidxm(i,:),1,12); % 3*12
dBe_tmp = 0.0;
dBe_tmp.CopyRows(dBe,(i+2)*3,(i+3)*3-1);
AddMult(dBe_tmp, dtaodxm_tmp, dtao2dxm);
}
DenseMatrix dtaodxm(3,12); dtaodxm = 0.0;//tao = tao1 cross tao2
for (int d=0; d<12; d++)
{
Vector dtaodxm_tmp(3); dtaodxm_tmp = 0.0;
Vector dtaodxm_tmp2(3); dtaodxm_tmp2 = 0.0;
Vector tmp1(3); tmp1 = 0.0; dtao1dxm.GetColumn(d,tmp1);
Vector m_dxrow2(3); m_dx.GetRow(1, m_dxrow2);
Vector m_dxrow1(3); m_dx.GetRow(0, m_dxrow1);
Vector tmp2(3); tmp2 = 0.0; dtao2dxm.GetColumn(d,tmp2);
cross(tmp1, m_dxrow2, dtaodxm_tmp);
cross(m_dxrow1,tmp2, dtaodxm_tmp2);
dtaodxm_tmp += dtaodxm_tmp2;
dtaodxm.SetCol(d, dtaodxm_tmp);
}
DenseMatrix dndxm(3,12); dndxm = 0.0;
dndxm += dtaodxm;
dndxm *= 1.0/nnorm;
AddMult_a(-1/nnorm, dndxs_tmp, dtaodxm, dndxm); //dndxs_tmp = normal'*normal
DenseMatrix dgvdxm(3,12); dgvdxm = 0.0;
dgvdxm -= Ne;
for (int i=0; i<2; i++)
{
Vector dxidxm_tmp(num_dofs2); dxidxm_tmp = 0.0;
dxidxm.GetRow(i,dxidxm_tmp);
DenseMatrix Be_tmp(3,12);
Be_tmp.CopyRows(Be,i*3,(i+1)*3-1);
DenseMatrix dgvdxm_tmp(12,12); dgvdxm_tmp = 0.0;
outer(m_coords_v, dxidxm_tmp, dgvdxm_tmp);
AddMult_a(-1.0, Be_tmp, dgvdxm_tmp, dgvdxm);
}
DenseMatrix dg2dxsxm(3,12); dg2dxsxm = 0.0;
DenseMatrix dg2dxsxm_tmp(3,3); dg2dxsxm_tmp = 0.0;
MultAtB(dgvdxs, dndxm, dg2dxsxm);
MultAtB(dndxs, dndxs_tmp, dg2dxsxm_tmp);
AddMult(dg2dxsxm_tmp, dgvdxm, dg2dxsxm); // += dndxs'*normal'*normal*dgvdxm;
DenseMatrix dgvdxsxmn(3,12); dgvdxsxmn = 0.0;
DenseMatrix dgvdxsxmn_tmp(3,2); dgvdxsxmn_tmp = 0.0;
MultAtB(dxidxs_m, nde2, dgvdxsxmn_tmp); //dxidxs_m: 2*3
AddMult_a(-1.0, dgvdxsxmn_tmp, dxidxm, dgvdxsxmn);
for (int i =0; i<2; i++)
{
DenseMatrix Be_tmp(3,12);
Be_tmp.CopyRows(Be,i*3,(i+1)*3-1);
Vector dxidxs_row(3); dxidxs_row = 0.0; dxidxs_m.GetRow(i,dxidxs_row);
DenseMatrix dgvdxsxmn_tmp2(3,3); dgvdxsxmn_tmp2 = 0.0;
outer(dxidxs_row, normal, dgvdxsxmn_tmp2);
AddMult_a(-1.0, dgvdxsxmn_tmp2, Be_tmp, dgvdxsxmn);
}
dg2dxsxm += dgvdxsxmn;
DenseMatrix dg2dxmxs(12,3); dg2dxmxs = 0.0;
DenseMatrix dg2dxmxs_tmp(12,3); dg2dxmxs_tmp = 0.0;
MultAtB(dgvdxm, dndxs, dg2dxmxs);
MultAtB(dndxm, dndxs_tmp, dg2dxmxs_tmp);
AddMult(dg2dxmxs_tmp, dgvdxs, dg2dxmxs);
DenseMatrix dgvdxmxsn(12,3); dgvdxmxsn = 0.0;
DenseMatrix dgvdxmxsn_tmp(12,2); dgvdxmxsn_tmp = 0.0;
MultAtB(dxidxm, nde2, dgvdxmxsn_tmp);
dgvdxmxsn_tmp *= -1.0;
AddMult(dgvdxmxsn_tmp, dxidxs_m, dgvdxmxsn);
for (int i =0; i<2; i++)
{
DenseMatrix Be_tmp(3,12);
Be_tmp.CopyRows(Be,i*3,(i+1)*3-1);
Be_tmp.Transpose(); // Be is now 12*3
Vector dxidxs_row(3); dxidxs_row = 0.0; dxidxs_m.GetRow(i,dxidxs_row);
DenseMatrix dgvdxmxsn_tmp2(3,3); dgvdxmxsn_tmp2 = 0.0;
outer(normal, dxidxs_row, dgvdxmxsn_tmp2);
AddMult_a(-1.0, Be_tmp, dgvdxmxsn_tmp2, dgvdxmxsn);
}
dg2dxmxs += dgvdxmxsn;
dg2dx.CopyMN(dg2dxs, 0, 0);
dg2dx.CopyMN(dg2dxm, 3, 3);
dg2dx.CopyMN(dg2dxsxm, 0, 3);
dg2dx.CopyMN(dg2dxmxs, 3, 0);
};
void NodeSegConPairs(const Vector x1, const Vector xi2,
const DenseMatrix coords2,
double& node_g, Vector& node_dg, DenseMatrix& node_dg2)
{
double gap = 0.0;
Vector normal(3); normal = 0.0;
Vector dgdxm(12); dgdxm = 0.0;
Vector dgdxs(3); dgdxs = 0.0;
ComputeGapJacobian(x1, xi2, coords2, gap, normal, dgdxm, dgdxs);
node_g = gap;
node_dg.SetSize(12+3);
for (int i=0; i<3; i++) { node_dg[i] = dgdxs[i]; }
for (int i=0; i<12; i++) { node_dg[i+3] = dgdxm[i]; }
DenseMatrix dg2dx(15,15); dg2dx = 0.0;
DenseMatrix dgvdxmxsn(12,3); dgvdxmxsn = 0.0;
ComputeGapHessian(x1, xi2, coords2, dg2dx);
node_dg2.SetSize(15,15);
node_dg2 = dg2dx;
/*
if(obj.space1.conns{e1}(i)==150) % for debugging purpose
v1 = 1:3;
v2 = 1:12;
%v1 = ones(1,3)
%v2 = ones(1,12)
v2 = reshape(v2,4,3);
x1n1 = x1 + 0.01*v1;
coords2n1 = coords2 + 0.001*v2;
[xi2n1, gapv1, ~, ~] = SlaveToMaster(obj, coords2n1, x1n1);
[gapn1, n1,dgdxmn1, dgdxsn1] = ComputeGapJacobian(obj, x1n1, xi2n1, coords2n1);
x1n2 = x1 - 0.01*v1;
coords2n2 = coords2 - 0.001*v2;
[xi2n2, gapv2, ~, ~] = SlaveToMaster(obj, coords2n2, x1n2);
[gapn2, n2,dgdxmn2, dgdxsn2] = ComputeGapJacobian(obj, x1n2, xi2n2, coords2n2);
fprintf('fd\n');
%gapv1-gapv2
[dgdxsn1(:)',dgdxmn1(:)'] - [dgdxsn2(:)',dgdxmn2(:)']
%dgdxsn1-dgdxsn2
fprintf('code\n');
v2n = v2';
%dg2dx(1:3,1:3)*0.04*ones(3,1)
temp = zeros(12,3);
for i = 1:4
temp1 = dg2dx(3+(i-1)*3+1:3+i*3,1:3);
temp((i-1)*3+1:i*3,:) = temp1';
end
temp2 = zeros(3,12);
for i = 1:4
temp3 = dg2dx(1:3,3+(i-1)*3+1:3+i*3);
temp2(:,(i-1)*3+1:i*3) = temp3';
end
%dg2dx
%dg2dx(4:end,1:3) = temp;
%dg2dx(1:3,4:end) = temp2;
%dgvdxm * 0.002*v2n(:)
(dg2dx*[0.02*v1(:)',0.002*v2n(:)']')'
%dg2dx(4:end,1:3)
end*/
};
// coordsm : (npoints*4, 3) use what class?
// m_conn: (npoints*4)
void Assemble_Contact(const int m, const int npoints, const int ndofs,
const Vector x_s,
const Vector xi, const DenseMatrix coordsm, const Array<int> s_conn,
const Array<int> m_conn, Vector& g, SparseMatrix& M,
std::vector<SparseMatrix>& dM)
{
int n = ndofs;
int ndim = 3;
g.SetSize(m);
g = 0.0;
//SparseMatrix M(m, n); // M needs to be the correct size
//dM.resize(m); // needs to clear?
double g_tmp = 0.;
Vector dg(4*ndim+ndim);
dg = 0.;
DenseMatrix dg2(4*ndim+ndim,4*ndim+ndim);
dg2 = 0.;
for (int i=0; i<npoints; i++)
{
Vector x1(ndim);
x1[0] = x_s[i*ndim];
x1[1] = x_s[i*ndim+1];
x1[2] = x_s[i*ndim+2];
Vector xi2(ndim-1);
xi2[0] = xi[i*(ndim-1)];
xi2[1] = xi[i*(ndim-1)+1];
DenseMatrix coords2(4,3);
coords2.CopyRows(coordsm, i*4,(i+1)*4-1);
//how to get coords2?
dg = 0.0;
dg2 = 0.;
NodeSegConPairs(x1, xi2, coords2, g_tmp, dg, dg2);
//x1.Print();
//xi2.Print();
//coords2.Print();
g[s_conn[i]] = g_tmp; // should be unique
Array<int> m_conn_i(4);
m_conn.GetSubArray(4*i, 4, m_conn_i);
Array<int> node_conn(5);
node_conn[0] = s_conn[i];
for (int j=0; j<4; j++)
{
node_conn[j+1] = m_conn_i[j];
}
Array<int> M_i_tmp(1);
M_i_tmp[0] = s_conn[i];
//j_idx = (node_conn-1)*obj.disp_field.num_components +repmat((1:obj.disp_field.num_components)', 1, length(node_conn{i}));
Array<int> j_idx(5*ndim); j_idx = 0;
for (int j=0; j< 5; j++)
{
for (int k=0; k<ndim; k++)
{
j_idx[j*ndim+k] = node_conn[j]*ndim+k;
}
}
DenseMatrix M_v_tmp(1, ndim*(4+1)); // SetData now?
M_v_tmp.SetRow(0, dg);
M.AddSubMatrix(M_i_tmp, j_idx, M_v_tmp);
Array<int> dM_i(ndim*(4+1));
Array<int> dM_j(ndim*(4+1));
for (int j=0; j< ndim*(4+1); j++)
{
dM_i[j] = j_idx[j];
dM_j[j] = j_idx[j];
}
//dg2.Print();
//dM[s_conn[i]].Print();
dM[s_conn[i]].AddSubMatrix(dM_i,dM_j, dg2);
}
};
-1
View File
@@ -187,7 +187,6 @@ int main(int argc, char *argv[])
{
// 1. Initialize MPI and HYPRE.
Mpi::Init(argc, argv);
int num_procs = Mpi::WorldSize();
int myid = Mpi::WorldRank();
Hypre::Init();
+10 -6
View File
@@ -248,7 +248,10 @@ int main(int argc, char *argv[])
// constraints for non-conforming AMR, static condensation, etc.
if (myid == 0) { cout << "matrix ... " << flush; }
if (static_cond) { a->EnableStaticCondensation(); }
a->Assemble();
// Here we want to try out block-size aware AMG solver in PETSc.
// For that to work properly, we need a fully-compliant block-size
// structure and we do not skip zeros when assembling.
a->Assemble(use_petsc ? 0 : 1);
Vector B, X;
if (!use_petsc)
@@ -294,13 +297,14 @@ int main(int argc, char *argv[])
cout << "done." << endl;
cout << "Size of linear system: " << A.M() << endl;
}
PetscPCGSolver *pcg = new PetscPCGSolver(A);
// Tell PETSc the matrix has a block structure
A.SetBlockSize(dim);
// The preconditioner for the PCG solver defined below is specified in the
// PETSc config file, rc_ex2p, since a Krylov solver in PETSc can also
// customize its preconditioner.
// The preconditioner for the PCG solver can be specified in the
// PETSc config file
PetscPCGSolver *pcg = new PetscPCGSolver(A);
PetscPreconditioner *prec = NULL;
if (use_nonoverlapping)
if (use_nonoverlapping) // Specialized BDDC construction
{
// Compute dofs belonging to the natural boundary
Array<int> nat_tdof_list, nat_bdr(pmesh->bdr_attributes.Max());
+1 -1
View File
@@ -450,7 +450,7 @@ int main(int argc, char *argv[])
for (int ti = 0; !done; )
{
// We cannot match exactly the time history of the Run method
// since we are explictly telling PETSc to use a time step
// since we are explicitly telling PETSc to use a time step
double dt_real = min(dt, t_final - t);
ode_solver->Step(*U, t, dt_real);
ti++;
+2
View File
@@ -78,6 +78,7 @@ EX1_ARGS_CUDA := -m ../../data/star.mesh --usepetsc --partial-assembly -
EX1_ARGS_CUDAAMG := -m ../../data/star.mesh --usepetsc --device cuda --petscopts rc_ex1p_cudaamg
EX2_ARGS := -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex2p
EX2_ARGS_BDDC := -m ../../data/beam-tri.mesh --usepetsc --nonoverlapping --petscopts rc_ex2p_bddc
EX2_ARGS_ASM := -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex2p_asm
EX3_ARGS := -m ../../data/klein-bottle.mesh -o 2 -f 0.1 --usepetsc --petscopts rc_ex3p_bddc --nonoverlapping
EX4_ARGS := -m ../../data/klein-bottle.mesh -o 2 --usepetsc --petscopts rc_ex4p_bddc --nonoverlapping
EX4_HYB_ARGS := -m ../../data/klein-bottle.mesh -o 2 --usepetsc --petscopts rc_ex4p_bddc --nonoverlapping --hybridization
@@ -109,6 +110,7 @@ endif
ex2p-test-par: ex2p
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX2_ARGS))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX2_ARGS_BDDC))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX2_ARGS_ASM))
ex3p-test-par: ex3p
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX3_ARGS))
ex4p-test-par: ex4p
+1
View File
@@ -14,4 +14,5 @@
-mg_levels_esteig_ksp_type cg
-mg_levels_esteig_ksp_max_it 10
-mg_levels_ksp_chebyshev_esteig 0,0.05,0,1.05
-pc_gamg_use_sa_esteig 0
-mg_levels_pc_type sor
+1 -2
View File
@@ -1,8 +1,7 @@
-ksp_converged_reason
# GAMG is still not used at its best,
# since we are not exploiting the
# block size (Ordering::byVDIM) and the RBMs
# since we are not exploiting the RBMs
-ksp_view
-pc_type gamg
+10
View File
@@ -0,0 +1,10 @@
# Additive Schwarz with Overlap
# This is not a good solver for elasticity
# These options are here only to describe
# the setup of the solver
-ksp_converged_reason
-ksp_view
-ksp_max_it 10
-pc_type asm
-pc_asm_overlap 1
-sub_pc_type icc
+3
View File
@@ -210,6 +210,9 @@ void visualize(ostream &os, Mesh *mesh, GridFunction *deformed_nodes,
int main(int argc, char *argv[])
{
// 0. Initialize SUNDIALS.
Sundials::Init();
// 1. Parse command-line options.
const char *mesh_file = "../../data/beam-quad.mesh";
int ref_levels = 2;
+2 -1
View File
@@ -215,10 +215,11 @@ void visualize(ostream &os, ParMesh *mesh, ParGridFunction *deformed_nodes,
int main(int argc, char *argv[])
{
// 1. Initialize MPI and HYPRE.
// 1. Initialize MPI, HYPRE, and SUNDIALS.
Mpi::Init(argc, argv);
int myid = Mpi::WorldRank();
Hypre::Init();
Sundials::Init();
// 2. Parse command-line options.
const char *mesh_file = "../../data/beam-quad.mesh";
+7 -1
View File
@@ -109,6 +109,9 @@ double InitialTemperature(const Vector &x);
int main(int argc, char *argv[])
{
// 0. Initialize SUNDIALS.
Sundials::Init();
// 1. Parse command-line options.
const char *mesh_file = "../../data/star.mesh";
int ref_levels = 2;
@@ -290,7 +293,10 @@ int main(int argc, char *argv[])
arkode->Init(oper);
arkode->SetSStolerances(reltol, abstol);
arkode->SetMaxStep(dt);
if (ode_solver_type == 11) { arkode->SetERKTableNum(FEHLBERG_13_7_8); }
if (ode_solver_type == 11)
{
arkode->SetERKTableNum(ARKODE_FEHLBERG_13_7_8);
}
ode_solver = arkode; break;
case 12:
arkode = new ARKStepSolver(ARKStepSolver::IMPLICIT);
+6 -2
View File
@@ -101,11 +101,12 @@ double InitialTemperature(const Vector &x);
int main(int argc, char *argv[])
{
// 1. Initialize MPI and HYPRE.
// 1. Initialize MPI, HYPRE, and SUNDIALS.
Mpi::Init(argc, argv);
int num_procs = Mpi::WorldSize();
int myid = Mpi::WorldRank();
Hypre::Init();
Sundials::Init();
// 2. Parse command-line options.
const char *mesh_file = "../../data/star.mesh";
@@ -327,7 +328,10 @@ int main(int argc, char *argv[])
arkode->Init(oper);
arkode->SetSStolerances(reltol, abstol);
arkode->SetMaxStep(dt);
if (ode_solver_type == 11) { arkode->SetERKTableNum(FEHLBERG_13_7_8); }
if (ode_solver_type == 11)
{
arkode->SetERKTableNum(ARKODE_FEHLBERG_13_7_8);
}
ode_solver = arkode; break;
case 12:
arkode = new ARKStepSolver(MPI_COMM_WORLD, ARKStepSolver::IMPLICIT);
+4 -1
View File
@@ -140,6 +140,9 @@ public:
int main(int argc, char *argv[])
{
// 0. Initialize SUNDIALS.
Sundials::Init();
// 1. Parse command-line options.
problem = 0;
const char *mesh_file = "../../data/periodic-hexagon.mesh";
@@ -408,7 +411,7 @@ int main(int argc, char *argv[])
arkode->Init(adv);
arkode->SetSStolerances(reltol, abstol);
arkode->SetMaxStep(dt);
arkode->SetERKTableNum(FEHLBERG_13_7_8);
arkode->SetERKTableNum(ARKODE_FEHLBERG_13_7_8);
ode_solver = arkode; break;
}
+6 -2
View File
@@ -152,11 +152,12 @@ public:
int main(int argc, char *argv[])
{
// 1. Initialize MPI and HYPRE.
// 1. Initialize MPI, HYPRE, and SUNDIALS.
Mpi::Init(argc, argv);
int num_procs = Mpi::WorldSize();
int myid = Mpi::WorldRank();
Hypre::Init();
Sundials::Init();
// 2. Parse command-line options.
problem = 0;
@@ -487,7 +488,10 @@ int main(int argc, char *argv[])
arkode->Init(adv);
arkode->SetSStolerances(reltol, abstol);
arkode->SetMaxStep(dt);
if (ode_solver_type == 9) { arkode->SetERKTableNum(FEHLBERG_13_7_8); }
if (ode_solver_type == 9)
{
arkode->SetERKTableNum(ARKODE_FEHLBERG_13_7_8);
}
ode_solver = arkode; break;
}
+1 -1
View File
@@ -35,7 +35,7 @@ add_mfem_examples(SUPERLU_EXAMPLES_SRCS ${PFX} "" test_superlu)
if (MFEM_ENABLE_TESTING)
# Command line options for the tests.
# Example 1: Test SuperLU on the simple Poisson problem
set(EX1_COMMON_OPTS -m ../../data/star.mesh -p 2)
set(EX1_COMMON_OPTS -m ../../data/star.mesh)
set(EX1P_TEST_OPTS ${EX1_COMMON_OPTS})
# Add the tests: one test per source file.
+9
View File
@@ -39,6 +39,7 @@ set(SRCS
complex_fem.cpp
convergence.cpp
datacollection.cpp
dgmassinv.cpp
doftrans.cpp
eltrans.cpp
estimators.cpp
@@ -72,6 +73,7 @@ set(SRCS
linearform.cpp
linearform_ext.cpp
lininteg.cpp
lininteg_boundary.cpp
lininteg_domain.cpp
lininteg_domain_grad.cpp
lor/lor.cpp
@@ -88,6 +90,7 @@ set(SRCS
fespacehierarchy.cpp
nonlininteg_vectorconvection.cpp
nonlininteg_vectorconvection_mf.cpp
qfunction.cpp
qinterp/det.cpp
qinterp/eval_by_nodes.cpp
qinterp/eval_by_vdim.cpp
@@ -95,6 +98,7 @@ set(SRCS
qinterp/grad_by_vdim.cpp
qinterp/grad_phys_by_nodes.cpp
qinterp/grad_phys_by_vdim.cpp
qspace.cpp
quadinterpolator.cpp
quadinterpolator_face.cpp
restriction.cpp
@@ -136,10 +140,13 @@ set(HDRS
bilinearform.hpp
bilinearform_ext.hpp
bilininteg.hpp
bilininteg_mass_pa.hpp
coefficient.hpp
complex_fem.hpp
convergence.hpp
datacollection.hpp
dgmassinv.hpp
dgmassinv_kernels.hpp
doftrans.hpp
eltrans.hpp
estimators.hpp
@@ -189,9 +196,11 @@ set(HDRS
nonlinearform.hpp
nonlinearform_ext.hpp
nonlininteg.hpp
qfunction.hpp
qinterp/dispatch.hpp
qinterp/eval.hpp
qinterp/grad.hpp
qspace.hpp
quadinterpolator.hpp
quadinterpolator_face.hpp
restriction.hpp
+3 -1
View File
@@ -124,6 +124,7 @@ void BilinearForm::SetAssemblyLevel(AssemblyLevel assembly_level)
case AssemblyLevel::LEGACY:
break;
case AssemblyLevel::FULL:
SetDiagonalPolicy( DIAG_ONE ); // Only diagonal policy supported on device
ext = new FABilinearFormExtension(this);
break;
case AssemblyLevel::ELEMENT:
@@ -136,7 +137,7 @@ void BilinearForm::SetAssemblyLevel(AssemblyLevel assembly_level)
ext = new MFBilinearFormExtension(this);
break;
default:
mfem_error("Unknown assembly level");
MFEM_ABORT("BilinearForm: unknown assembly level");
}
}
@@ -992,6 +993,7 @@ void BilinearForm::EliminateVDofs(const Array<int> &vdofs_,
mat_e = new SparseMatrix(height);
}
vdofs_.HostRead();
for (int i = 0; i < vdofs_.Size(); i++)
{
int vdof = vdofs_[i];
+23 -4
View File
@@ -26,7 +26,8 @@ namespace mfem
{
/** @brief Enumeration defining the assembly level for bilinear and nonlinear
form classes derived from Operator. */
form classes derived from Operator. For more details, see
https://mfem.org/howto/assembly_levels */
enum class AssemblyLevel
{
/// In the case of a BilinearForm LEGACY corresponds to a fully assembled
@@ -79,6 +80,9 @@ protected:
/** @brief Extension for supporting Full Assembly (FA), Element Assembly (EA),
Partial Assembly (PA), or Matrix Free assembly (MF). */
BilinearFormExtension *ext;
/** Indicates if the sparse matrix is sorted after assembly when using
Full Assembly (FA). */
bool sort_sparse_matrix = false;
/** @brief Indicates the Mesh::sequence corresponding to the current state of
the BilinearForm. */
@@ -177,9 +181,24 @@ public:
- AssemblyLevel::ELEMENT
- AssemblyLevel::NONE
This method must be called before assembly. */
If used, this method must be called before assembly. */
void SetAssemblyLevel(AssemblyLevel assembly_level);
/** @brief Force the sparse matrix column indices to be sorted when using
AssemblyLevel::FULL.
When assembling on device the assembly algorithm uses atomic operations
to insert values in the sparse matrix, which can result in different
column index orderings across runs. Calling this method with @a enable_it
set to @a true forces a sorting algorithm to be called at the end of the
assembly procedure to ensure sorted column indices (and therefore
deterministic results).
*/
void EnableSparseMatrixSorting(bool enable_it)
{
sort_sparse_matrix = enable_it;
}
/// Returns the assembly level
AssemblyLevel GetAssemblyLevel() const { return assembly; }
@@ -333,7 +352,7 @@ public:
/** @brief Nullifies the internal matrix \f$ M \f$ and returns a pointer
to it. Used for transfering ownership. */
to it. Used for transferring ownership. */
SparseMatrix *LoseMat() { SparseMatrix *tmp = mat; mat = NULL; return tmp; }
/** @brief Returns a const reference to the sparse matrix of eliminated b.c.:
@@ -774,7 +793,7 @@ public:
SparseMatrix &SpMat() { return *mat; }
/** @brief Nullifies the internal matrix \f$ M \f$ and returns a pointer
to it. Used for transfering ownership. */
to it. Used for transferring ownership. */
SparseMatrix *LoseMat() { SparseMatrix *tmp = mat; mat = NULL; return tmp; }
/// Adds a domain integrator. Assumes ownership of @a bfi.
+20 -13
View File
@@ -160,7 +160,7 @@ void MFBilinearFormExtension::Mult(const Vector &x, Vector &y) const
{
intFaceIntegrators[i]->AddMultMF(int_face_X, int_face_Y);
}
int_face_restrict_lex->AddMultTranspose(int_face_Y, y);
int_face_restrict_lex->AddMultTransposeInPlace(int_face_Y, y);
}
}
@@ -176,7 +176,7 @@ void MFBilinearFormExtension::Mult(const Vector &x, Vector &y) const
{
bdrFaceIntegrators[i]->AddMultMF(bdr_face_X, bdr_face_Y);
}
bdr_face_restrict_lex->AddMultTranspose(bdr_face_Y, y);
bdr_face_restrict_lex->AddMultTransposeInPlace(bdr_face_Y, y);
}
}
}
@@ -217,7 +217,7 @@ void MFBilinearFormExtension::MultTranspose(const Vector &x, Vector &y) const
{
intFaceIntegrators[i]->AddMultTransposeMF(int_face_X, int_face_Y);
}
int_face_restrict_lex->AddMultTranspose(int_face_Y, y);
int_face_restrict_lex->AddMultTransposeInPlace(int_face_Y, y);
}
}
@@ -233,7 +233,7 @@ void MFBilinearFormExtension::MultTranspose(const Vector &x, Vector &y) const
{
bdrFaceIntegrators[i]->AddMultTransposeMF(bdr_face_X, bdr_face_Y);
}
bdr_face_restrict_lex->AddMultTranspose(bdr_face_Y, y);
bdr_face_restrict_lex->AddMultTransposeInPlace(bdr_face_Y, y);
}
}
}
@@ -418,7 +418,7 @@ void PABilinearFormExtension::Mult(const Vector &x, Vector &y) const
{
intFaceIntegrators[i]->AddMultPA(int_face_X, int_face_Y);
}
int_face_restrict_lex->AddMultTranspose(int_face_Y, y);
int_face_restrict_lex->AddMultTransposeInPlace(int_face_Y, y);
}
}
@@ -434,7 +434,7 @@ void PABilinearFormExtension::Mult(const Vector &x, Vector &y) const
{
bdrFaceIntegrators[i]->AddMultPA(bdr_face_X, bdr_face_Y);
}
bdr_face_restrict_lex->AddMultTranspose(bdr_face_Y, y);
bdr_face_restrict_lex->AddMultTransposeInPlace(bdr_face_Y, y);
}
}
}
@@ -475,7 +475,7 @@ void PABilinearFormExtension::MultTranspose(const Vector &x, Vector &y) const
{
intFaceIntegrators[i]->AddMultTransposePA(int_face_X, int_face_Y);
}
int_face_restrict_lex->AddMultTranspose(int_face_Y, y);
int_face_restrict_lex->AddMultTransposeInPlace(int_face_Y, y);
}
}
@@ -491,7 +491,7 @@ void PABilinearFormExtension::MultTranspose(const Vector &x, Vector &y) const
{
bdrFaceIntegrators[i]->AddMultTransposePA(bdr_face_X, bdr_face_Y);
}
bdr_face_restrict_lex->AddMultTranspose(bdr_face_Y, y);
bdr_face_restrict_lex->AddMultTransposeInPlace(bdr_face_Y, y);
}
}
}
@@ -529,7 +529,7 @@ void EABilinearFormExtension::Assemble()
}
faceDofs = trial_fes ->
GetTraceElement(0, trial_fes->GetMesh()->GetFaceBaseGeometry(0)) ->
GetTraceElement(0, trial_fes->GetMesh()->GetFaceGeometry(0)) ->
GetDof();
MFEM_VERIFY(a->GetBBFI()->Size() == 0,
@@ -668,7 +668,7 @@ void EABilinearFormExtension::Mult(const Vector &x, Vector &y) const
Y(j, 0, f) += res;
});
// Apply the Interior Face Restriction transposed
int_face_restrict_lex->AddMultTranspose(int_face_Y, y);
int_face_restrict_lex->AddMultTransposeInPlace(int_face_Y, y);
}
}
@@ -699,7 +699,7 @@ void EABilinearFormExtension::Mult(const Vector &x, Vector &y) const
Y(j, f) += res;
});
// Apply the Boundary Face Restriction transposed
bdr_face_restrict_lex->AddMultTranspose(bdr_face_Y, y);
bdr_face_restrict_lex->AddMultTransposeInPlace(bdr_face_Y, y);
}
}
}
@@ -796,7 +796,7 @@ void EABilinearFormExtension::MultTranspose(const Vector &x, Vector &y) const
Y(j, 0, f) += res;
});
// Apply the Interior Face Restriction transposed
int_face_restrict_lex->AddMultTranspose(int_face_Y, y);
int_face_restrict_lex->AddMultTransposeInPlace(int_face_Y, y);
}
}
@@ -827,7 +827,7 @@ void EABilinearFormExtension::MultTranspose(const Vector &x, Vector &y) const
Y(j, f) += res;
});
// Apply the Boundary Face Restriction transposed
bdr_face_restrict_lex->AddMultTranspose(bdr_face_Y, y);
bdr_face_restrict_lex->AddMultTransposeInPlace(bdr_face_Y, y);
}
}
}
@@ -955,6 +955,10 @@ void FABilinearFormExtension::Assemble()
}
a->mat = mat;
}
if ( a->sort_sparse_matrix )
{
a->mat->SortColumnIndices();
}
}
@@ -975,6 +979,9 @@ void FABilinearFormExtension::RAP(OperatorHandle &A)
void FABilinearFormExtension::EliminateBC(const Array<int> &ess_dofs,
OperatorHandle &A)
{
MFEM_VERIFY(a->diag_policy == DiagonalPolicy::DIAG_ONE,
"Only DiagonalPolicy::DIAG_ONE supported with"
" FABilinearFormExtension.");
#ifdef MFEM_USE_MPI
if ( dynamic_cast<ParBilinearForm*>(a) )
{
+1 -5
View File
@@ -208,10 +208,6 @@ public:
Vector &x, Vector &b,
OperatorHandle &A, Vector &X, Vector &B) = 0;
virtual void AddMult(const Vector &x, Vector &y, const double c=1.0) const = 0;
virtual void AddMultTranspose(const Vector &x, Vector &y,
const double c=1.0) const = 0;
virtual void AssembleDiagonal_ADAt(const Vector &D, Vector &diag) const = 0;
virtual void Update() = 0;
@@ -287,7 +283,7 @@ public:
/// Partial assembly of all internal integrators
void Assemble();
void AddMult(const Vector &x, Vector &y, const double c) const;
void AddMult(const Vector &x, Vector &y, const double c=1.0) const;
void AddMultTranspose(const Vector &x, Vector &y, const double c=1.0) const;
+205 -2
View File
@@ -2003,6 +2003,83 @@ void CurlCurlIntegrator::AssembleElementMatrix
}
}
void CurlCurlIntegrator::AssembleElementMatrix2(const FiniteElement &trial_fe,
const FiniteElement &test_fe,
ElementTransformation &Trans,
DenseMatrix &elmat)
{
int tr_nd = trial_fe.GetDof();
int te_nd = test_fe.GetDof();
dim = trial_fe.GetDim();
int dimc = trial_fe.GetCurlDim();
double w;
#ifdef MFEM_THREAD_SAFE
Vector D;
DenseMatrix curlshape(tr_nd,dimc), curlshape_dFt(tr_nd,dimc), M;
DenseMatrix te_curlshape(te_nd,dimc), te_curlshape_dFt(te_nd,dimc);
#else
curlshape.SetSize(tr_nd,dimc);
curlshape_dFt.SetSize(tr_nd,dimc);
te_curlshape.SetSize(te_nd,dimc);
te_curlshape_dFt.SetSize(te_nd,dimc);
#endif
elmat.SetSize(te_nd, tr_nd);
if (MQ) { M.SetSize(dimc); }
if (DQ) { D.SetSize(dimc); }
const IntegrationRule *ir = IntRule;
if (ir == NULL)
{
int order;
if (trial_fe.Space() == FunctionSpace::Pk)
{
order = test_fe.GetOrder() + trial_fe.GetOrder() - 2;
}
else
{
order = test_fe.GetOrder() + trial_fe.GetOrder() + trial_fe.GetDim() - 1;
}
ir = &IntRules.Get(trial_fe.GetGeomType(), order);
}
elmat = 0.0;
for (int i = 0; i < ir->GetNPoints(); i++)
{
const IntegrationPoint &ip = ir->IntPoint(i);
Trans.SetIntPoint(&ip);
w = ip.weight * Trans.Weight();
trial_fe.CalcPhysCurlShape(Trans, curlshape_dFt);
test_fe.CalcPhysCurlShape(Trans, te_curlshape_dFt);
if (MQ)
{
MQ->Eval(M, Trans, ip);
M *= w;
Mult(te_curlshape_dFt, M, te_curlshape);
AddMultABt(te_curlshape, curlshape_dFt, elmat);
}
else if (DQ)
{
DQ->Eval(D, Trans, ip);
D *= w;
AddMultADBt(te_curlshape_dFt,D,curlshape_dFt,elmat);
}
else
{
if (Q)
{
w *= Q->Eval(Trans, ip);
}
curlshape_dFt *= w;
AddMultABt(te_curlshape_dFt, curlshape_dFt, elmat);
}
}
}
void CurlCurlIntegrator
::ComputeElementFlux(const FiniteElement &el, ElementTransformation &Trans,
Vector &u, const FiniteElement &fluxelem, Vector &flux,
@@ -2240,6 +2317,84 @@ double VectorCurlCurlIntegrator::GetElementEnergy(
return 0.5 * energy;
}
void MixedCurlIntegrator::AssembleElementMatrix2(
const FiniteElement &trial_fe, const FiniteElement &test_fe,
ElementTransformation &Trans, DenseMatrix &elmat)
{
int dim = trial_fe.GetDim();
int trial_dof = trial_fe.GetDof();
int test_dof = test_fe.GetDof();
int dimc = (dim == 3) ? 3 : 1;
MFEM_VERIFY(trial_fe.GetMapType() == mfem::FiniteElement::H_CURL ||
(dim == 2 && trial_fe.GetMapType() == mfem::FiniteElement::VALUE),
"Trial finite element must be either 2D/3D H(Curl) or 2D H1");
MFEM_VERIFY(test_fe.GetMapType() == mfem::FiniteElement::VALUE ||
test_fe.GetMapType() == mfem::FiniteElement::INTEGRAL,
"Test finite element must be in H1/L2");
bool spaceH1 = (trial_fe.GetMapType() == mfem::FiniteElement::VALUE);
if (spaceH1)
{
dshape.SetSize(trial_dof,dim);
curlshape.SetSize(trial_dof,dim);
dimc = dim;
}
else
{
curlshape.SetSize(trial_dof,dimc);
elmat_comp.SetSize(test_dof, trial_dof);
}
elmat.SetSize(dimc * test_dof, trial_dof);
shape.SetSize(test_dof);
elmat = 0.0;
double c;
Vector d_col;
const IntegrationRule *ir = IntRule;
if (ir == NULL)
{
int order = trial_fe.GetOrder() + test_fe.GetOrder() + Trans.OrderJ();
ir = &IntRules.Get(trial_fe.GetGeomType(), order);
}
for (int i = 0; i < ir->GetNPoints(); i++)
{
const IntegrationPoint &ip = ir->IntPoint(i);
Trans.SetIntPoint(&ip);
if (spaceH1)
{
trial_fe.CalcPhysDShape(Trans, dshape);
dshape.GradToVectorCurl2D(curlshape);
}
else
{
trial_fe.CalcPhysCurlShape(Trans, curlshape);
}
test_fe.CalcPhysShape(Trans, shape);
c = ip.weight*Trans.Weight();
if (Q)
{
c *= Q->Eval(Trans, ip);
}
shape *= c;
for (int d = 0; d < dimc; ++d)
{
double * curldata = &(curlshape.GetData())[d*trial_dof];
for (int jj = 0; jj < trial_dof; ++jj)
{
for (int ii = 0; ii < test_dof; ++ii)
{
elmat(d * test_dof + ii, jj) += shape(ii) * curldata[jj];
}
}
}
}
}
void VectorFEMassIntegrator::AssembleElementMatrix(
const FiniteElement &el,
@@ -2586,6 +2741,54 @@ void DivDivIntegrator::AssembleElementMatrix(
}
}
void DivDivIntegrator::AssembleElementMatrix2(
const FiniteElement &trial_fe,
const FiniteElement &test_fe,
ElementTransformation &Trans,
DenseMatrix &elmat)
{
int tr_nd = trial_fe.GetDof();
int te_nd = test_fe.GetDof();
double c;
#ifdef MFEM_THREAD_SAFE
Vector divshape(tr_nd);
Vector te_divshape(te_nd);
#else
divshape.SetSize(tr_nd);
te_divshape.SetSize(te_nd);
#endif
elmat.SetSize(te_nd,tr_nd);
const IntegrationRule *ir = IntRule;
if (ir == NULL)
{
int order = 2 * max(test_fe.GetOrder(),
trial_fe.GetOrder()) - 2; // <--- OK for RTk
ir = &IntRules.Get(test_fe.GetGeomType(), order);
}
elmat = 0.0;
for (int i = 0; i < ir -> GetNPoints(); i++)
{
const IntegrationPoint &ip = ir->IntPoint(i);
trial_fe.CalcDivShape(ip,divshape);
test_fe.CalcDivShape(ip,te_divshape);
Trans.SetIntPoint (&ip);
c = ip.weight / Trans.Weight();
if (Q)
{
c *= Q -> Eval (Trans, ip);
}
te_divshape *= c;
AddMultVWt(te_divshape, divshape, elmat);
}
}
void VectorDiffusionIntegrator::AssembleElementMatrix(
const FiniteElement &el,
@@ -3780,7 +3983,7 @@ void NormalTraceJumpIntegrator::AssembleFaceMatrix(
for (i = 0; i < ndof1; i++)
for (j = 0; j < face_ndof; j++)
{
elmat(i, j) -= shape1_n(i) * face_shape(j);
elmat(i, j) += shape1_n(i) * face_shape(j);
}
if (ndof2)
{
@@ -3788,7 +3991,7 @@ void NormalTraceJumpIntegrator::AssembleFaceMatrix(
for (i = 0; i < ndof2; i++)
for (j = 0; j < face_ndof; j++)
{
elmat(ndof1+i, j) += shape2_n(i) * face_shape(j);
elmat(ndof1+i, j) -= shape2_n(i) * face_shape(j);
}
}
}
+49 -7
View File
@@ -215,10 +215,10 @@ public:
function by any coefficients describing the
integrator.
@param[in] ir If passed (the default value is NULL), the implementation
of the method will ignore the integration rule provided
by the @a fluxelem parameter and, instead, compute the
discrete flux at the points specified by the integration
rule @a ir.
of the method will ignore the integration rule provided
by the @a fluxelem parameter and, instead, compute the
discrete flux at the points specified by the integration
rule @a ir.
*/
virtual void ComputeElementFlux(const FiniteElement &el,
ElementTransformation &Trans,
@@ -2174,6 +2174,7 @@ public:
/** Class for local mass matrix assembling a(u,v) := (Q u, v) */
class MassIntegrator: public BilinearFormIntegrator
{
friend class DGMassInverse;
protected:
#ifndef MFEM_THREAD_SAFE
Vector shape, te_shape;
@@ -2524,6 +2525,7 @@ private:
#ifndef MFEM_THREAD_SAFE
Vector D;
DenseMatrix curlshape, curlshape_dFt, M;
DenseMatrix te_curlshape, te_curlshape_dFt;
DenseMatrix vshape, projcurl;
#endif
@@ -2557,6 +2559,11 @@ public:
ElementTransformation &Trans,
DenseMatrix &elmat);
virtual void AssembleElementMatrix2(const FiniteElement &trial_fe,
const FiniteElement &test_fe,
ElementTransformation &Trans,
DenseMatrix &elmat);
virtual void ComputeElementFlux(const FiniteElement &el,
ElementTransformation &Trans,
Vector &u, const FiniteElement &fluxelem,
@@ -2602,6 +2609,35 @@ public:
const Vector &elfun);
};
/** Class for integrating the bilinear form a(u,v) := (Q curl u, v) where Q is
an optional scalar coefficient, and v is a vector with components v_i in
the L2 or H1 space. This integrator handles 3 cases:
(a) u H(curl) in 3D, v is a 3D vector with components v_i in L^2 or H^1
(b) u H(curl) in 2D, v is a scalar field in L^2 or H^1
(c) u is a scalar field in H^1, i.e, curl u := [0 1;-1 0]grad u and v is a
2D vector field with components v_i in L^2 or H^1 space.
Note: Case (b) can also be handled by MixedScalarCurlIntegrator */
class MixedCurlIntegrator : public BilinearFormIntegrator
{
protected:
Coefficient *Q;
private:
Vector shape;
DenseMatrix dshape;
DenseMatrix curlshape;
DenseMatrix elmat_comp;
public:
MixedCurlIntegrator() : Q{NULL} { }
MixedCurlIntegrator(Coefficient *q_) : Q{q_} { }
MixedCurlIntegrator(Coefficient &q) : Q{&q} { }
virtual void AssembleElementMatrix2(const FiniteElement &trial_fe,
const FiniteElement &test_fe,
ElementTransformation &Trans,
DenseMatrix &elmat);
};
/** Integrator for (Q u, v), where Q is an optional coefficient (of type scalar,
vector (diagonal matrix), or matrix), trial function u is in H(Curl) or
H(Div), and test function v is in H(Curl), H(Div), or v=(v1,...,vn), where
@@ -2725,7 +2761,7 @@ protected:
private:
#ifndef MFEM_THREAD_SAFE
Vector divshape;
Vector divshape, te_divshape;
#endif
// PA extension
@@ -2743,6 +2779,12 @@ public:
virtual void AssembleElementMatrix(const FiniteElement &el,
ElementTransformation &Trans,
DenseMatrix &elmat);
virtual void AssembleElementMatrix2(const FiniteElement &trial_fe,
const FiniteElement &test_fe,
ElementTransformation &Trans,
DenseMatrix &elmat);
const Coefficient *GetCoefficient() const { return Q; }
};
@@ -3017,8 +3059,8 @@ public:
/** Integrator for the DG form:
- < {(Q grad(u)).n}, [v] > + sigma < [u], {(Q grad(v)).n} >
+ kappa < {h^{-1} Q} [u], [v] >,
- < {(Q grad(u)).n}, [v] > + sigma < [u], {(Q grad(v)).n} >
+ kappa < {h^{-1} Q} [u], [v] >
where Q is a scalar or matrix diffusion coefficient and u, v are the trial
and test spaces, respectively. The parameters sigma and kappa determine the
+3 -58
View File
@@ -12,6 +12,7 @@
#include "../general/forall.hpp"
#include "bilininteg.hpp"
#include "gridfunc.hpp"
#include "qfunction.hpp"
#include "ceed/integrators/convection/convection.hpp"
#include "quadinterpolator.hpp"
@@ -1408,66 +1409,10 @@ void ConvectionIntegrator::AssemblePA(const FiniteElementSpace &fes)
dofs1D = maps->ndof;
quad1D = maps->nqpt;
pa_data.SetSize(symmDims * nq * ne, mt);
Vector vel;
if (VectorConstantCoefficient *cQ =
dynamic_cast<VectorConstantCoefficient*>(Q))
{
vel = cQ->GetVec();
}
else if (VectorGridFunctionCoefficient *vgfQ =
dynamic_cast<VectorGridFunctionCoefficient*>(Q))
{
vel.SetSize(dim * nq * ne, mt);
const GridFunction *gf = vgfQ->GetGridFunction();
const FiniteElementSpace &gf_fes = *gf->FESpace();
const QuadratureInterpolator *qi(gf_fes.GetQuadratureInterpolator(*ir));
const bool use_tensor_products = UsesTensorBasis(gf_fes);
const ElementDofOrdering ordering = use_tensor_products ?
ElementDofOrdering::LEXICOGRAPHIC :
ElementDofOrdering::NATIVE;
const Operator *R = gf_fes.GetElementRestriction(ordering);
QuadratureSpace qs(*mesh, *ir);
CoefficientVector vel(*Q, qs, CoefficientStorage::COMPRESSED);
Vector xe(R->Height(), mt);
xe.UseDevice(true);
R->Mult(*gf, xe);
qi->SetOutputLayout(QVectorLayout::byVDIM);
qi->DisableTensorProducts(!use_tensor_products);
qi->Values(xe,vel);
}
else if (VectorQuadratureFunctionCoefficient* vqfQ =
dynamic_cast<VectorQuadratureFunctionCoefficient*>(Q))
{
const QuadratureFunction &qFun = vqfQ->GetQuadFunction();
MFEM_VERIFY(qFun.Size() == dim * nq * ne,
"Incompatible QuadratureFunction dimension \n");
MFEM_VERIFY(ir == &qFun.GetSpace()->GetElementIntRule(0),
"IntegrationRule used within integrator and in"
" QuadratureFunction appear to be different");
qFun.Read();
vel.MakeRef(const_cast<QuadratureFunction &>(qFun),0);
}
else
{
vel.SetSize(dim * nq * ne);
auto C = Reshape(vel.HostWrite(), dim, nq, ne);
DenseMatrix MQ_ir;
for (int e = 0; e < ne; ++e)
{
ElementTransformation& T = *fes.GetElementTransformation(e);
Q->Eval(MQ_ir, T, *ir);
for (int q = 0; q < nq; ++q)
{
for (int i = 0; i < dim; ++i)
{
C(i,q,e) = MQ_ir(i,q);
}
}
}
}
PAConvectionSetup(dim, nq, ne, ir->GetWeights(), geom->J,
vel, alpha, pa_data);
}
+39 -105
View File
@@ -12,6 +12,7 @@
#include "../general/forall.hpp"
#include "bilininteg.hpp"
#include "gridfunc.hpp"
#include "qfunction.hpp"
#include "restriction.hpp"
using namespace std;
@@ -144,7 +145,7 @@ void DGTraceIntegrator::SetupPA(const FiniteElementSpace &fes, FaceType type)
// Assumes tensor-product elements
Mesh *mesh = fes.GetMesh();
const FiniteElement &el =
*fes.GetTraceElement(0, fes.GetMesh()->GetFaceBaseGeometry(0));
*fes.GetTraceElement(0, fes.GetMesh()->GetFaceGeometry(0));
FaceElementTransformations &T0 =
*fes.GetMesh()->GetFaceElementTransformations(0);
const IntegrationRule *ir = IntRule?
@@ -161,88 +162,24 @@ void DGTraceIntegrator::SetupPA(const FiniteElementSpace &fes, FaceType type)
dofs1D = maps->ndof;
quad1D = maps->nqpt;
pa_data.SetSize(symmDims * nq * nf, Device::GetMemoryType());
Vector vel;
if (VectorConstantCoefficient *c_u = dynamic_cast<VectorConstantCoefficient*>
(u))
{
vel = c_u->GetVec();
}
else if (VectorQuadratureFunctionCoefficient* qf_u =
dynamic_cast<VectorQuadratureFunctionCoefficient*>(u))
{
// Assumed to be in lexicographical ordering
const QuadratureFunction &qFun = qf_u->GetQuadFunction();
MFEM_VERIFY(qFun.Size() == dim * nq * nf,
"Incompatible QuadratureFunction dimension \n");
MFEM_VERIFY(ir == &qFun.GetSpace()->GetElementIntRule(0),
"IntegrationRule used within integrator and in"
" QuadratureFunction appear to be different");
qFun.Read();
vel.MakeRef(const_cast<QuadratureFunction &>(qFun),0);
}
else
FaceQuadratureSpace qs(*mesh, *ir, type);
CoefficientVector vel(*u, qs, CoefficientStorage::COMPRESSED);
CoefficientVector r(qs, CoefficientStorage::COMPRESSED);
if (rho == nullptr)
{
vel.SetSize(dim * nq * nf);
auto C = Reshape(vel.HostWrite(), dim, nq, nf);
Vector Vq(dim);
int f_ind = 0;
for (int f = 0; f < mesh->GetNumFacesWithGhost(); ++f)
{
Mesh::FaceInformation face = mesh->GetFaceInformation(f);
if (face.IsNonconformingCoarse())
{
// We skip nonconforming coarse faces as they are treated
// by the corresponding nonconforming fine faces.
continue;
}
else if ( face.IsOfFaceType(type) )
{
const int mask = FaceElementTransformations::HAVE_ELEM1 |
FaceElementTransformations::HAVE_LOC1;
FaceElementTransformations &T =
*fes.GetMesh()->GetFaceElementTransformations(f, mask);
for (int q = 0; q < nq; ++q)
{
// Convert to lexicographic ordering
int iq = ToLexOrdering(dim, face.element[0].local_face_id,
quad1D, q);
T.SetAllIntPoints(&ir->IntPoint(q));
const IntegrationPoint &eip1 = T.GetElement1IntPoint();
u->Eval(Vq, *T.Elem1, eip1);
for (int i = 0; i < dim; ++i)
{
C(i,iq,f_ind) = Vq(i);
}
}
f_ind++;
}
}
MFEM_VERIFY(f_ind==nf, "Incorrect number of faces.");
r.SetConstant(1.0);
}
Vector r;
if (rho==nullptr)
else if (ConstantCoefficient *const_rho = dynamic_cast<ConstantCoefficient*>
(rho))
{
r.SetSize(1);
r(0) = 1.0;
}
else if (ConstantCoefficient *c_rho = dynamic_cast<ConstantCoefficient*>(rho))
{
r.SetSize(1);
r(0) = c_rho->constant;
r.SetConstant(const_rho->constant);
}
else if (QuadratureFunctionCoefficient* qf_rho =
dynamic_cast<QuadratureFunctionCoefficient*>(rho))
{
const QuadratureFunction &qFun = qf_rho->GetQuadFunction();
MFEM_VERIFY(qFun.Size() == nq * nf,
"Incompatible QuadratureFunction dimension \n");
MFEM_VERIFY(ir == &qFun.GetSpace()->GetElementIntRule(0),
"IntegrationRule used within integrator and in"
" QuadratureFunction appear to be different");
qFun.Read();
r.MakeRef(const_cast<QuadratureFunction &>(qFun),0);
r.MakeRef(qf_rho->GetQuadFunction());
}
else
{
@@ -254,45 +191,42 @@ void DGTraceIntegrator::SetupPA(const FiniteElementSpace &fes, FaceType type)
for (int f = 0; f < mesh->GetNumFacesWithGhost(); ++f)
{
Mesh::FaceInformation face = mesh->GetFaceInformation(f);
if (face.IsNonconformingCoarse())
if (face.IsNonconformingCoarse() || !face.IsOfFaceType(type))
{
// We skip nonconforming coarse faces as they are treated
// by the corresponding nonconforming fine faces.
continue;
}
else if ( face.IsOfFaceType(type) )
FaceElementTransformations &T =
*fes.GetMesh()->GetFaceElementTransformations(f);
for (int q = 0; q < nq; ++q)
{
FaceElementTransformations &T =
*fes.GetMesh()->GetFaceElementTransformations(f);
for (int q = 0; q < nq; ++q)
// Convert to lexicographic ordering
int iq = ToLexOrdering(dim, face.element[0].local_face_id,
quad1D, q);
T.SetAllIntPoints(&ir->IntPoint(q));
const IntegrationPoint &eip1 = T.GetElement1IntPoint();
const IntegrationPoint &eip2 = T.GetElement2IntPoint();
double rq;
if (face.IsBoundary())
{
// Convert to lexicographic ordering
int iq = ToLexOrdering(dim, face.element[0].local_face_id,
quad1D, q);
T.SetAllIntPoints(&ir->IntPoint(q));
const IntegrationPoint &eip1 = T.GetElement1IntPoint();
const IntegrationPoint &eip2 = T.GetElement2IntPoint();
double rq;
if ( face.IsBoundary() )
{
rq = rho->Eval(*T.Elem1, eip1);
}
else
{
double udotn = 0.0;
for (int d=0; d<dim; ++d)
{
udotn += C_vel(d,iq,f_ind)*n(iq,d,f_ind);
}
if (udotn >= 0.0) { rq = rho->Eval(*T.Elem2, eip2); }
else { rq = rho->Eval(*T.Elem1, eip1); }
}
C(iq,f_ind) = rq;
rq = rho->Eval(*T.Elem1, eip1);
}
f_ind++;
else
{
double udotn = 0.0;
for (int d=0; d<dim; ++d)
{
udotn += C_vel(d,iq,f_ind)*n(iq,d,f_ind);
}
if (udotn >= 0.0) { rq = rho->Eval(*T.Elem2, eip2); }
else { rq = rho->Eval(*T.Elem1, eip1); }
}
C(iq,f_ind) = rq;
}
f_ind++;
}
MFEM_VERIFY(f_ind==nf, "Incorrect number of faces.");
}
+12 -110
View File
@@ -12,6 +12,7 @@
#include "../general/forall.hpp"
#include "bilininteg.hpp"
#include "gridfunc.hpp"
#include "qfunction.hpp"
#include "ceed/integrators/diffusion/diffusion.hpp"
using namespace std;
@@ -390,120 +391,21 @@ void DiffusionIntegrator::AssemblePA(const FiniteElementSpace &fes)
maps = &el.GetDofToQuad(*ir, DofToQuad::TENSOR);
dofs1D = maps->ndof;
quad1D = maps->nqpt;
int coeffDim = 1;
Vector coeff;
const int MQfullDim = MQ ? MQ->GetHeight() * MQ->GetWidth() : 0;
if (auto *SMQ = dynamic_cast<SymmetricMatrixCoefficient *>(MQ))
{
MFEM_VERIFY(SMQ->GetSize() == dim, "");
coeffDim = symmDims;
coeff.SetSize(symmDims * nq * ne);
DenseSymmetricMatrix sym_mat;
sym_mat.SetSize(dim);
QuadratureSpace qs(*mesh, *ir);
CoefficientVector coeff(qs, CoefficientStorage::COMPRESSED);
auto C = Reshape(coeff.HostWrite(), symmDims, nq, ne);
if (MQ) { coeff.ProjectTranspose(*MQ); }
else if (VQ) { coeff.Project(*VQ); }
else if (Q) { coeff.Project(*Q); }
else { coeff.SetConstant(1.0); }
for (int e=0; e<ne; ++e)
{
ElementTransformation *tr = mesh->GetElementTransformation(e);
for (int p=0; p<nq; ++p)
{
SMQ->Eval(sym_mat, *tr, ir->IntPoint(p));
int cnt = 0;
for (int i=0; i<dim; ++i)
for (int j=i; j<dim; ++j, ++cnt)
{
C(cnt, p, e) = sym_mat(i,j);
}
}
}
}
else if (MQ)
{
symmetric = false;
MFEM_VERIFY(MQ->GetHeight() == dim && MQ->GetWidth() == dim, "");
const int coeff_dim = coeff.GetVDim();
symmetric = (coeff_dim != dims*dims);
const int pa_size = symmetric ? symmDims : dims*dims;
coeffDim = MQfullDim;
coeff.SetSize(MQfullDim * nq * ne);
DenseMatrix mat;
mat.SetSize(dim);
auto C = Reshape(coeff.HostWrite(), MQfullDim, nq, ne);
for (int e=0; e<ne; ++e)
{
ElementTransformation *tr = mesh->GetElementTransformation(e);
for (int p=0; p<nq; ++p)
{
MQ->Eval(mat, *tr, ir->IntPoint(p));
for (int i=0; i<dim; ++i)
for (int j=0; j<dim; ++j)
{
C(j+(i*dim), p, e) = mat(i,j);
}
}
}
}
else if (VQ)
{
MFEM_VERIFY(VQ->GetVDim() == dim, "");
coeffDim = VQ->GetVDim();
coeff.SetSize(coeffDim * nq * ne);
auto C = Reshape(coeff.HostWrite(), coeffDim, nq, ne);
Vector DM(coeffDim);
for (int e=0; e<ne; ++e)
{
ElementTransformation *tr = mesh->GetElementTransformation(e);
for (int p=0; p<nq; ++p)
{
VQ->Eval(DM, *tr, ir->IntPoint(p));
for (int i=0; i<coeffDim; ++i)
{
C(i, p, e) = DM[i];
}
}
}
}
else if (Q == nullptr)
{
coeff.SetSize(1);
coeff(0) = 1.0;
}
else if (ConstantCoefficient* cQ = dynamic_cast<ConstantCoefficient*>(Q))
{
coeff.SetSize(1);
coeff(0) = cQ->constant;
}
else if (QuadratureFunctionCoefficient* qfQ =
dynamic_cast<QuadratureFunctionCoefficient*>(Q))
{
const QuadratureFunction &qFun = qfQ->GetQuadFunction();
MFEM_VERIFY(qFun.Size() == ne*nq,
"Incompatible QuadratureFunction dimension \n");
MFEM_VERIFY(ir == &qFun.GetSpace()->GetElementIntRule(0),
"IntegrationRule used within integrator and in"
" QuadratureFunction appear to be different");
qFun.Read();
coeff.MakeRef(const_cast<QuadratureFunction &>(qFun),0);
}
else
{
coeff.SetSize(nq * ne);
auto C = Reshape(coeff.HostWrite(), nq, ne);
for (int e = 0; e < ne; ++e)
{
ElementTransformation& T = *fes.GetElementTransformation(e);
for (int q = 0; q < nq; ++q)
{
C(q,e) = Q->Eval(T, ir->IntPoint(q));
}
}
}
pa_data.SetSize((symmetric ? symmDims : MQfullDim) * nq * ne, mt);
PADiffusionSetup(dim, sdim, dofs1D, quad1D, coeffDim, ne, ir->GetWeights(),
pa_data.SetSize(pa_size * nq * ne, mt);
PADiffusionSetup(dim, sdim, dofs1D, quad1D, coeff_dim, ne, ir->GetWeights(),
geom->J, coeff, pa_data);
}
+3 -39
View File
@@ -12,6 +12,7 @@
#include "../general/forall.hpp"
#include "bilininteg.hpp"
#include "gridfunc.hpp"
#include "qfunction.hpp"
using namespace std;
@@ -209,44 +210,8 @@ void GradientIntegrator::AssemblePA(const FiniteElementSpace &trial_fes,
"PA requires test and trial space to have same number of quadrature points!");
pa_data.SetSize(nq * dimsToStore * ne, Device::GetMemoryType());
Vector coeff;
if (Q == nullptr)
{
coeff.SetSize(1);
coeff(0) = 1.0;
}
else if (ConstantCoefficient* cQ = dynamic_cast<ConstantCoefficient*>(Q))
{
coeff.SetSize(1);
coeff(0) = cQ->constant;
}
else if (QuadratureFunctionCoefficient* qfQ =
dynamic_cast<QuadratureFunctionCoefficient*>(Q))
{
const QuadratureFunction &qFun = qfQ->GetQuadFunction();
MFEM_VERIFY(qFun.Size() == ne*nq,
"Incompatible QuadratureFunction dimension \n");
MFEM_VERIFY(ir == &qFun.GetSpace()->GetElementIntRule(0),
"IntegrationRule used within integrator and in"
" QuadratureFunction appear to be different");
qFun.Read();
coeff.MakeRef(const_cast<QuadratureFunction &>(qFun),0);
}
else
{
coeff.SetSize(nq * ne);
auto C = Reshape(coeff.HostWrite(), nq, ne);
for (int e = 0; e < ne; ++e)
{
ElementTransformation& T = *trial_fes.GetElementTransformation(e);
for (int q = 0; q < nq; ++q)
{
C(q,e) = Q->Eval(T, ir->IntPoint(q));
}
}
}
QuadratureSpace qs(*mesh, *ir);
CoefficientVector coeff(Q, qs, CoefficientStorage::COMPRESSED);
PAGradientSetup(dim, trial_dofs1D, test_dofs1D, quad1D,
ne, ir->GetWeights(), geom->J, coeff, pa_data);
@@ -865,4 +830,3 @@ void GradientIntegrator::AddMultTransposePA(const Vector &x, Vector &y) const
}
} // namespace mfem
+33 -169
View File
@@ -12,6 +12,7 @@
#include "../general/forall.hpp"
#include "bilininteg.hpp"
#include "gridfunc.hpp"
#include "qspace.hpp"
using namespace std;
@@ -967,8 +968,6 @@ void CurlCurlIntegrator::AssemblePA(const FiniteElementSpace &fes)
dim = mesh->Dimension();
MFEM_VERIFY(dim == 2 || dim == 3, "");
const int dimc = (dim == 3) ? 3 : 1;
ne = fes.GetNE();
geom = mesh->GetGeometricFactors(*ir, GeometricFactors::JACOBIANS);
mapsC = &el->GetDofToQuad(*ir, DofToQuad::TENSOR);
@@ -978,88 +977,19 @@ void CurlCurlIntegrator::AssemblePA(const FiniteElementSpace &fes)
MFEM_VERIFY(dofs1D == mapsO->ndof + 1 && quad1D == mapsO->nqpt, "");
auto SMQ = dynamic_cast<SymmetricMatrixCoefficient *>(MQ);
QuadratureSpace qs(*mesh, *ir);
CoefficientVector coeff(qs, CoefficientStorage::SYMMETRIC);
if (Q) { coeff.Project(*Q); }
else if (MQ) { coeff.ProjectTranspose(*MQ); }
else if (DQ) { coeff.Project(*DQ); }
else { coeff.SetConstant(1.0); }
const int MQsymmDim = SMQ ? (SMQ->GetSize() * (SMQ->GetSize() + 1)) / 2 : 0;
const int MQfullDim = MQ ? (MQ->GetHeight() * MQ->GetWidth()) : 0;
const int MQdim = SMQ ? MQsymmDim : MQfullDim;
const int coeffDim = MQ ? MQdim : (DQ ? DQ->GetVDim() : 1);
symmetric = (SMQ || MQ == NULL);
const int symmDims = (dims * (dims + 1)) / 2; // 1x1: 1, 2x2: 3, 3x3: 6
const int ndata = (dim == 2) ? 1 : (symmetric ? symmDims : MQfullDim);
const int coeff_dim = coeff.GetVDim();
symmetric = (coeff_dim != dim*dim);
const int sym_dims = (dims * (dims + 1)) / 2; // 1x1: 1, 2x2: 3, 3x3: 6
const int ndata = (dim == 2) ? 1 : (symmetric ? sym_dims : dim*dim);
pa_data.SetSize(ndata * nq * ne, Device::GetMemoryType());
Vector coeff(coeffDim * ne * nq);
coeff = 1.0;
auto coeffh = Reshape(coeff.HostWrite(), coeffDim, nq, ne);
if (Q || DQ || MQ)
{
Vector DM(DQ ? coeffDim : 0);
DenseMatrix GM;
DenseSymmetricMatrix SM;
if (DQ)
{
MFEM_VERIFY(coeffDim == dimc, "");
}
if (SMQ)
{
SM.SetSize(dimc);
MFEM_VERIFY(SMQ->GetSize() == dimc, "");
}
else if (MQ)
{
GM.SetSize(dimc);
MFEM_VERIFY(coeffDim == MQdim, "");
MFEM_VERIFY(MQ->GetHeight() == dimc && MQ->GetWidth() == dimc, "");
}
for (int e=0; e<ne; ++e)
{
ElementTransformation *tr = mesh->GetElementTransformation(e);
for (int p=0; p<nq; ++p)
{
if (SMQ)
{
SMQ->Eval(SM, *tr, ir->IntPoint(p));
int cnt = 0;
for (int i=0; i<dimc; ++i)
for (int j=i; j<dimc; ++j, ++cnt)
{
coeffh(cnt, p, e) = SM(i,j);
}
}
else if (MQ)
{
MQ->Eval(GM, *tr, ir->IntPoint(p));
for (int i=0; i<dimc; ++i)
for (int j=0; j<dimc; ++j)
{
coeffh(j+(i*dimc), p, e) = GM(i,j);
}
}
else if (DQ)
{
DQ->Eval(DM, *tr, ir->IntPoint(p));
for (int i=0; i<coeffDim; ++i)
{
coeffh(i, p, e) = DM[i];
}
}
else
{
coeffh(0, p, e) = Q->Eval(*tr, ir->IntPoint(p));
}
}
}
}
if (el->GetDerivType() != mfem::FiniteElement::CURL)
{
MFEM_ABORT("Unknown kernel.");
@@ -1067,7 +997,7 @@ void CurlCurlIntegrator::AssemblePA(const FiniteElementSpace &fes)
if (dim == 3)
{
PACurlCurlSetup3D(quad1D, coeffDim, ne, ir->GetWeights(), geom->J, coeff,
PACurlCurlSetup3D(quad1D, coeff_dim, ne, ir->GetWeights(), geom->J, coeff,
pa_data);
}
else
@@ -2780,7 +2710,7 @@ void CurlCurlIntegrator::AssembleDiagonalPA(Vector& diag)
}
}
// Apply to x corresponding to DOF's in H^1 (trial), whose gradients are
// Apply to x corresponding to DOFs in H^1 (trial), whose gradients are
// integrated against H(curl) test functions corresponding to y.
void PAHcurlH1Apply3D(const int D1D,
const int Q1D,
@@ -2970,7 +2900,7 @@ void PAHcurlH1Apply3D(const int D1D,
}); // end of element loop
}
// Apply to x corresponding to DOF's in H(curl), integrated
// Apply to x corresponding to DOFs in H(curl), integrated
// against gradients of H^1 functions corresponding to y.
void PAHcurlH1ApplyTranspose3D(const int D1D,
const int Q1D,
@@ -3169,7 +3099,7 @@ void PAHcurlH1ApplyTranspose3D(const int D1D,
}); // end of element loop
}
// Apply to x corresponding to DOF's in H^1 (trial), whose gradients are
// Apply to x corresponding to DOFs in H^1 (trial), whose gradients are
// integrated against H(curl) test functions corresponding to y.
void PAHcurlH1Apply2D(const int D1D,
const int Q1D,
@@ -3293,7 +3223,7 @@ void PAHcurlH1Apply2D(const int D1D,
}); // end of element loop
}
// Apply to x corresponding to DOF's in H(curl), integrated
// Apply to x corresponding to DOFs in H(curl), integrated
// against gradients of H^1 functions corresponding to y.
void PAHcurlH1ApplyTranspose2D(const int D1D,
const int Q1D,
@@ -3489,20 +3419,8 @@ void MixedScalarCurlIntegrator::AssemblePA(const FiniteElementSpace &trial_fes,
pa_data.SetSize(nq * ne, Device::GetMemoryType());
Vector coeff(ne * nq);
coeff = 1.0;
auto coeffh = Reshape(coeff.HostWrite(), nq, ne);
if (Q)
{
for (int e=0; e<ne; ++e)
{
ElementTransformation *tr = mesh->GetElementTransformation(e);
for (int p=0; p<nq; ++p)
{
coeffh(p, e) = Q->Eval(*tr, ir->IntPoint(p));
}
}
}
QuadratureSpace qs(*mesh, *ir);
CoefficientVector coeff(Q, qs, CoefficientStorage::FULL);
if (dim == 2)
{
@@ -3593,38 +3511,11 @@ void MixedVectorCurlIntegrator::AssemblePA(const FiniteElementSpace &trial_fes,
const int ndata = curlSpaces ? (coeffDim == 1 ? 1 : 9) : symmDims;
pa_data.SetSize(ndata * nq * ne, Device::GetMemoryType());
Vector coeff(coeffDim * nq * ne);
coeff = 1.0;
auto coeffh = Reshape(coeff.HostWrite(), coeffDim, nq, ne);
if (Q || DQ)
{
Vector V(coeffDim);
if (DQ)
{
MFEM_VERIFY(DQ->GetVDim() == coeffDim, "");
}
for (int e=0; e<ne; ++e)
{
ElementTransformation *tr = mesh->GetElementTransformation(e);
for (int p=0; p<nq; ++p)
{
if (DQ)
{
DQ->Eval(V, *tr, ir->IntPoint(p));
for (int i=0; i<coeffDim; ++i)
{
coeffh(i, p, e) = V[i];
}
}
else
{
coeffh(0, p, e) = Q->Eval(*tr, ir->IntPoint(p));
}
}
}
}
QuadratureSpace qs(*mesh, *ir);
CoefficientVector coeff(qs, CoefficientStorage::FULL);
if (Q) { coeff.Project(*Q); }
else if (DQ) { coeff.Project(*DQ); }
else { coeff.SetConstant(1.0); }
if (testType == mfem::FiniteElement::CURL &&
trialType == mfem::FiniteElement::CURL && dim == 3)
@@ -3652,7 +3543,7 @@ void MixedVectorCurlIntegrator::AssemblePA(const FiniteElementSpace &trial_fes,
}
}
// Apply to x corresponding to DOF's in H(curl) (trial), whose curl is
// Apply to x corresponding to DOFs 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>
static void PAHcurlL2Apply3D(const int D1D,
@@ -4015,7 +3906,7 @@ static void PAHcurlL2Apply3D(const int D1D,
}); // end of element loop
}
// Apply to x corresponding to DOF's in H(curl) (trial), whose curl is
// Apply to x corresponding to DOFs 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>
static void SmemPAHcurlL2Apply3D(const int D1D,
@@ -4325,7 +4216,7 @@ static void SmemPAHcurlL2Apply3D(const int D1D,
ForallWrap<3>(true, NE, device_kernel, host_kernel, Q1D, Q1D, Q1D);
}
// Apply to x corresponding to DOF's in H(curl) (trial), whose curl is
// Apply to x corresponding to DOFs 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>
static void PAHcurlHdivApply3D(const int D1D,
@@ -4681,7 +4572,7 @@ static void PAHcurlHdivApply3D(const int D1D,
}); // end of element loop
}
// Apply to x corresponding to DOF's in H(div) (test), integrated against the
// Apply to x corresponding to DOFs in H(div) (test), integrated against the
// curl of H(curl) trial functions corresponding to y.
template<int MAX_D1D = HCURL_MAX_D1D, int MAX_Q1D = HCURL_MAX_Q1D>
static void PAHcurlHdivApply3DTranspose(const int D1D,
@@ -5146,38 +5037,11 @@ void MixedVectorWeakCurlIntegrator::AssemblePA(const FiniteElementSpace
pa_data.SetSize(ndata * nq * ne, Device::GetMemoryType());
Vector coeff(coeffDim * nq * ne);
coeff = 1.0;
auto coeffh = Reshape(coeff.HostWrite(), coeffDim, nq, ne);
if (Q || DQ)
{
Vector V(coeffDim);
if (DQ)
{
MFEM_VERIFY(DQ->GetVDim() == coeffDim, "");
}
for (int e=0; e<ne; ++e)
{
ElementTransformation *tr = mesh->GetElementTransformation(e);
for (int p=0; p<nq; ++p)
{
if (DQ)
{
DQ->Eval(V, *tr, ir->IntPoint(p));
for (int i=0; i<coeffDim; ++i)
{
coeffh(i, p, e) = V[i];
}
}
else
{
coeffh(0, p, e) = Q->Eval(*tr, ir->IntPoint(p));
}
}
}
}
QuadratureSpace qs(*mesh, *ir);
CoefficientVector coeff(qs, CoefficientStorage::FULL);
if (Q) { coeff.Project(*Q); }
else if (DQ) { coeff.Project(*DQ); }
else { coeff.SetConstant(1.0); }
if (trialType == mfem::FiniteElement::CURL && dim == 3)
{
@@ -5203,7 +5067,7 @@ void MixedVectorWeakCurlIntegrator::AssemblePA(const FiniteElementSpace
}
}
// Apply to x corresponding to DOF's in H(curl) (trial), integrated against curl
// Apply to x corresponding to DOFs 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>
static void PAHcurlL2Apply3DTranspose(const int D1D,
+7 -28
View File
@@ -12,6 +12,7 @@
#include "../general/forall.hpp"
#include "bilininteg.hpp"
#include "gridfunc.hpp"
#include "qspace.hpp"
using namespace std;
@@ -1513,19 +1514,8 @@ void DivDivIntegrator::AssemblePA(const FiniteElementSpace &fes)
pa_data.SetSize(nq * ne, Device::GetMemoryType());
Vector coeff(ne * nq);
coeff = 1.0;
if (Q)
{
for (int e=0; e<ne; ++e)
{
ElementTransformation *tr = mesh->GetElementTransformation(e);
for (int p=0; p<nq; ++p)
{
coeff[p + (e * nq)] = Q->Eval(*tr, ir->IntPoint(p));
}
}
}
QuadratureSpace qs(*mesh, *ir);
CoefficientVector coeff(Q, qs, CoefficientStorage::FULL);
if (el->GetDerivType() == mfem::FiniteElement::DIV && dim == 3)
{
@@ -1783,19 +1773,8 @@ VectorFEDivergenceIntegrator::AssemblePA(const FiniteElementSpace &trial_fes,
pa_data.SetSize(nq * ne, Device::GetMemoryType());
Vector coeff(ne * nq);
coeff = 1.0;
if (Q)
{
for (int e=0; e<ne; ++e)
{
ElementTransformation *tr = mesh->GetElementTransformation(e);
for (int p=0; p<nq; ++p)
{
coeff[p + (e * nq)] = Q->Eval(*tr, ir->IntPoint(p));
}
}
}
QuadratureSpace qs(*mesh, *ir);
CoefficientVector coeff(Q, qs, CoefficientStorage::FULL);
if (test_el->GetMapType() == FiniteElement::INTEGRAL)
{
@@ -1818,7 +1797,7 @@ VectorFEDivergenceIntegrator::AssemblePA(const FiniteElementSpace &trial_fes,
}
}
// Apply to x corresponding to DOF's in H(div) (trial), whose divergence is
// Apply to x corresponding to DOFs in H(div) (trial), whose divergence is
// integrated against L_2 test functions corresponding to y.
static void PAHdivL2Apply3D(const int D1D,
const int Q1D,
@@ -1981,7 +1960,7 @@ static void PAHdivL2Apply3D(const int D1D,
}); // end of element loop
}
// Apply to x corresponding to DOF's in H(div) (trial), whose divergence is
// Apply to x corresponding to DOFs in H(div) (trial), whose divergence is
// integrated against L_2 test functions corresponding to y.
static void PAHdivL2Apply2D(const int D1D,
const int Q1D,
+40 -565
View File
@@ -12,7 +12,9 @@
#include "../general/forall.hpp"
#include "bilininteg.hpp"
#include "gridfunc.hpp"
#include "qfunction.hpp"
#include "ceed/integrators/mass/mass.hpp"
#include "bilininteg_mass_pa.hpp"
using namespace std;
@@ -54,49 +56,15 @@ void MassIntegrator::AssemblePA(const FiniteElementSpace &fes)
dim = mesh->Dimension();
ne = fes.GetMesh()->GetNE();
nq = ir->GetNPoints();
geom = mesh->GetGeometricFactors(*ir, GeometricFactors::COORDINATES |
GeometricFactors::JACOBIANS, mt);
geom = mesh->GetGeometricFactors(*ir, GeometricFactors::DETERMINANTS, mt);
maps = &el.GetDofToQuad(*ir, DofToQuad::TENSOR);
dofs1D = maps->ndof;
quad1D = maps->nqpt;
pa_data.SetSize(ne*nq, mt);
Vector coeff;
if (Q == nullptr)
{
coeff.SetSize(1);
coeff(0) = 1.0;
}
else if (ConstantCoefficient* cQ = dynamic_cast<ConstantCoefficient*>(Q))
{
coeff.SetSize(1);
coeff(0) = cQ->constant;
}
else if (QuadratureFunctionCoefficient* qfQ =
dynamic_cast<QuadratureFunctionCoefficient*>(Q))
{
const QuadratureFunction &qFun = qfQ->GetQuadFunction();
MFEM_VERIFY(qFun.Size() == nq * ne,
"Incompatible QuadratureFunction dimension \n");
MFEM_VERIFY(ir == &qFun.GetSpace()->GetElementIntRule(0),
"IntegrationRule used within integrator and in"
" QuadratureFunction appear to be different");
qFun.Read();
coeff.MakeRef(const_cast<QuadratureFunction &>(qFun),0);
}
else
{
coeff.SetSize(nq * ne);
auto C = Reshape(coeff.HostWrite(), nq, ne);
for (int e = 0; e < ne; ++e)
{
ElementTransformation& T = *fes.GetElementTransformation(e);
for (int q = 0; q < nq; ++q)
{
C(q,e) = Q->Eval(T, ir->IntPoint(q));
}
}
}
QuadratureSpace qs(*mesh, *ir);
CoefficientVector coeff(Q, qs, CoefficientStorage::COMPRESSED);
if (dim==1) { MFEM_ABORT("Not supported yet... stay tuned!"); }
if (dim==2)
{
@@ -105,7 +73,7 @@ void MassIntegrator::AssemblePA(const FiniteElementSpace &fes)
const bool const_c = coeff.Size() == 1;
const bool by_val = map_type == FiniteElement::VALUE;
const auto W = Reshape(ir->GetWeights().Read(), Q1D,Q1D);
const auto J = Reshape(geom->J.Read(), Q1D,Q1D,2,2,NE);
const auto J = Reshape(geom->detJ.Read(), Q1D,Q1D,NE);
const auto C = const_c ? Reshape(coeff.Read(), 1,1,1) :
Reshape(coeff.Read(), Q1D,Q1D,NE);
auto v = Reshape(pa_data.Write(), Q1D,Q1D, NE);
@@ -115,11 +83,7 @@ void MassIntegrator::AssemblePA(const FiniteElementSpace &fes)
{
MFEM_FOREACH_THREAD(qy,y,Q1D)
{
const double J11 = J(qx,qy,0,0,e);
const double J12 = J(qx,qy,1,0,e);
const double J21 = J(qx,qy,0,1,e);
const double J22 = J(qx,qy,1,1,e);
const double detJ = (J11*J22)-(J21*J12);
const double detJ = J(qx,qy,e);
const double coeff = const_c ? C(0,0,0) : C(qx,qy,e);
v(qx,qy,e) = W(qx,qy) * coeff * (by_val ? detJ : 1.0/detJ);
}
@@ -133,7 +97,7 @@ void MassIntegrator::AssemblePA(const FiniteElementSpace &fes)
const bool const_c = coeff.Size() == 1;
const bool by_val = map_type == FiniteElement::VALUE;
const auto W = Reshape(ir->GetWeights().Read(), Q1D,Q1D,Q1D);
const auto J = Reshape(geom->J.Read(), Q1D,Q1D,Q1D,3,3,NE);
const auto J = Reshape(geom->detJ.Read(), Q1D,Q1D,Q1D,NE);
const auto C = const_c ? Reshape(coeff.Read(), 1,1,1,1) :
Reshape(coeff.Read(), Q1D,Q1D,Q1D,NE);
auto v = Reshape(pa_data.Write(), Q1D,Q1D,Q1D,NE);
@@ -145,18 +109,7 @@ void MassIntegrator::AssemblePA(const FiniteElementSpace &fes)
{
MFEM_FOREACH_THREAD(qz,z,Q1D)
{
const double J11 = J(qx,qy,qz,0,0,e);
const double J21 = J(qx,qy,qz,1,0,e);
const double J31 = J(qx,qy,qz,2,0,e);
const double J12 = J(qx,qy,qz,0,1,e);
const double J22 = J(qx,qy,qz,1,1,e);
const double J32 = J(qx,qy,qz,2,1,e);
const double J13 = J(qx,qy,qz,0,2,e);
const double J23 = J(qx,qy,qz,1,2,e);
const double J33 = J(qx,qy,qz,2,2,e);
const double detJ = J11 * (J22 * J33 - J32 * J23) -
/* */ J21 * (J12 * J33 - J32 * J13) +
/* */ J31 * (J12 * J23 - J22 * J13);
const double detJ = J(qx,qy,qz,e);
const double coeff = const_c ? C(0,0,0,0) : C(qx,qy,qz,e);
v(qx,qy,qz,e) = W(qx,qy,qz) * coeff * (by_val ? detJ : 1.0/detJ);
}
@@ -590,85 +543,18 @@ static void PAMassApply2D(const int NE,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b_.Read(), Q1D, D1D);
auto Bt = Reshape(bt_.Read(), D1D, Q1D);
auto D = Reshape(d_.Read(), Q1D, Q1D, NE);
auto X = Reshape(x_.Read(), D1D, D1D, NE);
auto Y = Reshape(y_.ReadWrite(), D1D, D1D, NE);
MFEM_VERIFY(T_D1D ? T_D1D : d1d <= MAX_D1D, "");
MFEM_VERIFY(T_Q1D ? T_Q1D : q1d <= MAX_Q1D, "");
const auto B = b_.Read();
const auto Bt = bt_.Read();
const auto D = d_.Read();
const auto X = x_.Read();
auto Y = y_.ReadWrite();
MFEM_FORALL(e, NE,
{
const int D1D = T_D1D ? T_D1D : d1d; // nvcc workaround
const int Q1D = T_Q1D ? T_Q1D : q1d;
// the following variables are evaluated at compile time
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double sol_xy[max_Q1D][max_Q1D];
for (int qy = 0; qy < Q1D; ++qy)
{
for (int qx = 0; qx < Q1D; ++qx)
{
sol_xy[qy][qx] = 0.0;
}
}
for (int dy = 0; dy < D1D; ++dy)
{
double sol_x[max_Q1D];
for (int qy = 0; qy < Q1D; ++qy)
{
sol_x[qy] = 0.0;
}
for (int dx = 0; dx < D1D; ++dx)
{
const double s = X(dx,dy,e);
for (int qx = 0; qx < Q1D; ++qx)
{
sol_x[qx] += B(qx,dx)* s;
}
}
for (int qy = 0; qy < Q1D; ++qy)
{
const double d2q = B(qy,dy);
for (int qx = 0; qx < Q1D; ++qx)
{
sol_xy[qy][qx] += d2q * sol_x[qx];
}
}
}
for (int qy = 0; qy < Q1D; ++qy)
{
for (int qx = 0; qx < Q1D; ++qx)
{
sol_xy[qy][qx] *= D(qx,qy,e);
}
}
for (int qy = 0; qy < Q1D; ++qy)
{
double sol_x[max_D1D];
for (int dx = 0; dx < D1D; ++dx)
{
sol_x[dx] = 0.0;
}
for (int qx = 0; qx < Q1D; ++qx)
{
const double s = sol_xy[qy][qx];
for (int dx = 0; dx < D1D; ++dx)
{
sol_x[dx] += Bt(dx,qx) * s;
}
}
for (int dy = 0; dy < D1D; ++dy)
{
const double q2d = Bt(dy,qy);
for (int dx = 0; dx < D1D; ++dx)
{
Y(dx,dy,e) += q2d * sol_x[dx];
}
}
}
internal::PAMassApply2D_Element(e, NE, B, Bt, D, X, Y, d1d, q1d);
});
}
@@ -690,108 +576,13 @@ static void SmemPAMassApply2D(const int NE,
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
MFEM_VERIFY(D1D <= MD1, "");
MFEM_VERIFY(Q1D <= MQ1, "");
auto b = Reshape(b_.Read(), Q1D, D1D);
auto D = Reshape(d_.Read(), Q1D, Q1D, NE);
auto x = Reshape(x_.Read(), D1D, D1D, NE);
auto Y = Reshape(y_.ReadWrite(), D1D, D1D, NE);
const auto b = b_.Read();
const auto D = d_.Read();
const auto x = x_.Read();
auto Y = y_.ReadWrite();
MFEM_FORALL_2D(e, NE, Q1D, Q1D, NBZ,
{
const int tidz = MFEM_THREAD_ID(z);
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MDQ = (MQ1 > MD1) ? MQ1 : MD1;
MFEM_SHARED double BBt[MQ1*MD1];
double (*B)[MD1] = (double (*)[MD1]) BBt;
double (*Bt)[MQ1] = (double (*)[MQ1]) BBt;
MFEM_SHARED double sm0[NBZ][MDQ*MDQ];
MFEM_SHARED double sm1[NBZ][MDQ*MDQ];
double (*X)[MD1] = (double (*)[MD1]) (sm0 + tidz);
double (*DQ)[MQ1] = (double (*)[MQ1]) (sm1 + tidz);
double (*QQ)[MQ1] = (double (*)[MQ1]) (sm0 + tidz);
double (*QD)[MD1] = (double (*)[MD1]) (sm1 + tidz);
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
{
X[dy][dx] = x(dx,dy,e);
}
}
if (tidz == 0)
{
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(q,x,Q1D)
{
B[q][dy] = b(q,dy);
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(qx,x,Q1D)
{
double dq = 0.0;
for (int dx = 0; dx < D1D; ++dx)
{
dq += X[dy][dx] * B[qx][dx];
}
DQ[dy][qx] = dq;
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(qy,y,Q1D)
{
MFEM_FOREACH_THREAD(qx,x,Q1D)
{
double qq = 0.0;
for (int dy = 0; dy < D1D; ++dy)
{
qq += DQ[dy][qx] * B[qy][dy];
}
QQ[qy][qx] = qq * D(qx, qy, e);
}
}
MFEM_SYNC_THREAD;
if (tidz == 0)
{
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(q,x,Q1D)
{
Bt[dy][q] = b(q,dy);
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(qy,y,Q1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
{
double dq = 0.0;
for (int qx = 0; qx < Q1D; ++qx)
{
dq += QQ[qy][qx] * Bt[dx][qx];
}
QD[qy][dx] = dq;
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
{
double dd = 0.0;
for (int qy = 0; qy < Q1D; ++qy)
{
dd += (QD[qy][dx] * Bt[dy][qy]);
}
Y(dx, dy, e) += dd;
}
}
internal::SmemPAMassApply2D_Element<T_D1D,T_Q1D,T_NBZ>(e, NE, b, D, x, Y, d1d, q1d);
});
}
@@ -805,134 +596,18 @@ static void PAMassApply3D(const int NE,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b_.Read(), Q1D, D1D);
auto Bt = Reshape(bt_.Read(), D1D, Q1D);
auto D = Reshape(d_.Read(), Q1D, Q1D, Q1D, NE);
auto X = Reshape(x_.Read(), D1D, D1D, D1D, NE);
auto Y = Reshape(y_.ReadWrite(), D1D, D1D, D1D, NE);
MFEM_VERIFY(T_D1D ? T_D1D : d1d <= MAX_D1D, "");
MFEM_VERIFY(T_Q1D ? T_Q1D : q1d <= MAX_Q1D, "");
const auto B = b_.Read();
const auto Bt = bt_.Read();
const auto D = d_.Read();
const auto X = x_.Read();
auto Y = y_.ReadWrite();
MFEM_FORALL(e, NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double sol_xyz[max_Q1D][max_Q1D][max_Q1D];
for (int qz = 0; qz < Q1D; ++qz)
{
for (int qy = 0; qy < Q1D; ++qy)
{
for (int qx = 0; qx < Q1D; ++qx)
{
sol_xyz[qz][qy][qx] = 0.0;
}
}
}
for (int dz = 0; dz < D1D; ++dz)
{
double sol_xy[max_Q1D][max_Q1D];
for (int qy = 0; qy < Q1D; ++qy)
{
for (int qx = 0; qx < Q1D; ++qx)
{
sol_xy[qy][qx] = 0.0;
}
}
for (int dy = 0; dy < D1D; ++dy)
{
double sol_x[max_Q1D];
for (int qx = 0; qx < Q1D; ++qx)
{
sol_x[qx] = 0;
}
for (int dx = 0; dx < D1D; ++dx)
{
const double s = X(dx,dy,dz,e);
for (int qx = 0; qx < Q1D; ++qx)
{
sol_x[qx] += B(qx,dx) * s;
}
}
for (int qy = 0; qy < Q1D; ++qy)
{
const double wy = B(qy,dy);
for (int qx = 0; qx < Q1D; ++qx)
{
sol_xy[qy][qx] += wy * sol_x[qx];
}
}
}
for (int qz = 0; qz < Q1D; ++qz)
{
const double wz = B(qz,dz);
for (int qy = 0; qy < Q1D; ++qy)
{
for (int qx = 0; qx < Q1D; ++qx)
{
sol_xyz[qz][qy][qx] += wz * sol_xy[qy][qx];
}
}
}
}
for (int qz = 0; qz < Q1D; ++qz)
{
for (int qy = 0; qy < Q1D; ++qy)
{
for (int qx = 0; qx < Q1D; ++qx)
{
sol_xyz[qz][qy][qx] *= D(qx,qy,qz,e);
}
}
}
for (int qz = 0; qz < Q1D; ++qz)
{
double sol_xy[max_D1D][max_D1D];
for (int dy = 0; dy < D1D; ++dy)
{
for (int dx = 0; dx < D1D; ++dx)
{
sol_xy[dy][dx] = 0;
}
}
for (int qy = 0; qy < Q1D; ++qy)
{
double sol_x[max_D1D];
for (int dx = 0; dx < D1D; ++dx)
{
sol_x[dx] = 0;
}
for (int qx = 0; qx < Q1D; ++qx)
{
const double s = sol_xyz[qz][qy][qx];
for (int dx = 0; dx < D1D; ++dx)
{
sol_x[dx] += Bt(dx,qx) * s;
}
}
for (int dy = 0; dy < D1D; ++dy)
{
const double wy = Bt(dy,qy);
for (int dx = 0; dx < D1D; ++dx)
{
sol_xy[dy][dx] += wy * sol_x[dx];
}
}
}
for (int dz = 0; dz < D1D; ++dz)
{
const double wz = Bt(dz,qz);
for (int dy = 0; dy < D1D; ++dy)
{
for (int dx = 0; dx < D1D; ++dx)
{
Y(dx,dy,dz,e) += wz * sol_xy[dy][dx];
}
}
}
}
internal::PAMassApply3D_Element(e, NE, B, Bt, D, X, Y, d1d, q1d);
});
}
@@ -953,213 +628,13 @@ static void SmemPAMassApply3D(const int NE,
constexpr int M1D = T_D1D ? T_D1D : MAX_D1D;
MFEM_VERIFY(D1D <= M1D, "");
MFEM_VERIFY(Q1D <= M1Q, "");
auto b = Reshape(b_.Read(), Q1D, D1D);
auto d = Reshape(d_.Read(), Q1D, Q1D, Q1D, NE);
auto x = Reshape(x_.Read(), D1D, D1D, D1D, NE);
auto y = Reshape(y_.ReadWrite(), D1D, D1D, D1D, NE);
auto b = b_.Read();
auto d = d_.Read();
auto x = x_.Read();
auto y = y_.ReadWrite();
MFEM_FORALL_3D(e, NE, Q1D, Q1D, 1,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MDQ = (MQ1 > MD1) ? MQ1 : MD1;
MFEM_SHARED double sDQ[MQ1*MD1];
double (*B)[MD1] = (double (*)[MD1]) sDQ;
double (*Bt)[MQ1] = (double (*)[MQ1]) sDQ;
MFEM_SHARED double sm0[MDQ*MDQ*MDQ];
MFEM_SHARED double sm1[MDQ*MDQ*MDQ];
double (*X)[MD1][MD1] = (double (*)[MD1][MD1]) sm0;
double (*DDQ)[MD1][MQ1] = (double (*)[MD1][MQ1]) sm1;
double (*DQQ)[MQ1][MQ1] = (double (*)[MQ1][MQ1]) sm0;
double (*QQQ)[MQ1][MQ1] = (double (*)[MQ1][MQ1]) sm1;
double (*QQD)[MQ1][MD1] = (double (*)[MQ1][MD1]) sm0;
double (*QDD)[MD1][MD1] = (double (*)[MD1][MD1]) sm1;
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
{
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz)
{
X[dz][dy][dx] = x(dx,dy,dz,e);
}
}
MFEM_FOREACH_THREAD(dx,x,Q1D)
{
B[dx][dy] = b(dx,dy);
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(qx,x,Q1D)
{
double u[D1D];
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; dz++)
{
u[dz] = 0;
}
MFEM_UNROLL(MD1)
for (int dx = 0; dx < D1D; ++dx)
{
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz)
{
u[dz] += X[dz][dy][dx] * B[qx][dx];
}
}
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz)
{
DDQ[dz][dy][qx] = u[dz];
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(qy,y,Q1D)
{
MFEM_FOREACH_THREAD(qx,x,Q1D)
{
double u[D1D];
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; dz++)
{
u[dz] = 0;
}
MFEM_UNROLL(MD1)
for (int dy = 0; dy < D1D; ++dy)
{
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; dz++)
{
u[dz] += DDQ[dz][dy][qx] * B[qy][dy];
}
}
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; dz++)
{
DQQ[dz][qy][qx] = u[dz];
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(qy,y,Q1D)
{
MFEM_FOREACH_THREAD(qx,x,Q1D)
{
double u[Q1D];
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; qz++)
{
u[qz] = 0;
}
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz)
{
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; qz++)
{
u[qz] += DQQ[dz][qy][qx] * B[qz][dz];
}
}
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; qz++)
{
QQQ[qz][qy][qx] = u[qz] * d(qx,qy,qz,e);
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(d,y,D1D)
{
MFEM_FOREACH_THREAD(q,x,Q1D)
{
Bt[d][q] = b(q,d);
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(qy,y,Q1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
{
double u[Q1D];
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz)
{
u[qz] = 0;
}
MFEM_UNROLL(MQ1)
for (int qx = 0; qx < Q1D; ++qx)
{
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz)
{
u[qz] += QQQ[qz][qy][qx] * Bt[dx][qx];
}
}
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz)
{
QQD[qz][qy][dx] = u[qz];
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
{
double u[Q1D];
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz)
{
u[qz] = 0;
}
MFEM_UNROLL(MQ1)
for (int qy = 0; qy < Q1D; ++qy)
{
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz)
{
u[qz] += QQD[qz][qy][dx] * Bt[dy][qy];
}
}
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz)
{
QDD[qz][dy][dx] = u[qz];
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
{
double u[D1D];
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz)
{
u[dz] = 0;
}
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz)
{
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz)
{
u[dz] += QDD[qz][dy][dx] * Bt[dz][qz];
}
}
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz)
{
y(dx,dy,dz,e) += u[dz];
}
}
}
internal::SmemPAMassApply3D_Element<T_D1D,T_Q1D>(e, NE, b, d, x, y, d1d, q1d);
});
}
+632
View File
@@ -0,0 +1,632 @@
// Copyright (c) 2010-2022, 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_BILININTEG_MASS_PA_HPP
#define MFEM_BILININTEG_MASS_PA_HPP
#include "../config/config.hpp"
#include "../general/forall.hpp"
#include "../linalg/dtensor.hpp"
namespace mfem
{
namespace internal
{
template <bool ACCUMULATE = true>
MFEM_HOST_DEVICE inline
void PAMassApply2D_Element(const int e,
const int NE,
const double *b_,
const double *bt_,
const double *d_,
const double *x_,
double *y_,
const int d1d = 0,
const int q1d = 0)
{
const int D1D = d1d;
const int Q1D = q1d;
auto B = ConstDeviceMatrix(b_, Q1D, D1D);
auto Bt = ConstDeviceMatrix(bt_, D1D, Q1D);
auto D = ConstDeviceCube(d_, Q1D, Q1D, NE);
auto X = ConstDeviceCube(x_, D1D, D1D, NE);
auto Y = DeviceCube(y_, D1D, D1D, NE);
if (!ACCUMULATE)
{
for (int dy = 0; dy < D1D; ++dy)
{
for (int dx = 0; dx < D1D; ++dx)
{
Y(dx, dy, e) = 0.0;
}
}
}
constexpr int max_D1D = MAX_D1D;
constexpr int max_Q1D = MAX_Q1D;
double sol_xy[max_Q1D][max_Q1D];
for (int qy = 0; qy < Q1D; ++qy)
{
for (int qx = 0; qx < Q1D; ++qx)
{
sol_xy[qy][qx] = 0.0;
}
}
for (int dy = 0; dy < D1D; ++dy)
{
double sol_x[max_Q1D];
for (int qy = 0; qy < Q1D; ++qy)
{
sol_x[qy] = 0.0;
}
for (int dx = 0; dx < D1D; ++dx)
{
const double s = X(dx,dy,e);
for (int qx = 0; qx < Q1D; ++qx)
{
sol_x[qx] += B(qx,dx)* s;
}
}
for (int qy = 0; qy < Q1D; ++qy)
{
const double d2q = B(qy,dy);
for (int qx = 0; qx < Q1D; ++qx)
{
sol_xy[qy][qx] += d2q * sol_x[qx];
}
}
}
for (int qy = 0; qy < Q1D; ++qy)
{
for (int qx = 0; qx < Q1D; ++qx)
{
sol_xy[qy][qx] *= D(qx,qy,e);
}
}
for (int qy = 0; qy < Q1D; ++qy)
{
double sol_x[max_D1D];
for (int dx = 0; dx < D1D; ++dx)
{
sol_x[dx] = 0.0;
}
for (int qx = 0; qx < Q1D; ++qx)
{
const double s = sol_xy[qy][qx];
for (int dx = 0; dx < D1D; ++dx)
{
sol_x[dx] += Bt(dx,qx) * s;
}
}
for (int dy = 0; dy < D1D; ++dy)
{
const double q2d = Bt(dy,qy);
for (int dx = 0; dx < D1D; ++dx)
{
Y(dx,dy,e) += q2d * sol_x[dx];
}
}
}
}
template<int T_D1D, int T_Q1D, int T_NBZ, bool ACCUMULATE = true>
MFEM_HOST_DEVICE inline
void SmemPAMassApply2D_Element(const int e,
const int NE,
const double *b_,
const double *d_,
const double *x_,
double *y_,
int d1d = 0,
int q1d = 0)
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MDQ = (MQ1 > MD1) ? MQ1 : MD1;
auto b = ConstDeviceMatrix(b_, Q1D, D1D);
auto D = ConstDeviceCube(d_, Q1D, Q1D, NE);
auto x = ConstDeviceCube(x_, D1D, D1D, NE);
auto Y = DeviceCube(y_, D1D, D1D, NE);
const int tidz = MFEM_THREAD_ID(z);
MFEM_SHARED double BBt[MQ1*MD1];
double (*B)[MD1] = (double (*)[MD1]) BBt;
double (*Bt)[MQ1] = (double (*)[MQ1]) BBt;
MFEM_SHARED double sm0[NBZ][MDQ*MDQ];
MFEM_SHARED double sm1[NBZ][MDQ*MDQ];
double (*X)[MD1] = (double (*)[MD1]) (sm0 + tidz);
double (*DQ)[MQ1] = (double (*)[MQ1]) (sm1 + tidz);
double (*QQ)[MQ1] = (double (*)[MQ1]) (sm0 + tidz);
double (*QD)[MD1] = (double (*)[MD1]) (sm1 + tidz);
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
{
X[dy][dx] = x(dx,dy,e);
}
}
if (tidz == 0)
{
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(q,x,Q1D)
{
B[q][dy] = b(q,dy);
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(qx,x,Q1D)
{
double dq = 0.0;
for (int dx = 0; dx < D1D; ++dx)
{
dq += X[dy][dx] * B[qx][dx];
}
DQ[dy][qx] = dq;
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(qy,y,Q1D)
{
MFEM_FOREACH_THREAD(qx,x,Q1D)
{
double qq = 0.0;
for (int dy = 0; dy < D1D; ++dy)
{
qq += DQ[dy][qx] * B[qy][dy];
}
QQ[qy][qx] = qq * D(qx, qy, e);
}
}
MFEM_SYNC_THREAD;
if (tidz == 0)
{
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(q,x,Q1D)
{
Bt[dy][q] = b(q,dy);
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(qy,y,Q1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
{
double dq = 0.0;
for (int qx = 0; qx < Q1D; ++qx)
{
dq += QQ[qy][qx] * Bt[dx][qx];
}
QD[qy][dx] = dq;
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
{
double dd = 0.0;
for (int qy = 0; qy < Q1D; ++qy)
{
dd += (QD[qy][dx] * Bt[dy][qy]);
}
if (ACCUMULATE)
{
Y(dx, dy, e) += dd;
}
else
{
Y(dx, dy, e) = dd;
}
}
}
}
template <bool ACCUMULATE = true>
MFEM_HOST_DEVICE inline
void PAMassApply3D_Element(const int e,
const int NE,
const double *b_,
const double *bt_,
const double *d_,
const double *x_,
double *y_,
const int d1d,
const int q1d)
{
const int D1D = d1d;
const int Q1D = q1d;
auto B = ConstDeviceMatrix(b_, Q1D, D1D);
auto Bt = ConstDeviceMatrix(bt_, D1D, Q1D);
auto D = DeviceTensor<4,const double>(d_, Q1D, Q1D, Q1D, NE);
auto X = DeviceTensor<4,const double>(x_, D1D, D1D, D1D, NE);
auto Y = DeviceTensor<4,double>(y_, D1D, D1D, D1D, NE);
if (!ACCUMULATE)
{
for (int dz = 0; dz < D1D; ++dz)
{
for (int dy = 0; dy < D1D; ++dy)
{
for (int dx = 0; dx < D1D; ++dx)
{
Y(dx, dy, dz, e) = 0.0;
}
}
}
}
constexpr int max_D1D = MAX_D1D;
constexpr int max_Q1D = MAX_Q1D;
double sol_xyz[max_Q1D][max_Q1D][max_Q1D];
for (int qz = 0; qz < Q1D; ++qz)
{
for (int qy = 0; qy < Q1D; ++qy)
{
for (int qx = 0; qx < Q1D; ++qx)
{
sol_xyz[qz][qy][qx] = 0.0;
}
}
}
for (int dz = 0; dz < D1D; ++dz)
{
double sol_xy[max_Q1D][max_Q1D];
for (int qy = 0; qy < Q1D; ++qy)
{
for (int qx = 0; qx < Q1D; ++qx)
{
sol_xy[qy][qx] = 0.0;
}
}
for (int dy = 0; dy < D1D; ++dy)
{
double sol_x[max_Q1D];
for (int qx = 0; qx < Q1D; ++qx)
{
sol_x[qx] = 0;
}
for (int dx = 0; dx < D1D; ++dx)
{
const double s = X(dx,dy,dz,e);
for (int qx = 0; qx < Q1D; ++qx)
{
sol_x[qx] += B(qx,dx) * s;
}
}
for (int qy = 0; qy < Q1D; ++qy)
{
const double wy = B(qy,dy);
for (int qx = 0; qx < Q1D; ++qx)
{
sol_xy[qy][qx] += wy * sol_x[qx];
}
}
}
for (int qz = 0; qz < Q1D; ++qz)
{
const double wz = B(qz,dz);
for (int qy = 0; qy < Q1D; ++qy)
{
for (int qx = 0; qx < Q1D; ++qx)
{
sol_xyz[qz][qy][qx] += wz * sol_xy[qy][qx];
}
}
}
}
for (int qz = 0; qz < Q1D; ++qz)
{
for (int qy = 0; qy < Q1D; ++qy)
{
for (int qx = 0; qx < Q1D; ++qx)
{
sol_xyz[qz][qy][qx] *= D(qx,qy,qz,e);
}
}
}
for (int qz = 0; qz < Q1D; ++qz)
{
double sol_xy[max_D1D][max_D1D];
for (int dy = 0; dy < D1D; ++dy)
{
for (int dx = 0; dx < D1D; ++dx)
{
sol_xy[dy][dx] = 0;
}
}
for (int qy = 0; qy < Q1D; ++qy)
{
double sol_x[max_D1D];
for (int dx = 0; dx < D1D; ++dx)
{
sol_x[dx] = 0;
}
for (int qx = 0; qx < Q1D; ++qx)
{
const double s = sol_xyz[qz][qy][qx];
for (int dx = 0; dx < D1D; ++dx)
{
sol_x[dx] += Bt(dx,qx) * s;
}
}
for (int dy = 0; dy < D1D; ++dy)
{
const double wy = Bt(dy,qy);
for (int dx = 0; dx < D1D; ++dx)
{
sol_xy[dy][dx] += wy * sol_x[dx];
}
}
}
for (int dz = 0; dz < D1D; ++dz)
{
const double wz = Bt(dz,qz);
for (int dy = 0; dy < D1D; ++dy)
{
for (int dx = 0; dx < D1D; ++dx)
{
Y(dx,dy,dz,e) += wz * sol_xy[dy][dx];
}
}
}
}
}
template<int T_D1D, int T_Q1D, bool ACCUMULATE = true>
MFEM_HOST_DEVICE inline
void SmemPAMassApply3D_Element(const int e,
const int NE,
const double *b_,
const double *d_,
const double *x_,
double *y_,
const int d1d = 0,
const int q1d = 0)
{
constexpr int D1D = T_D1D ? T_D1D : d1d;
constexpr int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MDQ = (MQ1 > MD1) ? MQ1 : MD1;
auto b = ConstDeviceMatrix(b_, Q1D, D1D);
auto d = DeviceTensor<4,const double>(d_, Q1D, Q1D, Q1D, NE);
auto x = DeviceTensor<4,const double>(x_, D1D, D1D, D1D, NE);
auto y = DeviceTensor<4,double>(y_, D1D, D1D, D1D, NE);
MFEM_SHARED double sDQ[MQ1*MD1];
double (*B)[MD1] = (double (*)[MD1]) sDQ;
double (*Bt)[MQ1] = (double (*)[MQ1]) sDQ;
MFEM_SHARED double sm0[MDQ*MDQ*MDQ];
MFEM_SHARED double sm1[MDQ*MDQ*MDQ];
double (*X)[MD1][MD1] = (double (*)[MD1][MD1]) sm0;
double (*DDQ)[MD1][MQ1] = (double (*)[MD1][MQ1]) sm1;
double (*DQQ)[MQ1][MQ1] = (double (*)[MQ1][MQ1]) sm0;
double (*QQQ)[MQ1][MQ1] = (double (*)[MQ1][MQ1]) sm1;
double (*QQD)[MQ1][MD1] = (double (*)[MQ1][MD1]) sm0;
double (*QDD)[MD1][MD1] = (double (*)[MD1][MD1]) sm1;
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
{
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz)
{
X[dz][dy][dx] = x(dx,dy,dz,e);
}
}
MFEM_FOREACH_THREAD(dx,x,Q1D)
{
B[dx][dy] = b(dx,dy);
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(qx,x,Q1D)
{
double u[D1D];
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; dz++)
{
u[dz] = 0;
}
MFEM_UNROLL(MD1)
for (int dx = 0; dx < D1D; ++dx)
{
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz)
{
u[dz] += X[dz][dy][dx] * B[qx][dx];
}
}
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz)
{
DDQ[dz][dy][qx] = u[dz];
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(qy,y,Q1D)
{
MFEM_FOREACH_THREAD(qx,x,Q1D)
{
double u[D1D];
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; dz++)
{
u[dz] = 0;
}
MFEM_UNROLL(MD1)
for (int dy = 0; dy < D1D; ++dy)
{
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; dz++)
{
u[dz] += DDQ[dz][dy][qx] * B[qy][dy];
}
}
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; dz++)
{
DQQ[dz][qy][qx] = u[dz];
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(qy,y,Q1D)
{
MFEM_FOREACH_THREAD(qx,x,Q1D)
{
double u[Q1D];
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; qz++)
{
u[qz] = 0;
}
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz)
{
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; qz++)
{
u[qz] += DQQ[dz][qy][qx] * B[qz][dz];
}
}
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; qz++)
{
QQQ[qz][qy][qx] = u[qz] * d(qx,qy,qz,e);
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(di,y,D1D)
{
MFEM_FOREACH_THREAD(q,x,Q1D)
{
Bt[di][q] = b(q,di);
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(qy,y,Q1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
{
double u[Q1D];
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz)
{
u[qz] = 0;
}
MFEM_UNROLL(MQ1)
for (int qx = 0; qx < Q1D; ++qx)
{
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz)
{
u[qz] += QQQ[qz][qy][qx] * Bt[dx][qx];
}
}
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz)
{
QQD[qz][qy][dx] = u[qz];
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
{
double u[Q1D];
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz)
{
u[qz] = 0;
}
MFEM_UNROLL(MQ1)
for (int qy = 0; qy < Q1D; ++qy)
{
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz)
{
u[qz] += QQD[qz][qy][dx] * Bt[dy][qy];
}
}
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz)
{
QDD[qz][dy][dx] = u[qz];
}
}
}
MFEM_SYNC_THREAD;
MFEM_FOREACH_THREAD(dy,y,D1D)
{
MFEM_FOREACH_THREAD(dx,x,D1D)
{
double u[D1D];
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz)
{
u[dz] = 0;
}
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz)
{
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz)
{
u[dz] += QDD[qz][dy][dx] * Bt[dz][qz];
}
}
MFEM_UNROLL(MD1)
for (int dz = 0; dz < D1D; ++dz)
{
if (ACCUMULATE)
{
y(dx,dy,dz,e) += u[dz];
}
else
{
y(dx,dy,dz,e) = u[dz];
}
}
}
}
MFEM_SYNC_THREAD;
}
} // namespace internal
} // namespace mfem
#endif
+4 -4
View File
@@ -75,7 +75,7 @@ void TransposeIntegrator::AssembleEAInteriorFaces(const FiniteElementSpace& fes,
Vector ea_data_ext_tmp(ea_data_ext.Size());
bfi->AssembleEAInteriorFaces(fes, ea_data_int_tmp, ea_data_ext_tmp, false);
const int faceDofs = fes.GetTraceElement(0,
fes.GetMesh()->GetFaceBaseGeometry(0))->GetDof();
fes.GetMesh()->GetFaceGeometry(0))->GetDof();
auto A_int = Reshape(ea_data_int_tmp.Read(), faceDofs, faceDofs, 2, nf);
auto A_ext = Reshape(ea_data_ext_tmp.Read(), faceDofs, faceDofs, 2, nf);
auto AT_int = Reshape(ea_data_int.ReadWrite(), faceDofs, faceDofs, 2, nf);
@@ -102,7 +102,7 @@ void TransposeIntegrator::AssembleEAInteriorFaces(const FiniteElementSpace& fes,
{
bfi->AssembleEAInteriorFaces(fes, ea_data_int, ea_data_ext, false);
const int faceDofs = fes.GetTraceElement(0,
fes.GetMesh()->GetFaceBaseGeometry(0))->GetDof();
fes.GetMesh()->GetFaceGeometry(0))->GetDof();
auto A_int = Reshape(ea_data_int.ReadWrite(), faceDofs, faceDofs, 2, nf);
auto A_ext = Reshape(ea_data_ext.ReadWrite(), faceDofs, faceDofs, 2, nf);
MFEM_FORALL(f, nf,
@@ -146,7 +146,7 @@ void TransposeIntegrator::AssembleEABoundaryFaces(const FiniteElementSpace& fes,
Vector ea_data_bdr_tmp(ea_data_bdr.Size());
bfi->AssembleEABoundaryFaces(fes, ea_data_bdr_tmp, false);
const int faceDofs = fes.GetTraceElement(0,
fes.GetMesh()->GetFaceBaseGeometry(0))->GetDof();
fes.GetMesh()->GetFaceGeometry(0))->GetDof();
auto A_bdr = Reshape(ea_data_bdr_tmp.Read(), faceDofs, faceDofs, nf);
auto AT_bdr = Reshape(ea_data_bdr.ReadWrite(), faceDofs, faceDofs, nf);
MFEM_FORALL(f, nf,
@@ -165,7 +165,7 @@ void TransposeIntegrator::AssembleEABoundaryFaces(const FiniteElementSpace& fes,
{
bfi->AssembleEABoundaryFaces(fes, ea_data_bdr, false);
const int faceDofs = fes.GetTraceElement(0,
fes.GetMesh()->GetFaceBaseGeometry(0))->GetDof();
fes.GetMesh()->GetFaceGeometry(0))->GetDof();
auto A_bdr = Reshape(ea_data_bdr.ReadWrite(), faceDofs, faceDofs, nf);
MFEM_FORALL(f, nf,
{
+3 -36
View File
@@ -12,6 +12,7 @@
#include "../general/forall.hpp"
#include "bilininteg.hpp"
#include "gridfunc.hpp"
#include "qfunction.hpp"
#include "ceed/integrators/diffusion/diffusion.hpp"
using namespace std;
@@ -175,43 +176,9 @@ void VectorDiffusionIntegrator::AssemblePA(const FiniteElementSpace &fes)
MFEM_VERIFY(!VQ && !MQ,
"Only scalar coefficient supported for partial assembly for VectorDiffusionIntegrator");
Vector coeff;
if (Q == nullptr)
{
coeff.SetSize(1);
coeff(0) = 1.0;
}
else if (ConstantCoefficient* cQ = dynamic_cast<ConstantCoefficient*>(Q))
{
coeff.SetSize(1);
coeff(0) = cQ->constant;
}
else if (QuadratureFunctionCoefficient* qfQ =
dynamic_cast<QuadratureFunctionCoefficient*>(Q))
{
const QuadratureFunction &qFun = qfQ->GetQuadFunction();
MFEM_VERIFY(qFun.Size() == ne*nq,
"Incompatible QuadratureFunction dimension \n");
MFEM_VERIFY(ir == &qFun.GetSpace()->GetElementIntRule(0),
"IntegrationRule used within integrator and in"
" QuadratureFunction appear to be different");
qFun.Read();
coeff.MakeRef(const_cast<QuadratureFunction &>(qFun),0);
}
else
{
coeff.SetSize(nq * ne);
auto Co = Reshape(coeff.HostWrite(), nq, ne);
for (int e = 0; e < ne; ++e)
{
ElementTransformation& T = *fes.GetElementTransformation(e);
for (int q = 0; q < nq; ++q)
{
Co(q,e) = Q->Eval(T, ir->IntPoint(q));
}
}
}
QuadratureSpace qs(*mesh, *ir);
CoefficientVector coeff(Q, qs, CoefficientStorage::COMPRESSED);
const Array<double> &w = ir->GetWeights();
const Vector &j = geom->J;
+23 -110
View File
@@ -11,6 +11,7 @@
#include "../general/forall.hpp"
#include "bilininteg.hpp"
#include "qspace.hpp"
#include "gridfunc.hpp"
namespace mfem
@@ -793,140 +794,63 @@ void VectorFEMassIntegrator::AssemblePA(const FiniteElementSpace &trial_fes,
trial_fetype = trial_el->GetDerivType();
test_fetype = test_el->GetDerivType();
auto SMQ = dynamic_cast<SymmetricMatrixCoefficient *>(MQ);
const int MQsymmDim = SMQ ? (SMQ->GetSize() * (SMQ->GetSize() + 1)) / 2 : 0;
const int MQfullDim = MQ ? (MQ->GetHeight() * MQ->GetWidth()) : 0;
const int MQdim = SMQ ? MQsymmDim : MQfullDim;
const int coeffDim = MQ ? MQdim : (DQ ? DQ->GetVDim() : 1);
symmetric = (SMQ || MQ == NULL);
const bool trial_curl = (trial_fetype == mfem::FiniteElement::CURL);
const bool trial_div = (trial_fetype == mfem::FiniteElement::DIV);
const bool test_curl = (test_fetype == mfem::FiniteElement::CURL);
const bool test_div = (test_fetype == mfem::FiniteElement::DIV);
QuadratureSpace qs(*mesh, *ir);
CoefficientVector coeff(qs, CoefficientStorage::SYMMETRIC);
if (Q) { coeff.Project(*Q); }
else if (MQ) { coeff.ProjectTranspose(*MQ); }
else if (DQ) { coeff.Project(*DQ); }
else { coeff.SetConstant(1.0); }
const int coeff_dim = coeff.GetVDim();
symmetric = (coeff_dim != dim*dim);
if ((trial_curl && test_div) || (trial_div && test_curl))
pa_data.SetSize((coeffDim == 1 ? 1 : dim*dim) * nq * ne,
pa_data.SetSize((coeff_dim == 1 ? 1 : dim*dim) * nq * ne,
Device::GetMemoryType());
else
pa_data.SetSize((symmetric ? symmDims : MQfullDim) * nq * ne,
pa_data.SetSize((symmetric ? symmDims : dims*dims) * nq * ne,
Device::GetMemoryType());
Vector coeff;
auto *qf_c = dynamic_cast<QuadratureFunctionCoefficient*>(Q);
if (qf_c)
{
const QuadratureFunction &qf = qf_c->GetQuadFunction();
qf.Read();
coeff.MakeRef(const_cast<QuadratureFunction&>(qf), 0);
}
else
{
coeff.SetSize(coeffDim * ne * nq);
coeff = 1.0;
auto coeffh = Reshape(coeff.HostWrite(), coeffDim, nq, ne);
if (Q || DQ || MQ)
{
Vector DM(DQ ? coeffDim : 0);
DenseMatrix M;
DenseSymmetricMatrix SM;
if (DQ)
{
MFEM_VERIFY(coeffDim == dim, "");
}
if (SMQ)
{
MFEM_VERIFY(SMQ->GetSize() == dim, "");
SM.SetSize(dim);
}
else if (MQ)
{
MFEM_VERIFY(coeffDim == MQdim, "");
MFEM_VERIFY(MQ->GetHeight() == dim && MQ->GetWidth() == dim, "");
M.SetSize(dim);
}
for (int e=0; e<ne; ++e)
{
ElementTransformation *tr = mesh->GetElementTransformation(e);
for (int p=0; p<nq; ++p)
{
if (SMQ)
{
SMQ->Eval(SM, *tr, ir->IntPoint(p));
int cnt = 0;
for (int i=0; i<dim; ++i)
for (int j=i; j<dim; ++j, ++cnt)
{
coeffh(cnt, p, e) = SM(i,j);
}
}
else if (MQ)
{
MQ->Eval(M, *tr, ir->IntPoint(p));
for (int i=0; i<dim; ++i)
for (int j=0; j<dim; ++j)
{
coeffh(j+(i*dim), p, e) = M(i,j);
}
}
else if (DQ)
{
DQ->Eval(DM, *tr, ir->IntPoint(p));
for (int i=0; i<coeffDim; ++i)
{
coeffh(i, p, e) = DM[i];
}
}
else
{
coeffh(0, p, e) = Q->Eval(*tr, ir->IntPoint(p));
}
}
}
}
}
if (trial_curl && test_curl && dim == 3)
{
PADiffusionSetup3D(quad1D, coeffDim, ne, ir->GetWeights(), geom->J,
PADiffusionSetup3D(quad1D, coeff_dim, ne, ir->GetWeights(), geom->J,
coeff, pa_data);
}
else if (trial_curl && test_curl && dim == 2)
{
PADiffusionSetup2D<2>(quad1D, coeffDim, ne, ir->GetWeights(), geom->J,
PADiffusionSetup2D<2>(quad1D, coeff_dim, ne, ir->GetWeights(), geom->J,
coeff, pa_data);
}
else if (trial_div && test_div && dim == 3)
{
PAHdivSetup3D(quad1D, coeffDim, ne, ir->GetWeights(), geom->J,
PAHdivSetup3D(quad1D, coeff_dim, ne, ir->GetWeights(), geom->J,
coeff, pa_data);
}
else if (trial_div && test_div && dim == 2)
{
PAHdivSetup2D(quad1D, coeffDim, ne, ir->GetWeights(), geom->J,
PAHdivSetup2D(quad1D, coeff_dim, ne, ir->GetWeights(), geom->J,
coeff, pa_data);
}
else if (((trial_curl && test_div) || (trial_div && test_curl)) &&
test_fel->GetOrder() == trial_fel->GetOrder())
{
if (coeffDim == 1)
if (coeff_dim == 1)
{
PAHcurlL2Setup(nq, coeffDim, ne, ir->GetWeights(), coeff, pa_data);
PAHcurlL2Setup(nq, coeff_dim, ne, ir->GetWeights(), coeff, pa_data);
}
else
{
const bool tr = (trial_div && test_curl);
if (dim == 3)
PAHcurlHdivSetup3D(quad1D, coeffDim, ne, tr, ir->GetWeights(),
PAHcurlHdivSetup3D(quad1D, coeff_dim, ne, tr, ir->GetWeights(),
geom->J, coeff, pa_data);
else
PAHcurlHdivSetup2D(quad1D, coeffDim, ne, tr, ir->GetWeights(),
PAHcurlHdivSetup2D(quad1D, coeff_dim, ne, tr, ir->GetWeights(),
geom->J, coeff, pa_data);
}
}
@@ -1168,19 +1092,8 @@ void MixedVectorGradientIntegrator::AssemblePA(const FiniteElementSpace
pa_data.SetSize(symmDims * nq * ne, Device::GetMemoryType());
Vector coeff(ne * nq);
coeff = 1.0;
if (Q)
{
for (int e=0; e<ne; ++e)
{
ElementTransformation *tr = mesh->GetElementTransformation(e);
for (int p=0; p<nq; ++p)
{
coeff[p + (e * nq)] = Q->Eval(*tr, ir->IntPoint(p));
}
}
}
QuadratureSpace qs(*mesh, *ir);
CoefficientVector coeff(Q, qs, CoefficientStorage::FULL);
// Use the same setup functions as VectorFEMassIntegrator.
if (test_el->GetDerivType() == mfem::FiniteElement::CURL && dim == 3)
+1 -1
View File
@@ -112,7 +112,7 @@ static void InitBasisImpl(const FiniteElementSpace &fes,
const bool tensor = dynamic_cast<const mfem::TensorBasisElement *>
(&fe) != nullptr;
// Init or retreive key values
// Init or retrieve key values
if (basis_itr == mfem::internal::ceed_basis_map.end())
{
if ( tensor )
+5 -4
View File
@@ -20,6 +20,7 @@
#include "../../../linalg/dtensor.hpp"
#include "../../../mesh/mesh.hpp"
#include "../../gridfunc.hpp"
#include "../../qfunction.hpp"
#include "util.hpp"
#include "ceed.hpp"
@@ -121,7 +122,7 @@ void InitCoefficient(mfem::Coefficient *Q, mfem::Mesh &mesh,
MFEM_VERIFY(qFun.Size() == nq * ne,
"Incompatible QuadratureFunction dimension \n");
MFEM_VERIFY(&ir == &qFun.GetSpace()->GetElementIntRule(0),
MFEM_VERIFY(&ir == &qFun.GetSpace()->GetIntRule(0),
"IntegrationRule used within integrator and in"
" QuadratureFunction appear to be different");
qFun.Read();
@@ -195,7 +196,7 @@ void InitCoefficient(mfem::VectorCoefficient *VQ, mfem::Mesh &mesh,
MFEM_VERIFY(qFun.Size() == dim * nq * ne,
"Incompatible QuadratureFunction dimension \n");
MFEM_VERIFY(&ir == &qFun.GetSpace()->GetElementIntRule(0),
MFEM_VERIFY(&ir == &qFun.GetSpace()->GetIntRule(0),
"IntegrationRule used within integrator and in"
" QuadratureFunction appear to be different");
qFun.Read();
@@ -279,7 +280,7 @@ void InitCoefficientWithIndices(mfem::Coefficient *Q, mfem::Mesh &mesh,
MFEM_VERIFY(qFun.Size() == nq * ne,
"Incompatible QuadratureFunction dimension \n");
MFEM_VERIFY(&ir == &qFun.GetSpace()->GetElementIntRule(0),
MFEM_VERIFY(&ir == &qFun.GetSpace()->GetIntRule(0),
"IntegrationRule used within integrator and in"
" QuadratureFunction appear to be different");
ceedCoeff->coeff.SetSize(nq * nelem);
@@ -369,7 +370,7 @@ void InitCoefficientWithIndices(mfem::VectorCoefficient *VQ, mfem::Mesh &mesh,
MFEM_VERIFY(qFun.Size() == dim * nq * ne,
"Incompatible QuadratureFunction dimension \n");
MFEM_VERIFY(&ir == &qFun.GetSpace()->GetElementIntRule(0),
MFEM_VERIFY(&ir == &qFun.GetSpace()->GetIntRule(0),
"IntegrationRule used within integrator and in"
" QuadratureFunction appear to be different");
ceedCoeff->coeff.SetSize(dim * nq * nelem);
+3 -1
View File
@@ -69,9 +69,11 @@ void Operator::Mult(const mfem::Vector &x, mfem::Vector &y) const
#endif
}
void Operator::AddMult(const mfem::Vector &x, mfem::Vector &y) const
void Operator::AddMult(const mfem::Vector &x, mfem::Vector &y,
const double a) const
{
#ifdef MFEM_USE_CEED
MFEM_VERIFY(a == 1.0, "General coefficient case is not yet supported!");
const CeedScalar *x_ptr;
CeedScalar *y_ptr;
CeedMemType mem;
+2 -1
View File
@@ -38,7 +38,8 @@ public:
Operator(CeedOperator op);
#endif
void Mult(const mfem::Vector &x, mfem::Vector &y) const override;
void AddMult(const mfem::Vector &x, mfem::Vector &y) const;
void AddMult(const mfem::Vector &x, mfem::Vector &y,
const double a = 1.0) const override;
void GetDiagonal(mfem::Vector &diag) const;
using mfem::Operator::SetupRAP;
virtual ~Operator()
+3 -3
View File
@@ -232,7 +232,7 @@ void InitRestriction(const FiniteElementSpace &fes,
RestrKey restr_key(&fes, nelem, P, ncomp, restr_type::Standard);
auto restr_itr = mfem::internal::ceed_restr_map.find(restr_key);
// Init or retreive key values
// Init or retrieve key values
if (restr_itr == mfem::internal::ceed_restr_map.end())
{
InitRestrictionImpl(fes, ceed, restr);
@@ -257,7 +257,7 @@ void InitRestrictionWithIndices(const FiniteElementSpace &fes,
RestrKey restr_key(&fes, nelem, P, ncomp, restr_type::Standard);
auto restr_itr = mfem::internal::ceed_restr_map.find(restr_key);
// Init or retreive key values
// Init or retrieve key values
if (restr_itr == mfem::internal::ceed_restr_map.end())
{
InitRestrictionWithIndicesImpl(fes, nelem, indices, ceed, restr);
@@ -281,7 +281,7 @@ void InitCoeffRestrictionWithIndices(const FiniteElementSpace &fes,
RestrKey restr_key(&fes, nelem, nquads, ncomp, restr_type::Coeff);
auto restr_itr = mfem::internal::ceed_restr_map.find(restr_key);
// Init or retreive key values
// Init or retrieve key values
if (restr_itr == mfem::internal::ceed_restr_map.end())
{
InitCoeffRestrictionWithIndicesImpl(fes, nelem, indices, nquads, ncomp,

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