Compare commits

...
Author SHA1 Message Date
Tucker Hartland 0e5f41221f including an obstacle problem variant wherein the essential dofs are not given to the optimizer as free variables that it must choose the values for. 2024-03-01 14:58:16 -08:00
Tucker Hartland d2794dd0da removing bug in the evaluation of the optimality measures wherein all processors now see the same value of the optimality error 2023-11-10 10:43:20 -08:00
Tucker Hartland 88372c99ee clean up... using a GeneralOptimizationProblem class and an OptimizationProblem class and no longer using the specific ContactProblem class as the generality of the Parent class does not have anything per say to do with contact 2023-10-10 11:33:29 -07:00
Tucker Hartland 52bfc8618d Merge branch 'contactIPM-dev' of https://github.com/mfem/mfem into contactIPM-dev 2023-08-07 10:07:55 -07:00
Tucker Hartland 977cb839b4 adding the ability to use the Hessian of the constraints in the optimizer, for the two sided Dirichlet obstacle problem it is observed that the number of outer Newton iterations is relatively constant only when the Hessian of the constraints are included in the Newton linear system 2023-08-07 10:06:35 -07:00
Socratis Petrides a52c7f036a bug fix 2023-07-25 19:20:04 -07:00
Socratis Petrides 39c32b9454 removing leftover print 2023-07-25 17:01:44 -07:00
Socratis Petrides 49041b062b simplifying dirichlet dofs handling 2023-07-25 16:26:21 -07:00
Socratis Petrides ed2d0846f6 small edits fixing compiler warnings 2023-07-24 14:34:22 -07:00
Tucker Hartland a1f6b3cf42 renaming descriptions of Optimization Problems... the general optimization problem which is more useful for PDE- and bound-constrained optimization is now described just as that GeneralOptProblem... the problem format min E(u) s.t. g(u) >= 0 and where (as the interior-point solver sees) the bound-constrained variable is a slack variable is now the less general but fairly descriptive OptProblem... the QPOptProblem (formerly QPContactProblem) now is more aptly described as there is nothing specific to contact that the class invokes 2023-07-21 12:40:04 -07:00
Tucker Hartland b8f4fbc84f updating a problem description 2023-07-21 10:11:17 -07:00
Tucker Hartland a2fef97289 removing the distinction between DirichletObstacle and ObstacleProblems 2023-07-21 10:06:58 -07:00
Tucker Hartland 07f22f98d3 removing DirichletObstacleProblem in favor of the ObstacleProblem class which has the ability to utilize Dirichlet boundary conditions 2023-07-20 18:44:34 -07:00
Tucker Hartland 9d5f4fd4ea removed all usages of typedef Number and all unnecessary ipopt stuff... moving meshes to the example/contact subdirectory and out of data directory... makefile now copies the meshes to the out of source directory when appropriate... problems now have more functionality for the inclusion of the Hessian of the constraint functions 2023-07-20 16:40:48 -07:00
tuckerh 17139c5fe8 fixing issue of a null Jacobian that shows up with certain builds/compilers/systems... the order of the gap function evaluation and gap function Jacobian in exQPContact was out of order and the Jacobian that is owned by the problem and passed to main was being deleted after a subsequent call of the gap function. Strange that this issue did not show up with all compilers 2023-07-20 09:51:05 -07:00
Tucker Hartland 3d201cd4ef removing comment about how function is leaking memory, since it is no longer leaking memory 2023-07-19 16:42:07 -07:00
Tucker Hartland 272f816245 fixing a memory leak via a FreeData call on the FindPointsGSLIB finder object in FindPointsInMesh 2023-07-19 16:29:54 -07:00
Tucker Hartland d18539aae2 fixing bug when not compiled with SUITESPARSE 2023-07-19 14:13:25 -07:00
Tucker Hartland 03aa2308d1 using more utility functions... ownership of blocks of IP-Newton system now owned by the problem and not the optimizer/solver... less copying in QPcontact and removing more of the functionality for ipopt 2023-07-17 17:36:44 -07:00
Tucker Hartland 27bcb49294 removing unnecessary copy when using dyanmic_cast, as well as removing unnecessary delete of the dynamic_cast variable to avoid dangling pointers 2023-07-17 15:27:23 -07:00
Tucker Hartland 90ca8bd551 including the QP contact block problem example... the infastructure in problems, additional meshes in data 2023-07-17 11:09:18 -07:00
Tucker Hartland 762fbedb42 more descriptions in Parallel Spherical example problem, as well as outputting the error of the numerical solution and that of the analytic solution 2023-07-06 12:09:32 -07:00
Tucker Hartland 028bbfbc20 Spherical obstacle problem in parallel... more consistent/descriptive variables for the parallel interior-point solver...including a parallel Dirichlet obstacle problem description 2023-07-05 17:35:17 -07:00
Tucker Hartland c2f85de2f9 added a new example wherein the Dirichlet condition and the obstacle coincide 2023-07-03 18:26:04 -07:00
Tucker Hartland c4c9962a0b small modification of the DirichletObstacleProblem that fixes a memory leak 2023-07-03 13:08:27 -07:00
tuckerh 5d15f6c2eb removing an unnecessary item 2023-06-29 13:38:48 -07:00
tuckerh 64e3cf5a52 making the ParIPSolver consistent with the IPsolver.... in particular the reduced print messages and also what the linSolver i.d.s correspond to 2023-06-29 13:18:43 -07:00
Tucker Hartland 81c0094f96 Spherical obstacle problem -- solving an obstacle problem with Dirichlet boundary conditions, able to check numerical solution against analytic to see convergence of the optimizer under mesh refinement to the analytic solution. problems.*pp contains new functionality for being able to describe an obstacle problem with Dirichlet boundary conditions. There has been a minor change to the IPsolver, so that there are fewer statements about the intermediate status of the optimizer 2023-06-29 12:35:21 -07:00
Tucker Hartland 91d8d5da29 removing unnecessary iterative solve option with the Schur-complement approximation Huu + D of the true Schur-complement Huu + Ju^T D Ju 2023-06-06 13:37:57 -07:00
tuckerh e4dd3399ac adding direct and iterative method options to solve IP-Newton-contact system via the Schur complement/stiffness by contact system matrix... including option to set the linear solve tolerance used by the iterative solver from the application code 2023-05-25 08:41:24 -07:00
Tucker Hartland aeff128c42 altering the logic of how the linear solver is chosen in the interior-point method, specifically to expose the newly available iterative method to builds that do not use SUITESPARSE 2023-05-25 07:14:05 -07:00
Tucker Hartland 617c9e2f21 adding new linear solver options and reducing the optimization tolerance so as to avoid conflicts with tolerances for Krylov-subspace solvers 2023-05-24 18:28:39 -07:00
Tucker Hartland 9fd2ae2229 using more descriptive language to describe various member functions 2023-05-24 10:57:18 -07:00
tuckerh bec6766ddb having sorted out the issue with the HypreMatrix from blocks function, we now remove unnecessary print statements and also include the fix 2023-05-15 17:07:02 -07:00
tuckerh 81fa2ca541 updating so that things are current even though there are failures with cpardiso on quartz 2023-05-15 14:12:35 -07:00
tuckerh dadfad3321 updated makefile so we can use either MUMPS or CPARDISO for the parallel sparse direct solver... using NULL instead of nullptr in order to try to be more consistent with the use of HypreParMatrixFromBlocks 2023-05-15 10:00:39 -07:00
tuckerh 18d3d7182c adding ability to use CPardiso sparse direct solvers 2023-05-12 13:23:47 -07:00
Socratis Petrides 994310c49e bug fix 2023-05-10 18:27:10 -07:00
Socratis Petrides 6396772300 first iteration of obstacle problem in parallel 2023-05-09 16:30:50 -07:00
Socratis Petrides a2b5fca7d4 minor changes to fix compiler warnings 2023-05-09 16:30:00 -07:00
Tucker Hartland 891a1aa72d new Mult function included in IPSolver so that the user does not need to be aware of the variable for which the bound-constraints are applied m >= ml, this is useful for contact mechanics problems wherein the bound-constraint variable is actually a slack variable and will not be especially important to the user. obstacleProblem.cpp is now cleaned up a bit, there is no longer a need to create a BlockVector and use this as input to the Mult IPM solution call and so it has been removed in favor of just working with a Vector representation of the primal variable 2023-05-05 15:21:50 -07:00
Tucker Hartland 332cc0e9da including another argument in the constructor of the abstract ContactProblem class, so that we pass the number of inequality constraints, this removes the need to copy the so-called boiler plate code into each of the child ContractProblem classes 2023-05-05 14:13:09 -07:00
Tucker Hartland 82c14b7544 altering various optimization problem member functions so that they no longer are of void type and take a reference to a SparseMatrix pointer but rather they just return a SparseMatrix pointer. the obstacleProblem now expects a function pointer to be passed when initialized, so that the right hand side forcing term is specified from the application side 2023-05-04 13:25:34 -07:00
Tucker Hartland c4cc5b600b adding initial serial features for contact... optimizer and the obstacleProblem. 2023-04-18 11:24:44 -07:00
Veselin Dobrev d84944d9af Merge pull request #3579 from mfem/array-makeref
Change Array::MakeRef to use MakeAlias
2023-04-15 21:06:40 -07:00
Tzanio Kolev 46dd1b779f Merge pull request #3137 from mfem/tmop-bif
Updates to TMOP-based interface and boundary fitting method
2023-04-15 17:27:43 -07:00
Tzanio Kolev ca5b285c44 Merge pull request #3529 from mfem/1D-NURBS-dev
Add 1D NURBS [1D-NURBS-dev]
2023-04-14 07:01:23 -07:00
Tzanio Kolev e7e2850b5c Merge pull request #3202 from mfem/dof-doc-dev
Expanding documentation related to DoFs [dof-doc-dev]
2023-04-14 07:00:05 -07:00
Tzanio Kolev 3705df79bc Merge pull request #3552 from mfem/hiop-new-x
Access to HiOp's new_x
2023-04-14 06:59:34 -07:00
Veselin Dobrev 1f4cc7c9ae In MemoryManager::Register_, check for alias after checking for
nullptr -- it is okay to try to register an alias to nullptr.
2023-04-12 23:39:43 -07:00
Veselin Dobrev 3ec5edbfb1 Add the new miniapp 'pmesh-fitting' to 'config/sample-runs.sh' 2023-04-11 17:33:39 -07:00
Ketan Mittal a1d643ef77 update paper title 2023-04-11 11:20:57 -07:00
Ketan Mittal 041c9362e1 Merge branch 'master' of https://github.com/mfem/mfem into tmop-bif 2023-04-11 11:07:44 -07:00
Veselin Dobrev fc0602cf16 In the memory manager, when creating an alias memory to nullptr,
do not set the flag OWNS_INTERNAL of the alias.
2023-04-10 20:20:08 -07:00
Will Pazner 18330cc31c Merge pull request #3578 from mfem/fix-warnings-2023-04
Fix warnings from non-debug build with new Apple-clang
2023-04-10 16:55:42 -07:00
Will Pazner fa1f8cf075 Merge pull request #3571 from adam-sim-dev/gmres
Init j and resid for GMRES
2023-04-10 16:55:09 -07:00
Tzanio Kolev 0061c55699 Merge branch 'master' into tmop-bif 2023-04-09 17:55:56 -07:00
Tzanio Kolev 72fd6dcb62 Merge pull request #3393 from mfem/rt-face-restriction
RT FaceRestriction and VectorFEBoundaryFluxLFIntegrator kernels
2023-04-09 17:48:17 -07:00
Tzanio Kolev 23565af525 Merge pull request #3444 from mfem/vectorfe-linearform-ext
Support RT VectorFEDomainLFIntegrator on device
2023-04-09 17:47:26 -07:00
Tzanio Kolev 7dc0b2a541 Merge branch 'master' into tmop-bif 2023-04-09 13:45:05 -07:00
Tzanio Kolev c7780a3085 Merge branch 'master' into rt-face-restriction 2023-04-09 13:33:13 -07:00
Tzanio Kolev 01772b0ad6 Merge branch 'master' into 1D-NURBS-dev 2023-04-09 13:32:16 -07:00
Tzanio Kolev 80bc91f811 Merge branch 'master' into hiop-new-x 2023-04-09 13:20:07 -07:00
Tzanio Kolev 2dc923a624 Merge branch 'master' into dof-doc-dev 2023-04-09 13:09:45 -07:00
Tzanio Kolev 782e69270b Merge branch 'master' into vectorfe-linearform-ext 2023-04-09 13:05:27 -07:00
Veselin Dobrev e9eddf8205 Merge pull request #3409 from mfem/ex20p-determinism-dev
Quest for ex20p deterministic output [ex20p-determinism-dev]
2023-04-07 19:02:34 -07:00
Will Pazner 11ec97fe5f Revert inadvertent comment change 2023-04-06 09:09:56 -07:00
Will Pazner 2d3b216c95 Fix bug in ConformingFaceRestriction
When constructing ConformingFaceRestriction from the derived class
ParNCH1FaceRestriction, vol_dof_map was not initialized because of an early
return.
2023-04-05 22:07:06 -07:00
Will Pazner f9e69ad1df Move SpaceType enum to namespace in unit test 2023-04-05 22:06:50 -07:00
Veselin Dobrev 3c64ca0841 Remove GitLab test using old gcc v4.9.3 on Quartz.
There is no need to add the same test with newer gcc version
because we already have it -- with gcc v6.1.0.
2023-04-05 20:29:17 -07:00
Veselin DobrevandWill Pazner 700208c3db Apply reviewer suggestion: update fem/tmop_tools.cpp
Co-authored-by: Will Pazner <11493037+pazner@users.noreply.github.com>
2023-04-05 16:44:18 -07:00
Will Pazner f6df4a9c09 Make LinearFormIntegrator::SupportsDevice const
Required for compatibility with PR #3393
2023-04-04 14:18:43 -07:00
Will Pazner 468f49e29c Define main on Windows in test_debug_device.cpp 2023-04-04 09:17:01 -07:00
Will Pazner 3cd8f8a328 Add REQUIRE_NOTHROW to Array::MakeRef test 2023-04-04 09:16:42 -07:00
Will Pazner 3045411a09 Allow multiple test cases in debug device tests 2023-04-04 08:06:31 -07:00
Will Pazner 6a09aab038 Change Array::MakeRef to use MakeAlias 2023-04-04 08:06:13 -07:00
Ido Akkerman 3033b32339 Make macos compiler happy 3 2023-04-04 12:36:14 +02:00
Ido Akkerman 6ba52de1af Make macos compiler happy 2 2023-04-04 12:20:18 +02:00
Ido Akkerman 936fd0b24a Make macos compiler happy 2023-04-04 12:02:44 +02:00
Ido Akkerman 054b543e8a Sort and clean 1D data array 2023-04-04 11:26:36 +02:00
Ido Akkerman d5ef001b45 instance in lowercase 2023-04-04 10:59:27 +02:00
Ido Akkerman ea084b06dd Fix typo 2023-04-04 10:58:58 +02:00
Veselin Dobrev 2cb8f5d764 Fix a few comments 2023-04-03 23:29:47 -07:00
Will Pazner d05ae0be96 Add namespace internal to face_map_utils.cpp 2023-04-03 20:42:19 -07:00
Will Pazner 5bb11cfde0 Rename H1_ND_RT_FaceRestriction to ConformingFaceRestriction 2023-04-03 20:40:12 -07:00
Will Pazner 8ddbd51116 Add note about return in a MFEM_FORALL lambda 2023-04-03 20:37:51 -07:00
Will Pazner cdfb022714 Improve GetFaceMap Doxygen comment 2023-04-03 20:34:47 -07:00
Will Pazner da2bd5e422 Move face map utils to mfem::internal namespace 2023-04-03 20:30:25 -07:00
Will Pazner 436163bd75 Rename GetNodalTensorFaceMap to GetTensorFaceMap 2023-04-03 20:28:27 -07:00
Will Pazner 0a676e66cc Pass offsets by reference in FillFaceMap 2023-04-03 20:27:28 -07:00
Will Pazner 3e944fd215 Verify H1 space in ParNCH1FaceRestriction 2023-04-03 20:27:28 -07:00
Will Pazner 128a3cef7e Delete out-of-date comment 2023-04-03 20:25:03 -07:00
Veselin Dobrev 3fb16431b3 Fix a shadow variable warning 2023-04-03 14:17:19 -07:00
Veselin Dobrev d52b81fcf2 Update copyright to 2023 2023-04-03 13:59:35 -07:00
Veselin Dobrev d1ef99f4cf Merge branch 'master' into rt-face-restriction
Resolved conflicts:
   CHANGELOG
2023-04-03 12:35:18 -07:00
Veselin Dobrev 393c0104e0 Drop 'virtual' from some methods marked with both 'virtual' and
'override'

In methods related to face restriction, rename 'e_ordering' or
'ordering' to 'f_ordering' to emphasize that this is reordering
for the face dofs. Also, clarified that doxygen comments.

In class H1_ND_RT_FaceRestriction, rename some variables for better
clarity; do not use 'f_ordering' to make decisions about element
dofs.

Remove the declaration of GetFaceDofs() whose definition was
removed earlier in this branch.
2023-04-03 12:18:15 -07:00
Veselin Dobrev 16df54d667 Fix warnings from non-debug build with new Apple-clang 2023-04-03 11:32:41 -07:00
Tzanio Kolev 70083ae9d9 Merge branch 'master' into hiop-new-x 2023-04-03 09:04:28 -07:00
Ketan Mittal da0062988b update changelog 2023-03-31 09:26:48 -07:00
Ketan Mittal fca4583833 Merge branch 'master' of https://github.com/mfem/mfem into tmop-bif 2023-03-31 09:22:32 -07:00
Adam bc1b23bf8c Init j and resid
This PR sets j and resid. They are not initialized if beta <= final_norm, while they are printed later.
2023-03-31 08:49:43 +08:00
Tzanio Kolev 1349c34886 Merge branch 'master' into vectorfe-linearform-ext 2023-03-30 11:55:14 -07:00
Tzanio Kolev d4bc14a48a Merge pull request #3466 from mfem/ab-am-fix
Small fix in Adams Moulton and Adams Bashforth integrators [ab-am-fix]
2023-03-30 11:50:35 -07:00
Tzanio Kolev 34ad9fca15 Merge pull request #3316 from mfem/nurbs-attr
NURBS patch attributes
2023-03-30 11:50:06 -07:00
Tzanio Kolev c1a1c0ba16 Merge pull request #3550 from mfem/tmop-fit-bug
Corrections in TMOP_Integrator::GetSurfaceFittingErrors
2023-03-30 11:48:48 -07:00
Ido Akkerman ff5bce20e3 Fix init order 2023-03-30 14:23:22 +02:00
Ido Akkerman b2cbb1ed92 Fix compile error?? 2023-03-30 14:13:56 +02:00
Ido Akkerman 18f28e0fbf Added checks and comments 2023-03-30 10:08:07 +02:00
Vladimir Z Tomov c4ccb28184 added some deletes and minor edits 2023-03-29 16:17:24 -07:00
Ketan Mittal db5bfb536e Merge branch 'master' of https://github.com/mfem/mfem into tmop-bif 2023-03-29 09:13:47 -07:00
Ketan Mittal 7d6ad1639d fix default metric id for test 2023-03-29 09:13:19 -07:00
Ketan Mittal f1344306e1 typo 2023-03-28 20:21:27 -07:00
Tzanio Kolev bcea3019b4 Merge pull request #3131 from mfem/mesh-ptr-doc-dev
Adding Doxygen comments for returned pointers in mesh classes [mesh-ptr-doc-dev]
2023-03-28 17:02:33 -07:00
Ketan Mittal 2bdecef57a update gitignore 2023-03-28 16:23:59 -07:00
Ketan Mittal 8f93f66541 add common namespace to shifted miniapps 2023-03-28 14:49:59 -07:00
Ketan Mittal 55228baed8 rename file and fix header 2023-03-28 14:35:02 -07:00
Ketan Mittal ea1403a9da rename files and edit makefile 2023-03-28 14:31:53 -07:00
Ketan Mittal eed32e52db resolve conflicts 2023-03-28 14:21:54 -07:00
Ketan Mittal e222c576e7 refactor gradient and hessian for fitting term 2023-03-28 13:45:00 -07:00
Ketan Mittal ec3d524b9a reviewer comments 2023-03-28 11:25:18 -07:00
Dylan Copeland fc279d85ca CHANGELOG 2023-03-27 10:27:30 -07:00
Vladimir Z Tomov 7d6d7249b4 cosmetic edits in tmop-fitting.cpp, no changes in execution. 2023-03-26 17:55:31 -07:00
Vladimir Z Tomov 0d0c4a3b79 improved comments and spacing in tmop.hpp/cpp. 2023-03-26 16:32:27 -07:00
Vladimir Z Tomov 6477552732 edits related to min-detJ_threshold. 2023-03-26 12:50:55 -07:00
Vladimir Z Tomov e10a991272 CountZones - made it virtual, changed the name.
other minor edits.
2023-03-26 12:28:13 -07:00
Tzanio Kolev 7d2be1e37c Merge branch 'master' into nurbs-attr 2023-03-25 18:12:25 -07:00
Tzanio Kolev fa603e6793 Merge branch 'master' into ex20p-determinism-dev 2023-03-25 17:57:55 -07:00
Tzanio Kolev 664bb278ef Merge branch 'master' into 1D-NURBS-dev 2023-03-25 17:49:04 -07:00
Will Pazner 75b88ab5c8 Update copyright to 2023 in lininteg_vectorfe_domain.cpp 2023-03-25 14:28:07 -07:00
Will Pazner d2f15700a3 Merge remote-tracking branch 'origin/master' into vectorfe-linearform-ext 2023-03-25 14:26:27 -07:00
Tzanio Kolev 92bf531fab Merge pull request #3556 from mfem/new-dev-version-4.5.3
Update version numbers to 4.5.3 -- a new development version
2023-03-24 17:10:58 -07:00
Stowell, Mark L 84f65c049d Typo caught by @hughcars 2023-03-24 13:56:17 -07:00
Stowell, Mark L bb70eb3657 Reverting an unintended change in error.hpp 2023-03-24 10:42:50 -07:00
Veselin Dobrev d054509853 Update version numbers to 4.5.3 -- a new development version 2023-03-24 09:43:38 -07:00
Stowell, Mark L 8fce609951 Improvements suggested by @jamiebramwell 2023-03-23 15:49:14 -07:00
Tzanio Kolev 00b2a0705f Merge pull request #3384 from mfem/mfem-4.5.2-dev
Final changes for mfem-4.5.2
2023-03-23 15:33:44 -07:00
Tzanio Kolev 98d4b369ba Final edits in the CHANGELOG for mfem-4.5.2 2023-03-23 15:30:22 -07:00
Stowell, Mark L 12fcd41115 Typos and other improvements suggested by @acfisher 2023-03-23 15:10:54 -07:00
Stowell, Mark L 5a2b434c2c Typo found by @v-dobrev 2023-03-23 15:10:03 -07:00
Stowell, Mark L 9b3c7e7211 Merge remote-tracking branch 'origin/master' into mesh-ptr-doc-dev
# Conflicts:
#	mesh/mesh.hpp
#	mesh/pmesh.hpp
2023-03-23 09:46:31 -07:00
Stowell, Mark L dada0326ef Changes suggested by @acfisher 2023-03-23 09:21:14 -07:00
Vladimir Z Tomov 1f53683c64 style 2023-03-22 13:03:33 -07:00
Vladimir Z Tomov a8f0bfbafe forgot to return it. 2023-03-22 13:00:23 -07:00
Vladimir Z Tomov f73f677b00 Added access to hiop's new_x field. 2023-03-22 12:59:04 -07:00
Veselin Dobrev af6e5e7b21 Merge branch 'master' into mfem-4.5.2-dev 2023-03-21 13:13:59 -07:00
Veselin DobrevandTzanio Kolev 0f6cd97b1a Update CHANGELOG with v4.5.2 release date
Co-authored-by: Tzanio Kolev <tzanio@llnl.gov>
2023-03-21 13:13:39 -07:00
Veselin Dobrev 2106ea4039 Merge pull request #3532 from mfem/2023-copyright
Updated COPYRIGHT to 2010-2023
2023-03-21 13:11:37 -07:00
Veselin Dobrev a152e48fd3 Update config/githooks/pre-push 2023-03-21 11:16:17 -07:00
Vladimir Z Tomov 3c4e67dbe1 unused variable in serial 2023-03-21 10:54:13 -07:00
Vladimir Z Tomov b0614c26d0 corrections in TMOP_Integrator::GetSurfaceFittingErrors() 2023-03-21 10:42:02 -07:00
Ido Akkerman 9105a3aa22 Merge branch '1D-NURBS-dev' of https://github.com/mfem/mfem into 1D-NURBS-dev 2023-03-16 11:42:18 +01:00
Ido Akkerman ada6d009cf Add 1D periodicity to NURBS 2023-03-16 09:41:16 +01:00
Will Pazner 701870a7da Merge pull request #3438 from mfem/sjg/pyr-ref-leak
Fix memory leak in pyramid mesh refinement for MFEM_USE_MEMALLOC
2023-03-15 13:27:07 -07:00
Ido Akkerman c866f52b69 Merge branch 'master' into 1D-NURBS-dev 2023-03-15 09:11:50 +01:00
Ido Akkerman f68365a0a0 Merge branch 'master' into ab-am-fix 2023-03-15 09:10:55 +01:00
Will Pazner 25d6fbc4ea Fix grammar in face map comments 2023-03-14 22:15:38 -07:00
Will Pazner cd9e718ea9 Fix GetFaceNormal3D Doxygen comment 2023-03-14 21:52:26 -07:00
Will Pazner 3beb66b7cc Fix comment grammar 2023-03-14 21:50:12 -07:00
Will Pazner 8869ad64a0 Improve Doxygen comment for H1_ND_RT_FaceRestriction 2023-03-14 21:49:22 -07:00
Will Pazner 9b0c3f7d13 Add comment to RT face restriction unit test 2023-03-14 21:48:13 -07:00
Will Pazner a78c2fee04 Implement PositiveTensorFiniteElement::GetFaceMap
Factor out logic in NodalTensorFiniteElement::GetFaceMap to
GetNodalTensorFaceMap, reuse for the case of Bernstein basis.
2023-03-14 14:04:42 -07:00
Will Pazner 6b7d72147f Add comment to FiniteElement::GetFaceMap 2023-03-14 14:02:41 -07:00
Will Pazner c3acad6dbd Merge remote-tracking branch 'origin/master' into rt-face-restriction
# Conflicts:
#	fem/fe/fe_base.hpp
#	fem/restriction.cpp
2023-03-14 11:23:26 -07:00
Veselin Dobrev a46650042b Fix some warnings 2023-03-14 09:11:41 -07:00
Veselin Dobrev b4bece1e0f Small tweak in the HiOp header to avoid recursive header
inclusion: 'linalg.hpp' and 'hiop.hpp' were including each
other (harmless due to header guards).
2023-03-13 06:10:57 -07:00
Veselin Dobrev e3e413bdae Fix warnings when building with Ginkgo 1.5.0 2023-03-13 06:09:50 -07:00
Veselin Dobrev 1792b1a90c In fem/picojson.h, use 'serialize_' instead of '_serialize' to
avoid a clash with a macro defined in GCC 11.2.
2023-03-13 06:05:40 -07:00
Tzanio Kolev 96e00dc815 Updated COPYRIGHT to 2010-2023 2023-03-11 16:58:18 -08:00
Veselin Dobrev 4f0a7d4773 Small updates:
* Bugfix in SparseMatrix::SortColumnIndices()
* More general definition of AsConst()
* Fix nvcc warning in miniapps/meshing/reflector.cpp
2023-03-10 23:48:14 -08:00
Ido Akkerman e3fb8fd88d Make style 2023-03-10 11:54:43 +01:00
Ido Akkerman d368e96e14 together with previous commit -- adding 1D weak BCs 2023-03-10 11:49:18 +01:00
Ido Akkerman d2a9fd1efa mesh/mesh.cpp 2023-03-10 11:48:07 +01:00
Ido Akkerman cffa32e98a Add Point to NURBS fe collection 2023-03-09 15:31:43 +01:00
Ido Akkerman 3fabd09cb9 Make pedantic compiler happy 2023-03-09 14:53:27 +01:00
Ido Akkerman 78a05c527a make style 2023-03-09 14:44:58 +01:00
Ido Akkerman 781d15969b Add parallel function def 2023-03-09 14:35:25 +01:00
Ido Akkerman 54b1ea497a Make pedantic test happy 2023-03-09 14:22:07 +01:00
Ido Akkerman e4d3533c9c Fix include 2 2023-03-09 14:16:07 +01:00
Ido Akkerman b87c6c5ba7 Fix include 2023-03-09 14:14:27 +01:00
Ido Akkerman 1f15ca161a Merge branch 'ab-am-fix' of https://github.com/mfem/mfem into ab-am-fix 2023-03-09 14:07:06 +01:00
Ido Akkerman f9998e6ca9 Memory errors 2023-03-09 14:04:33 +01:00
Ido Akkerman caab78bde3 Make style 2023-03-09 14:03:09 +01:00
Ido Akkerman 721ba15b38 Add test case and 1D output to nurbs miniapp 2023-03-09 13:15:47 +01:00
Ido Akkerman 16f107a79b make style 2023-03-09 10:45:20 +01:00
Ido Akkerman ec6990ce79 Change print mechanicsm and correct includes 2023-03-09 09:18:35 +01:00
Ido Akkerman dbfb30b9d4 Works? 2023-03-09 09:03:06 +01:00
Ido Akkerman 265ff5a817 More NURBS fixes 2023-03-09 08:48:48 +01:00
Veselin Dobrev 5335942a92 Merge branch 'master' into mfem-4.5.2-dev 2023-03-08 18:44:07 -08:00
Mark L. Stowell 888b8eca6d Merge pull request #3513 from mfem/shared-msvc-dev-v2
Add support for shared builds on Windows with MSVC using CMake
2023-03-08 17:39:58 -08:00
Mark L. Stowell 5c6000512d Merge branch 'master' into shared-msvc-dev-v2 2023-03-08 16:48:16 -08:00
Ido Akkerman 43b770ac26 First fixes to get things running 2023-03-08 18:08:37 +01:00
Ido Akkerman 0f8c634181 Add 1D NURBS mesh 2023-03-08 17:47:20 +01:00
Ido Akkerman d111505b94 Change patch data access operators 2023-03-08 17:32:00 +01:00
Ido Akkerman 369a5e03a1 Add 1D functions to NURBS classes 2023-03-08 16:42:01 +01:00
Veselin Dobrev ddfb7d48e2 In CHANGELOG, move a bullet added after v4.5.0 from the
v4.5.0 section to the v4.5.2 section.
2023-03-07 22:18:14 -08:00
Veselin Dobrev 1d95c85a0d Merge branch 'master' into mfem-4.5.2-dev 2023-03-07 22:04:28 -08:00
Ido Akkerman 2238dadd06 Merge branch 'master' into ab-am-fix 2023-03-07 10:30:14 +01:00
Veselin Dobrev ea56d41dd3 Mention the shared MSVC build support in CHANGELOG and
document the MFEM_EXPORT macro in config.hpp.
2023-03-06 17:48:51 -08:00
Veselin Dobrev e941c8ba91 More tweaks in .gitignore and 'make clean' 2023-03-06 02:43:07 -08:00
Veselin Dobrev fa142c9b59 Small tweaks to .gitignore and 'make clean' 2023-03-06 01:14:53 -08:00
Veselin Dobrev 9d5f62de33 Merge branch 'master' into mfem-4.5.2-dev 2023-03-05 20:27:25 -08:00
Veselin Dobrev f250ee95bb Merge pull request #3520 from lcheng9/master
Initialize two pointers.
2023-03-05 20:24:53 -08:00
Veselin Dobrev 2daf9762a4 Merge branch 'master' into shared-msvc-dev-v2 2023-03-04 21:36:37 -08:00
Veselin Dobrev 8356dd015f In GitHub actions: replace the static build with a shared
build in the windows-par-opt job.
2023-03-04 21:32:41 -08:00
Liang 8c8deaed95 Initialize null pointers.
Some compilers may complain about these two uninitialized pointers, simply resolve it.
2023-03-03 23:24:40 -05:00
Veselin Dobrev 78467f4268 Fix the shared build on Windows with MinGW-w64 2023-03-03 06:36:22 -08:00
Veselin Dobrev e75ab127c8 Bugfix for GitHub issue #3516 2023-03-02 17:25:15 -08:00
Veselin Dobrev fff74aca98 Suppress Doxygen warnings in geom.hpp 2023-02-28 21:00:49 -08:00
Sebastian Grimberg 0412f7f9ea Merge branch 'master' into sjg/pyr-ref-leak 2023-02-28 16:24:27 -08:00
Veselin Dobrev ce505ceab2 In the Appveyor CI, test only the serial shared build since
both static and shared tests take too long.

Try to speed up the hypre build with -j 4.
2023-02-27 22:50:44 -08:00
Veselin DobrevandKenny Weiss c3dbd8041b Add support for shared builds on Windows with MSVC using CMake.
This commit based to a large extend on PR #1401.

Co-authored-by: Kenny Weiss <kennyweiss@users.noreply.github.com>
2023-02-27 19:31:21 -08:00
Veselin Dobrev bbd1b42bab Merge branch 'master' into mfem-4.5.2-dev 2023-02-24 16:49:21 -08:00
Veselin Dobrev 546e96c2a2 Merge branch 'master' into mfem-4.5.2-dev 2023-02-23 09:42:52 -08:00
Veselin Dobrev b9b17575fb Merge branch 'master' into mfem-4.5.2-dev 2023-02-23 09:27:28 -08:00
Ido Akkerman da7ae3d7fe Merge branch 'master' into ab-am-fix 2023-02-23 10:50:34 +01:00
Ido Akkerman ae32fddc73 Merge branch 'ab-am-fix' of https://github.com/mfem/mfem into ab-am-fix 2023-02-23 10:48:08 +01:00
Ido Akkerman d21eb9f5b2 Remove guard and prevent warning output at first timestep 2023-02-23 10:43:01 +01:00
Veselin Dobrev 946ecc4623 Github actions: use v2.3 of the mfem-build action which solves the
slow linking on Ubuntu + CMake. Keep the ability to set additional
configuration options in the build matrix.
2023-02-22 23:41:53 -08:00
Veselin Dobrev 86786df48e Github actions: try another way to pass config-options to the
Ubuntu + CMake build.
2023-02-22 18:37:39 -08:00
Veselin Dobrev 15aae11753 Try to resolve the slow linking issue on Ubuntu + CMake. 2023-02-22 18:10:04 -08:00
Veselin Dobrev 7cda15237b Merge branch 'master' into mfem-4.5.2-dev
Resolved conflicts:
   CHANGELOG
2023-02-22 18:07:58 -08:00
Veselin Dobrev 94573fcaec Merge branch 'master' into mfem-4.5.2-dev 2023-02-21 12:51:03 -08:00
Tzanio Kolev 3f566ab46f Merge branch 'master' into dof-doc-dev 2023-02-21 11:48:37 -08:00
Ben Southworth 6fa71acdd6 fix space in printout 2023-02-21 08:52:20 -07:00
Ben Southworth 1f1fc6e6e5 add missing space 2023-02-21 06:18:35 -07:00
Veselin Dobrev 764898e186 Suppress a warning from CMake about HDF5_ROOT.
In MfemCmakeUtilities.cmake, tweak mfem_find_package() and
mfem_get_target_options() to handle imported libraries better.
2023-02-20 15:22:42 -08:00
Ido Akkerman 61848a0627 Fix print if root statement 2023-02-20 16:33:28 +01:00
Ido Akkerman 4c59647387 Fixing compile error and warning message 2023-02-20 14:59:20 +01:00
Veselin DobrevandChris White 93cdcae163 Fix some CMake issues in FindNetCDF.cmake related to HDF5
Reported-by: Jamie Bramwell <jamiebramwell@users.noreply.github.com>
Co-authored-by: Chris White <white238@users.noreply.github.com>
2023-02-17 16:22:10 -08:00
Ido Akkerman ffbb844a22 Add timestep check to AM and AB solvers. FLush history if timestep changes 2023-02-17 17:34:45 +01:00
Ido Akkerman 3c8f827c8e Small improvement to ODE unit tester 2023-02-15 15:47:32 +01:00
Ido Akkerman 200f146a81 Correct time increment in AB & AM ode integrators 2023-02-15 15:47:20 +01:00
Tzanio Kolev 8053bc25e4 Updated CHANGELOG for the mfem-4.5.2 release 2023-02-14 15:02:48 -08:00
Veselin Dobrev c8aa9544c3 Merge branch 'master' into mfem-4.5.2-dev 2023-02-11 23:33:39 -08:00
Veselin Dobrev 72596e45d4 In defaults.mk, replace the '--amdgpu-target' flag with
'--offload-arch' since new versions of hipcc generate warning
about it; older versions should still work fine with
'--offload-arch'.
2023-02-11 23:27:40 -08:00
Tzanio Kolev 66de366701 Merge branch 'master' into vectorfe-linearform-ext 2023-02-09 10:19:26 -08:00
Sebastian Grimberg ae8ed6bb92 Merge branch 'master' into sjg/pyr-ref-leak 2023-02-07 20:25:56 -08:00
Veselin Dobrev b90350b234 Bugfix for issue #3433 2023-02-06 12:04:44 -08:00
Will Pazner 45c373a02c Use static constexpr for lambda capture constants
Otherwise Windows build complains about error:

error C2131: expression did not evaluate to a constant
2023-02-06 11:31:07 -08:00
Will Pazner dadd863539 Support VectorFEDomainLFIntegrator on device 2023-02-06 11:31:06 -08:00
Tzanio Kolev b8b3dc2f73 Merge branch 'master' into nurbs-attr 2023-02-06 11:02:17 -08:00
Veselin Dobrev 0a50fe2fde CMake fix for using (with the tests) and exporting the MPI variables
MPI_CXX_COMPILE_FLAGS and MPI_CXX_LINK_FLAGS when defined.
2023-02-05 21:26:41 -08:00
Veselin Dobrev ada669ff40 Merge branch 'master' into mfem-4.5.2-dev 2023-02-05 21:25:46 -08:00
Veselin Dobrev 3764f6e15c Merge branch 'master' into mfem-4.5.2-dev 2023-02-03 13:47:38 -08:00
Dylan Copeland 08b5a285be Merge branch 'master' of github.com:mfem/mfem into nurbs-attr 2023-01-30 16:30:40 -08:00
Dylan Copeland 9d62c10fbe Setting patch boundary elements on setup rather than on demand. 2023-01-30 16:28:04 -08:00
Sebastian Grimberg c7e701807a Fix memory leak in pyramid mesh refinement for MFEM_USE_MEMALLOC 2023-01-27 10:51:43 -08:00
Mark L. Stowell 3538641b58 Merge branch 'master' into dof-doc-dev 2023-01-11 15:38:53 -05:00
Mark L. Stowell 22f4f06bae Merge branch 'master' into mesh-ptr-doc-dev 2023-01-11 15:37:40 -05:00
Stowell, Mark L 122061b0ed Switch to using MPI_Gather 2023-01-11 09:37:55 -05:00
Will Pazner 35cea24e21 Move face map logic from restriction.cpp into FiniteElement derived classes
Use inheritance instead of switch statement to dispatch
2023-01-09 20:46:51 -08:00
Will Pazner 9732e4dc6f Make SupportsDevice const
In both LinearFormIntegrator and LinearForm classes
2023-01-09 19:40:21 -08:00
Will Pazner 035301c212 Comment 2023-01-09 19:35:51 -08:00
Will Pazner f6efd6e56b Fix comment 2023-01-09 19:17:26 -08:00
Will Pazner 896922fbe4 Update CHANGELOG 2023-01-08 17:14:57 -08:00
Veselin Dobrev 4882231889 Merge branch 'master' into mfem-4.5.2-dev 2023-01-06 09:19:34 -08:00
Will Pazner f726606b96 Add GetFaceNormal3D to help manage 3D hexahedron face cases 2023-01-05 08:55:45 -08:00
Will Pazner 02fa406807 Refactor FillFaceMap and add explanatory comment 2023-01-05 08:55:20 -08:00
Will Pazner 1e34a98337 ND face restriction 2023-01-05 08:55:19 -08:00
Will Pazner bbd28f5f45 VectorFEBoundaryFluxLFIntegrator kernel in 3D 2023-01-04 18:49:04 -08:00
Will Pazner f413481bff RT face restriction in 3D 2023-01-04 18:49:04 -08:00
Will Pazner 61a922a812 Fix Mesh::FaceInformation output with operator<<
Newline was missing after face topology.

Also use '\n' instead of std::endl for all but last newline since there is no
reason to flush the buffer before then.
2023-01-04 18:48:46 -08:00
Will Pazner 25ba954475 Test device kernel for VectorFEBoundaryFluxLFIntegrator in 2D 2023-01-04 18:48:46 -08:00
Will Pazner a9829da2cb Add device kernel for VectorFEBoundaryFluxLFIntegrator 2023-01-04 18:48:46 -08:00
Will Pazner 1b2ab9253b Add test case for 2D RT face restriction 2023-01-04 18:48:44 -08:00
Will Pazner 067f571dc4 Support 2D RT elements in H1_ND_RT_FaceRestriction 2023-01-04 14:18:27 -08:00
Will Pazner 452cf127c6 Rename H1FaceRestriction to H1_ND_RT_FaceRestriction
The same class should be able to be used for H1, ND, and RT spaces
2023-01-04 14:18:27 -08:00
Will Pazner 328df07f5d Refactor GetFaceDofs to use offset and strides 2023-01-04 14:18:27 -08:00
Veselin Dobrev f8f20ba147 Merge branch 'master' into mfem-4.5.2-dev 2022-12-28 10:41:48 -08:00
Veselin Dobrev b657fd4d74 Initial changes for the v4.5.2 release 2022-12-24 15:06:13 -08:00
Ketan Mittal cb9d36b293 fix dist_solver include 2022-12-14 14:45:26 -08:00
Ketan Mittal 23f45ab9df remove trimming option 2022-12-14 14:35:06 -08:00
Ketan Mittal e2e9bd0061 update fitting miniapp 2022-12-14 10:38:20 -08:00
Ketan Mittal 9fe24667c4 fit CMake for shifting dist_solver 2022-12-14 09:46:49 -08:00
Ketan Mittal 1525caaee9 minor clean up and make style 2022-12-14 09:43:45 -08:00
Ketan Mittal 445ffbe037 merge with master, resolve conflict, and make style 2022-12-14 09:27:02 -08:00
Dylan Copeland bde55a3686 Merge branch 'master' into nurbs-attr 2022-12-09 09:59:43 -08:00
Ketan Mittal 77f958695b some optimizations and fix node count in serial/parallel for weight of surface fitting term 2022-12-07 11:10:42 -08:00
Dylan Copeland 11abc26e00 Setting patch_to_el after setting el_to_patch. 2022-11-14 21:55:22 -08:00
Dylan Copeland 707befe264 Documenting some new functions. 2022-11-14 21:38:39 -08:00
Dylan Copeland ae50320b05 Editing a comment. 2022-11-09 12:18:33 -08:00
Dylan Copeland 2366754d19 Adding functions to set and get attributes on NURBS patches. 2022-11-09 12:06:19 -08:00
Ketan Mittal 4ccf6d31ad Merge branch 'master' of https://github.com/mfem/mfem into tmop-bif 2022-09-20 09:40:59 -06:00
Ketan Mittal 153dc6aeac make style and parameterize some components 2022-09-20 09:40:45 -06:00
Stowell, Mark L 66077d66a1 Adding comments about DofTransformation as a returned object 2022-09-09 13:45:26 -07:00
Stowell, Mark L 8a8d2ec0d9 Adding a mention of DofTransformation in ldof description 2022-09-09 13:29:33 -07:00
Stowell, Mark L dd8a19d180 Merge remote-tracking branch 'origin/master' into mesh-ptr-doc-dev 2022-09-09 12:55:51 -07:00
Stowell, Mark L 30c728bc84 Merge remote-tracking branch 'origin/master' into dof-doc-dev 2022-09-09 12:55:03 -07:00
Stowell, Mark L bc745ada10 Expanding docs for the VDoF methods (mostly) 2022-09-09 10:48:47 -07:00
Stowell, Mark L 8e75633838 Adding references to dof type descriptions 2022-09-08 14:09:09 -07:00
Ketan Mittal 84a43d74e6 add weighting for surface fitting terms 2022-08-28 07:59:51 -07:00
Ketan Mittal b8a62066b4 Merge branch 'master' of https://github.com/mfem/mfem into tmop-bif 2022-08-22 15:12:42 -07:00
Stowell, Mark L f30fcbf828 Documenting dof types in FiniteElementSpace class docs 2022-08-19 14:23:51 -07:00
Ketan Mittal 477b676190 misc clean up, remove unneeded level sets 2022-08-11 16:26:17 -07:00
Ketan Mittal 64218c7509 make style 2022-08-09 16:27:16 -07:00
Ketan Mittal 1ce8f6ea37 merge with master and resolve conflicts 2022-08-09 16:26:55 -07:00
Ketan Mittal f17ee1133a remove spaces from inline-hex 2022-08-09 15:14:01 -07:00
Stowell, Mark L 9f03e9f682 Extending documentation for pmesh nurbs and element 2022-08-04 14:59:45 -07:00
Stowell, Mark L 3fadacb72b Merge remote-tracking branch 'origin/master' into mesh-ptr-doc-dev 2022-08-03 17:12:04 -07:00
Stowell, Mark L 94ae0d9c5e Expanding comments in mesh.hpp 2022-08-03 17:09:33 -07:00
Ketan Mittal b3385367f0 misc updates.. still debugging 2022-08-01 15:45:59 -07:00
Stowell, Mark L 8709602daa Small documentation changes to Mesh 2022-07-26 14:23:49 -07:00
Ketan Mittal 1baccc786c modify LSF for 3D case to use r-function 2022-06-16 11:28:49 -07:00
Ketan Mittal 25d06a62b5 work for different node ordering 2022-06-14 13:14:33 -07:00
Ketan Mittal 0cf3bc7f14 doxygen comment 2022-05-24 13:33:22 -07:00
Ketan Mittal 42a7bd8e2f Merge branch 'pmesh-to-serial-mesh' of https://github.com/mfem/mfem into tmop-bif 2022-05-24 12:02:37 -07:00
Ketan Mittal fca9768dc2 Merge branch 'master' of https://github.com/mfem/mfem into tmop-bif 2022-05-24 11:49:46 -07:00
Ketan Mittal dce4047d0f remove par mesh save with attributes 2022-05-24 11:49:25 -07:00
Ketan Mittal 6148f1e015 make style 2022-05-05 14:00:50 -07:00
Ketan Mittal b19a02b488 add 3D example and fix pmesh save with attributes 2022-05-05 14:00:31 -07:00
Ketan Mittal cb5e7adf45 misc changes 2022-04-21 09:57:53 -07:00
Ketan Mittal fab5fc1552 minor changes 2022-04-15 12:54:10 -07:00
Ketan Mittal 0f6c6d28fe use custom scaling for penalization weight and max num of increments 2022-04-11 08:32:51 -07:00
Ketan Mittal 4fc789bc7c option to work using distance function on current mesh 2022-04-04 18:09:13 -07:00
Ketan Mittal 92f246dd54 update miniapp 2022-04-04 14:31:42 -07:00
Ketan Mittal a2166e2dd1 add machinery for source mesh for fitting 2022-04-04 14:31:04 -07:00
Ketan Mittal e6198e2617 move distance solver to common 2022-04-04 14:30:32 -07:00
Ketan Mittal 78dc0db5d8 initial commit 2022-04-04 10:46:57 -07:00
855 changed files with 12383 additions and 2125 deletions
+14 -8
View File
@@ -31,7 +31,7 @@ install:
- ps: ( get-content "GKlib\gk_arch.h") | % { If ($_.ReadCount -ge 52) {$_ -replace "#ifdef __MSC__","#ifdef DISABLE_THIS_ANCIENT_MSC_CHECK"} Else {$_} } | set-content "GKlib\gk_arch.h"
- cmake -H. -Bbuild
# -DCMAKE_BUILD_TYPE=Release
- cmake --build build
- cmake --build build --target metis -j 4
- set METIS_PATH=%cd%
- cd ..
@@ -40,7 +40,7 @@ install:
- 7z x v2.19.0.tar.gz -so | 7z x -si -ttar > nul
- cd hypre-2.19.0/src
- cmake -H. -Bbuild
- cmake --build build
- cmake --build build -j 4
- cmake --build build --target install
- cd ../..
@@ -49,14 +49,20 @@ install:
# MFEM
before_build:
- cmake -H. -DCMAKE_INSTALL_PREFIX=install -Bbuild_parallel -DMFEM_USE_MPI=TRUE -DMFEM_USE_METIS_5=TRUE -DHYPRE_DIR=%cd%\..\hypre-2.19.0\src\hypre -DMETIS_LIBRARIES=%METIS_PATH%\build\libmetis\Debug\metis.lib -DMETIS_INCLUDE_DIRS=%METIS_PATH%\include
- cmake -H. -DCMAKE_INSTALL_PREFIX=install -Bbuild_serial -DMFEM_USE_MPI=FALSE
- cmake . -Bbuild_parallel -DMFEM_USE_MPI=TRUE -DMFEM_USE_METIS_5=TRUE -DHYPRE_DIR=%cd%\..\hypre-2.19.0\src\hypre -DMETIS_LIBRARIES=%METIS_PATH%\build\libmetis\Debug\metis.lib -DMETIS_INCLUDE_DIRS=%METIS_PATH%\include
# - cmake . -Bbuild_serial -DMFEM_USE_MPI=FALSE
- cmake . -Bbuild_shared_serial -DMFEM_USE_MPI=FALSE -DBUILD_SHARED_LIBS=ON
build_script:
- cmake --build build_parallel --config Release -j 4
- cmake --build build_serial --config Release -j 4
- cmake --build build_serial --target exec --config Release -j 4
- cmake --build build_parallel --config Debug -j 4
# - cmake --build build_serial --config Release -j 4
# - cmake --build build_serial --target exec --config Release -j 4
- cmake --build build_shared_serial --config Release -j 4
- cmake --build build_shared_serial --target exec --config Release -j 4
after_build:
- cd build_serial
# - cd build_serial
# - ctest -C Release --output-on-failure
# - cd ..
- cd build_shared_serial
- ctest -C Release --output-on-failure
+10 -3
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
@@ -74,12 +74,19 @@ jobs:
codecov: YES
- os: windows-latest
codecov: NO
- os: windows-latest
target: opt
mpi: par
config-opts: '-DBUILD_SHARED_LIBS=ON'
- os: ubuntu-latest
target: opt
codecov: NO
mpi: par
build-system: cmake
hypre-target: int32
# This option can be set to pass additional configuration options to
# the MFEM configuration command.
# config-opts: '-DCMAKE_VERBOSE_MAKEFILE=ON'
- os: ubuntu-latest
target: opt
codecov: NO
@@ -210,7 +217,7 @@ jobs:
# MFEM build and test
- name: build
uses: mfem/github-actions/build-mfem@v2.2
uses: mfem/github-actions/build-mfem@v2.3
env:
VCPKG_DEFAULT_BINARY_CACHE: ${{ github.workspace }}/vcpkg_cache
with:
@@ -222,7 +229,7 @@ jobs:
hypre-dir: ${{ env.HYPRE_TOP_DIR }}
metis-dir: ${{ env.METIS_TOP_DIR }}
mfem-dir: ${{ env.MFEM_TOP_DIR }}
config-options: ${{ env.MFEM_EXTRA_CONFIG }}
config-options: ${{ matrix.config-opts }}
library-only: ${{ matrix.target == 'dbg' }}
# Run checks (and only checks) on debug targets
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+13 -7
View File
@@ -21,6 +21,9 @@ CMakeFiles/
# Default install location
/mfem/
# Typical build directory
/build/
# Generated files in main directory, config/ and docs/
/deps.mk
config/_config.hpp
@@ -118,11 +121,9 @@ examples/amgx/sol.gf
examples/amgx/mesh.*
examples/amgx/sol.*
examples/gingko/ex1
examples/gingko/refined.mesh
examples/gingko/sol.gf
examples/gingko/mesh.*
examples/gingko/sol.*
examples/ginkgo/ex1
examples/ginkgo/refined.mesh
examples/ginkgo/sol.gf
examples/hiop/ex9
examples/hiop/ex9p
@@ -148,8 +149,8 @@ examples/petsc/velocity.*
examples/petsc/elastic_energy.*
examples/petsc/mode_*
examples/pumi/ex1
examples/pumi/ex[126]p
examples/pumi/ex[12]
examples/pumi/ex[16]p
examples/pumi/refined.mesh
examples/pumi/sol.gf
examples/pumi/mesh.*
@@ -194,6 +195,9 @@ miniapps/gslib/field-diff
miniapps/gslib/field-interp
miniapps/gslib/findpts
miniapps/gslib/pfindpts
miniapps/gslib/schwarz_ex1
miniapps/gslib/schwarz_ex1p
miniapps/gslib/interpolated.gf
miniapps/meshing/mobius-strip
miniapps/meshing/klein-bottle
@@ -206,6 +210,7 @@ miniapps/meshing/trimmer
miniapps/meshing/reflector
miniapps/meshing/mesh-optimizer
miniapps/meshing/pmesh-optimizer
miniapps/meshing/pmesh-fitting
miniapps/meshing/minimal-surface
miniapps/meshing/pminimal-surface
miniapps/meshing/polar-nc
@@ -245,6 +250,7 @@ miniapps/navier/navier_tgv
miniapps/navier/navier_shear
miniapps/navier/navier_3dfoc
miniapps/navier/navier_turbchan
miniapps/navier/navier_cht
miniapps/navier/tgv_out*.txt
miniapps/navier/*_output
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -6
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
@@ -27,11 +27,6 @@ allocate_resource:
timeout: 6h
# GitLab jobs for the Quartz machine at LLNL
debug_ser_gcc_4_9_3:
variables:
SPEC: "%gcc@4.9.3 +debug~mpi"
extends: .build_and_test_on_quartz
debug_ser_gcc_6_1_0:
variables:
SPEC: "%gcc@6.1.0 +debug~mpi"
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
@@ -1,6 +1,6 @@
#!/bin/bash
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
@@ -1,6 +1,6 @@
#!/bin/bash
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+48 -38
View File
@@ -8,61 +8,69 @@
https://mfem.org
Version 4.5.1 (development)
Version 4.5.3 (development)
===========================
- When using discontinuous (L2) spaces, use local (element-wise) L2 projection
as the coarsening operator for non-conforming AMR meshes.
Meshing improvements
--------------------
- Added new methods in the Mesh class to set and get attributes on NURBS patches
and patch boundaries.
New and updated examples and miniapps
-------------------------------------
- Added a miniapp pmesh-fitting in miniapps/meshing for interface and boundary fitting to implicit domains defined using level-set functions.
- Moved the distance solver methods from miniapps/shifted to miniapps/common.
Discretization improvements
---------------------------
- Face restriction operators for Nedelec and Raviart-Thomas finite element
spaces are now supported through the ConformingFaceRestriction class.
- VectorFEBoundaryFluxLFIntegrator is now supported on device/GPU.
Version 4.5.2, released on March 23, 2023
=========================================
- Added support for pyramids in non-conforming meshes. Currently only isotropic
refinement is supported in this case.
- Removed the support for the Mesquite toolkit. We recommend using MFEM's TMOP
functionality instead for mesh optimization. See the mesh-optimizer miniapp.
- Added a fast normalization-based distance solver, see the Distance miniapp
in the miniapps/shifted/ directory.
- Added a new meshing miniapp, Reflector, which reflects a high-order or NURBS
hexahedral mesh about a plane.
- Updated logic in FindPointsGSLIB to ignore points found near (but outside) the
domain boundary.
- Added support for pyramids in Gmsh meshes.
- Added an option to auto-balance compound TMOP metrics.
- Fixed a bug in TMOP metric 301.
- Added an option to auto-balance compound TMOP metrics.
- When using discontinuous (L2) spaces, use local (element-wise) L2 projection
as the coarsening operator for non-conforming AMR meshes.
Discretization improvements
---------------------------
- TBD
- Added support for GridFunction::GetGradients() and GetVectorGradient() on
face-neighbor elements.
Linear and nonlinear solvers
----------------------------
- Added a fast normalization-based distance solver, see the Distance miniapp
in the miniapps/shifted/ directory.
- Added support for pyramids in Gmsh meshes.
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. See option 'D' in the menu.
- 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.
- VisItDataCollection now correctly handles data collection names containing
underscores.
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.
- Added support for shared Windows builds with MSVC through CMake.
Developers note: this enhancement is facilitated by the addition of the macro
MFEM_EXPORT, see config.hpp for more details on its usage.
- 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 *'
@@ -73,6 +81,11 @@ API changes
deprecated, and Mesh::GetFaceGeometry (which provides identical functionality)
should be used instead.
- 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 SetPadDigitsRank().
Version 4.5, released on October 22, 2022
=========================================
@@ -116,9 +129,6 @@ Discretization improvements
- 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.
+42 -9
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
@@ -13,6 +13,7 @@
# 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)
message(STATUS "CMake version: ${CMAKE_VERSION}")
set(USER_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/config/user.cmake" CACHE PATH
"Path to optional user configuration file.")
@@ -24,8 +25,11 @@ set(CMAKE_CXX_EXTENSIONS OFF)
# Load user settings before the defaults - this way the defaults will not
# overwrite the user set options. If the user has not set all options, we still
# have the defaults.
message(STATUS "(optional) USER_CONFIG = ${USER_CONFIG}")
include("${USER_CONFIG}" OPTIONAL)
include("${USER_CONFIG}" OPTIONAL RESULT_VARIABLE USER_CONFIG_LOADED)
if (USER_CONFIG_LOADED)
set(USER_CONFIG_LOADED "LOADED")
endif()
message(STATUS "Loading USER_CONFIG = ${USER_CONFIG} (${USER_CONFIG_LOADED})")
include("${CMAKE_CURRENT_SOURCE_DIR}/config/defaults.cmake")
# Allow overwriting of the compiler by setting CXX/MPICXX on the command line or
@@ -53,7 +57,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.5.1)
set(${PROJECT_NAME}_VERSION 4.5.3)
# Prohibit in-source build
if (${PROJECT_SOURCE_DIR} STREQUAL ${PROJECT_BINARY_DIR})
@@ -183,6 +187,23 @@ else()
set(MFEM_DEBUG OFF)
endif()
# Shared build on Windows
if (WIN32 AND BUILD_SHARED_LIBS)
# CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS works only with MSVC?
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON CACHE BOOL
"Automatically export symbols for shared Windows DLL build")
# Place all .dll and .exe files in the same sub-directory, 'bin/<config>', of
# the build directory, so that the .exe files can find the .dll files at
# runtime:
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
# Note: CMake tests are run from the build-tree sub-directory where the test
# is defined, e.g. <build-dir>/tests/unit, so hard coded paths to meshes still
# work fine.
# Not strictly necessary:
# set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
# set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
endif()
# AMD HIP
if (MFEM_USE_HIP)
if (HIP_ARCH)
@@ -519,6 +540,7 @@ list(REVERSE TPL_LIBRARIES)
list(REMOVE_DUPLICATES TPL_INCLUDE_DIRS)
# message(STATUS "TPL_INCLUDE_DIRS = ${TPL_INCLUDE_DIRS}")
message(STATUS "MFEM shared library: BUILD_SHARED_LIBS = ${BUILD_SHARED_LIBS}")
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}")
@@ -574,7 +596,19 @@ target_include_directories(mfem
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
# The INSTALL_INTERFACE is handled below
${TPL_INCLUDE_DIRS})
if (MFEM_USE_MPI)
if (MPI_CXX_COMPILE_FLAGS)
separate_arguments(MPI_CXX_COMPILE_ARGS UNIX_COMMAND
"${MPI_CXX_COMPILE_FLAGS}")
target_compile_options(mfem PUBLIC ${MPI_CXX_COMPILE_ARGS})
endif()
if (MPI_CXX_LINK_FLAGS)
target_link_libraries(mfem PUBLIC ${MPI_CXX_LINK_FLAGS})
endif()
endif()
set_target_properties(mfem PROPERTIES VERSION "${mfem_VERSION}")
set_target_properties(mfem PROPERTIES SOVERSION "${mfem_VERSION}")
@@ -586,6 +620,7 @@ if (NOT ("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}"))
endif()
# Generate configuration file in the build directory: config/_config.hpp.
set(MFEM_SHARED_BUILD ${BUILD_SHARED_LIBS})
configure_file(
"${PROJECT_SOURCE_DIR}/config/cmake/config.hpp.in"
"${PROJECT_BINARY_DIR}/config/_config.hpp")
@@ -705,7 +740,7 @@ set(INSTALL_LIB_DIR lib
set(INSTALL_CMAKE_DIR lib/cmake/mfem
CACHE PATH "Relative path for installing cmake config files.")
target_include_directories(mfem
target_include_directories(mfem BEFORE
PUBLIC
$<INSTALL_INTERFACE:${INSTALL_INCLUDE_DIR}>)
@@ -757,10 +792,8 @@ endif()
# Install the configuration header files
install(FILES ${PROJECT_BINARY_DIR}/config/_config.hpp
DESTINATION ${INSTALL_INCLUDE_DIR}/mfem/config
RENAME config.hpp)
install(FILES ${PROJECT_SOURCE_DIR}/config/tconfig.hpp
${PROJECT_SOURCE_DIR}/config/config.hpp
${PROJECT_SOURCE_DIR}/config/tconfig.hpp
DESTINATION ${INSTALL_INCLUDE_DIR}/mfem/config)
# Package the whole thing up nicely
+1 -1
View File
@@ -1,6 +1,6 @@
BSD 3-Clause License
Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC
Copyright (c) 2010-2023, Lawrence Livermore National Security, LLC
All rights reserved.
Redistribution and use in source and binary forms, with or without
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+4 -1
View File
@@ -1,4 +1,4 @@
// Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
// Copyright (c) 2010-2023, 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.
//
@@ -39,6 +39,9 @@
// Description of the git commit used to build MFEM.
#cmakedefine MFEM_GIT_STRING "@MFEM_GIT_STRING@"
// Enable shared library build of MFEM.
#cmakedefine MFEM_SHARED_BUILD
// Build the parallel MFEM library.
// Requires an MPI compiler, and the libraries HYPRE and METIS.
#cmakedefine MFEM_USE_MPI
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+11 -4
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
@@ -21,8 +21,15 @@ if(EXISTS ${CONDUIT_DIR}/include/conduit/conduit_relay_hdf5.hpp)
# we only need HDF5 if Conduit was built with HDF5 support
set(Conduit_REQUIRED_PACKAGES "HDF5" CACHE STRING
"Additional packages required by Conduit.")
else()
message(STATUS "Conduit Relay HDF5 Support is DISABLED")
# Suppress warning about HDF5_ROOT being set
if (POLICY CMP0074)
cmake_policy(SET CMP0074 NEW)
endif()
# HDF5_ROOT is needed in some cases, e.g. when HDF5_TARGET_NAMES is set and
# MFEM's FindHDF5.cmake is not used.
set(HDF5_ROOT ${HDF5_DIR} CACHE PATH "")
else()
message(STATUS "Conduit Relay HDF5 Support is DISABLED")
endif()
include(MfemCmakeUtilities)
@@ -32,4 +39,4 @@ mfem_find_package(Conduit CONDUIT CONDUIT_DIR
ADD_COMPONENT relay
"include;include/conduit" conduit_relay.hpp "lib" conduit_relay
ADD_COMPONENT blueprint
"include;include/conduit" conduit_blueprint.hpp "lib" conduit_blueprint)
"include;include/conduit" conduit_blueprint.hpp "lib" conduit_blueprint)
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+17 -6
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
@@ -14,11 +14,17 @@
# - NETCDF_LIBRARIES
# - NETCDF_INCLUDE_DIRS
# Suppress warning about HDF5_ROOT being set
if (POLICY CMP0074)
cmake_policy(SET CMP0074 NEW)
endif()
include(MfemCmakeUtilities)
# FindHDF5.cmake uses HDF5_ROOT, so we "translate" from the MFEM convention
# (MFEM's FindHDF5.cmake does not need HDF5_ROOT)
# set(HDF5_ROOT ${HDF5_DIR} CACHE PATH "")
# (Needed in some cases, e.g. when HDF5_TARGET_NAMES is set and MFEM's
# FindHDF5.cmake is not used.)
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
@@ -35,6 +41,11 @@ mfem_find_package(NetCDF NETCDF NETCDF_DIR "include" netcdf.h "lib" netcdf
# 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
# (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})
# (Needed in some cases, e.g. when HDF5_TARGET_NAMES is set and MFEM's
# FindHDF5.cmake is not used.)
if (HDF5_C_LIBRARY_hdf5_hl)
list(INSERT NETCDF_LIBRARIES 1 ${HDF5_C_LIBRARY_hdf5_hl})
if (NOT NetCDF_FIND_QUIETLY)
message(STATUS "Updated NetCDF libraries: ${NETCDF_LIBRARIES}")
endif()
endif()
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+38 -59
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
@@ -103,25 +103,6 @@ macro(add_mfem_examples EXE_SRCS)
${MFEM_EXEC_PREREQUISITES_TARGET_NAME} ${EXE_PREREQUISITE})
target_link_libraries(${EXE_NAME} mfem)
if (MFEM_USE_MPI)
# Not needed: (mfem already links with MPI_CXX_LIBRARIES)
# target_link_libraries(${EXE_NAME} ${MPI_CXX_LIBRARIES})
# Language-specific include directories:
if (MPI_CXX_INCLUDE_PATH)
target_include_directories(${EXE_NAME} PRIVATE "${MPI_CXX_INCLUDE_PATH}")
endif()
if (MPI_CXX_COMPILE_FLAGS)
separate_arguments(MPI_CXX_COMPILE_ARGS UNIX_COMMAND
"${MPI_CXX_COMPILE_FLAGS}")
target_compile_options(${EXE_NAME} PRIVATE ${MPI_CXX_COMPILE_ARGS})
endif()
if (MPI_CXX_LINK_FLAGS)
set_target_properties(${EXE_NAME} PROPERTIES
LINK_FLAGS "${MPI_CXX_LINK_FLAGS}")
endif()
endif()
endforeach(SRC_FILE)
endmacro()
@@ -172,26 +153,6 @@ macro(add_mfem_miniapp MFEM_EXE_NAME)
if (EXTRA_DEFINES_LIST)
target_compile_definitions(${MFEM_EXE_NAME} PRIVATE ${EXTRA_DEFINES_LIST})
endif()
# Handle the MPI separately
if (MFEM_USE_MPI)
# Add MPI_CXX_LIBRARIES, in case this target does not link with mfem.
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)
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)
set_target_properties(${MFEM_EXE_NAME} PROPERTIES
LINK_FLAGS "${MPI_CXX_LINK_FLAGS}")
endif()
endif()
endmacro()
@@ -436,9 +397,9 @@ function(mfem_find_package Name Prefix DirVar IncSuffixes Header LibSuffixes
break()
endif()
endforeach()
if (${Required} AND NOT ${ReqPack}_FOUND)
if (Required AND NOT ${ReqPack}_FOUND)
message(FATAL_ERROR " *** Required package ${ReqPack} not found."
"Checked target names: ${ReqPack} ${${ReqPack}_TARGET_NAMES}")
" Checked target names: ${ReqPack} ${${ReqPack}_TARGET_NAMES}")
endif()
endif()
endif()
@@ -504,14 +465,18 @@ function(mfem_find_package Name Prefix DirVar IncSuffixes Header LibSuffixes
endif()
get_target_property(IsImported ${TargetName} IMPORTED)
if (IsImported)
get_target_property(ImpConfigs ${TargetName} IMPORTED_CONFIGURATIONS)
# message(STATUS "${ReqPack} imported configs: ${ImpConfigs}")
set(ImportConfig ${${ReqPack}_IMPORT_CONFIG})
if (NOT ImportConfig)
set(ImportConfig RELEASE)
list(FIND ImpConfigs ${ImportConfig} _Index)
if (_Index EQUAL -1)
list(GET ImpConfigs 0 ImportConfig)
endif()
endif()
set(ImportConfigSuffix "_${ImportConfig}")
get_target_property(ImpConfigs ${TargetName} IMPORTED_CONFIGURATIONS)
list(FIND ImpConfigs ${ImportConfig} _Index)
if ((_Index EQUAL -1) OR ("${ImportConfig}" STREQUAL "NO_CONFIG"))
if ((NOT ImportConfig) OR ("${ImportConfig}" STREQUAL "NO_CONFIG"))
set(ImportConfig "NO_CONFIG")
set(ImportConfigSuffix "")
# message(FATAL_ERROR " *** ${ReqPack}: configuration "
@@ -529,7 +494,8 @@ function(mfem_find_package Name Prefix DirVar IncSuffixes Header LibSuffixes
else()
# Set _Pack_LIBS from the target properties for ImportConfig
foreach (_prop IMPORTED_LOCATION${ImportConfigSuffix}
IMPORTED_LINK_INTERFACE_LIBRARIES${ImportConfigSuffix})
IMPORTED_LINK_INTERFACE_LIBRARIES${ImportConfigSuffix}
INTERFACE_LINK_LIBRARIES)
get_target_property(_value ${TargetName} ${_prop})
if (_value)
list(APPEND _Pack_LIBS ${_value})
@@ -780,6 +746,7 @@ function(mfem_get_target_options Target CompileOptsVar LinkOptsVar)
list(APPEND CompileOpts "-isystem \"${SysDir}\"")
endforeach()
endif()
set(AddInterfaceLinkLibs TRUE)
if ("${type}" STREQUAL "STATIC_LIBRARY")
get_target_property(Location ${tgt} LOCATION)
if (Location)
@@ -801,18 +768,7 @@ function(mfem_get_target_options Target CompileOptsVar LinkOptsVar)
message(STATUS " *** Warning: [${tgt}] LOCATION not defined!")
endif()
elseif ("${type}" STREQUAL "INTERFACE_LIBRARY")
get_target_property(Libs ${tgt} INTERFACE_LINK_LIBRARIES)
if (Libs)
foreach(Lib ${Libs})
if (NOT (TARGET ${Lib}))
list(APPEND LinkOpts "${Lib}")
else()
mfem_get_target_options(${Lib} COpts LOpts)
list(APPEND CompileOpts ${COpts})
list(APPEND LinkOpts ${LOpts})
endif()
endforeach()
endif()
# The INTERFACE_LINK_LIBRARIES property is handled below.
# Other properties we may need to handle:
# INTERFACE_LINK_DEPENDS
# INTERFACE_LINK_DIRECTORIES
@@ -820,6 +776,26 @@ function(mfem_get_target_options Target CompileOptsVar LinkOptsVar)
else()
message(STATUS " *** Warning: [${tgt}] uses target type '${type}'"
" which is not supported!")
set(AddInterfaceLinkLibs FALSE)
endif()
if (AddInterfaceLinkLibs)
get_target_property(Libs ${tgt} INTERFACE_LINK_LIBRARIES)
# message(STATUS "${tgt}[INTERFACE_LINK_LIBRARIES]: ${Libs}")
if (Libs)
foreach(Lib ${Libs})
if (NOT (TARGET ${Lib}))
# message(STATUS "Lib = ${Lib}")
# Filter-out generator expressions
if (NOT ("${Lib}" MATCHES "^\\$"))
list(APPEND LinkOpts "${Lib}")
endif()
else()
mfem_get_target_options(${Lib} COpts LOpts)
list(APPEND CompileOpts ${COpts})
list(APPEND LinkOpts ${LOpts})
endif()
endforeach()
endif()
endif()
# Other potentially relevant properties:
@@ -843,6 +819,9 @@ function(mfem_get_target_options Target CompileOptsVar LinkOptsVar)
set(${CompileOptsVar} "${CompileOpts}" PARENT_SCOPE)
set(${LinkOptsVar} "${LinkOpts}" PARENT_SCOPE)
# message(STATUS "${tgt}[CompileOpts]: ${CompileOpts}")
# message(STATUS "${tgt}[LinkOpts]: ${LinkOpts}")
endfunction(mfem_get_target_options)
@@ -894,7 +873,7 @@ function(mfem_export_mk_files)
"${cxx_std_flag} ${CMAKE_CXX_FLAGS_${BUILD_TYPE}} ${CMAKE_CXX_FLAGS}"
MFEM_CXXFLAGS)
set(MFEM_TPLFLAGS "")
foreach(dir ${MFEM_TPL_INCLUDE_DIRS})
foreach(dir ${TPL_INCLUDE_DIRS})
set(MFEM_TPLFLAGS "${MFEM_TPLFLAGS} -I${dir}")
endforeach()
# TODO: MFEM_TPLFLAGS: add other TPL flags, in addition to the -I flags.
+22 -3
View File
@@ -1,4 +1,4 @@
// Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
// Copyright (c) 2010-2023, 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.
//
@@ -30,11 +30,30 @@
#endif
// Windows specific options
#ifdef _WIN32
#ifndef _USE_MATH_DEFINES
#if defined(_WIN32) && !defined(_USE_MATH_DEFINES)
// Macro needed to get defines like M_PI from <cmath>. (Visual Studio C++ only?)
#define _USE_MATH_DEFINES
#endif
// Macro MFEM_EXPORT: this macro is used when declaring exported global
// variables and static class variables in public header files, e.g.:
// extern MFEM_EXPORT Geometry Geometries;
// static MFEM_EXPORT Device device_singleton;
// In cases where a class contains multiple static variables, instead of marking
// all such variables with MFEM_EXPORT, one can mark the class with MFEM_EXPORT,
// e.g.:
// class MFEM_EXPORT MemoryManager ...
// Note: MFEM's GitHub CI includes a shared MSVC build that will fail if a
// variable that needs MFEM_EXPORT does not have it. However, builds with
// optional external libraries are not tested and may require separate checks to
// determine the necessity of MFEM_EXPORT.
#if defined(_MSC_VER) && defined(MFEM_SHARED_BUILD)
#ifdef mfem_EXPORTS
#define MFEM_EXPORT __declspec(dllexport)
#else
#define MFEM_EXPORT __declspec(dllimport)
#endif
#else
#define MFEM_EXPORT
#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.
+4 -1
View File
@@ -1,4 +1,4 @@
// Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
// Copyright (c) 2010-2023, 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.
//
@@ -39,6 +39,9 @@
// Description of the git commit used to build MFEM.
// #define MFEM_GIT_STRING "@MFEM_GIT_STRING@"
// Enable shared library build of MFEM.
// #define MFEM_SHARED_BUILD
// Build the parallel MFEM library.
// Requires an MPI compiler, and the libraries HYPRE and METIS.
// #define MFEM_USE_MPI
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+2 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
@@ -19,6 +19,7 @@ if (NOT CMAKE_BUILD_TYPE)
endif()
# MFEM options. Set to mimic the default "defaults.mk" file.
option(BUILD_SHARED_LIBS "Enable shared library build of MFEM" OFF)
option(MFEM_USE_MPI "Enable MPI parallel build" OFF)
option(MFEM_USE_METIS "Enable METIS usage" ${MFEM_USE_MPI})
option(MFEM_USE_EXCEPTIONS "Enable the use of exceptions" OFF)
+2 -2
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
@@ -58,7 +58,7 @@ HIP_CXX = hipcc
# example: gfx600 (tahiti), gfx700 (kaveri), gfx701 (hawaii), gfx801 (carrizo),
# gfx900, gfx1010, etc.
HIP_ARCH = gfx900
HIP_FLAGS = --amdgpu-target=$(HIP_ARCH)
HIP_FLAGS = --offload-arch=$(HIP_ARCH)
HIP_XCOMPILER =
HIP_XLINKER = -Wl,
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
// Copyright (c) 2010-2023, 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.
//
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
// Copyright (c) 2010-2023, 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.
//
+3 -3
View File
@@ -1,6 +1,6 @@
#!/bin/bash
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
@@ -35,8 +35,8 @@ cd $(git rev-parse --show-toplevel)
# copyright check
copyright=true
if [[ "${option}" == "--copyright" || "${option}" == "" ]]; then
if git grep -l "^\(#\|//\).*\(\-2021\|\ 2010,\)" > matches.txt; then
echo "Please update the following files to Copyright (c) 2010-2022:"
if git grep -n "^\(#\|//\).*Copyright.*2010-20\(2[^3]\|[^2].\)" > matches.txt; then
echo "Please update the following files to Copyright (c) 2010-2023:"
cat matches.txt
copyright=false
fi
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+3 -3
View File
@@ -1,6 +1,6 @@
#!/bin/bash
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
@@ -138,7 +138,7 @@ groups_parallel=(
'"meshing"
"Meshing miniapps:"
"miniapps/meshing"
"pmesh-optimizer.cpp pminimal-surface.cpp"'
"pmesh-optimizer.cpp pmesh-fitting.cpp pminimal-surface.cpp"'
'"electromagnetics"
"Electromagnetics miniapps:"
"miniapps/electromagnetics"
@@ -227,7 +227,7 @@ groups_all=(
"Meshing miniapps:"
"miniapps/meshing"
"mobius-strip.cpp klein-bottle.cpp extruder.cpp toroid.cpp
{,p}mesh-optimizer.cpp {,p}minimal-surface.cpp"'
{,p}mesh-optimizer.cpp pmesh-fitting.cpp {,p}minimal-surface.cpp"'
'"electromagnetics"
"Electromagnetics miniapps:"
"miniapps/electromagnetics"
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
// Copyright (c) 2010-2023, 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.
//
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+109
View File
@@ -0,0 +1,109 @@
MFEM NURBS mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# SEGMENT = 1
# SQUARE = 3
# CUBE = 5
#
dimension
2
elements
5
1 3 4 5 6 7
1 3 0 1 5 4
1 3 1 2 6 5
1 3 3 7 6 2
1 3 0 4 7 3
boundary
4
1 1 0 1
1 1 2 3
1 1 1 2
1 1 3 0
edges
12
0 0 1
0 4 5
0 7 6
0 3 2
1 1 2
1 5 6
1 4 7
1 0 3
2 0 4
2 1 5
2 2 6
2 3 7
vertices
8
knotvectors
3
2 3 0 0 0 1 1 1
2 3 0 0 0 1 1 1
2 3 0 0 0 1 1 1
weights
1
1
1
1
1
1
1
1
0.70710678118655
1
1
0.70710678118655
0.70710678118655
1
1
0.70710678118655
1
1
1
1
1
0.85355339059327
0.85355339059327
0.85355339059327
0.85355339059327
FiniteElementSpace
FiniteElementCollection: NURBS2
VDim: 2
Ordering: 1
-0.70710678118 -0.70710678118
0.70710678118 -0.70710678118
0.70710678118 0.70710678118
-0.70710678118 0.70710678118
-0.35355339059 -0.35355339059
0.35355339059 -0.35355339059
0.35355339059 0.35355339059
-0.35355339059 0.35355339059
0 -1.41421356236
0 -0.35355339059
0 0.35355339059
0 1.41421356236
1.41421356236 0
0.35355339059 0
-0.35355339059 0
-1.41421356236 0
-0.530330085885 -0.530330085885
0.530330085885 -0.530330085885
0.530330085885 0.530330085885
-0.530330085885 0.530330085885
0 0
0 -0.883883476475
0.883883476475 0
0 0.883883476475
-0.883883476475 0
+46
View File
@@ -0,0 +1,46 @@
MFEM NURBS mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# SEGMENT = 1
# SQUARE = 3
# CUBE = 5
#
dimension
1
elements
1
1 1 0 1
boundary
2
1 0 0
2 0 1
edges
1
0 0 1
vertices
2
knotvectors
1
1 2 0 0 1 1
weights
1
1
FiniteElementSpace
FiniteElementCollection: NURBS1
VDim: 1
Ordering: 1
0
1
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
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.5.1
PROJECT_NUMBER = v4.5.3
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# Copyright (c) 2010-2023, 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.
#
@@ -0,0 +1,141 @@
#include "mfem.hpp"
#include "Problems.hpp"
#include "IPsolver.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
double fRhs(const Vector &pt);
double obstacle(const Vector &pt);
double dmanufacturedFun(const Vector &pt);
int main(int argc, char *argv[])
{
int FEorder = 1; // order of the finite elements
int linSolver = 0;
int maxIPMiters = 30;
bool iAmRoot = true;
int ref_levels = 3;
OptionsParser args(argc, argv);
args.AddOption(&FEorder, "-o", "--order",\
"Order of the finite elements.");
args.AddOption(&linSolver, "-linSolver", "--linearSolver", \
"IP-Newton linear system solution strategy.");
args.AddOption(&maxIPMiters, "-IPMiters", "--IPMiters",\
"Maximum number of IPM iterations");
args.AddOption(&ref_levels, "-r", "--mesh_refinement", \
"Mesh Refinement");
args.Parse();
if(!args.Good())
{
args.PrintUsage(cout);
return 1;
}
else
{
if( iAmRoot )
{
args.PrintOptions(cout);
}
}
const char *meshFile = "../../data/inline-quad.mesh";
Mesh *mesh = new Mesh(meshFile, 1, 1);
int dim = mesh->Dimension(); // geometric dimension of the domain
for (int l = 0; l < ref_levels; l++)
{
mesh->UniformRefinement();
}
FiniteElementCollection *fec = new H1_FECollection(FEorder, dim);
FiniteElementSpace *Vh = new FiniteElementSpace(mesh, fec);
Array<int> ess_tdof_list;
if (mesh->bdr_attributes.Size())
{
Array<int> ess_bdr(mesh->bdr_attributes.Max());
ess_bdr = 1;
Vh->GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
}
double DC_val = 0.0;
int dimD = Vh->GetTrueVSize();
Vector x0(dimD); x0 = DC_val;
Vector xf(dimD); xf = 0.0;
ObstacleProblem problem(Vh, x0, &fRhs, &obstacle, ess_tdof_list);
InteriorPointSolver optimizer(&problem);
optimizer.SetTol(1.e-7);
optimizer.SetLinearSolver(linSolver);
optimizer.SetMaxIter(maxIPMiters);
optimizer.Mult(x0, xf);
double Einitial = problem.E(x0);
double Efinal = problem.E(xf);
cout << "Energy objective at initial point = " << Einitial << endl;
cout << "Energy objective at optimizer = " << Efinal << endl;
GridFunction d_gf(Vh);
d_gf = xf;
FunctionCoefficient dm_fc(dmanufacturedFun); // pseudo-manufactured solution
GridFunction dm_gf(Vh);
dm_gf.ProjectCoefficient(dm_fc);
ParaViewDataCollection paraview_dc("BarrierProblemSolution", mesh);
paraview_dc.SetPrefixPath("ParaView");
paraview_dc.SetLevelsOfDetail(FEorder);
paraview_dc.SetDataFormat(VTKFormat::BINARY);
paraview_dc.SetHighOrderOutput(true);
paraview_dc.SetCycle(0);
paraview_dc.SetTime(0.0);
paraview_dc.RegisterField("d(x) (numerical)", &d_gf);
paraview_dc.RegisterField("d(x) (pseudo-manufactured)", &dm_gf);
paraview_dc.Save();
delete Vh;
delete fec;
delete mesh;
return 0;
}
double dmanufacturedFun(const Vector &pt)
{
double alpha = 16.5;
return sin(M_PI * pt(1)) * (sin(M_PI * pt(0)) - alpha * pow(pt(0) * (1. - pt(0)), 2));
}
// f(x) forcing term... which enters the objective energy functional
// E(d) = 0.5 d^T K d - f^T d, where f is a discrete vector representation
// of f(x). f(x) is such that in the absence of bound-constraints then
// the solution of the optimization problem satisfies the PDE
// -div(grad(d)) + d = f + homogeneous Neumann conditions on the unit interval,
// for d(x) = cos(2 \pi x) + a0 + a3 (x^3 - 1.5 x^2), a2 = 0.2, a3 = -2
double fRhs(const Vector &pt)
{
double alpha = 16.5;
double fx;
fx = pow(M_PI, 2) * sin(M_PI * pt(0));
fx += alpha * (2. * pow(pt(0), 2) + 2. * pow(1.-pt(0), 2) - 8. * pt(0) * (1.-pt(0)));
fx += pow(M_PI, 2) * sin(M_PI * pt(0)) * dmanufacturedFun(pt);
fx *= sin(M_PI * pt(1));
return fx;
}
double obstacle(const Vector &pt)
{
return 0.0;
}
@@ -0,0 +1,156 @@
#include "mfem.hpp"
#include "Problems.hpp"
#include "IPsolver.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
double fRhs(const Vector &pt);
double obstacle(const Vector &pt);
double dmanufacturedFun(const Vector &pt);
int main(int argc, char *argv[])
{
int FEorder = 1; // order of the finite elements
int linSolver = 0;
int maxIPMiters = 30;
bool iAmRoot = true;
int ref_levels = 3;
OptionsParser args(argc, argv);
args.AddOption(&FEorder, "-o", "--order",\
"Order of the finite elements.");
args.AddOption(&linSolver, "-linSolver", "--linearSolver", \
"IP-Newton linear system solution strategy.");
args.AddOption(&maxIPMiters, "-IPMiters", "--IPMiters",\
"Maximum number of IPM iterations");
args.AddOption(&ref_levels, "-r", "--mesh_refinement", \
"Mesh Refinement");
args.Parse();
if(!args.Good())
{
args.PrintUsage(cout);
return 1;
}
else
{
if( iAmRoot )
{
args.PrintOptions(cout);
}
}
const char *meshFile = "../../data/inline-quad.mesh";
Mesh *mesh = new Mesh(meshFile, 1, 1);
int dim = mesh->Dimension(); // geometric dimension of the domain
for (int l = 0; l < ref_levels; l++)
{
mesh->UniformRefinement();
}
FiniteElementCollection *fec = new H1_FECollection(FEorder, dim);
FiniteElementSpace *Vh = new FiniteElementSpace(mesh, fec);
Array<int> ess_tdof_list;
if (mesh->bdr_attributes.Size())
{
Array<int> ess_bdr(mesh->bdr_attributes.Max());
ess_bdr = 1;
Vh->GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
}
double DC_val = 0.06;
Vector x0DC(Vh->GetTrueVSize()); x0DC = DC_val;
int dimD = Vh->GetTrueVSize() - ess_tdof_list.Size();
Vector x0(dimD); x0 = 0.0;
Vector xf(dimD); xf = 0.0;
ObstacleProblemVariant problem(Vh, x0DC, &fRhs, &obstacle, ess_tdof_list);
InteriorPointSolver optimizer(&problem);
optimizer.SetTol(1.e-7);
optimizer.SetLinearSolver(linSolver);
optimizer.SetMaxIter(maxIPMiters);
optimizer.Mult(x0, xf);
double Einitial = problem.E(x0);
double Efinal = problem.E(xf);
cout << "Energy objective at initial point = " << Einitial << endl;
cout << "Energy objective at optimizer = " << Efinal << endl;
Array<int> noness_tdof_list;
noness_tdof_list.SetSize(dimD);
int i = 0;
for(int j = 0; j < Vh->GetTrueVSize(); j++)
{
if(ess_tdof_list.Find(j) == -1)
{
noness_tdof_list[i] = j;
i += 1;
}
}
GridFunction d_gf(Vh);
d_gf.Set(1.0, x0DC);
d_gf.SetSubVector(noness_tdof_list, xf);
FunctionCoefficient dm_fc(dmanufacturedFun); // pseudo-manufactured solution
GridFunction dm_gf(Vh);
dm_gf.ProjectCoefficient(dm_fc);
ParaViewDataCollection paraview_dc("BarrierProblemSolution", mesh);
paraview_dc.SetPrefixPath("ParaView");
paraview_dc.SetLevelsOfDetail(FEorder);
paraview_dc.SetDataFormat(VTKFormat::BINARY);
paraview_dc.SetHighOrderOutput(true);
paraview_dc.SetCycle(0);
paraview_dc.SetTime(0.0);
paraview_dc.RegisterField("d(x) (numerical)", &d_gf);
paraview_dc.RegisterField("d(x) (pseudo-manufactured)", &dm_gf);
paraview_dc.Save();
delete Vh;
delete fec;
delete mesh;
return 0;
}
double dmanufacturedFun(const Vector &pt)
{
double alpha = 16.5;
return sin(M_PI * pt(1)) * (sin(M_PI * pt(0)) - alpha * pow(pt(0) * (1. - pt(0)), 2));
}
// f(x) forcing term... which enters the objective energy functional
// E(d) = 0.5 d^T K d - f^T d, where f is a discrete vector representation
// of f(x). f(x) is such that in the absence of bound-constraints then
// the solution of the optimization problem satisfies the PDE
// -div(grad(d)) + d = f + homogeneous Neumann conditions on the unit interval,
// for d(x) = cos(2 \pi x) + a0 + a3 (x^3 - 1.5 x^2), a2 = 0.2, a3 = -2
double fRhs(const Vector &pt)
{
double alpha = 16.5;
double fx;
fx = pow(M_PI, 2) * sin(M_PI * pt(0));
fx += alpha * (2. * pow(pt(0), 2) + 2. * pow(1.-pt(0), 2) - 8. * pt(0) * (1.-pt(0)));
fx += pow(M_PI, 2) * sin(M_PI * pt(0)) * dmanufacturedFun(pt);
fx *= sin(M_PI * pt(1));
return fx;
}
double obstacle(const Vector &pt)
{
return 0.0;
}
+827
View File
@@ -0,0 +1,827 @@
#include "mfem.hpp"
#include "IPsolver.hpp"
#include "Problems.hpp"
#include <fstream>
#include <iostream>
#include <cstdlib>
using namespace std;
using namespace mfem;
InteriorPointSolver::InteriorPointSolver(GeneralOptProblem * Problem) : optProblem(Problem), block_offsetsumlz(5), block_offsetsuml(4), block_offsetsx(3),
Huu(nullptr), Hum(nullptr), Hmu(nullptr), Hmm(nullptr), Wmm(nullptr), D(nullptr), Ju(nullptr), Jm(nullptr), JuT(nullptr), JmT(nullptr), Huucl(nullptr), HLuu(nullptr), saveLogBarrierIterates(false)
{
rel_tol = 1.e-2;
max_iter = 20;
mu_k = 1.0;
sMax = 1.e2;
kSig = 1.e10; // control deviation from primal Hessian
tauMin = 0.8; // control rate at which iterates can approach the boundary
eta = 1.e-4; // backtracking constant
thetaMin = 1.e-4; // allowed violation of the equality constraints
// constants in line-step A-5.4
delta = 1.0;
sTheta = 1.1;
sPhi = 2.3;
// control the rate at which the penalty parameter is decreased
kMu = 0.2;
thetaMu = 1.5;
// TO DO -- include the filter
thetaMax = 1.e6; // maximum constraint violation
// data for the second order correction
kSoc = 0.99;
// equation (18)
gTheta = 1.e-5;
gPhi = 1.e-5;
kEps = 1.e1;
dimU = optProblem->GetDimU();
dimM = optProblem->GetDimM();
dimC = optProblem->GetDimC();
ckSoc.SetSize(dimC);
block_offsetsumlz[0] = 0;
block_offsetsumlz[1] = dimU; // u
block_offsetsumlz[2] = dimM; // m
block_offsetsumlz[3] = dimC; // lambda
block_offsetsumlz[4] = dimM; // zl
block_offsetsumlz.PartialSum();
for(int i = 0; i < block_offsetsuml.Size(); i++) { block_offsetsuml[i] = block_offsetsumlz[i]; }
for(int i = 0; i < block_offsetsx.Size(); i++) { block_offsetsx[i] = block_offsetsuml[i] ; }
// lower-bound for the inequality constraint m >= ml
ml = optProblem->Getml();
lk.SetSize(dimC); lk = 0.0;
zlk.SetSize(dimM); zlk = 0.0;
linSolver = 0;
MyRank = 0;
iAmRoot = MyRank == 0 ? true : false;
}
double InteriorPointSolver::MaxStepSize(Vector &x, Vector &xl, Vector &xhat, double tau)
{
double alphaMaxloc = 1.0;
double alphaTmp;
for(int i = 0; i < x.Size(); i++)
{
if( xhat(i) < 0. )
{
alphaTmp = -1. * tau * (x(i) - xl(i)) / xhat(i);
alphaMaxloc = min(alphaMaxloc, alphaTmp);
}
}
// alphaMaxloc is the local maximum step size which is
// distinct on each MPI process. Need to compute
// the global maximum step size
double alphaMaxglb;
alphaMaxglb = alphaMaxloc;
return alphaMaxglb;
}
double InteriorPointSolver::MaxStepSize(Vector &x, Vector &xhat, double tau)
{
Vector zero(x.Size()); zero = 0.0;
return MaxStepSize(x, zero, xhat, tau);
}
void InteriorPointSolver::Mult(const Vector &x0, Vector &xf)
{
BlockVector x0block(block_offsetsx); x0block = 0.0;
x0block.GetBlock(0).Set(1.0, x0);
// To do: give options for user specificiation of initialization m0
x0block.GetBlock(1) = 100.;
x0block.GetBlock(1).Add(1.0, ml);
BlockVector xfblock(block_offsetsx); xfblock = 0.0;
Mult(x0block, xfblock);
xf.Set(1.0, xfblock.GetBlock(0));
}
void InteriorPointSolver::Mult(const BlockVector &x0, BlockVector &xf)
{
converged = false;
BlockVector xk(block_offsetsx), xhat(block_offsetsx); xk = 0; xhat = 0.0;
BlockVector Xk(block_offsetsumlz), Xhat(block_offsetsumlz); Xk = 0.0; Xhat = 0.0;
BlockVector Xhatuml(block_offsetsuml); Xhatuml = 0.0;
Vector zlhat(dimM); zlhat = 0.0;
xk.GetBlock(0).Set(1.0, x0.GetBlock(0));
xk.GetBlock(1).Set(1.0, x0.GetBlock(1));
// running estimate of the final values of the Lagrange multipliers
lk = 0.0;
zlk = 0.0;
for(int i = 0; i < dimM; i++)
{
zlk(i) = 1.e1 * mu_k / (xk(i+dimU) - ml(i));
}
Xk.GetBlock(0).Set(1.0, xk.GetBlock(0));
Xk.GetBlock(1).Set(1.0, xk.GetBlock(1));
Xk.GetBlock(2).Set(1.0, lk);
Xk.GetBlock(3).Set(1.0, zlk);
/* set theta0 = theta(x0)
* thetaMin
* thetaMax
* when theta(xk) < thetaMin and the switching condition holds
* then we ask for the Armijo sufficient decrease of the barrier
* objective to be satisfied, in order to accept the trial step length alphakl
*
* thetaMax controls how the filter is initialized for each log-barrier subproblem
* F0 = {(th, phi) s.t. th > thetaMax}
* that is the filter does not allow for iterates where the constraint violation
* is larger than that of thetaMax
*/
double theta0 = theta(xk);
thetaMin = 1.e-4 * max(1.0, theta0);
thetaMax = 1.e8 * thetaMin;
double Eeval, maxBarrierSolves, Eevalmu0;
bool printOptimalityError; // control optimality error print to console for log-barrier subproblems
maxBarrierSolves = 10;
for(jOpt = 0; jOpt < max_iter; jOpt++)
{
mfem::out << "interior-point solve step " << jOpt << endl;
// A-2. Check convergence of overall optimization problem
printOptimalityError = false;
Eevalmu0 = E(xk, lk, zlk, printOptimalityError);
if(Eevalmu0 < rel_tol)
{
converged = true;
mfem::out << "solved optimization problem :)\n";
break;
}
if(jOpt > 0) { maxBarrierSolves = 1; }
for(int i = 0; i < maxBarrierSolves; i++)
{
// A-3. Check convergence of the barrier subproblem
printOptimalityError = true;
Eeval = E(xk, lk, zlk, mu_k, printOptimalityError);
if(Eeval < kEps * mu_k)
{
mfem::out << "solved barrier subproblem, for mu = " << mu_k << endl;
// A-3.1. Recompute the barrier parameter
mu_k = max(rel_tol / 10., min(kMu * mu_k, pow(mu_k, thetaMu)));
// A-3.2. Re-initialize the filter
F1.DeleteAll();
F2.DeleteAll();
}
else
{
break;
}
}
// A-4. Compute the search direction
// solve for (uhat, mhat, lhat)
mfem::out << "\n** A-4. IP-Newton solve **\n";
zlhat = 0.0; Xhatuml = 0.0;
// why do we have Xhatuml ....???
// TO DO: remove Xhatuml in favor of passing Xhat
IPNewtonSolve(xk, lk, zlk, zlhat, Xhatuml, mu_k, false);
// assign data stack, X = (u, m, l, zl)
Xk = 0.0;
Xk.GetBlock(0).Set(1.0, xk.GetBlock(0));
Xk.GetBlock(1).Set(1.0, xk.GetBlock(1));
Xk.GetBlock(2).Set(1.0, lk);
Xk.GetBlock(3).Set(1.0, zlk);
// assign data stack, Xhat = (uhat, mhat, lhat, zlhat)
Xhat = 0.0;
for(int i = 0; i < 3; i++)
{
Xhat.GetBlock(i).Set(1.0, Xhatuml.GetBlock(i));
}
Xhat.GetBlock(3).Set(1.0, zlhat);
// A-5. Backtracking line search.
mfem::out << "\n** A-5. Linesearch **\n";
mfem::out << "mu = " << mu_k << endl;
lineSearch(Xk, Xhat, mu_k);
if(lineSearchSuccess)
{
if(!switchCondition || !sufficientDecrease)
{
F1.Append( (1. - gTheta) * thx0);
F2.Append( phx0 - gPhi * thx0);
}
// ----- A-6: Accept the trial point
// print info regarding zl...
xk.GetBlock(0).Add(alpha, Xhat.GetBlock(0));
xk.GetBlock(1).Add(alpha, Xhat.GetBlock(1));
lk.Add(alpha, Xhat.GetBlock(2));
zlk.Add(alphaz, Xhat.GetBlock(3));
projectZ(xk, zlk, mu_k);
}
else
{
mfem::out << "lineSearch not successful :(\n";
mfem::out << "attempting feasibility restoration with theta = " << thx0 << endl;
mfem::out << "no feasibility restoration implemented, exiting now \n";
break;
}
//
if(jOpt + 1 == max_iter)
{
mfem::out << "maximum optimization iterations :(\n";
}
}
// done with optimization routine, just reassign data to xf reference so
// that the application code has access to the optimal point
xf = 0.0;
xf.GetBlock(0).Set(1.0, xk.GetBlock(0));
xf.GetBlock(1).Set(1.0, xk.GetBlock(1));
}
void InteriorPointSolver::FormIPNewtonMat(BlockVector & x, Vector & l, Vector &zl, BlockOperator &Ak)
{
// WARNING: Huu, Hum, Hmu, Hmm should all be Hessian terms of the Lagrangian, currently we
// them by Hessian terms of the objective function and neglect the Hessian of l^T c
Huu = optProblem->Duuf(x); Hum = optProblem->Dumf(x);
Hmu = optProblem->Dmuf(x); Hmm = optProblem->Dmmf(x);
Vector DiagLogBar(dimM); DiagLogBar = 0.0;
for(int ii = 0; ii < dimM; ii++)
{
DiagLogBar(ii) = zl(ii) / (x(ii+dimU) - ml(ii));
}
if(saveLogBarrierIterates)
{
std::ofstream diagStream;
char diagString[100];
snprintf(diagString, 100, "logBarrierHessiandata/D%d.dat", jOpt);
diagStream.open(diagString, ios::out | ios::trunc);
for(int ii = 0; ii < dimM; ii++)
{
diagStream << setprecision(30) << DiagLogBar(ii) << endl;
}
diagStream.close();
}
D = new SparseMatrix(DiagLogBar);
if(Hmm != nullptr)
{
Wmm = new SparseMatrix(*Hmm);
Wmm->Add(1.0, *D);
}
else
{
Wmm = D;
}
Ju = optProblem->Duc(x); JuT = Transpose(*Ju);
Jm = optProblem->Dmc(x); JmT = Transpose(*Jm);
Huucl = optProblem->lDuuc(x, l);
if(Huucl != nullptr)
{
HLuu = Add(*Huucl, *Huu);
Ak.SetBlock(0, 0, HLuu);
}
else
{
Ak.SetBlock(0, 0, Huu);
}
// IP-Newton system matrix
// Ak = [[H_(u,u) H_(u,m) J_u^T]
// [H_(m,u) W_(m,m) J_m^T]
// [ J_u J_m 0 ]]
Ak.SetBlock(0, 2, JuT);
Ak.SetBlock(1, 1, Wmm); Ak.SetBlock(1, 2, JmT);
Ak.SetBlock(2, 0, Ju); Ak.SetBlock(2, 1, Jm);
if(Hum != nullptr) { Ak.SetBlock(0, 1, Hum); Ak.SetBlock(1, 0, Hmu); }
}
// perturbed KKT system solve
// determine the search direction
void InteriorPointSolver::IPNewtonSolve(BlockVector &x, Vector &l, Vector &zl, Vector &zlhat, BlockVector &Xhat, double mu, bool socSolve)
{
// solve A x = b, where A is the IP-Newton matrix
BlockOperator A(block_offsetsuml, block_offsetsuml); BlockVector b(block_offsetsuml); b = 0.0;
FormIPNewtonMat(x, l, zl, A);
// [grad_u phi + Ju^T l]
// b = - [grad_m phi + Jm^T l]
// [ c ]
BlockVector gradphi(block_offsetsx); gradphi = 0.0;
BlockVector JTl(block_offsetsx); JTl = 0.0;
Dxphi(x, mu, gradphi);
(A.GetBlock(0,2)).Mult(l, JTl.GetBlock(0));
(A.GetBlock(1,2)).Mult(l, JTl.GetBlock(1));
for(int ii = 0; ii < 2; ii++)
{
b.GetBlock(ii).Set(1.0, gradphi.GetBlock(ii));
b.GetBlock(ii).Add(1.0, JTl.GetBlock(ii));
}
if(!socSolve)
{
optProblem->c(x, b.GetBlock(2));
}
else
{
b.GetBlock(2).Set(1.0, ckSoc);
}
b *= -1.0;
Xhat = 0.0;
#ifdef MFEM_USE_SUITESPARSE
// Direct solve for IP-Newton saddle-point system
// A = [ [ Huu 0 Ju^T]
// [ 0 D -I ]
// [ Ju -I 0 ]]
if(linSolver == 0)
{
BlockMatrix ABlockMatrix(block_offsetsuml, block_offsetsuml);
for(int ii = 0; ii < 3; ii++)
{
for(int jj = 0; jj < 3; jj++)
{
if(!A.IsZeroBlock(ii, jj))
{
ABlockMatrix.SetBlock(ii, jj, dynamic_cast<SparseMatrix *>(&(A.GetBlock(ii, jj))));
}
}
}
/* direct solve of the 3x3 IP-Newton linear system */
UMFPackSolver ASolver;
SparseMatrix *ASparse = ABlockMatrix.CreateMonolithic();
ASolver.SetOperator(*ASparse);
ASolver.Mult(b, Xhat);
Vector residual(Xhat.Size());
ASparse->Mult(Xhat, residual);
residual.Add(-1.0, b);
delete ASparse;
}
else if(linSolver == 1)
{
// Direct solve for 0,0 Schur complement of IP-Newton system, Huu + Ju^T Wmm Ju,
// where Wmm = D for contact problems
SparseMatrix * Huuloc = dynamic_cast<SparseMatrix *>(&(A.GetBlock(0, 0)));
SparseMatrix * Wmmloc = dynamic_cast<SparseMatrix *>(&(A.GetBlock(1, 1)));
SparseMatrix * Juloc = dynamic_cast<SparseMatrix *>(&(A.GetBlock(2, 0)));
SparseMatrix * JuTloc = dynamic_cast<SparseMatrix *>(&(A.GetBlock(0, 2)));
Vector DVec(dimM); DVec = 0.0;
Vector one(dimM); one = 1.0;
D->Mult(one, DVec);
SparseMatrix *JuTDJu = Mult_AtDA(*Juloc, DVec); // Ju^T D Ju
SparseMatrix *Areduced = Add(*Huuloc, *JuTDJu); // Huu + Ju^T D Ju
/* prepare the reduced rhs */
// breduced = bu + Ju^T (bm + Wmm bl)
Vector breduced(dimU); breduced = 0.0;
Vector tempVec(dimM); tempVec = 0.0;
Wmmloc->Mult(b.GetBlock(2), tempVec);
tempVec.Add(1.0, b.GetBlock(1));
JuTloc->Mult(tempVec, breduced);
breduced.Add(1.0, b.GetBlock(0));
// solve the reduced linear system
UMFPackSolver AreducedSolver;
AreducedSolver.SetOperator(*Areduced);
AreducedSolver.Mult(breduced, Xhat.GetBlock(0));
// now propagate solved uhat to obtain mhat and lhat
// xm = Ju xu - bl
Juloc->Mult(Xhat.GetBlock(0), Xhat.GetBlock(1));
Xhat.GetBlock(1).Add(-1.0, b.GetBlock(2));
// xl = Wmm xm - bm
Wmmloc->Mult(Xhat.GetBlock(1), Xhat.GetBlock(2));
Xhat.GetBlock(2).Add(-1.0, b.GetBlock(1));
delete JuTDJu;
delete Areduced;
}
#else
MFEM_VERIFY(linSolver > 1, "linSolver = 0, 1 require MFEM_USE_SUITESPARSE=YES");
#endif
if(linSolver > 1)
{
// Iterative solve for 0,0 Schur complement of IP-Newton system, Huu + Ju^T Wmm Ju,
// where Wmm = D for contact problems
// here the iterative solver is a Jacobi-preconditioned CG-solve
SparseMatrix * Huuloc = dynamic_cast<SparseMatrix *>(&(A.GetBlock(0, 0)));
SparseMatrix * Wmmloc = dynamic_cast<SparseMatrix *>(&(A.GetBlock(1, 1)));
SparseMatrix * Juloc = dynamic_cast<SparseMatrix *>(&(A.GetBlock(2, 0)));
SparseMatrix * JuTloc = dynamic_cast<SparseMatrix *>(&(A.GetBlock(0, 2)));
Vector DVec(dimM); DVec = 0.0;
Vector one(dimM); one = 1.0;
D->Mult(one, DVec);
SparseMatrix *JuTDJu = Mult_AtDA(*Juloc, DVec); // Ju^T D Ju
SparseMatrix *Areduced = Add(*Huuloc, *JuTDJu); // Huu + Ju^T D Ju
/* prepare the reduced rhs */
// breduced = bu + Ju^T (bm + Wmm bl)
Vector breduced(dimU); breduced = 0.0;
Vector tempVec(dimM); tempVec = 0.0;
Wmmloc->Mult(b.GetBlock(2), tempVec);
tempVec.Add(1.0, b.GetBlock(1));
JuTloc->Mult(tempVec, breduced);
breduced.Add(1.0, b.GetBlock(0));
if (linSolver == 2)
{
/* Jacobi preconditioned conjugate-gradient solve */
DSmoother AreducedPrec((SparseMatrix &)(*Areduced));
CGSolver AreducedSolver;
AreducedSolver.SetOperator(*Areduced);
AreducedSolver.SetAbsTol(1.e-12);
AreducedSolver.SetRelTol(1.e-8);
AreducedSolver.SetMaxIter(500);
AreducedSolver.SetPreconditioner(AreducedPrec);
AreducedSolver.SetPrintLevel(1);
AreducedSolver.Mult(breduced, Xhat.GetBlock(0));
}
else
{
/* Gauss-Seidel preconditioned GMRES solve */
GSSmoother AreducedPrec((SparseMatrix &)(*Areduced));
GMRESSolver AreducedSolver;
AreducedSolver.SetOperator(*Areduced);
AreducedSolver.SetAbsTol(1.e-12);
AreducedSolver.SetRelTol(1.e-8);
AreducedSolver.SetMaxIter(500);
AreducedSolver.SetPreconditioner(AreducedPrec);
AreducedSolver.SetPrintLevel(1);
AreducedSolver.Mult(breduced, Xhat.GetBlock(0));
}
// now propagate solved uhat to obtain mhat and lhat
// xm = Ju xu - bl
Juloc->Mult(Xhat.GetBlock(0), Xhat.GetBlock(1));
Xhat.GetBlock(1).Add(-1.0, b.GetBlock(2));
// xl = Wmm xm - bm
Wmmloc->Mult(Xhat.GetBlock(1), Xhat.GetBlock(2));
Xhat.GetBlock(2).Add(-1.0, b.GetBlock(1));
delete JuTDJu;
delete Areduced;
}
/* backsolve to determine zlhat */
for(int ii = 0; ii < dimM; ii++)
{
zlhat(ii) = -1.*(zl(ii) + (zl(ii) * Xhat(ii + dimU) - mu) / (x(ii + dimU) - ml(ii)) );
}
// free memory
if(Hmm != nullptr)
{
delete Wmm;
}
if( Huucl != nullptr)
{
delete HLuu; HLuu = nullptr;
}
delete D;
delete JuT;
delete JmT;
}
// here Xhat, X will be BlockVectors w.r.t. the 4 partitioning X = (u, m, l, zl)
void InteriorPointSolver::lineSearch(BlockVector& X0, BlockVector& Xhat, double mu)
{
double tau = max(tauMin, 1.0 - mu);
Vector u0 = X0.GetBlock(0);
Vector m0 = X0.GetBlock(1);
Vector l0 = X0.GetBlock(2);
Vector z0 = X0.GetBlock(3);
Vector uhat = Xhat.GetBlock(0);
Vector mhat = Xhat.GetBlock(1);
Vector lhat = Xhat.GetBlock(2);
Vector zhat = Xhat.GetBlock(3);
double alphaMax = MaxStepSize(m0, ml, mhat, tau);
double alphaMaxz = MaxStepSize(z0, zhat, tau);
alphaz = alphaMaxz;
BlockVector x0(block_offsetsx); x0 = 0.0;
x0.GetBlock(0).Set(1.0, u0);
x0.GetBlock(1).Set(1.0, m0);
BlockVector xhat(block_offsetsx); xhat = 0.0;
xhat.GetBlock(0).Set(1.0, uhat);
xhat.GetBlock(1).Set(1.0, mhat);
BlockVector xtrial(block_offsetsx); xtrial = 0.0;
BlockVector Dxphi0(block_offsetsx); Dxphi0 = 0.0;
int maxBacktrack = 20;
alpha = alphaMax;
Vector ck0(dimC); ck0 = 0.0;
Vector zhatsoc(dimM); zhatsoc = 0.0;
BlockVector Xhatumlsoc(block_offsetsuml); Xhatumlsoc = 0.0;
BlockVector xhatsoc(block_offsetsx); xhatsoc = 0.0;
Vector uhatsoc(dimU); uhatsoc = 0.0;
Vector mhatsoc(dimM); mhatsoc = 0.0;
Dxphi(x0, mu, Dxphi0);
Dxphi0_xhat = InnerProduct(Dxphi0, xhat);
descentDirection = Dxphi0_xhat < 0. ? true : false;
if(descentDirection)
{
mfem::out << "is a descent direction for the log-barrier objective\n";
}
else
{
mfem::out << "is not a descent direction for the log-barrier objective\n";
}
mfem::out << "Dxphi^T xhat / (|| Dxphi||_2 * || xhat ||_2) = " << Dxphi0_xhat / (xhat.Norml2() * Dxphi0.Norml2()) << endl;
thx0 = theta(x0);
phx0 = phi(x0, mu);
lineSearchSuccess = false;
for(int i = 0; i < maxBacktrack; i++)
{
mfem::out << "\n--------- alpha = " << alpha << " ---------\n";
// ----- A-5.2. Compute trial point: xtrial = x0 + alpha_i xhat
xtrial.Set(1.0, x0);
xtrial.Add(alpha, xhat);
// ------ A-5.3. if not in filter region go to A.5.4 otherwise go to A-5.5.
thxtrial = theta(xtrial);
phxtrial = phi(xtrial, mu);
filterCheck(thxtrial, phxtrial);
if(!inFilterRegion)
{
mfem::out << "not in filter region :)\n";
// ------ A.5.4: Check sufficient decrease
if(!descentDirection)
{
switchCondition = false;
}
else
{
switchCondition = (alpha * pow(abs(Dxphi0_xhat), sPhi) > delta * pow(thx0, sTheta)) ? true : false;
}
mfem::out << "theta(x0) = " << thx0 << ", thetaMin = " << thetaMin << endl;
mfem::out << "theta(xtrial) = " << thxtrial << ", (1-gTheta) *theta(x0) = " << (1. - gTheta) * thx0 << endl;
mfem::out << "phi(xtrial) = " << phxtrial << ", phi(x0) - gPhi *theta(x0) = " << phx0 - gPhi * thx0 << endl;
// Case I
if(thx0 <= thetaMin && switchCondition)
{
sufficientDecrease = phxtrial <= phx0 + eta * alpha * Dxphi0_xhat ? true : false;
if(sufficientDecrease)
{
mfem::out << "Accepted step length -- sufficient decrease in log-barrier objective.\n";
// accept the trial step
lineSearchSuccess = true;
break;
}
}
else
{
if(thxtrial <= (1. - gTheta) * thx0 || phxtrial <= phx0 - gPhi * thx0)
{
mfem::out << "Accepted step length -- decrease in either constraint violation or log-barrier objective.\n";
// accept the trial step
lineSearchSuccess = true;
break;
}
}
// A-5.5: Initialize the second-order correction
if((!(thx0 < thxtrial)) && i == 0)
{
mfem::out << "second order correction\n";
optProblem->c(xtrial, ckSoc);
optProblem->c(x0, ck0);
ckSoc.Add(alphaMax, ck0);
// A-5.6 Compute the second-order correction.
IPNewtonSolve(x0, l0, z0, zhatsoc, Xhatumlsoc, mu, true);
mhatsoc.Set(1.0, Xhatumlsoc.GetBlock(1));
// alphasoc = MaxStepSize(m0, ml, mhatsoc, tau);
//WARNING: not complete but currently solver isn't entering this region
}
}
else
{
mfem::out << "in filter region\n";
}
// include more if needed
alpha *= 0.5;
}
}
void InteriorPointSolver::projectZ(const Vector &x, Vector &z, double mu)
{
double zi;
double mudivmml;
for(int i = 0; i < dimM; i++)
{
zi = z(i);
mudivmml = mu / (x(i + dimU) - ml(i));
z(i) = max(min(zi, kSig * mudivmml), mudivmml / kSig);
}
}
void InteriorPointSolver::filterCheck(double th, double ph)
{
inFilterRegion = false;
if(th > thetaMax)
{
inFilterRegion = true;
}
else
{
for(int i = 0; i < F1.Size(); i++)
{
if(th >= F1[i] && ph >= F2[i])
{
inFilterRegion = true;
break;
}
}
}
}
double InteriorPointSolver::E(const BlockVector &x, const Vector &l, const Vector &zl, double mu, bool print)
{
double E1, E2, E3;
double sc, sd;
BlockVector gradL(block_offsetsx); gradL = 0.0; // stationarity grad L = grad f + J^T l - z
Vector cx(dimC); cx = 0.0; // feasibility c = c(x)
Vector comp(dimM); comp = 0.0; // complementarity M Z - mu 1
DxL(x, l, zl, gradL);
E1 = gradL.Normlinf();
optProblem->c(x, cx);
E2 = cx.Normlinf();
for(int ii = 0; ii < dimM; ii++)
{
comp(ii) = x(dimU + ii) * zl(ii) - mu;
}
E3 = comp.Normlinf();
double ll1, zl1;
zl1 = zl.Norml1() / double(dimC + dimM);
ll1 = l.Norml1();
sc = max(sMax, zl1 / (double(dimM)) ) / sMax;
sd = max(sMax, (ll1 + zl1) / (double(dimC + dimM))) / sMax;
if(print)
{
mfem::out << "evaluating optimality error for mu = " << mu << endl;
mfem::out << "stationarity measure = " << E1 / sd << endl;
mfem::out << "feasibility measure = " << E2 << endl;
mfem::out << "complimentarity measure = " << E3 / sc << endl;
}
return max(max(E1 / sd, E2), E3 / sc);
}
double InteriorPointSolver::E(const BlockVector &x, const Vector &l, const Vector &zl, bool print)
{
return E(x, l, zl, 0.0, print);
}
double InteriorPointSolver::theta(const BlockVector &x)
{
Vector cx(dimC); cx = 0.0;
optProblem->c(x, cx);
return cx.Norml2();
}
// log-barrier objective
double InteriorPointSolver::phi(const BlockVector &x, double mu)
{
double fx = optProblem->CalcObjective(x);
double logBarrierLoc = 0.0;
for(int i = 0; i < dimM; i++)
{
logBarrierLoc += log(x(dimU+i)-ml(i));
}
double logBarrierGlb = 0.0;
logBarrierGlb = logBarrierLoc;
return fx - mu * logBarrierGlb;
}
// gradient of log-barrier objective with respect to x = (u, m)
void InteriorPointSolver::Dxphi(const BlockVector &x, double mu, BlockVector &y)
{
optProblem->CalcObjectiveGrad(x, y);
for(int i = 0; i < dimM; i++)
{
y(dimU + i) -= mu / (x(dimU + i));
}
}
// Lagrangian function evaluation
// L(x, l, zl) = f(x) + l^T c(x) - zl^T m
double InteriorPointSolver::L(const BlockVector &x, const Vector &l, const Vector &zl)
{
double fx = optProblem->CalcObjective(x);
Vector cx(dimC); optProblem->c(x, cx);
return (fx + InnerProduct(cx, l) - InnerProduct(x.GetBlock(1), zl));
}
void InteriorPointSolver::DxL(const BlockVector &x, const Vector &l, const Vector &zl, BlockVector &y)
{
// evaluate the gradient of the objective with respect to the primal variables x = (u, m)
BlockVector gradxf(block_offsetsx); gradxf = 0.0;
optProblem->CalcObjectiveGrad(x, gradxf);
SparseMatrix *Jacu, *Jacm, *JacuT, *JacmT;
Jacu = optProblem->Duc(x); Jacm = optProblem->Dmc(x);
JacuT = Transpose(*Jacu);
JacmT = Transpose(*Jacm);
JacuT->Mult(l, y.GetBlock(0));
JacmT->Mult(l, y.GetBlock(1));
delete JacuT;
delete JacmT;
y.Add(1.0, gradxf);
(y.GetBlock(1)).Add(-1.0, zl);
}
bool InteriorPointSolver::GetConverged() const
{
return converged;
}
void InteriorPointSolver::SetTol(double Tol)
{
rel_tol = Tol;
}
void InteriorPointSolver::SetMaxIter(int max_it)
{
max_iter = max_it;
}
void InteriorPointSolver::SetBarrierParameter(double mu_0)
{
mu_k = mu_0;
}
void InteriorPointSolver::SaveLogBarrierHessianIterates(bool save)
{
MFEM_ASSERT(MyRank == 0 || save == false, "currently can only save logbarrier hessian in serial codes");
saveLogBarrierIterates = save;
}
void InteriorPointSolver::SetLinearSolver(int LinSolver)
{
linSolver = LinSolver;
}
InteriorPointSolver::~InteriorPointSolver()
{
F1.DeleteAll();
F2.DeleteAll();
block_offsetsx.DeleteAll();
block_offsetsumlz.DeleteAll();
block_offsetsuml.DeleteAll();
ml.SetSize(0);
}
+80
View File
@@ -0,0 +1,80 @@
#include "mfem.hpp"
#include "Problems.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
#ifndef IPSOLVER
#define IPSOLVER
class InteriorPointSolver
{
protected:
GeneralOptProblem* optProblem;
double rel_tol;
int max_iter;
double mu_k; // \mu_k
Vector lk, zlk;
double sMax, kSig, tauMin, eta, thetaMin, delta, sTheta, sPhi, kMu, thetaMu;
double thetaMax, kSoc, gTheta, gPhi, kEps;
// filter
Array<double> F1, F2;
// quantities computed in lineSearch
double alpha, alphaz;
double thx0, thxtrial;
double phx0, phxtrial;
bool descentDirection, switchCondition, sufficientDecrease, lineSearchSuccess, inFilterRegion;
double Dxphi0_xhat;
int dimU, dimM, dimC;
Array<int> block_offsetsumlz, block_offsetsuml, block_offsetsx;
Vector ml;
Vector ckSoc;
SparseMatrix * Huu, * Hum, * Hmu, * Hmm, * Wmm, *D, * Ju, * Jm, * JuT, * JmT;
SparseMatrix * Huucl, *HLuu;
int jOpt;
bool converged;
int MyRank;
bool iAmRoot;
bool saveLogBarrierIterates;
int linSolver;
public:
InteriorPointSolver(GeneralOptProblem*);
void Mult(const BlockVector& , BlockVector&); // used when the user wants to be aware of bound-constrained variable m >= ml
void Mult(const Vector&, Vector &); // useful when the user doesn't need to know about bound-constrained variable m >= ml, e.g., when m is a slack variable
double MaxStepSize(Vector& , Vector& , Vector& , double);
double MaxStepSize(Vector& , Vector& , double);
void FormIPNewtonMat(BlockVector& , Vector& , Vector& , BlockOperator &);
void IPNewtonSolve(BlockVector& , Vector& , Vector& , Vector&, BlockVector& , double, bool);
void lineSearch(BlockVector& , BlockVector& , double);
void projectZ(const Vector & , Vector &, double);
void filterCheck(double, double);
double E(const BlockVector &, const Vector &, const Vector &, double, bool);
double E(const BlockVector &, const Vector &, const Vector &, bool);
bool GetConverged() const;
// TO DO: include Hessian of Lagrangian
double theta(const BlockVector &);
double phi(const BlockVector &, double);
void Dxphi(const BlockVector &, double, BlockVector &);
double L(const BlockVector &, const Vector &, const Vector &);
void DxL(const BlockVector &, const Vector &, const Vector &, BlockVector &);
void SetTol(double);
void SetMaxIter(int);
void SetBarrierParameter(double);
void SaveLogBarrierHessianIterates(bool);
void SetLinearSolver(int);
virtual ~InteriorPointSolver();
};
#endif
+125
View File
@@ -0,0 +1,125 @@
#include "mfem.hpp"
#include "Problems.hpp"
#include "IPsolver.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
double dmanufacturedFun(const Vector &);
double fRhs(const Vector &);
double obstacle(const Vector &);
int main(int argc, char *argv[])
{
int FEorder = 1; // order of the finite elements
int linSolver = 0;
int maxIPMiters = 30;
bool iAmRoot = true;
OptionsParser args(argc, argv);
args.AddOption(&FEorder, "-o", "--order",\
"Order of the finite elements.");
args.AddOption(&linSolver, "-linSolver", "--linearSolver", \
"IP-Newton linear system solution strategy.");
args.AddOption(&maxIPMiters, "-IPMiters", "--IPMiters",\
"Maximum number of IPM iterations");
args.Parse();
if(!args.Good())
{
args.PrintUsage(cout);
return 1;
}
else
{
if( iAmRoot )
{
args.PrintOptions(cout);
}
}
const char *meshFile = "../../data/inline-quad.mesh";
Mesh *mesh = new Mesh(meshFile, 1, 1);
int dim = mesh->Dimension(); // geometric dimension of the domain
{
int ref_levels = 3;
for (int l = 0; l < ref_levels; l++)
{
mesh->UniformRefinement();
}
}
FiniteElementCollection *fec = new H1_FECollection(FEorder, dim);
FiniteElementSpace *Vh = new FiniteElementSpace(mesh, fec);
ObstacleProblem problem(Vh, &fRhs, &obstacle);
int dimD = problem.GetDimD();
Vector x0(dimD); x0 = 0.0;
Vector xf(dimD); xf = 0.0;
InteriorPointSolver optimizer(&problem);
optimizer.SetTol(1.e-7);
optimizer.SetLinearSolver(linSolver);
optimizer.SetMaxIter(maxIPMiters);
optimizer.Mult(x0, xf);
double Einitial = problem->E(x0);
double Efinal = problem->E(xf);
cout << "Energy objective at initial point = " << Einitial << endl;
cout << "Energy objective at QP optimizer = " << Efinal << endl;
GridFunction d_gf(Vh);
d_gf = xf;
FunctionCoefficient dm_fc(dmanufacturedFun); // pseudo-manufactured solution
GridFunction dm_gf(Vh);
dm_gf.ProjectCoefficient(dm_fc);
ParaViewDataCollection paraview_dc("BarrierProblemSolution", mesh);
paraview_dc.SetPrefixPath("ParaView");
paraview_dc.SetLevelsOfDetail(FEorder);
paraview_dc.SetDataFormat(VTKFormat::BINARY);
paraview_dc.SetHighOrderOutput(true);
paraview_dc.SetCycle(0);
paraview_dc.SetTime(0.0);
paraview_dc.RegisterField("d(x) (numerical)", &d_gf);
paraview_dc.RegisterField("d(x) (pseudo-manufactured)", &dm_gf);
paraview_dc.Save();
delete Vh;
delete fec;
delete mesh;
return 0;
}
double dmanufacturedFun(const Vector &x)
{
return cos(2*M_PI*x(0)) + 0.2 - 2.0*(pow(x(0),3) - 1.5*pow(x(0),2));
}
// f(x) forcing term... which enters the objective energy functional
// E(d) = 0.5 d^T K d - f^T d, where f is a discrete vector representation
// of f(x). f(x) is such that in the absence of bound-constraints then
// the solution of the optimization problem satisfies the PDE
// -div(grad(d)) + d = f + homogeneous Neumann conditions on the unit interval,
// for d(x) = cos(2 \pi x) + a0 + a3 (x^3 - 1.5 x^2), a2 = 0.2, a3 = -2
double fRhs(const Vector &x)
{
double fx = 0.;
fx = 0.2 - 2.0 * (pow(x(0),3)- 1.5*pow(x(0),2.) - 6 * x(0) + 3.) + (1. + pow(2.*M_PI,2))*cos(2.*M_PI*x(0));
return fx;
}
double obstacle(const Vector &x)
{
return 0.0;
}
+834
View File
@@ -0,0 +1,834 @@
#include "mfem.hpp"
#include "ParIPsolver.hpp"
#include "ParProblems.hpp"
#include <fstream>
#include <iostream>
#include <cstdlib>
using namespace std;
using namespace mfem;
ParInteriorPointSolver::ParInteriorPointSolver(ParGeneralOptProblem * problem_)
: problem(problem_),
block_offsetsumlz(5), block_offsetsuml(4), block_offsetsx(3),
Huu(nullptr), Hum(nullptr), Hmu(nullptr),
Hmm(nullptr), Wmm(nullptr), D(nullptr),
Ju(nullptr), Jm(nullptr), JuT(nullptr), JmT(nullptr),
saveLogBarrierIterates(false)
{
OptTol = 1.e-2;
max_iter = 20;
mu_k = 1.0;
sMax = 1.e2;
kSig = 1.e10; // control deviation from primal Hessian
tauMin = 0.8; // control rate at which iterates can approach the boundary
eta = 1.e-4; // backtracking constant
thetaMin = 1.e-4; // allowed violation of the equality constraints
// constants in line-step A-5.4
delta = 1.0;
sTheta = 1.1;
sPhi = 2.3;
// control the rate at which the penalty parameter is decreased
kMu = 0.2;
thetaMu = 1.5;
thetaMax = 1.e6; // maximum constraint violation
// data for the second order correction
kSoc = 0.99;
// equation (18)
gTheta = 1.e-5;
gPhi = 1.e-5;
kEps = 1.e1;
dimU = problem->GetDimU();
dimM = problem->GetDimM();
dimC = problem->GetDimC();
MPI_Allreduce(&dimU, &dimUglb, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
MPI_Allreduce(&dimM, &dimMglb, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
MPI_Allreduce(&dimC, &dimCglb, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
ckSoc.SetSize(dimC);
block_offsetsumlz[0] = 0;
block_offsetsumlz[1] = dimU; // u
block_offsetsumlz[2] = dimM; // m
block_offsetsumlz[3] = dimC; // lambda
block_offsetsumlz[4] = dimM; // zl
block_offsetsumlz.PartialSum();
for(int i = 0; i < block_offsetsuml.Size(); i++)
{
block_offsetsuml[i] = block_offsetsumlz[i];
}
for(int i = 0; i < block_offsetsx.Size(); i++)
{
block_offsetsx[i] = block_offsetsuml[i] ;
}
ml = problem->Getml();
lk.SetSize(dimC); lk = 0.0;
zlk.SetSize(dimM); zlk = 0.0;
linSolver = 0;
linSolveTol = 1.e-8;
MyRank = Mpi::WorldRank();
iAmRoot = MyRank == 0 ? true : false;
}
double ParInteriorPointSolver::MaxStepSize(Vector &x, Vector &xl, Vector &xhat, double tau)
{
double alphaMaxloc = 1.0;
double alphaTmp;
for(int i = 0; i < x.Size(); i++)
{
if( xhat(i) < 0. )
{
alphaTmp = -1. * tau * (x(i) - xl(i)) / xhat(i);
alphaMaxloc = min(alphaMaxloc, alphaTmp);
}
}
// alphaMaxloc is the local maximum step size which is
// distinct on each MPI process. Need to compute
// the global maximum step size
double alphaMaxglb;
MPI_Allreduce(&alphaMaxloc, &alphaMaxglb, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD);
return alphaMaxglb;
}
double ParInteriorPointSolver::MaxStepSize(Vector &x, Vector &xhat, double tau)
{
Vector zero(x.Size()); zero = 0.0;
return MaxStepSize(x, zero, xhat, tau);
}
void ParInteriorPointSolver::Mult(const Vector &x0, Vector &xf)
{
BlockVector x0block(block_offsetsx); x0block = 0.0;
x0block.GetBlock(0).Set(1.0, x0);
x0block.GetBlock(1) = 100.;
x0block.GetBlock(1).Add(1.0, ml);
BlockVector xfblock(block_offsetsx); xfblock = 0.0;
Mult(x0block, xfblock);
xf.Set(1.0, xfblock.GetBlock(0));
}
void ParInteriorPointSolver::Mult(const BlockVector &x0, BlockVector &xf)
{
converged = false;
BlockVector xk(block_offsetsx), xhat(block_offsetsx); xk = 0; xhat = 0.0;
BlockVector Xk(block_offsetsumlz), Xhat(block_offsetsumlz); Xk = 0.0; Xhat = 0.0;
BlockVector Xhatuml(block_offsetsuml); Xhatuml = 0.0;
Vector zlhat(dimM); zlhat = 0.0;
xk.GetBlock(0).Set(1.0, x0.GetBlock(0));
xk.GetBlock(1).Set(1.0, x0.GetBlock(1));
// running estimate of the final values of the Lagrange multipliers
lk = 0.0;
zlk = 0.0;
for(int i = 0; i < dimM; i++)
{
zlk(i) = 1.e1 * mu_k / (xk(i+dimU) - ml(i));
}
Xk.GetBlock(0).Set(1.0, xk.GetBlock(0));
Xk.GetBlock(1).Set(1.0, xk.GetBlock(1));
Xk.GetBlock(2).Set(1.0, lk);
Xk.GetBlock(3).Set(1.0, zlk);
/* set theta0 = theta(x0)
* thetaMin
* thetaMax
* when theta(xk) < thetaMin and the switching condition holds
* then we ask for the Armijo sufficient decrease of the barrier
* objective to be satisfied, in order to accept the trial step length alphakl
*
* thetaMax controls how the filter is initialized for each log-barrier subproblem
* F0 = {(th, phi) s.t. th > thetaMax}
* that is the filter does not allow for iterates where the constraint violation
* is larger than that of thetaMax
*/
double theta0 = theta(xk);
thetaMin = 1.e-4 * max(1.0, theta0);
thetaMax = 1.e8 * thetaMin; // 1.e4 * max(1.0, theta0)
double Eeval, maxBarrierSolves, Eevalmu0;
bool printOptimalityError; // control optimality error print to console for log-barrier subproblems
maxBarrierSolves = 10;
for(jOpt = 0; jOpt < max_iter; jOpt++)
{
if(iAmRoot)
{
cout << "interior-point solve step " << jOpt << endl;
}
// A-2. Check convergence of overall optimization problem
printOptimalityError = false;
Eevalmu0 = E(xk, lk, zlk, printOptimalityError);
if(Eevalmu0 < OptTol)
{
converged = true;
if(iAmRoot)
{
cout << "solved optimization problem :)\n";
}
break;
}
if(jOpt > 0) { maxBarrierSolves = 1; }
for(int i = 0; i < maxBarrierSolves; i++)
{
// A-3. Check convergence of the barrier subproblem
printOptimalityError = true;
Eeval = E(xk, lk, zlk, mu_k, printOptimalityError);
if(iAmRoot)
{
cout << "E = " << Eeval << endl;
}
if(Eeval < kEps * mu_k)
{
if(iAmRoot)
{
cout << "solved barrier subproblem :), for mu = " << mu_k << endl;
}
// A-3.1. Recompute the barrier parameter
mu_k = max(OptTol / 10., min(kMu * mu_k, pow(mu_k, thetaMu)));
// A-3.2. Re-initialize the filter
F1.DeleteAll();
F2.DeleteAll();
}
else
{
break;
}
}
// A-4. Compute the search direction
// solve for (uhat, mhat, lhat)
if(iAmRoot)
{
cout << "\n** A-4. IP-Newton solve **\n";
}
zlhat = 0.0; Xhatuml = 0.0;
// why do we have Xhatuml ....???
// TO DO: remove Xhatuml in favor of passing Xhat
IPNewtonSolve(xk, lk, zlk, zlhat, Xhatuml, mu_k, false);
// assign data stack, X = (u, m, l, zl)
Xk = 0.0;
Xk.GetBlock(0).Set(1.0, xk.GetBlock(0));
Xk.GetBlock(1).Set(1.0, xk.GetBlock(1));
Xk.GetBlock(2).Set(1.0, lk);
Xk.GetBlock(3).Set(1.0, zlk);
// assign data stack, Xhat = (uhat, mhat, lhat, zlhat)
Xhat = 0.0;
for(int i = 0; i < 3; i++)
{
Xhat.GetBlock(i).Set(1.0, Xhatuml.GetBlock(i));
}
Xhat.GetBlock(3).Set(1.0, zlhat);
// A-5. Backtracking line search.
if(iAmRoot)
{
cout << "\n** A-5. Linesearch **\n";
cout << "mu = " << mu_k << endl;
}
lineSearch(Xk, Xhat, mu_k);
if(lineSearchSuccess)
{
if(iAmRoot)
{
cout << "lineSearch successful :)\n";
}
if(!switchCondition || !sufficientDecrease)
{
F1.Append( (1. - gTheta) * thx0);
F2.Append( phx0 - gPhi * thx0);
}
// ----- A-6: Accept the trial point
// print info regarding zl...
xk.GetBlock(0).Add(alpha, Xhat.GetBlock(0));
xk.GetBlock(1).Add(alpha, Xhat.GetBlock(1));
lk.Add(alpha, Xhat.GetBlock(2));
zlk.Add(alphaz, Xhat.GetBlock(3));
projectZ(xk, zlk, mu_k);
}
else
{
if(iAmRoot)
{
cout << "lineSearch not successful :(\n";
cout << "attempting feasibility restoration with theta = " << thx0 << endl;
cout << "no feasibility restoration implemented, exiting now \n";
}
break;
}
if(jOpt + 1 == max_iter && iAmRoot)
{
cout << "maximum optimization iterations :(\n";
}
}
// done with optimization routine, just reassign data to xf reference so
// that the application code has access to the optimal point
xf = 0.0;
xf.GetBlock(0).Set(1.0, xk.GetBlock(0));
xf.GetBlock(1).Set(1.0, xk.GetBlock(1));
}
void ParInteriorPointSolver::FormIPNewtonMat(BlockVector & x, Vector & l, Vector &zl, BlockOperator &Ak)
{
// WARNING: Huu, Hum, Hmu, Hmm should all be Hessian terms of the Lagrangian, currently we
// them by Hessian terms of the objective function and neglect the Hessian of l^T c
Huu = problem->Duuf(x);
Hum = problem->Dumf(x);
Hmu = problem->Dmuf(x);
Hmm = problem->Dmmf(x);
Vector DiagLogBar(dimM); DiagLogBar = 0.0;
for(int ii = 0; ii < dimM; ii++)
{
DiagLogBar(ii) = zl(ii) / (x(ii+dimU) - ml(ii));
}
if(saveLogBarrierIterates)
{
std::ofstream diagStream;
char diagString[100];
snprintf(diagString, 100, "logBarrierHessiandata/D%d.dat", jOpt);
diagStream.open(diagString, ios::out | ios::trunc);
for(int ii = 0; ii < dimM; ii++)
{
diagStream << setprecision(30) << DiagLogBar(ii) << endl;
}
diagStream.close();
}
SparseMatrix * Ds = new SparseMatrix(DiagLogBar);
ParFiniteElementSpace * fes = problem->GetfesM();
D = new HypreParMatrix(fes->GetComm(), fes->GlobalTrueVSize(), fes->GetTrueDofOffsets(), Ds);
HypreStealOwnership(*D,*Ds);
delete Ds;
if(Hmm != nullptr)
{
Wmm = Hmm;
Wmm->Add(1.0, *D);
}
else
{
Wmm = D;
}
Ju = problem->Duc(x); JuT = Ju->Transpose();
Jm = problem->Dmc(x); JmT = Jm->Transpose();
// IP-Newton system matrix
// Ak = [[H_(u,u) H_(u,m) J_u^T]
// [H_(m,u) W_(m,m) J_m^T]
// [ J_u J_m 0 ]]
Ak.SetBlock(0, 0, Huu); Ak.SetBlock(0, 2, JuT);
Ak.SetBlock(1, 1, Wmm); Ak.SetBlock(1, 2, JmT);
Ak.SetBlock(2, 0, Ju); Ak.SetBlock(2, 1, Jm);
if(Hum != nullptr) { Ak.SetBlock(0, 1, Hum); Ak.SetBlock(1, 0, Hmu); }
}
// perturbed KKT system solve
// determine the search direction
void ParInteriorPointSolver::IPNewtonSolve(BlockVector &x, Vector &l, Vector &zl, Vector &zlhat, BlockVector &Xhat, double mu, bool socSolve)
{
// solve A x = b, where A is the IP-Newton matrix
BlockOperator A(block_offsetsuml, block_offsetsuml); BlockVector b(block_offsetsuml); b = 0.0;
FormIPNewtonMat(x, l, zl, A);
// [grad_u phi + Ju^T l]
// b = - [grad_m phi + Jm^T l]
// [ c ]
BlockVector gradphi(block_offsetsx); gradphi = 0.0;
BlockVector JTl(block_offsetsx); JTl = 0.0;
Dxphi(x, mu, gradphi);
(A.GetBlock(0,2)).Mult(l, JTl.GetBlock(0));
(A.GetBlock(1,2)).Mult(l, JTl.GetBlock(1));
for(int ii = 0; ii < 2; ii++)
{
b.GetBlock(ii).Set(1.0, gradphi.GetBlock(ii));
b.GetBlock(ii).Add(1.0, JTl.GetBlock(ii));
}
if(!socSolve)
{
problem->c(x, b.GetBlock(2));
}
else
{
b.GetBlock(2).Set(1.0, ckSoc);
}
b *= -1.0;
Xhat = 0.0;
// Direct solver (default)
if(linSolver == 0)
{
Array2D<HypreParMatrix *> ABlockMatrix(3,3);
for(int ii = 0; ii < 3; ii++)
{
for(int jj = 0; jj < 3; jj++)
{
if(!A.IsZeroBlock(ii, jj))
{
ABlockMatrix(ii, jj) = dynamic_cast<HypreParMatrix *>(&(A.GetBlock(ii, jj)));
}
else
{
ABlockMatrix(ii, jj) = nullptr;
}
}
}
HypreParMatrix * Ah = HypreParMatrixFromBlocks(ABlockMatrix);
/* direct solve of the 3x3 IP-Newton linear system */
#ifdef MFEM_USE_MUMPS
MUMPSSolver ASolver;
ASolver.SetPrintLevel(0);
ASolver.SetMatrixSymType(MUMPSSolver::MatType::SYMMETRIC_INDEFINITE);
ASolver.SetOperator(*Ah);
ASolver.Mult(b, Xhat);
#else
#ifdef MFEM_USE_MKL_CPARDISO
CPardisoSolver ASolver(MPI_COMM_WORLD);
ASolver.SetOperator(*Ah);
ASolver.Mult(b, Xhat);
#else
MFEM_VERIFY(false, "linSolver 0 will not work unless compiled with MUMPS or MKL");
#endif
#endif
delete Ah;
}
else if(linSolver == 1 || linSolver == 2)
{
// form A = Huu + Ju^T D Ju, Wmm = D for contact
HypreParMatrix * Huuloc = dynamic_cast<HypreParMatrix *>(&(A.GetBlock(0, 0)));
HypreParMatrix * Wmmloc = dynamic_cast<HypreParMatrix *>(&(A.GetBlock(1, 1)));
HypreParMatrix * Juloc = dynamic_cast<HypreParMatrix *>(&(A.GetBlock(2, 0)));
HypreParMatrix * JuTloc = dynamic_cast<HypreParMatrix *>(&(A.GetBlock(0, 2)));
HypreParMatrix *JuTDJu = RAP(Wmmloc, Juloc); // Ju^T D Ju
HypreParMatrix *Areduced = ParAdd(Huuloc, JuTDJu); // Huu + Ju^T D Ju
/* prepare the reduced rhs */
// breduced = bu + Ju^T (bm + Wmm bl)
Vector breduced(dimU); breduced = 0.0;
Vector tempVec(dimM); tempVec = 0.0;
Wmmloc->Mult(b.GetBlock(2), tempVec);
tempVec.Add(1.0, b.GetBlock(1));
JuTloc->Mult(tempVec, breduced);
breduced.Add(1.0, b.GetBlock(0));
if(linSolver == 1)
{
// setup the solver for the reduced linear system
#ifdef MFEM_USE_MUMPS
MUMPSSolver AreducedSolver;
AreducedSolver.SetPrintLevel(0);
AreducedSolver.SetMatrixSymType(MUMPSSolver::MatType::SYMMETRIC_INDEFINITE);
AreducedSolver.SetOperator(*Areduced);
AreducedSolver.Mult(breduced, Xhat.GetBlock(0));
#else
#ifdef MFEM_USE_MKL_CPARDISO
CPardisoSolver AreducedSolver(MPI_COMM_WORLD);
AreducedSolver.SetOperator(*Areduced);
AreducedSolver.Mult(breduced, Xhat.GetBlock(0));
#else
MFEM_VERIFY(false, "linSolver 1 will not work unless compiled with MUMPS or MKL");
#endif
#endif
}
else
{
HyprePCG AreducedSolver(MPI_COMM_WORLD);
AreducedSolver.SetOperator(*Areduced);
HypreBoomerAMG AreducedPrec;
AreducedSolver.SetTol(linSolveTol);
AreducedSolver.SetMaxIter(500);
AreducedSolver.SetPreconditioner(AreducedPrec);
AreducedSolver.SetResidualConvergenceOptions(); // convergence criteria based on residual norm
AreducedSolver.SetPrintLevel(2);
AreducedSolver.Mult(breduced, Xhat.GetBlock(0));
}
// now propagate solved uhat to obtain mhat and lhat
// xm = Ju xu - bl
Juloc->Mult(Xhat.GetBlock(0), Xhat.GetBlock(1));
Xhat.GetBlock(1).Add(-1.0, b.GetBlock(2));
// xl = Wmm xm - bm
Wmmloc->Mult(Xhat.GetBlock(1), Xhat.GetBlock(2));
Xhat.GetBlock(2).Add(-1.0, b.GetBlock(1));
delete JuTDJu;
delete Areduced;
}
/* backsolve to determine zlhat */
for(int ii = 0; ii < dimM; ii++)
{
zlhat(ii) = -1.*(zl(ii) + (zl(ii) * Xhat(ii + dimU) - mu) / (x(ii + dimU) - ml(ii)) );
}
// free memory
delete D;
delete JuT;
delete JmT;
if(Hmm != nullptr)
{
delete Wmm;
}
}
// here Xhat, X will be BlockVectors w.r.t. the 4 partitioning X = (u, m, l, zl)
void ParInteriorPointSolver::lineSearch(BlockVector& X0, BlockVector& Xhat, double mu)
{
double tau = max(tauMin, 1.0 - mu);
Vector u0 = X0.GetBlock(0);
Vector m0 = X0.GetBlock(1);
Vector l0 = X0.GetBlock(2);
Vector z0 = X0.GetBlock(3);
Vector uhat = Xhat.GetBlock(0);
Vector mhat = Xhat.GetBlock(1);
Vector lhat = Xhat.GetBlock(2);
Vector zhat = Xhat.GetBlock(3);
double alphaMax = MaxStepSize(m0, ml, mhat, tau);
double alphaMaxz = MaxStepSize(z0, zhat, tau);
alphaz = alphaMaxz;
BlockVector x0(block_offsetsx); x0 = 0.0;
x0.GetBlock(0).Set(1.0, u0);
x0.GetBlock(1).Set(1.0, m0);
BlockVector xhat(block_offsetsx); xhat = 0.0;
xhat.GetBlock(0).Set(1.0, uhat);
xhat.GetBlock(1).Set(1.0, mhat);
BlockVector xtrial(block_offsetsx); xtrial = 0.0;
BlockVector Dxphi0(block_offsetsx); Dxphi0 = 0.0;
int maxBacktrack = 20;
alpha = alphaMax;
Vector ck0(dimC); ck0 = 0.0;
Vector zhatsoc(dimM); zhatsoc = 0.0;
BlockVector Xhatumlsoc(block_offsetsuml); Xhatumlsoc = 0.0;
BlockVector xhatsoc(block_offsetsx); xhatsoc = 0.0;
Vector uhatsoc(dimU); uhatsoc = 0.0;
Vector mhatsoc(dimM); mhatsoc = 0.0;
Dxphi(x0, mu, Dxphi0);
Dxphi0_xhat = InnerProduct(MPI_COMM_WORLD, Dxphi0, xhat);
descentDirection = Dxphi0_xhat < 0. ? true : false;
if(descentDirection)
{
if (iAmRoot)
{
cout << "is a descent direction for the log-barrier objective\n";
}
}
else
{
cout << "is not a descent direction for the log-barrier objective\n";
}
thx0 = theta(x0);
phx0 = phi(x0, mu);
lineSearchSuccess = false;
for(int i = 0; i < maxBacktrack; i++)
{
if (iAmRoot)
{
cout << "\n--------- alpha = " << alpha << " ---------\n";
}
// ----- A-5.2. Compute trial point: xtrial = x0 + alpha_i xhat
xtrial.Set(1.0, x0);
xtrial.Add(alpha, xhat);
// ------ A-5.3. if not in filter region go to A.5.4 otherwise go to A-5.5.
thxtrial = theta(xtrial);
phxtrial = phi(xtrial, mu);
filterCheck(thxtrial, phxtrial);
if(!inFilterRegion)
{
if (iAmRoot)
{
cout << "not in filter region :)\n";
}
// ------ A.5.4: Check sufficient decrease
if(!descentDirection)
{
switchCondition = false;
}
else
{
switchCondition = (alpha * pow(abs(Dxphi0_xhat), sPhi) > delta * pow(thx0, sTheta)) ? true : false;
}
if (iAmRoot)
{
cout << "theta(x0) = " << thx0 << ", thetaMin = " << thetaMin << endl;
cout << "theta(xtrial) = " << thxtrial << ", (1-gTheta) *theta(x0) = " << (1. - gTheta) * thx0 << endl;
cout << "phi(xtrial) = " << phxtrial << ", phi(x0) - gPhi *theta(x0) = " << phx0 - gPhi * thx0 << endl;
}
// Case I
if(thx0 <= thetaMin && switchCondition)
{
sufficientDecrease = (phxtrial <= phx0 + eta * alpha * Dxphi0_xhat) ? true : false;
if(sufficientDecrease)
{
if(iAmRoot) { cout << "Line search successful: sufficient decrease in log-barrier objective.\n"; }
// accept the trial step
lineSearchSuccess = true;
break;
}
}
else
{
if(thxtrial <= (1. - gTheta) * thx0 || phxtrial <= phx0 - gPhi * thx0)
{
if(iAmRoot) { cout << "Line search successful: infeasibility or log-barrier objective decreased.\n"; }
// accept the trial step
lineSearchSuccess = true;
break;
}
}
// A-5.5: Initialize the second-order correction
if((!(thx0 < thxtrial)) && i == 0)
{
if (iAmRoot)
{
cout << "second order correction\n";
}
problem->c(xtrial, ckSoc);
problem->c(x0, ck0);
ckSoc.Add(alphaMax, ck0);
// A-5.6 Compute the second-order correction.
IPNewtonSolve(x0, l0, z0, zhatsoc, Xhatumlsoc, mu, true);
mhatsoc.Set(1.0, Xhatumlsoc.GetBlock(1));
//WARNING: not complete but currently solver isn't entering this region
}
}
else
{
if (iAmRoot)
{
cout << "in filter region :(\n";
}
}
// include more if needed
alpha *= 0.5;
}
}
void ParInteriorPointSolver::projectZ(const Vector &x, Vector &z, double mu)
{
double zi;
double mudivmml;
for(int i = 0; i < dimM; i++)
{
zi = z(i);
mudivmml = mu / (x(i + dimU) - ml(i));
z(i) = max(min(zi, kSig * mudivmml), mudivmml / kSig);
}
}
void ParInteriorPointSolver::filterCheck(double th, double ph)
{
inFilterRegion = false;
if(th > thetaMax)
{
inFilterRegion = true;
}
else
{
for(int i = 0; i < F1.Size(); i++)
{
if(th >= F1[i] && ph >= F2[i])
{
inFilterRegion = true;
break;
}
}
}
}
double ParInteriorPointSolver::E(const BlockVector &x, const Vector &l, const Vector &zl, double mu, bool printEeval)
{
double E1, E2, E3;
double sc, sd;
BlockVector gradL(block_offsetsx); gradL = 0.0; // stationarity grad L = grad f + J^T l - z
Vector cx(dimC); cx = 0.0; // feasibility c = c(x)
Vector comp(dimM); comp = 0.0; // complementarity M Z - mu 1
DxL(x, l, zl, gradL);
E1 = GlobalLpNorm(infinity(), gradL.Normlinf(), MPI_COMM_WORLD);
problem->c(x, cx);
E2 = GlobalLpNorm(infinity(), cx.Normlinf(), MPI_COMM_WORLD);
for(int ii = 0; ii < dimM; ii++)
{
comp(ii) = x(dimU + ii) * zl(ii) - mu;
}
E3 = GlobalLpNorm(infinity(), comp.Normlinf(), MPI_COMM_WORLD);
double ll1, zl1;
zl1 = GlobalLpNorm(1, zl.Norml1(), MPI_COMM_WORLD)/ double(dimCglb + dimMglb);
ll1 = GlobalLpNorm(1, l.Norml1(), MPI_COMM_WORLD);
sc = max(sMax, zl1 / (double(dimMglb)) ) / sMax;
sd = max(sMax, (ll1 + zl1) / (double(dimCglb + dimMglb))) / sMax;
if(iAmRoot && printEeval)
{
cout << "evaluating optimality error for mu = " << mu << endl;
cout << "stationarity measure = " << E1 / sd << endl;
cout << "feasibility measure = " << E2 << endl;
cout << "complimentarity measure = " << E3 / sc << endl;
}
return max(max(E1 / sd, E2), E3 / sc);
}
double ParInteriorPointSolver::E(const BlockVector &x, const Vector &l, const Vector &zl, bool printEeval)
{
return E(x, l, zl, 0.0, printEeval);
}
double ParInteriorPointSolver::theta(const BlockVector &x)
{
Vector cx(dimC); cx = 0.0;
problem->c(x, cx);
return sqrt(InnerProduct(MPI_COMM_WORLD,cx, cx));
}
// log-barrier objective
double ParInteriorPointSolver::phi(const BlockVector &x, double mu)
{
double fx = problem->CalcObjective(x);
double logBarrierLoc = 0.0;
for(int i = 0; i < dimM; i++)
{
logBarrierLoc += log(x(dimU+i)-ml(i));
}
double logBarrierGlb;
MPI_Allreduce(&logBarrierLoc, &logBarrierGlb, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
return fx - mu * logBarrierGlb;
}
// gradient of log-barrier objective with respect to x = (u, m)
void ParInteriorPointSolver::Dxphi(const BlockVector &x, double mu, BlockVector &y)
{
problem->CalcObjectiveGrad(x, y);
for(int i = 0; i < dimM; i++)
{
y(dimU + i) -= mu / (x(dimU + i));
}
}
// Lagrangian function evaluation
// L(x, l, zl) = f(x) + l^T c(x) - zl^T m
double ParInteriorPointSolver::L(const BlockVector &x, const Vector &l, const Vector &zl)
{
double fx = problem->CalcObjective(x);
Vector cx(dimC); problem->c(x, cx);
return (fx + InnerProduct(MPI_COMM_WORLD,cx, l) - InnerProduct(MPI_COMM_WORLD, x.GetBlock(1), zl));
}
void ParInteriorPointSolver::DxL(const BlockVector &x, const Vector &l, const Vector &zl, BlockVector &y)
{
// evaluate the gradient of the objective with respect to the primal variables x = (u, m)
BlockVector gradxf(block_offsetsx); gradxf = 0.0;
problem->CalcObjectiveGrad(x, gradxf);
HypreParMatrix *Jacu, *Jacm, *JacuT, *JacmT;
Jacu = problem->Duc(x);
Jacm = problem->Dmc(x);
JacuT = Jacu->Transpose();
JacmT = Jacm->Transpose();
JacuT->Mult(l, y.GetBlock(0));
JacmT->Mult(l, y.GetBlock(1));
delete JacuT;
delete JacmT;
y.Add(1.0, gradxf);
(y.GetBlock(1)).Add(-1.0, zl);
}
bool ParInteriorPointSolver::GetConverged() const
{
return converged;
}
void ParInteriorPointSolver::SetTol(double Tol)
{
OptTol = Tol;
}
void ParInteriorPointSolver::SetMaxIter(int max_it)
{
max_iter = max_it;
}
void ParInteriorPointSolver::SetBarrierParameter(double mu_0)
{
mu_k = mu_0;
}
void ParInteriorPointSolver::SaveLogBarrierHessianIterates(bool save)
{
MFEM_ASSERT(MyRank == 0 || save == false, "currently can only save logbarrier hessian in serial codes");
saveLogBarrierIterates = save;
}
void ParInteriorPointSolver::SetLinearSolver(int LinSolver)
{
linSolver = LinSolver;
}
void ParInteriorPointSolver::SetLinearSolveTol(double Tol)
{
linSolveTol = Tol;
}
ParInteriorPointSolver::~ParInteriorPointSolver()
{
F1.DeleteAll();
F2.DeleteAll();
block_offsetsx.DeleteAll();
block_offsetsumlz.DeleteAll();
block_offsetsuml.DeleteAll();
ml.SetSize(0);
}
+82
View File
@@ -0,0 +1,82 @@
#include "mfem.hpp"
#include "ParProblems.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
#ifndef PARIPSOLVER
#define PARIPSOLVER
class ParInteriorPointSolver
{
protected:
ParGeneralOptProblem* problem;
double OptTol;
int max_iter;
double mu_k; // \mu_k
Vector lk, zlk;
double sMax, kSig, tauMin, eta, thetaMin, delta, sTheta, sPhi, kMu, thetaMu;
double thetaMax, kSoc, gTheta, gPhi, kEps;
// filter
Array<double> F1, F2;
// quantities computed in lineSearch
double alpha, alphaz;
double thx0, thxtrial;
double phx0, phxtrial;
bool descentDirection, switchCondition, sufficientDecrease, lineSearchSuccess, inFilterRegion;
double Dxphi0_xhat;
int dimU, dimM, dimC;
int dimUglb, dimMglb, dimCglb;
Array<int> block_offsetsumlz, block_offsetsuml, block_offsetsx;
Vector ml;
Vector ckSoc;
HypreParMatrix * Huu, * Hum, * Hmu, * Hmm, * Wmm, *D, * Ju, * Jm, * JuT, * JmT;
int jOpt;
bool converged;
int MyRank;
bool iAmRoot;
bool saveLogBarrierIterates;
int linSolver;
double linSolveTol;
public:
ParInteriorPointSolver(ParGeneralOptProblem*);
double MaxStepSize(Vector& , Vector& , Vector& , double);
double MaxStepSize(Vector& , Vector& , double);
void Mult(const BlockVector& , BlockVector&);
void Mult(const Vector&, Vector &);
void FormIPNewtonMat(BlockVector& , Vector& , Vector& , BlockOperator &);
void IPNewtonSolve(BlockVector& , Vector& , Vector& , Vector&, BlockVector& , double, bool);
void lineSearch(BlockVector& , BlockVector& , double);
void projectZ(const Vector & , Vector &, double);
void filterCheck(double, double);
double E(const BlockVector &, const Vector &, const Vector &, double, bool);
double E(const BlockVector &, const Vector &, const Vector &, bool);
bool GetConverged() const;
// TO DO: include Hessian of Lagrangian
double theta(const BlockVector &);
double phi(const BlockVector &, double);
void Dxphi(const BlockVector &, double, BlockVector &);
double L(const BlockVector &, const Vector &, const Vector &);
void DxL(const BlockVector &, const Vector &, const Vector &, BlockVector &);
void SetTol(double);
void SetMaxIter(int);
void SetBarrierParameter(double);
void SaveLogBarrierHessianIterates(bool);
void SetLinearSolver(int);
void SetLinearSolveTol(double);
virtual ~ParInteriorPointSolver();
};
#endif
+129
View File
@@ -0,0 +1,129 @@
// Obstacle Problem
//
//
// Compile with: make ParObstacleProblem
//
// Sample runs: mpirun -np 4 ./ParObstacleProblem
//
//
// Description: This example code demonstrates the use of MFEM to solve the
// bound-constrained energy minimization problem
//
// minimize (||∇u||² + ||u||²) subject to u ≥ ϕ in H¹.
#include "mfem.hpp"
#include "ParProblems.hpp"
#include "ParIPsolver.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
double dmanufacturedFun(const Vector &);
double fRhs(const Vector &);
int main(int argc, char *argv[])
{
// Initialize MPI
Mpi::Init();
int num_procs = Mpi::WorldSize();
int myid = Mpi::WorldRank();
Hypre::Init();
int FEorder = 1; // order of the finite elements
int linSolver = 2;
int maxIPMiters = 30;
int ref_levels = 3;
OptionsParser args(argc, argv);
args.AddOption(&FEorder, "-o", "--order",\
"Order of the finite elements.");
args.AddOption(&linSolver, "-linSolver", "--linearSolver", \
"IP-Newton linear system solution strategy.");
args.AddOption(&maxIPMiters, "-IPMiters", "--IPMiters",\
"Maximum number of IPM iterations");
args.AddOption(&ref_levels, "-r", "--mesh_refinement", \
"Mesh Refinement");
args.Parse();
if(!args.Good())
{
args.PrintUsage(cout);
return 1;
}
else
{
if(Mpi::Root())
{
args.PrintOptions(cout);
}
}
const char *meshFile = "../../data/inline-quad.mesh";
Mesh mesh(meshFile, 1, 1);
int dim = mesh.Dimension(); // geometric dimension of the meshed domain
{
for (int l = 0; l < ref_levels; l++)
{
mesh.UniformRefinement();
}
}
ParMesh pmesh(MPI_COMM_WORLD, mesh);
FiniteElementCollection *fec = new H1_FECollection(FEorder, dim);
ParFiniteElementSpace *Vh = new ParFiniteElementSpace(&pmesh, fec);
ParObstacleProblem problem(Vh,Vh,&fRhs);
int dimD = problem.GetDimD();
Vector x0(dimD); x0 = 100.0;
Vector xf(dimD); xf = 0.0;
ParInteriorPointSolver optimizer(&problem);
optimizer.SetTol(1.e-8);
optimizer.SetLinearSolveTol(1.e-10);
optimizer.SetLinearSolver(linSolver);
optimizer.SetMaxIter(maxIPMiters);
optimizer.Mult(x0, xf);
ParGridFunction d_gf(Vh);
d_gf.SetFromTrueDofs(xf);
FunctionCoefficient dm_fc(dmanufacturedFun); // manufactured solution
ParGridFunction dm_gf(Vh);
dm_gf.ProjectCoefficient(dm_fc);
char vishost[] = "localhost";
int visport = 19916;
socketstream exact_sock(vishost, visport);
exact_sock.precision(8);
exact_sock << "parallel " << num_procs << " " << myid << "\n";
exact_sock << "solution\n" << pmesh << dm_gf
<< "window_title 'Manufactured solution'" << flush;
socketstream sol_sock(vishost, visport);
sol_sock.precision(8);
sol_sock << "parallel " << num_procs << " " << myid << "\n";
sol_sock << "solution\n" << pmesh << d_gf
<< "window_title 'Numerical solution'" << flush;
delete Vh;
delete fec;
return 0;
}
double dmanufacturedFun(const Vector &x)
{
return cos(2*M_PI*x(0)) + 0.2 - 2.0*(pow(x(0),3) - 1.5*pow(x(0),2));
}
double fRhs(const Vector &x)
{
double fx = 0.;
fx = 0.2 - 2.0 * (pow(x(0),3)- 1.5*pow(x(0),2.) - 6 * x(0) + 3.) + (1. + pow(2.*M_PI,2))*cos(2.*M_PI*x(0));
return fx;
}
+212
View File
@@ -0,0 +1,212 @@
#include "mfem.hpp"
#include "ParProblems.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
ParGeneralOptProblem::ParGeneralOptProblem(ParFiniteElementSpace * fesU_, ParFiniteElementSpace * fesM_)
: fesU(fesU_), fesM(fesM_)
{
dimU = fesU->GetTrueVSize();
dimM = fesM->GetTrueVSize();
dimC = fesM->GetTrueVSize();
}
void ParGeneralOptProblem::CalcObjectiveGrad(const BlockVector &x, BlockVector &y) const
{
Duf(x, y.GetBlock(0));
Dmf(x, y.GetBlock(1));
}
ParGeneralOptProblem::~ParGeneralOptProblem()
{
block_offsetsx.DeleteAll();
}
// min E(d) s.t. g(d) >= 0
// min_(d,s) E(d) s.t. c(d,s) := g(d) - s = 0, s >= 0
ParOptProblem::ParOptProblem(ParFiniteElementSpace * fesU_,
ParFiniteElementSpace * fesM_)
: ParGeneralOptProblem(fesU_, fesM_), block_offsetsx(3)
{
block_offsetsx[0] = 0;
block_offsetsx[1] = dimU;
block_offsetsx[2] = dimM;
block_offsetsx.PartialSum();
ml.SetSize(dimM); ml = 0.0;
Vector negIdentDiag(dimM);
negIdentDiag = -1.0;
SparseMatrix * diag = new SparseMatrix(negIdentDiag);
Ih = new HypreParMatrix(fesM->GetComm(), fesM->GlobalTrueVSize(),
fesM->GetTrueDofOffsets(), diag);
HypreStealOwnership(*Ih, *diag);
delete diag;
}
double ParOptProblem::CalcObjective(const BlockVector &x) const { return E(x.GetBlock(0)); }
void ParOptProblem::Duf(const BlockVector &x, Vector &y) const { DdE(x.GetBlock(0), y); }
void ParOptProblem::Dmf(const BlockVector &x, Vector &y) const { y = 0.0; }
HypreParMatrix * ParOptProblem::Duuf(const BlockVector &x)
{
return DddE(x.GetBlock(0));
}
HypreParMatrix * ParOptProblem::Dumf(const BlockVector &x) { return nullptr; }
HypreParMatrix * ParOptProblem::Dmuf(const BlockVector &x) { return nullptr; }
HypreParMatrix * ParOptProblem::Dmmf(const BlockVector &x) { return nullptr; }
void ParOptProblem::c(const BlockVector &x, Vector &y) const // c(u,m) = g(u) - m
{
g(x.GetBlock(0), y);
y.Add(-1.0, x.GetBlock(1));
}
HypreParMatrix * ParOptProblem::Duc(const BlockVector &x)
{
return Ddg(x.GetBlock(0));
}
HypreParMatrix * ParOptProblem::Dmc(const BlockVector &x)
{
return Ih;
}
ParOptProblem::~ParOptProblem()
{
delete Ih;
}
// Obstacle Problem, no essential boundary conditions enforced
// Hessian of energy term is K + M (stiffness + mass)
ParObstacleProblem::ParObstacleProblem(ParFiniteElementSpace *fesU_,
ParFiniteElementSpace *fesM_,
double (*fSource)(const Vector &)) :
ParOptProblem(fesU_,fesM_), f(dimU), psi(dimU), J(nullptr)
{
Kform = new ParBilinearForm(fesU);
Kform->AddDomainIntegrator(new MassIntegrator);
Kform->AddDomainIntegrator(new DiffusionIntegrator);
Kform->Assemble();
Kform->Finalize();
Kform->FormSystemMatrix(ess_tdof_list, K);
FunctionCoefficient fcoeff(fSource);
fform = new ParLinearForm(fesU);
fform->AddDomainIntegrator(new DomainLFIntegrator(fcoeff));
fform->Assemble();
Vector F(dimU);
fform->ParallelAssemble(F);
f.SetSize(dimU);
f.Set(1.0, F);
psi = 0.0;
Vector iDiag(dimU); iDiag = 1.0;
SparseMatrix * Jacg = new SparseMatrix(iDiag);
J = new HypreParMatrix(fesU->GetComm(),fesU->GlobalTrueVSize(),fesU->GetTrueDofOffsets(),Jacg);
HypreStealOwnership(*J, *Jacg);
delete Jacg;
}
// Obstacle Problem, essential boundary conditions enforced
// Hessian of energy term is K (stiffness)
ParObstacleProblem::ParObstacleProblem(ParFiniteElementSpace *fesU_,
ParFiniteElementSpace *fesM_,
double (*fSource)(const Vector &),
double (*obstacleSource)(const Vector &),
Array<int> tdof_list, Vector &xDC) : ParOptProblem(fesU_,fesM_), f(dimU), psi(dimU), J(nullptr)
{
// elastic energy functional terms
ess_tdof_list = tdof_list;
Kform = new ParBilinearForm(fesU);
Kform->AddDomainIntegrator(new DiffusionIntegrator);
Kform->Assemble();
Kform->Finalize();
Kform->FormSystemMatrix(ess_tdof_list, K);
FunctionCoefficient fcoeff(fSource);
fform = new ParLinearForm(fesU);
fform->AddDomainIntegrator(new DomainLFIntegrator(fcoeff));
fform->Assemble();
Vector F(dimU);
fform->ParallelAssemble(F);
f.SetSize(dimU);
f.Set(1.0, F);
Kform->EliminateVDofsInRHS(ess_tdof_list, xDC, f);
// obstacle constraints --
Vector iDiag(dimU); iDiag = 1.0;
for(int i = 0; i < ess_tdof_list.Size(); i++)
{
iDiag(ess_tdof_list[i]) = 0.0;
}
SparseMatrix * Jacg = new SparseMatrix(iDiag);
J = new HypreParMatrix(fesU->GetComm(),fesU->GlobalTrueVSize(),fesU->GetTrueDofOffsets(),Jacg);
HypreStealOwnership(*J, *Jacg);
delete Jacg;
FunctionCoefficient psi_fc(obstacleSource);
ParGridFunction psi_gf(fesU);
psi_gf.ProjectCoefficient(psi_fc);
psi.Set(1.0, (*psi_gf.GetTrueDofs()));
for(int i = 0; i < ess_tdof_list.Size(); i++)
{
psi(ess_tdof_list[i]) -= 1.e-8;
}
}
double ParObstacleProblem::E(const Vector &d) const
{
Vector Kd(K.Height()); Kd = 0.0;
MFEM_VERIFY(d.Size() == K.Width(), "ParObstacleProblem::E - Inconsistent dimensions");
K.Mult(d, Kd);
return 0.5 * InnerProduct(MPI_COMM_WORLD, d, Kd) - InnerProduct(MPI_COMM_WORLD, f, d);
}
void ParObstacleProblem::DdE(const Vector &d, Vector &gradE) const
{
gradE.SetSize(K.Height());
MFEM_VERIFY(d.Size() == K.Width(), "ParObstacleProblem::DdE - Inconsistent dimensions");
K.Mult(d, gradE);
MFEM_VERIFY(f.Size() == K.Height(), "ParObstacleProblem::DdE - Inconsistent dimensions");
gradE.Add(-1.0, f);
}
HypreParMatrix * ParObstacleProblem::DddE(const Vector &d)
{
return &K;
}
// g(d) = d >= \psi
void ParObstacleProblem::g(const Vector &d, Vector &gd) const
{
MFEM_VERIFY(d.Size() == J->Width(), "ParObstacleProblem::g - Inconsistent dimensions");
J->Mult(d, gd);
MFEM_VERIFY(gd.Size() == J->Height(), "ParObstacleProblem::g - Inconsistent dimensions");
gd.Add(-1.0, psi);
}
HypreParMatrix * ParObstacleProblem::Ddg(const Vector &d)
{
return J;
}
ParObstacleProblem::~ParObstacleProblem()
{
delete Kform;
delete fform;
delete J;
}
+107
View File
@@ -0,0 +1,107 @@
#include "mfem.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
#ifndef PARPROBLEM_DEFS
#define PARPROBLEM_DEFS
// abstract ParGeneralOptProblem class
// of the form
// min_(u,m) f(u,m) s.t. c(u,m)=0 and m>=ml
// the primal variable (u, m) is represented as a BlockVector
// think about supporting general lower and upper bounds (see HiOP user manual)
class ParGeneralOptProblem
{
protected:
int dimU, dimM, dimC;
ParFiniteElementSpace * fesU = nullptr;
ParFiniteElementSpace * fesM = nullptr;
Array<int> block_offsetsx;
Vector ml;
public:
ParGeneralOptProblem(ParFiniteElementSpace * fesU_, ParFiniteElementSpace * fesM_); // constructor
virtual double CalcObjective(const BlockVector &) const = 0;
virtual void Duf(const BlockVector &, Vector &) const = 0;
virtual void Dmf(const BlockVector &, Vector &) const = 0;
void CalcObjectiveGrad(const BlockVector &, BlockVector &) const;
virtual HypreParMatrix * Duuf(const BlockVector &) = 0;
virtual HypreParMatrix * Dumf(const BlockVector &) = 0;
virtual HypreParMatrix * Dmuf(const BlockVector &) = 0;
virtual HypreParMatrix * Dmmf(const BlockVector &) = 0;
virtual HypreParMatrix * Duc(const BlockVector &) = 0;
virtual HypreParMatrix * Dmc(const BlockVector &) = 0;
// TO DO: include Hessian terms of constraint c
virtual void c(const BlockVector &, Vector &) const = 0;
int GetDimU() const { return dimU; };
int GetDimM() const { return dimM; };
int GetDimC() const { return dimC; };
ParFiniteElementSpace * GetfesU() {return fesU;}
ParFiniteElementSpace * GetfesM() {return fesM;}
Vector Getml() const { return ml; };
~ParGeneralOptProblem(); // destructor
};
// abstract ContactProblem class
// of the form
// min_d e(d) s.t. g(d) >= 0
class ParOptProblem : public ParGeneralOptProblem
{
protected:
Array<int> block_offsetsx;
HypreParMatrix * Ih;
public:
ParOptProblem(ParFiniteElementSpace * fesU_, ParFiniteElementSpace * fesM_); // constructor
double CalcObjective(const BlockVector &) const; // objective e
void Duf(const BlockVector &, Vector &) const;
void Dmf(const BlockVector &, Vector &) const;
HypreParMatrix * Duuf(const BlockVector &);
HypreParMatrix * Dumf(const BlockVector &);
HypreParMatrix * Dmuf(const BlockVector &);
HypreParMatrix * Dmmf(const BlockVector &);
HypreParMatrix * Duc(const BlockVector &);
HypreParMatrix * Dmc(const BlockVector &);
void c(const BlockVector &, Vector &) const;
virtual double E(const Vector &) const = 0; // objective e(d) (energy function)
virtual void DdE(const Vector &, Vector &) const = 0; // gradient of objective De / Dd
virtual HypreParMatrix * DddE(const Vector &) = 0;
// Hessian of objective D^2 e / D d^2
virtual HypreParMatrix * Ddg(const Vector &) = 0;
// Jacobian of inequality constraint Dg / Dd
virtual void g(const Vector &, Vector &) const = 0; // inequality constraint g(d) >= 0 (gap function)
int GetDimD() const { return fesU->GetTrueVSize(); };
int GetDimS() const { return fesM->GetTrueVSize(); };
virtual ~ParOptProblem();
};
class ParObstacleProblem : public ParOptProblem
{
protected:
// data to define energy objective function e(d) = 0.5 d^T K d - f^T d, g(d) = d >= \psi
// stiffness matrix used to define objective
ParBilinearForm *Kform;
ParLinearForm *fform;
Array<int> ess_tdof_list; // needed for calls to FormSystemMatrix
HypreParMatrix K;
HypreParMatrix *J;
ParFiniteElementSpace *Vh;
Vector f;
Vector psi;
public :
ParObstacleProblem(ParFiniteElementSpace*, ParFiniteElementSpace*, double (*fSource)(const Vector &));
ParObstacleProblem(ParFiniteElementSpace*, ParFiniteElementSpace*, double (*fSource)(const Vector &), double (*obstacleSource)(const Vector &), Array<int> tdof_list, Vector &);
double E(const Vector &) const;
void DdE(const Vector &, Vector &) const;
HypreParMatrix* DddE(const Vector &);
void g(const Vector &, Vector &) const;
HypreParMatrix* Ddg(const Vector &);
virtual ~ParObstacleProblem();
};
#endif
@@ -0,0 +1,173 @@
// Spherical Obstacle Problem
//
//
// Compile with: make ParSphericalObstacleProblem
//
// Sample runs: mpirun -np 4 ./ParSphericalObstacleProblem -linSolver 0
// mpirun -np 4 ./ParSphericalObstacleProblem -linSolver 1
// mpirun -np 4 ./ParSphericalObstacleProblem -linSolver 2
//
//
// Description: This example code demonstrates the use of MFEM to solve the
// bound-constrained energy minimization problem
//
// minimize ||∇u||² subject to u ≥ ϕ in H¹₀.
#include "mfem.hpp"
#include "ParProblems.hpp"
#include "ParIPsolver.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
double fRhs(const Vector &);
double spherical_obstacle(const Vector &);
double exact_solution_obstacle(const Vector &);
int main(int argc, char *argv[])
{
// Initialize MPI
Mpi::Init();
int num_procs = Mpi::WorldSize();
int myid = Mpi::WorldRank();
Hypre::Init();
int FEorder = 1; // order of the finite elements
int linSolver = 2;
int maxIPMiters = 30;
int ref_levels = 3;
OptionsParser args(argc, argv);
args.AddOption(&FEorder, "-o", "--order",\
"Order of the finite elements.");
args.AddOption(&linSolver, "-linSolver", "--linearSolver", \
"IP-Newton linear system solution strategy.");
args.AddOption(&maxIPMiters, "-IPMiters", "--IPMiters",\
"Maximum number of IPM iterations");
args.AddOption(&ref_levels, "-r", "--mesh_refinement", \
"Mesh Refinement");
args.Parse();
if(!args.Good())
{
args.PrintUsage(cout);
return 1;
}
else
{
if(myid == 0)
{
args.PrintOptions(cout);
}
}
const char *meshFile = "../../data/disk.mesh";
Mesh mesh(meshFile, 1, 1);
int dim = mesh.Dimension(); // geometric dimension of the meshed domain
{
for (int l = 0; l < ref_levels; l++)
{
mesh.UniformRefinement();
}
}
ParMesh pmesh(MPI_COMM_WORLD, mesh);
FiniteElementCollection *fec = new H1_FECollection(FEorder, dim);
ParFiniteElementSpace *Vh = new ParFiniteElementSpace(&pmesh, fec);
Array<int> boundary_dofs;
Vh->GetBoundaryTrueDofs(boundary_dofs);
int dimD = Vh->GetTrueVSize();
Vector xDC(dimD); xDC = 0.0;
ParObstacleProblem problem(Vh, Vh, &fRhs, &spherical_obstacle, boundary_dofs, xDC);
Vector x0(dimD); x0.Set(1.0, xDC);
Vector xf(dimD); xf = 0.0;
ParInteriorPointSolver optimizer(&problem);
optimizer.SetTol(1.e-7);
optimizer.SetLinearSolveTol(1.e-10);
optimizer.SetLinearSolver(linSolver);
optimizer.SetMaxIter(maxIPMiters);
optimizer.Mult(x0, xf);
ParGridFunction d_gf(Vh);
d_gf.SetFromTrueDofs(xf);
FunctionCoefficient dtrue_fc(exact_solution_obstacle); // analytic solution
ParGridFunction dtrue_gf(Vh);
dtrue_gf.ProjectCoefficient(dtrue_fc);
double L2error = d_gf.ComputeL2Error(dtrue_fc);
if (myid == 0)
{
cout << "\n|| u_h - u ||_{L^2} = " << L2error << '\n' << endl;
}
ParaViewDataCollection paraview_dc("SphericalObstacleProblem", &pmesh);
paraview_dc.SetPrefixPath("ParaView");
paraview_dc.SetLevelsOfDetail(FEorder);
paraview_dc.SetDataFormat(VTKFormat::BINARY);
paraview_dc.SetHighOrderOutput(true);
paraview_dc.SetCycle(0);
paraview_dc.SetTime(0.0);
paraview_dc.RegisterField("u(x,y) (analytic)", &dtrue_gf);
paraview_dc.RegisterField("u(x,y) (numerical)", &d_gf);
paraview_dc.Save();
delete Vh;
delete fec;
return 0;
}
double fRhs(const Vector &x)
{
return 0.;
}
double spherical_obstacle(const Vector &pt)
{
double x = pt(0), y = pt(1);
double r = sqrt(x*x + y*y);
double r0 = 0.5;
double beta = 0.9;
double b = r0*beta;
double tmp = sqrt(r0*r0 - b*b);
double B = tmp + b*b/tmp;
double C = -b/tmp;
if (r > b)
{
return B + r * C;
}
else
{
return sqrt(r0*r0 - r*r);
}
}
double exact_solution_obstacle(const Vector &pt)
{
double x = pt(0), y = pt(1);
double r = sqrt(x*x + y*y);
double r0 = 0.5;
double a = 0.348982574111686;
double A = -0.340129705945858;
if (r > a)
{
return A * log(r);
}
else
{
return sqrt(r0*r0-r*r);
}
}

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