Compare commits

...
185 Commits
Author SHA1 Message Date
Hennes Hajduk 6497f4d829 minor 2020-11-05 10:02:01 +01:00
Hennes Hajduk 3b533595b8 save-animation.glvs 2020-11-05 09:36:18 +01:00
HennesHajduk d21491f91e burgers something 2020-11-03 08:28:35 +01:00
HennesHajduk 0a1f3a0b0a minor, new script 2020-10-30 16:07:07 +01:00
Hennes Hajduk 438a9968ce benchmark data and glvis scripts 2020-10-29 19:47:07 +01:00
Hennes Hajduk b1a343f514 updated scripts, changed initial condition for stationary burgers 2020-10-29 16:04:40 +01:00
HennesHajduk a0a29e3303 overestimated burgers wave speed. Implemented lumped L2 projection. minor. 2020-10-28 18:24:34 +01:00
HennesHajduk a921f56177 minor 2020-10-27 11:57:31 +01:00
HennesHajduk 2a6edf7d43 style 2020-10-26 11:38:39 +01:00
HennesHajduk d6fa604631 started on fixing advection 2020-10-26 11:38:06 +01:00
HennesHajduk 3add636a18 removed some absolute paths 2020-10-25 11:45:44 +01:00
HennesHajduk 21000a319e removed MoST from euler 2020-10-21 13:41:06 +02:00
HennesHajduk 95703e3a6d new test cases. 2020-10-21 13:32:47 +02:00
HennesHajduk 39dfcac5b3 config/burgers.sh 2020-10-21 13:27:51 +02:00
HennesHajduk 45b618fab2 changed mesh back, enabled warning 2020-10-08 21:47:08 +02:00
HennesHajduk 22838a13af minor 2020-10-08 16:33:23 +02:00
HennesHajduk ee58c6828a changed mesh 2020-10-08 11:35:19 +02:00
HennesHajduk b50b0c0ac1 . 2020-10-06 21:55:35 +02:00
HennesHajduk 6c40560766 disabled warning 2020-10-06 21:54:07 +02:00
Hennes Hajduk cadc4516ef merge 2020-10-06 16:51:36 +02:00
Hennes Hajduk bb584f04f8 minor 2020-10-06 16:51:01 +02:00
HennesHajduk cec500bb11 most gimmick for swe 2020-10-02 17:03:14 +02:00
HennesHajduk a88917276a changed default quadrature rule (gridfunc) + config, BL equation 2020-10-02 11:24:04 +02:00
HennesHajduk 2227958c30 update 2020-08-13 17:06:45 +02:00
HennesHajduk 8c0d8c3708 config, meshes, hll, wip 2020-08-07 19:03:18 +02:00
HennesHajduk d9c7e28444 wip 2020-08-03 18:27:10 +02:00
HennesHajduk 5dd725f5f0 wip. done with apps directory 2020-08-03 17:23:17 +02:00
HennesHajduk 9405bc04b3 rescaled some tests for euler, swe, improved grids, corrected double-mach boundary type, wip 2020-07-30 19:16:02 +02:00
HennesHajduk 6ddaa46fc2 updated apps subdir. 2020-07-30 12:32:47 +02:00
HennesHajduk 4400dc08ae wip, some cleanup, wave speed with abs of height/density now. 2020-07-29 18:25:07 +02:00
HennesHajduk e90095d854 wip, todo swe euler cleanup 2020-07-27 18:00:02 +02:00
HennesHajduk c1154025e3 wip, BL, some changes in design of HyperbolicSystem's routines. 2020-07-27 14:07:18 +02:00
HennesHajduk fcfe3c8353 update. most TODOs in apps. Missing: advection with general velocity. 2020-07-27 10:37:19 +02:00
HennesHajduk 143da8287a derived quantities, save instead SaveAsOne, output dir + minor 2020-07-06 17:52:18 +02:00
HennesHajduk 23d0f0b637 with git pull 2020-07-05 12:15:36 +02:00
HennesHajduk 08af14793b merge master 2020-07-05 12:13:31 +02:00
HennesHajduk 6b6b871999 merge 2020-07-05 12:05:23 +02:00
HennesHajduk 02d9c69c0d BL equation + update of scripts and configs 2020-07-05 12:00:51 +02:00
Hennes Hajduk efd7aa8686 minor 2020-06-30 16:48:09 +02:00
Hennes Hajduk 4abec105c3 change in config 2020-06-23 18:05:39 +02:00
HennesHajduk 723f891e37 bugfix, change in config 2020-06-23 10:04:01 +02:00
HennesHajduk 889a7598f4 minor 2020-06-20 10:26:23 +02:00
Hennes Hajduk 6a76844b4f sequential bound version that seems to work and converge. 2020-06-18 19:29:58 +02:00
Hennes Hajduk d8550d7309 ex15 2020-06-17 10:27:25 +02:00
HennesHajduk a86534bba6 . 2020-06-12 18:37:57 +02:00
Hennes Hajduk a01a4ace7a data 2020-06-12 18:33:18 +02:00
HennesHajduk 070cdb3c6a wip on bounds, reincluded all bar states for height 2020-06-10 18:10:44 +02:00
Hennes Hajduk 13818643c1 gresho, not quite working yet. some changes in mcl. 2020-06-09 19:05:50 +02:00
HennesHajduk 61f60d2f88 denomminator free implementation again. WIP on chosing the right bounds. 2020-06-09 15:17:14 +02:00
HennesHajduk 3c1cf15c04 minor 2020-06-09 15:04:46 +02:00
HennesHajduk 6624e2250c removed results from github 2020-06-03 16:04:39 +02:00
HennesHajduk eff0a9c79f no actual changes, just comments, scripts, gitignore 2020-05-29 11:06:27 +02:00
HennesHajduk b814cf96d5 Bugfix bounds - extended bounds by closest nbrs for first unknown. Double Mach works. 2020-05-22 17:50:51 +02:00
HennesHajduk 5ff5022af3 updated bounds as I believe it makes sense. TODO find differnce between serial and parallel 2020-05-22 13:39:41 +02:00
HennesHajduk 3623bd2994 bugfix bounds for scalar problems 2020-05-20 15:52:22 +02:00
HennesHajduk cccbb11057 WIP. Sequential limiting for volume and flux terms. Bounds work fine for problems with shocks. 2020-05-20 14:40:38 +02:00
HennesHajduk 0de495cc3c GMS for Euler - just in case. 2020-05-15 18:35:25 +02:00
HennesHajduk c95db258bd added min max with zero for face terms, abort check in 1D. Included bar states in bounds for volume terms. Using bar states instead of w's + minor. 2020-05-13 11:04:05 +02:00
HennesHajduk 2aa2759192 closest nbrs for cubes 2020-05-08 12:04:36 +02:00
HennesHajduk 1fa4323498 minor 2020-05-07 18:28:03 +02:00
HennesHajduk fde74a329b restructured fe_evol methods slightly 2020-05-07 17:28:25 +02:00
HennesHajduk 319d4e7f05 minor 2020-05-07 16:58:01 +02:00
HennesHajduk ecb9d77a29 Restructured and optimized MCL Evolution. 2020-05-07 16:48:25 +02:00
HennesHajduk c7d5ee2654 Restructering of apps, idea of rescaling t in config, new swe dam break test case. 2020-05-07 16:39:38 +02:00
HennesHajduk a0e0c15913 included bound classes 2020-05-06 18:30:24 +02:00
HennesHajduk 4fda37f739 New bounds classes - functionality that was previously in dofs. WIP. Bounds are computed correctly in serial and parallel. 2020-05-06 18:01:15 +02:00
HennesHajduk 7b5e078731 wip 2020-05-05 18:38:48 +02:00
HennesHajduk 7511d65aa9 minor 2020-05-05 17:40:47 +02:00
HennesHajduk 18adf880d7 updated (p)dofs. 2020-05-05 17:28:02 +02:00
HennesHajduk 8df51cbc3f Fixed DG flux term limiting 2020-05-05 13:27:48 +02:00
HennesHajduk a8634a7fa0 MCL almost done. Works for all considered element types. Currently using low order scheme for DG fluxes, other TODO: Bound computation for systems 2020-05-04 18:32:52 +02:00
HennesHajduk 0541c74f08 bugfix - proper bounds 2020-05-04 17:29:18 +02:00
HennesHajduk 95f77d6c9a new burgers test, new functionality in dofs (Q-spaces seem to work, bug for triangles). 2020-05-04 16:09:52 +02:00
HennesHajduk f469d54afa MCL limiting for scalars works now. 2020-04-28 17:16:37 +02:00
HennesHajduk b4951bd02d TriangleDofMap + minor 2020-04-28 17:14:07 +02:00
HennesHajduk f5137a5eed Improved MCL low order scheme 2020-04-27 11:40:14 +02:00
HennesHajduk 9ad28ce2c8 dof2LocNbr in MCL, new euler test cases or modified them, low order method used in MCL 2020-04-27 10:09:31 +02:00
HennesHajduk 92aa5d65e2 Changed AntiDiff to DenseTensor. Moved LORMassMat and added option for it. 2020-04-24 16:08:05 +02:00
HennesHajduk d4c7b609b1 updated burgers.sh, subcell-distribution works, bound computation for scalars. 2020-04-24 13:47:54 +02:00
HennesHajduk 3c53e9a9c5 Implemented ElFlux differently. 2020-04-23 17:28:21 +02:00
HennesHajduk fb9726d4f8 all anti-diffusive fluxes are now working. 2020-04-23 16:30:34 +02:00
HennesHajduk 84bdebeb8c Changed advection. For now only constant velocity fields are supported. New test case in swe. Some TODOs left. 2020-04-23 16:09:25 +02:00
HennesHajduk 8448b32bb1 Changed order of parameters and orientation of BdrDofs for triangles. 2020-04-23 15:56:41 +02:00
HennesHajduk 5bf4712efd wip, updated test.sh 2020-04-23 15:28:10 +02:00
HennesHajduk 1d571c04a8 split integration weight from BdrTerms, WIP on ADF. HO volume fluxes ready. 2020-04-17 11:50:19 +02:00
HennesHajduk 4aec552eeb merge master 2020-04-14 13:33:55 +02:00
HennesHajduk a9c9808b49 wip on ADFs: galerkin and low order method can be reccovered properly. TODO all the DG flux terms and ADFs gi 2020-04-10 12:10:32 +02:00
HennesHajduk 0aff563810 revert to not overriding routines in fe_evol classes. 2020-04-10 10:17:57 +02:00
HennesHajduk a3ce5422d9 wip on anti-diffusive fluxes 2020-04-10 09:58:15 +02:00
HennesHajduk 2f3010f2f0 wip on mcl, optimized problem dependent fluxes, mass error computed in terms of first unknown. 2020-04-09 14:42:58 +02:00
HennesHajduk b4dd6b5997 Low order IDP for MCL works fine. Advection with non-const velocity doesn't work for now. Reorganized fe_evol stuff. New scripts. WIP 2020-04-03 19:02:47 +02:00
HennesHajduk a739bcd2f8 . 2020-04-02 18:29:30 +02:00
HennesHajduk ffbe7710b9 style. 2020-04-02 18:27:32 +02:00
HennesHajduk 22a9fa0892 wip on MCL low order works mostly. change in valuerange for glvis. 2020-04-02 18:26:27 +02:00
HennesHajduk 45ca17f09c Changes in advection 2020-04-02 17:47:35 +02:00
HennesHajduk 3014937c08 NodalQuadRule option for face integrals 2020-04-02 17:42:41 +02:00
HennesHajduk c29c742a29 restructured and extendede (p)dofs by subcellcross 2020-04-02 17:41:34 +02:00
HennesHajduk 2e0d1d89bc wip, low order method works fine in some cases, still some problems. removed some meshes, new config scripts started. 2020-04-02 17:19:38 +02:00
Hennes Hajduk c35ad8f18a wip 2020-03-30 11:35:59 +02:00
HennesHajduk 2d289a1a0a wip, switch for nodal eval in advection. todo: fix rusanov dij for general problems. 2020-03-29 15:04:23 +02:00
HennesHajduk 53634954d6 sub2ind for triangles. other than that MCL-LO method seems to work for simple 1d advection. WIP 2020-03-27 18:11:30 +01:00
HennesHajduk b880107442 wip on mcl 2020-03-25 19:09:55 +01:00
HennesHajduk a25fbaa530 Renaming, restructuring, MCL introduced. 2020-03-25 13:34:29 +01:00
HennesHajduk 17c653afae fe_evol directory 2020-03-25 11:43:20 +01:00
HennesHajduk 3567ff10af removed variable scheme 2020-03-25 10:49:34 +01:00
HennesHajduk f2b1c68fd3 header 2020-03-24 18:42:55 +01:00
HennesHajduk a996e039a0 mass error check for sum of variables. 2020-03-24 18:13:11 +01:00
HennesHajduk c2f300a13b fixed lumpedMassMatrix 2020-03-24 18:09:07 +01:00
HennesHajduk a63c2adeac Mostly done with reorganizing. Some TODOs left and moving stuff to derived classes from FE_Evolution constructor is necessary 2020-03-24 17:56:10 +01:00
HennesHajduk c14d057b33 Initial working restructured code 2020-03-24 16:52:48 +01:00
HennesHajduk 268dabe5b3 reorganized evolution schemes to separete classes. 2020-03-24 15:43:30 +01:00
HennesHajduk 89adf31fa9 Only restructuring. 2020-03-23 10:17:18 +01:00
Hennes Hajduk 1818159e6e WIP 2020-03-20 18:21:35 +01:00
Hennes Hajduk 39c4b2c6eb minor, wip, 2 new euler test cases (don't work yet) 2020-03-20 18:02:42 +01:00
Hennes Hajduk 26f28aef94 Reorganized directory 2020-03-20 16:59:34 +01:00
Hennes Hajduk 14ff697e6d Restructured some hyperbolic systems, new grids, minor, wip. 2020-03-20 16:48:23 +01:00
Hennes Hajduk 0024f03b36 bdr ids as supposed to again 2020-03-20 10:37:32 +01:00
Hennes Hajduk 7cf631f2ae minor fix plus stlye. 2020-03-20 10:35:37 +01:00
Hennes Hajduk bf6660abe7 valuerange 2020-03-20 10:27:55 +01:00
HennesHajduk aab7cbd0ba preliminary [0,1] scaling. TODO custom for example and problem. 2020-03-19 20:15:18 +01:00
Hennes Hajduk 5e04c9e759 wip 2020-03-19 17:55:12 +01:00
Hennes Hajduk 78deadd0b2 using bdr attributes in DofInfo class 2020-03-19 09:50:04 +01:00
Hennes Hajduk c88d99a660 wip, b.c 2020-03-18 19:33:10 +01:00
Hennes Hajduk ef5e133a06 Merge branch 'master' into hypsys-dev 2020-03-18 17:07:42 +01:00
Hennes Hajduk 97e2e04ef1 b.c. wip 2020-03-18 16:59:16 +01:00
Hennes Hajduk 1c87d3aec9 WIP on bdr cond. new Euler test case 2020-03-17 18:43:14 +01:00
Hennes Hajduk 5944bc1e98 Reorganized (P)FE_Evolution, plus minor. 2020-03-16 11:48:02 +01:00
Hennes Hajduk a92b985363 some todos, minor, apps 2020-03-12 18:36:47 +01:00
Hennes Hajduk a71d9f4aa2 removed inflow from HyperbolicSystem class. 2020-03-12 18:06:55 +01:00
Hennes Hajduk 438f5cd0f1 WIP, glvis window title, minor output bug fixed 2020-03-12 17:34:59 +01:00
Hennes Hajduk ccee9d48ba Bugfix 2020-03-12 12:07:40 +01:00
Hennes Hajduk f7d2aad9dd makefile 2020-03-11 16:15:09 +01:00
Hennes Hajduk 420af6dacd valgrind mpi 2020-03-06 18:13:06 +01:00
Hennes Hajduk 0e05495bad wip /parallel valgrind debug 2020-03-06 10:58:17 +01:00
Hennes Hajduk d70fe9904e Correct bdr cond projections. 2020-03-06 10:21:14 +01:00
Hennes Hajduk 2591ff1f61 valgrind check mpi - wip 2020-03-05 11:26:16 +01:00
Hennes Hajduk 77407972c0 minor 2020-03-05 10:47:24 +01:00
Hennes Hajduk 8e3dda40eb fixed destructor in HyperbolicSystem. 2020-03-04 11:05:43 +01:00
Hennes Hajduk fcc0bcbd4c euler 2020-03-03 11:45:11 +01:00
HennesHajduk c60edb07f4 wip 2020-02-21 15:20:26 +01:00
HennesHajduk 6cdf650c44 renamed hypsys.hpp + minor 2020-02-21 12:35:22 +01:00
HennesHajduk 85651b4737 bugfix 2020-02-21 12:05:29 +01:00
HennesHajduk 055d9f1052 minor 2020-02-21 11:54:02 +01:00
HennesHajduk 7b92942e96 minor, bugfix 2020-02-19 18:06:44 +01:00
HennesHajduk 679739b1e3 KPP problem 2020-02-18 18:00:06 +01:00
HennesHajduk 7abd2a94e8 WriteErrors as Function of hypsys, minor, changes required in template 2020-02-18 17:30:49 +01:00
HennesHajduk 1f119edde1 style 2020-02-18 17:11:55 +01:00
HennesHajduk ad86262437 Burgers implemneted and working. Inflow is now time-dependent and member of fe_evol, rather than of hyp. Some TODOs remain at this stage. 2020-02-18 17:09:19 +01:00
Hennes Hajduk 07497cae07 minor, valgrind issue in advection. 2020-02-14 17:25:14 +01:00
Hennes Hajduk c617b3afd4 advection and swe work in serial and parallel. 2020-02-14 14:46:11 +01:00
Hennes Hajduk bc27a94112 WIP: only problem is now solving systems in parallel due to wrong NbrDof indexing. 2020-02-12 17:51:37 +01:00
Hennes Hajduk 460492012e WIP, changed swe test case 2020-02-12 17:46:48 +01:00
Hennes Hajduk bc258e1d94 Manuel's H1 codes for monolithic convex limiting 2020-02-12 17:42:34 +01:00
Hennes Hajduk e0b0472bf2 style 2020-02-10 18:11:05 +01:00
Hennes Hajduk 71855ba554 SWE and advection now using same fe_evolution. 2020-02-10 18:10:17 +01:00
Hennes Hajduk 229fe92b41 wip 2020-02-10 16:03:24 +01:00
Hennes Hajduk 2b8cf51e09 wip, swe and advection work (in serial) 2020-02-10 15:20:18 +01:00
Hennes Hajduk bfffa918f7 wip, parallel works again for advection. 2020-02-07 16:20:37 +01:00
Hennes Hajduk a40bd2f790 Merge branch 'master' into hypsys-dev
updating my branch.
2020-02-07 15:49:25 +01:00
Hennes Hajduk b2382119da merging systems with advection - wip 2020-02-06 17:35:41 +01:00
Hennes Hajduk 7995844fb9 wip 2020-02-06 17:21:00 +01:00
Hennes Hajduk 5225e2dea3 wip 2020-02-06 09:07:51 +01:00
Hennes Hajduk 0ba34e52e3 wip 2020-02-05 09:18:12 +01:00
Hennes Hajduk baaddcf782 tic, toc, astyle 2020-02-04 09:18:21 +01:00
HennesHajduk ab2251197f minor 2020-01-31 17:05:17 +01:00
HennesHajduk 3f9dc61322 make style 2020-01-31 16:36:32 +01:00
Hennes Hajduk 421f43f6ec makefile, Lax-Friedrichs-type flux plus minor. 2020-01-31 16:20:14 +01:00
Hennes Hajduk 101cb10b18 advection in serial and parallel. 2020-01-30 19:51:49 +01:00
Hennes Hajduk 265aa483ca new serial/parallel structure 2020-01-28 18:01:21 +01:00
Hennes Hajduk d685787c50 Merge branch 'master' into hypsys-dev
occasional merge.
2020-01-27 17:16:53 +01:00
Hennes Hajduk 0741c02a38 minor 2020-01-27 17:10:03 +01:00
Hennes Hajduk eb3c078e94 wip merge with parallel 2020-01-21 14:36:09 +01:00
Hennes Hajduk 50c56fdc83 merge with parallel 2020-01-21 13:50:02 +01:00
Hennes Hajduk 35331da9c9 Minor. 2020-01-16 18:48:56 +01:00
Hennes Hajduk 3fc885ed73 wip, minor fixes in serial. 2020-01-16 15:04:57 +01:00
Hennes Hajduk d09d927b86 started work on parallel. 2020-01-14 18:00:32 +01:00
Hennes Hajduk 32b67c327c serial code works for advection. 2020-01-14 17:02:56 +01:00
Hennes Hajduk 39827e802f infrastructure for grid convergence studies. 2020-01-14 10:41:42 +01:00
Hennes Hajduk cac649144f WIP 2020-01-13 17:00:02 +01:00
Hennes Hajduk 7903b11b9b Memory issues 2020-01-13 11:54:42 +01:00
Hennes Hajduk 8d17794793 WIP, advection equation is working. 2020-01-10 17:48:07 +01:00
Hennes Hajduk 175c47d8ff wip 2020-01-07 19:00:22 +01:00
Hennes Hajduk f3bdd37ecf wip 2020-01-06 17:37:53 +01:00
Hennes Hajduk 5e943f7998 added mesh. 2019-12-17 15:44:32 +01:00
HennesHajduk 43555a801d Initial commit for hypsys miniapp. 2019-12-01 20:38:01 +01:00
104 changed files with 31159 additions and 5 deletions
+14
View File
@@ -163,6 +163,20 @@ miniapps/electromagnetics/Tesla-AMR*
miniapps/electromagnetics/Maxwell-Parallel*
miniapps/electromagnetics/Joule_*
miniapps/hypsys/build
miniapps/hypsys/errors.txt
miniapps/hypsys/grid*
miniapps/hypsys/hypsys
miniapps/hypsys/initial*
miniapps/hypsys/output
miniapps/hypsys/phypsys
miniapps/hypsys/pressure*
miniapps/hypsys/results
miniapps/hypsys/scripts/gridfunc-scatter
miniapps/hypsys/ultimate*
miniapps/hypsys/velocity*
miniapps/hypsys/various
miniapps/meshing/mobius-strip
miniapps/meshing/klein-bottle
miniapps/meshing/toroid
+8 -1
View File
@@ -254,7 +254,7 @@ int main(int argc, char *argv[])
// 5. Define the discontinuous DG finite element space of the given
// polynomial order on the refined mesh.
DG_FECollection fec(order, dim, BasisType::GaussLobatto);
DG_FECollection fec(order, dim, BasisType::Positive);
FiniteElementSpace fes(&mesh, &fec);
cout << "Number of unknowns: " << fes.GetVSize() << endl;
@@ -378,6 +378,10 @@ int main(int argc, char *argv[])
// iterations, ti, with a time-step dt).
FE_Evolution adv(m, k, b);
Vector masses(u.Size());
m.SpMat().Mult(u, masses);
double mass = masses.Sum();
double t = 0.0;
adv.SetTime(t);
ode_solver->Init(adv);
@@ -424,6 +428,9 @@ int main(int argc, char *argv[])
u.Save(osol);
}
m.SpMat().Mult(u, masses);
cout << "Mass difference:" << abs(mass - masses.Sum()) << endl;
// 10. Free the used memory.
delete ode_solver;
delete pd;
+2 -2
View File
@@ -2984,7 +2984,7 @@ double GridFunction::ComputeLpError(const double p, Coefficient &exsol,
}
else
{
int intorder = 2*fe->GetOrder() + 3; // <----------
int intorder = 2*fe->GetOrder() + 1; // <----------
ir = &(IntRules.Get(fe->GetGeomType(), intorder));
}
GetValues(i, *ir, vals);
@@ -3117,7 +3117,7 @@ double GridFunction::ComputeLpError(const double p, VectorCoefficient &exsol,
}
else
{
int intorder = 2*fe->GetOrder() + 3; // <----------
int intorder = 2*fe->GetOrder() + 1; // <----------
ir = &(IntRules.Get(fe->GetGeomType(), intorder));
}
T = fes->GetElementTransformation(i);
+371
View File
@@ -0,0 +1,371 @@
#include "advection.hpp"
Configuration ConfigAdv;
void AnalyticalSolutionAdv(const Vector &x, double t, Vector &u);
void InitialConditionAdv(const Vector &x, Vector &u);
void InflowFunctionAdv(const Vector &x, double t, Vector &u);
void VelocityFunctionAdv(const Vector &x, Vector &v);
Advection::Advection(FiniteElementSpace *fes_, BlockVector &u_block,
Configuration &config_, bool NodalQuadRule)
: HyperbolicSystem(fes_, u_block, 1, config_,
VectorFunctionCoefficient (1, InflowFunctionAdv))
{
DiscreteUpwinding = true;
ConfigAdv = config_;
VectorFunctionCoefficient ic(NumEq, InitialConditionAdv);
switch (ConfigAdv.ConfigNum)
{
case 0:
{
ProblemName = "Advection - Smooth Circular Convection";
glvis_scale = "on";
SolutionKnown = true;
SteadyState = true;
TimeDepBC = false;
ProjType = 0;
L2_Projection(ic, u0);
break;
}
case 1:
{
ProblemName = "Advection - Solid Body Rotation";
glvis_scale = "on";
SolutionKnown = true;
SteadyState = false;
TimeDepBC = false;
ProjType = 1;
u0.ProjectCoefficient(ic);
break;
}
case 2:
{
ProblemName = "Advection - Step function";
glvis_scale = "on";
SolutionKnown = true;
SteadyState = false;
TimeDepBC = false;
ProjType = 1;
u0.ProjectCoefficient(ic);
break;
}
case 3:
{
ProblemName = "Advection - Smooth profile";
glvis_scale = "on";
SolutionKnown = true;
SteadyState = false;
TimeDepBC = false;
ProjType = 0;
L2_Projection(ic, u0);;
break;
}
case 4:
{
ProblemName = "Advection - Discontinuous and Smooth profile";
glvis_scale = "on";
SolutionKnown = true;
SteadyState = false;
TimeDepBC = false;
ProjType = 1;
u0.ProjectCoefficient(ic);
break;
}
case 5:
{
ProblemName = "Advection - C1 curve";
glvis_scale = "on";
SolutionKnown = true;
SteadyState = false;
TimeDepBC = false;
ProjType = 1;
u0.ProjectCoefficient(ic);
break;
}
default:
MFEM_ABORT("No such test case implemented.");
}
// The following computes and stores all necessary evaluations of the time-independent velocity.
Mesh *mesh = fes->GetMesh();
DofInfo dofs(fes);
const int ne = fes->GetNE();
const IntegrationRule *IntRuleElem = GetElementIntegrationRule(fes);
const IntegrationRule *IntRuleFace = GetFaceIntegrationRule(fes);
const IntegrationRule *nodes = GetElementIntegrationRule(fes, true);
const int nqe = IntRuleElem->GetNPoints();
nqf = IntRuleFace->GetNPoints();
Vector vec, vval;
VelocityVector.SetSize(dim);
DenseMatrix VelEval, mat(dim, nqe);
VelElem.SetSize(dim, nqe, ne);
VelFace.SetSize(dim, dofs.NumBdrs, ne*nqf);
VelNode.SetSize(dim, nd, ne);
VectorFunctionCoefficient velocity(dim, VelocityFunctionAdv);
Array<int> bdrs, orientation;
Array<IntegrationPoint> eip(nqf*dofs.NumBdrs);
if (dim==1) { mesh->GetElementVertices(0, bdrs); }
else if (dim==2) { mesh->GetElementEdges(0, bdrs, orientation); }
else if (dim==3) { mesh->GetElementFaces(0, bdrs, orientation); }
for (int i = 0; i < dofs.NumBdrs; i++)
{
FaceElementTransformations *help
= mesh->GetFaceElementTransformations(bdrs[i]);
if (help->Elem1No != 0)
{
// NOTE: If this error ever occurs, use neighbor element to
// obtain the correct quadrature points and weight.
MFEM_ABORT("First element has inward pointing normal.");
}
for (int k = 0; k < nqf; k++)
{
const IntegrationPoint &ip = IntRuleFace->IntPoint(k);
help->Loc1.Transform(ip, eip[i*nqf + k]);
}
}
for (int e = 0; e < ne; e++)
{
ElementTransformation *eltrans = fes->GetElementTransformation(e);
velocity.Eval(VelEval, *eltrans, *IntRuleElem);
for (int k = 0; k < nqe; k++)
{
VelEval.GetColumnReference(k, vec);
mat.SetCol(k, vec);
}
VelElem(e) = mat;
for (int i = 0; i < nd; i++)
{
const IntegrationPoint ip = nodes->IntPoint(i);
velocity.Eval(vec, *eltrans, ip);
VelNode(e).SetCol(i, vec);
}
if (dim==1) { mesh->GetElementVertices(e, bdrs); }
else if (dim==2) { mesh->GetElementEdges(e, bdrs, orientation); }
else if (dim==3) { mesh->GetElementFaces(e, bdrs, orientation); }
for (int i = 0; i < dofs.NumBdrs; i++)
{
FaceElementTransformations *facetrans
= mesh->GetFaceElementTransformations(bdrs[i]);
for (int k = 0; k < nqf; k++)
{
if (facetrans->Elem1No != e)
{
velocity.Eval(vval, *facetrans->Elem2, eip[i * nqf + k]);
}
else
{
velocity.Eval(vval, *facetrans->Elem1, eip[i * nqf + k]);
}
for (int l = 0; l < dim; l++)
{
VelFace(l, i, e * nqf + k) = vval(l);
}
}
}
}
}
void Advection::EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
int e, int k, int i) const
{
Vector x(dim), v(dim);
VelocityFunctionAdv(x, v);
v *= u(0);
FluxEval.SetRow(0, v);
if (i == -1) // Element terms
{
VelocityVector = VelElem(e).GetColumn(k);
VelocityVector *= u(0);
FluxEval.SetRow(0, VelocityVector);
}
else
{
VelocityVector = VelFace(e*nqf+k).GetColumn(i);
VelocityVector *= u(0);
FluxEval.SetRow(0, VelocityVector);
}
}
double Advection::GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
int i) const
{
if (i == -1) // Element terms
{
VelocityVector = VelElem(e).GetColumn(k);
}
else
{
VelocityVector = VelFace(e*nqf+k).GetColumn(i);
}
return abs(VelocityVector * n);
}
void Advection::ComputeErrors(Array<double> &errors, const GridFunction &u,
double DomainSize, double t) const
{
errors.SetSize(3);
VectorFunctionCoefficient uAnalytic(NumEq, AnalyticalSolutionAdv);
uAnalytic.SetTime(t);
errors[0] = u.ComputeLpError(1., uAnalytic) / DomainSize;
errors[1] = u.ComputeLpError(2., uAnalytic) / DomainSize;
errors[2] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic);
}
void VelocityFunctionAdv(const Vector &x, Vector &v)
{
const int dim = x.Size();
Vector X(dim);
double s = 1.0;
for (int i = 0; i < dim; i++)
{
switch (ConfigAdv.ConfigNum)
{
case 0:
case 1:
case 4:
case 5: // Map to the reference domain [0,1]^d.
{
X(i) = (x(i) - ConfigAdv.bbMin(i)) / (ConfigAdv.bbMax(i) - ConfigAdv.bbMin(i));
s *= ConfigAdv.bbMax(i) - ConfigAdv.bbMin(i);
break;
}
case 2:
case 3: // Map to the reference domain [-1,1]^d.
{
double center = 0.5 * (ConfigAdv.bbMin(i) + ConfigAdv.bbMax(i));
X(i) = 2. * (x(i) - center) / (ConfigAdv.bbMax(i) - ConfigAdv.bbMin(i));
s *= ConfigAdv.bbMax(i) - ConfigAdv.bbMin(i);
break;
}
}
}
// Scale to be normed to a full revolution.
s = pow(s, 1./dim);
switch (ConfigAdv.ConfigNum)
{
case 0: // Rotation around corner.
{
switch (dim)
{
case 1: v(0) = s; break;
case 2: s *= 2.0 * M_PI; v(0) = s*X(1); v(1) = -s*X(0); break;
case 3: s *= 2.0 * M_PI; v(0) = s*X(1); v(1) = -s*X(0); v(2) = 0.0; break;
}
break;
}
case 1: // Rotation around center.
{
switch (dim)
{
case 1: v(0) = s; break;
case 2: s *= 2.0 * M_PI; v(0) = s * (0.5-X(1)); v(1) = s*(X(0)-0.5); break;
case 3: s *= 2.0 * M_PI; v(0) = s * (0.5-X(1)); v(1) = s*(X(0)-0.5); v(2) = 0.0;
break;
}
break;
}
case 2:
case 3:
case 4:
case 5:
{
switch (dim)
{
case 1: v(0) = s; break;
case 2: v(0) = s; v(1) = -0.5*s; break;
case 3: v(0) = s; v(1) = -0.5*s; v(2) = 0.25*s; break;
}
break;
}
}
}
void AnalyticalSolutionAdv(const Vector &x, double t, Vector &u)
{
const int dim = x.Size();
Vector X(dim);
for (int i = 0; i < dim; i++)
{
switch (ConfigAdv.ConfigNum)
{
case 0:
case 1:
case 4:
case 5: // Map to the reference domain [0,1]^d.
{
X(i) = (x(i) - ConfigAdv.bbMin(i)) / (ConfigAdv.bbMax(i) - ConfigAdv.bbMin(i));
break;
}
case 2:
case 3: // Map to the reference domain [-1,1]^d.
{
double center = 0.5 * (ConfigAdv.bbMin(i) + ConfigAdv.bbMax(i));
X(i) = 2.0 * (x(i) - center) / (ConfigAdv.bbMax(i) - ConfigAdv.bbMin(i));
break;
}
}
}
double r = X.Norml2();
switch (ConfigAdv.ConfigNum)
{
case 0:
{
double a = 0.5, b = 0.03, c = 0.1;
u(0) = 0.25 * (1. + tanh((r+c-a)/b)) * (1. - tanh((r-c-a)/b));
break;
}
case 1:
{
if (dim==1) { MFEM_ABORT("Test case not implemented in 1D."); }
double s = 0.15;
double cone = sqrt(pow(X(0)-0.5, 2.) + pow(X(1)-0.25, 2.));
double hump = sqrt(pow(X(0)-0.25, 2.) + pow(X(1)-0.5, 2.));
u(0) = (1. - cone / s) * (cone <= s) +
0.25 * (1. + cos(M_PI*hump / s)) * (hump <= s) +
( ( sqrt(pow(X(0)-0.5, 2.) + pow(X(1)-0.75, 2.)) <= s ) &&
( abs(X(0)-0.5) >= 0.025 || (X(1) >= 0.85) ) ? 1. : 0. );
break;
}
case 2: { u(0) = r < 0.2 ? 1. : 0.; break; }
case 3: { u(0) = exp(-25.0 * r*r); break; }
case 4: { u(0) = abs(r - 0.3) < 0.1 ? 1. : ( (abs(r-0.7) < 0.2) ? (exp(10.)*exp(-1./(r-0.5))*exp(1./(r-0.9))) : 0. ); break; }
case 5: { u(0) = abs(r-0.25) <= 0.15 ? 0.5*(1.+cos(M_PI*(r-0.25)/0.15)) : 0.; break; }
}
}
void InitialConditionAdv(const Vector &x, Vector &u)
{
AnalyticalSolutionAdv(x, 0.0, u);
}
void InflowFunctionAdv(const Vector &x, double t, Vector &u)
{
AnalyticalSolutionAdv(x, t, u);
}
+26
View File
@@ -0,0 +1,26 @@
#ifndef HYPSYS_ADVECTION
#define HYPSYS_ADVECTION
#include "hyperbolic_system.hpp"
#include "../lib/dofs.hpp"
class Advection : public HyperbolicSystem
{
public:
explicit Advection(FiniteElementSpace *fes_, BlockVector &u_block,
Configuration &config_, bool NodalQuadRule);
~Advection() { };
virtual void EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
int e, int k, int i = -1) const;
virtual double GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
int i) const;
virtual void ComputeErrors(Array<double> &errors, const GridFunction &u,
double DomainSize, double t) const override;
int nqf;
DenseTensor VelElem, VelFace;
mutable Vector VelocityVector;
};
#endif
+118
View File
@@ -0,0 +1,118 @@
#include "buckley_leverett.hpp"
Configuration ConfigBL;
double BLConst;
void InitialConditionBuckleyLeverett(const Vector &x, Vector &u);
void InflowFunctionBuckleyLeverett(const Vector &x, double t, Vector &u);
BuckleyLeverett::BuckleyLeverett(FiniteElementSpace *fes_, BlockVector &u_block,
Configuration &config_)
: HyperbolicSystem(fes_, u_block, 1, config_,
VectorFunctionCoefficient(1, InflowFunctionBuckleyLeverett))
{
ConfigBL = config_;
VectorFunctionCoefficient ic(NumEq, InitialConditionBuckleyLeverett);
switch (ConfigBL.ConfigNum)
{
case 1:
{
ProblemName = "Buckley-Leverett - 1D";
glvis_scale = "on";
BLConst = 0.5;
SolutionKnown = false;
SteadyState = false;
TimeDepBC = false;
ProjType = 0;
L2_Projection(ic, u0);
break;
}
case 2:
{
ProblemName = "Buckley-Leverett - 2D";
glvis_scale = "on";
BLConst = 1.0;
SolutionKnown = false;
SteadyState = false;
TimeDepBC = false;
ProjType = 1;
u0.ProjectCoefficient(ic);
break;
}
default:
MFEM_ABORT("No such test case implemented.");
}
}
void BuckleyLeverett::EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
int e, int k, int i) const
{
double coef = u(0)*u(0) / (u(0)*u(0) + BLConst * (1.0-u(0))*(1.0-u(0)));
FluxEval(0,0) = coef;
if (dim > 1)
{
FluxEval(0,1) = coef * (1.0 - 5.0 * (1.0-u(0))*(1.0-u(0)));
}
if (dim > 2) { MFEM_ABORT("Not implemented."); }
}
double BuckleyLeverett::GetWaveSpeed(const Vector &u, const Vector n, int e,
int k,
int i) const
{
if (dim == 1)
{
return abs( 2.0 * BLConst * u(0) * (1.0-u(0)) / pow(u(0)*u(0) + BLConst *
(1.0-u(0))*(1.0-u(0)), 2.0) );
}
else if (dim == 2)
{
return 3.4;
}
else { MFEM_ABORT("Not implemented."); }
}
void InitialConditionBuckleyLeverett(const Vector &x, Vector &u)
{
const int dim = x.Size();
// Map to the reference domain [-1,1]^d.
Vector X(dim);
for (int i = 0; i < dim; i++)
{
double center = 0.5 * (ConfigBL.bbMin(i) + ConfigBL.bbMax(i));
X(i) = 2. * (x(i) - center) / (ConfigBL.bbMax(i) - ConfigBL.bbMin(i));
}
switch (ConfigBL.ConfigNum)
{
case 1:
{
u(0) = X(0) < 0.0 ? -3.0 : 3.0;
break;
}
case 2:
{
u(0) = X.Norml2()*X.Norml2() < 2.0 / 9.0 ? 1.0 : 0.0;
break;
}
}
}
void InflowFunctionBuckleyLeverett(const Vector &x, double t, Vector &u)
{
switch (ConfigBL.ConfigNum)
{
case 1:
{
u(0) = x(0) < 0.0 ? 3.0 : -3.0;
break;
}
case 2:
{
u(0) = 0.0;
break;
}
}
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef HYPSYS_BUCKLEYLEVERETT
#define HYPSYS_BUCKLEYLEVERETT
#include "hyperbolic_system.hpp"
class BuckleyLeverett : public HyperbolicSystem
{
public:
explicit BuckleyLeverett(FiniteElementSpace *fes_, BlockVector &u_block,
Configuration &config_);
~BuckleyLeverett() { };
virtual void EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
int e, int k, int i = -1) const;
virtual double GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
int i) const;
};
#endif
+175
View File
@@ -0,0 +1,175 @@
#include "burgers.hpp"
Configuration ConfigBurgers;
void AnalyticalSolutionBurgers(const Vector &x, double t, Vector &u);
void InitialConditionBurgers(const Vector &x, Vector &u);
void InflowFunctionBurgers(const Vector &x, double t, Vector &u);
Burgers::Burgers(FiniteElementSpace *fes_, BlockVector &u_block,
Configuration &config_)
: HyperbolicSystem(fes_, u_block, 1, config_,
VectorFunctionCoefficient (1, InflowFunctionBurgers))
{
ConfigBurgers = config_;
VectorFunctionCoefficient ic(NumEq, InitialConditionBurgers);
switch (ConfigBurgers.ConfigNum)
{
case 0:
{
ProblemName = "Burgers Equation - 1D";
glvis_scale = "on";
SolutionKnown = true;
SteadyState = false;
TimeDepBC = false;
ProjType = 1;
L2_Projection(ic, u0);
break;
}
case 1:
{
ProblemName = "Burgers Equation - Riemann Problem";
glvis_scale = "on";
SolutionKnown = true;
SteadyState = false;
TimeDepBC = true;
ProjType = 1;
L2_Projection(ic, u0);
break;
}
case 2:
{
ProblemName = "Burgers Equation - Steady State";
glvis_scale = "on";
SolutionKnown = true;
SteadyState = true;
TimeDepBC = false;
ProjType = 1;
u0.ProjectCoefficient(ic);
break;
}
default:
MFEM_ABORT("No such test case implemented.");
}
}
void Burgers::EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
int e, int k, int i) const
{
FluxEval = 0.5 * u(0) * u(0);
}
double Burgers::GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
int i) const
{
return abs(u(0) * double(n.Size()));
}
void Burgers::ComputeErrors(Array<double> &errors, const GridFunction &u,
double DomainSize, double t) const
{
errors.SetSize(3);
VectorFunctionCoefficient uAnalytic(NumEq, AnalyticalSolutionBurgers);
uAnalytic.SetTime(t);
errors[0] = u.ComputeLpError(1., uAnalytic) / DomainSize;
errors[1] = u.ComputeLpError(2., uAnalytic) / DomainSize;
errors[2] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic);
}
void AnalyticalSolutionBurgers(const Vector &x, double t, Vector &u)
{
const int dim = x.Size();
Vector X(dim);
// Map to the reference domain [0,1]^d.
for (int i = 0; i < dim; i++)
{
double factor = 1.0 / ( ConfigBurgers.bbMax(i) - ConfigBurgers.bbMin(i));
X(i) = factor * (x(i) - ConfigBurgers.bbMin(i));
t *= pow(factor, 1.0 / (double(dim)));
}
switch (ConfigBurgers.ConfigNum)
{
case 0:
{
if (dim != 1) { MFEM_ABORT("Test case only implemented in 1D."); }
double un = sin(2.0*M_PI*X(0));
double fn, fpn;
double tol = 1.E-15;
double error = 1.0;
int iter = 0, maxiter = 100;
while (error > tol)
{
// Do not trust this solution at a time later than t = 0.1.
if (iter == maxiter) { break; }
fn = sin(2.0*M_PI*(X(0)-un*t))-un;
fpn = -2.0*M_PI*t*cos(2.*M_PI*(X(0)-un*t))-1.0;
un -= fn/fpn;
error = abs(sin(2.*M_PI*(X(0)-un*t))-un);
iter++;
}
u(0) = un;
break;
}
case 1:
{
if (dim != 2) { MFEM_ABORT("Test case only implemented in 2D."); }
if (X(0) <= 0.5 - 0.6 * t)
{
u(0) = X(1) >= 0.5 + 0.15 * t ? -0.2 : 0.5;
}
else if (X(0) < 0.5 - 0.25 * t)
{
u(0) = X(1) > -8. / 7. * X(0) + 15. / 14. - 15. / 28. * t ? -1. : 0.5;
}
else if (X(0) < 0.5 + 0.5 * t)
{
u(0) = X(1) > X(0) / 6. + 5. / 12. - 5. / 24. * t ? -1. : 0.5;
}
else if (X(0) < 0.5 + 0.8 * t)
{
u(0) = X(1) > X(0) - 5. / (18. * t) * (X(0) + t - 0.5)
* (X(0) + t - 0.5) ? -1. : (2. * X(0) - 1.) / (2 * t);
}
else
{
u(0) = X(1) >= 0.5 - 0.1 * t ? -1 : 0.8;
}
break;
}
case 2:
{
u(0) = X.Sum() < 0.5 ? 1.0 : -1.0;
break;
}
}
}
void InitialConditionBurgers(const Vector &x,Vector &u)
{
switch (ConfigBurgers.ConfigNum)
{
case 0:
case 1:
case 2: { AnalyticalSolutionBurgers(x, 0.0, u); break; }
}
}
void InflowFunctionBurgers(const Vector &x, double t, Vector &u)
{
switch (ConfigBurgers.ConfigNum)
{
case 0:
case 1:
case 2: { AnalyticalSolutionBurgers(x, t, u); break; }
}
}
+21
View File
@@ -0,0 +1,21 @@
#ifndef HYPSYS_BURGERS
#define HYPSYS_BURGERS
#include "hyperbolic_system.hpp"
class Burgers : public HyperbolicSystem
{
public:
explicit Burgers(FiniteElementSpace *fes_, BlockVector &u_block,
Configuration &config_);
~Burgers() { };
virtual void EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
int e, int k, int i = -1) const;
virtual double GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
int i) const;
virtual void ComputeErrors(Array<double> &errors, const GridFunction &u,
double DomainSize, double t) const override;
};
#endif
+647
View File
@@ -0,0 +1,647 @@
#include "euler.hpp"
Configuration ConfigEuler;
double SpHeatRatio;
void AnalyticalSolutionEuler(const Vector &x, double t, Vector &u);
void InitialConditionEuler(const Vector &x, Vector &u);
void InflowFunctionEuler(const Vector &x, double t, Vector &u);
Euler::Euler(FiniteElementSpace *fes_, BlockVector &u_block,
Configuration &config_)
: HyperbolicSystem(fes_, u_block, fes_->GetMesh()->Dimension() + 2, config_,
VectorFunctionCoefficient(fes_->GetMesh()->Dimension() + 2,
InflowFunctionEuler))
{
ConfigEuler = config_;
VectorFunctionCoefficient ic(NumEq, InitialConditionEuler);
switch (ConfigEuler.ConfigNum)
{
case 0:
{
// Periodic meshes must be used for this problem.
ProblemName = "Euler Equations of Gas dynamics - Smooth Vortex";
glvis_scale = "on";
SpHeatRatio = 1.4;
SolutionKnown = true;
SteadyState = false;
TimeDepBC = false;
ProjType = 0;
L2_Projection(ic, u0);
break;
}
case 1:
{
ProblemName = "Euler Equations of Gas dynamics - SOD Shock Tube";
glvis_scale = "on";
SpHeatRatio = 1.4;
SolutionKnown = false;
SteadyState = false;
TimeDepBC = false;
ProjType = 1;
L2_Projection(ic, u0);
break;
}
case 2:
{
ProblemName = "Euler Equations of Gas dynamics - Woodward Colella";
glvis_scale = "on";
SpHeatRatio = 1.4;
SolutionKnown = false;
SteadyState = false;
TimeDepBC = false;
ProjType = 1;
u0.ProjectCoefficient(ic);
break;
}
case 3:
{
ProblemName = "Euler Equations of Gas dynamics - Double Mach Reflection";
glvis_scale = "on";
SpHeatRatio = 1.4;
SolutionKnown = false;
SteadyState = false;
TimeDepBC = true;
ProjType = 1;
u0.ProjectCoefficient(ic);
break;
}
case 4:
{
ProblemName = "Euler Equations of Gas dynamics - Sedov Blast";
glvis_scale = "on";
SpHeatRatio = 5.0 / 3.0;
SolutionKnown = false;
SteadyState = false;
TimeDepBC = true;
ProjType = 1;
u0.ProjectCoefficient(ic);
break;
}
case 5:
{
ProblemName = "Euler Equations of Gas dynamics - Noh Problem";
glvis_scale = "on";
SpHeatRatio = 5.0 / 3.0;
SolutionKnown = true;
SteadyState = false;
TimeDepBC = true;
ProjType = 1;
u0.ProjectCoefficient(ic);
break;
}
case 6:
{
ProblemName = "Euler Equations of Gas dynamics - Gresho Vortex";
glvis_scale = "on";
SpHeatRatio = 1.4;
SolutionKnown = true;
SteadyState = true;
TimeDepBC = false;
ProjType = 0;
u0.ProjectCoefficient(ic);
break;
}
case 7:
{
ProblemName = "Euler Equations of Gas dynamics - Constricted Channel";
glvis_scale = "on";
SpHeatRatio = 1.4;
SolutionKnown = false;
SteadyState = true;
TimeDepBC = false;
ProjType = 0;
u0.ProjectCoefficient(ic);
break;
}
default:
MFEM_ABORT("No such test case implemented.");
}
}
double Euler::EvaluatePressure(const Vector &u) const
{
double aux = 0.0;
for (int l = 0; l < dim; l++)
{
aux += u(1+l) * u(1+l);
}
double pressure = (SpHeatRatio - 1.0) * (u(dim+1) - 0.5 * aux / u(0));
if (pressure < 0.)
{
ostringstream press_str;
press_str << pressure;
string err_msg = "Negative pressure p = ";
MFEM_ABORT(err_msg << press_str.str());
}
return pressure;
}
void Euler::EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
int e, int k, int i) const
{
double pressure = EvaluatePressure(u);
CheckAdmissibility(u);
switch (dim)
{
case 1:
{
double vx = u(1) / u(0);
FluxEval(0,0) = u(1);
FluxEval(1,0) = u(1) * vx + pressure;
FluxEval(2,0) = (u(2) + pressure) * vx;
break;
}
case 2:
{
double vx = u(1) / u(0);
double vy = u(2) / u(0);
double energy = u(3) + pressure;
FluxEval(0,0) = u(1);
FluxEval(0,1) = u(2);
FluxEval(1,0) = u(1) * vx + pressure;
FluxEval(1,1) = u(1) * vy;
FluxEval(2,0) = u(2) * vx;
FluxEval(2,1) = u(2) * vy + pressure;
FluxEval(3,0) = energy * vx;
FluxEval(3,1) = energy * vy;
break;
}
case 3:
{
double vx = u(1) / u(0);
double vy = u(2) / u(0);
double vz = u(3) / u(0);
double energy = u(4) + pressure;
FluxEval(0,0) = u(1);
FluxEval(0,1) = u(2);
FluxEval(0,2) = u(3);
FluxEval(1,0) = u(1) * vx + pressure;
FluxEval(1,1) = u(1) * vy;
FluxEval(1,2) = u(1) * vz;
FluxEval(2,0) = u(2) * vx;
FluxEval(2,1) = u(2) * vy + pressure;
FluxEval(2,2) = u(2) * vz;
FluxEval(3,0) = u(3) * vx;
FluxEval(3,1) = u(3) * vy;
FluxEval(3,2) = u(3) * vz + pressure;
FluxEval(4,0) = energy * vx;
FluxEval(4,1) = energy * vy;
FluxEval(4,2) = energy * vz;
break;
}
default:
MFEM_ABORT("Invalid space dimension.");
}
}
double Euler::GetGMS(const Vector &uL, const Vector &uR,
const Vector &normal) const
{
CheckAdmissibility(uL);
CheckAdmissibility(uR);
double pL = EvaluatePressure(uL);
double pR = EvaluatePressure(uR);
double aL = sqrt(SpHeatRatio * pL / uL(0));
double aR = sqrt(SpHeatRatio * pR / uR(0));
double vL = uL(1)/uL(0) * normal(0);
double vR = uR(1)/uR(0) * normal(0);
double p = pow( (aL+aR-0.5*(SpHeatRatio-1.)*(vR-vL)) / (aL*pow(pL,
(1.-SpHeatRatio)/(2.*SpHeatRatio)) + aR*pow(pR,
(1.-SpHeatRatio)/(2.*SpHeatRatio)) ), 2.*SpHeatRatio/(SpHeatRatio-1.) );
double lambda1 = vL - aL * sqrt( 1. + (SpHeatRatio+1.)/(2.*SpHeatRatio) * max(
0., (p-pL)/pL) );
double lambda3 = vR + aR * sqrt( 1. + (SpHeatRatio+1.)/(2.*SpHeatRatio) * max(
0., (p-pR)/pR) );
return max(abs(lambda1), abs(lambda3));
}
double Euler::GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
int i) const
{
CheckAdmissibility(u);
switch (u.Size())
{
case 3:
return abs( u(1)*n(0) / u(0) ) + sqrt(SpHeatRatio * EvaluatePressure(u) / u(0));
case 4:
return abs( (u(1)*n(0) + u(2)*n(1)) / u(0) )
+ sqrt(SpHeatRatio * EvaluatePressure(u) / u(0));
case 5:
return abs( (u(1)*n(0) + u(2)*n(1) + u(3)*n(2)) / u(0) )
+ sqrt(SpHeatRatio * EvaluatePressure(u) / u(0));
}
}
void Euler::CheckAdmissibility(const Vector &u) const
{
double RhoMin = 1.e-12;
if (u.Size() != NumEq) { MFEM_ABORT("Invalid solution vector."); }
if (u(0) < RhoMin)
{
ostringstream rho_str;
rho_str << u(0);
string err_msg = "Density too small rho = ";
MFEM_ABORT(err_msg << rho_str.str());
}
}
void Euler::SetBdrCond(const Vector &y1, Vector &y2, const Vector &normal,
int attr) const
{
switch (attr)
{
case -1: // wall boundary
{
if (dim == 1)
{
y2(0) = y1(0);
y2(1) = -y1(1);
y2(2) = y1(2);
}
else if (dim == 2)
{
double MomTimesNorm = y1(1) * normal(0) + y1(2) * normal(1);
y2(0) = y1(0);
y2(1) = y1(1) - 2. * MomTimesNorm * normal(0);
y2(2) = y1(2) - 2. * MomTimesNorm * normal(1);
y2(3) = y1(3);
}
else
{
double MomTimesNorm = y1(1) * normal(0) + y1(2) * normal(1) + y1(3) * normal(2);
y2(0) = y1(0);
y2(1) = y1(1) - 2. * MomTimesNorm * normal(0);
y2(2) = y1(2) - 2. * MomTimesNorm * normal(1);
y2(3) = y1(3) - 2. * MomTimesNorm * normal(2);
y2(4) = y1(4);
}
break;
}
case -2: // supersonic outlet
{
y2 = y1;
break;
}
case -3: // supersonic inlet
{
break;
}
// TODO subsonic in- and outlet
default:
MFEM_ABORT("Invalid boundary attribute.");
}
}
void Euler::ComputeDerivedQuantities(const GridFunction &u, GridFunction &d1,
GridFunction &d2) const
{
double density, momentum;
const IntegrationRule ir = u.FESpace()->GetFE(0)->GetNodes();
for (int e = 0; e < ne; e++)
{
for (int i = 0; i < nd; i++)
{
const IntegrationPoint &ip = ir.IntPoint(i);
density = u.GetValue(e, ip, 1);
momentum = u.GetValue(e, ip, 2);
d1(e*nd + i) = pow(momentum / density, 2.0);
if (dim > 1)
{
momentum = u.GetValue(e, ip, 3);
d1(e*nd + i) += pow(momentum / density, 2.0);
}
if (dim > 2)
{
momentum = u.GetValue(e, ip, 4);
d1(e*nd + i) += pow(momentum / density, 2.0);
}
d2(e*nd + i) = (SpHeatRatio - 1.0) * (u.GetValue(e, ip,
dim+2) - 0.5 * density * d1(e*nd + i));
d1(e*nd + i) = sqrt(d1(e*nd + i));
}
}
}
void Euler::ComputeErrors(Array<double> & errors, const GridFunction &u,
double DomainSize, double t) const
{
errors.SetSize(NumEq*3);
Vector component(dim+2);
VectorFunctionCoefficient uAnalytic(NumEq, AnalyticalSolutionEuler);
if (ConfigEuler.ConfigNum == 0) { uAnalytic.SetTime(0); }
else { uAnalytic.SetTime(t); }
component = 0.0;
component(0) = 1.0;
VectorConstantCoefficient weight1(component);
errors[0] = u.ComputeLpError(1.0, uAnalytic, NULL, &weight1) / DomainSize;
errors[1] = u.ComputeLpError(2.0, uAnalytic, NULL, &weight1) / DomainSize;
errors[2] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic,
NULL, &weight1);
component = 0.0;
component(1) = 1.0;
VectorConstantCoefficient weight2(component);
errors[3] = u.ComputeLpError(1.0, uAnalytic, NULL, &weight2) / DomainSize;
errors[4] = u.ComputeLpError(2.0, uAnalytic, NULL, &weight2) / DomainSize;
errors[5] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic,
NULL, &weight2);
component = 0.0;
component(2) = 1.0;
VectorConstantCoefficient weight3(component);
errors[6] = u.ComputeLpError(1.0, uAnalytic, NULL, &weight3) / DomainSize;
errors[7] = u.ComputeLpError(2.0, uAnalytic, NULL, &weight3) / DomainSize;
errors[8] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic,
NULL, &weight3);
if (dim > 1)
{
component = 0.0;
component(3) = 1.0;
VectorConstantCoefficient weight4(component);
errors[9] = u.ComputeLpError(1.0, uAnalytic, NULL, &weight4) / DomainSize;
errors[10] = u.ComputeLpError(2.0, uAnalytic, NULL, &weight4) / DomainSize;
errors[11] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic,
NULL, &weight4);
}
if (dim > 2)
{
component = 0.0;
component(4) = 1.0;
VectorConstantCoefficient weight5(component);
errors[12] = u.ComputeLpError(1.0, uAnalytic, NULL, &weight5) / DomainSize;
errors[13] = u.ComputeLpError(2.0, uAnalytic, NULL, &weight5) / DomainSize;
errors[14] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic,
NULL, &weight5);
}
}
void EvaluateEnergy(Vector &u, const double &pressure)
{
const int dim = u.Size() - 2;
double aux = 0.0;
for (int l = 0; l < dim; l++)
{
aux += u(1+l)*u(1+l);
}
u(dim+1) = pressure / (SpHeatRatio - 1.0) + 0.5 * aux / u(0);
}
void AnalyticalSolutionEuler(const Vector &x, double t, Vector &u)
{
const int dim = x.Size();
Vector X(dim);
for (int i = 0; i < dim; i++)
{
switch (ConfigEuler.ConfigNum)
{
case 0:
case 5:
case 6: // Map to the reference domain [-1,1]^d.
{
double center = 0.5 * (ConfigEuler.bbMin(i) + ConfigEuler.bbMax(i));
double factor = 2.0 / (ConfigEuler.bbMax(i) - ConfigEuler.bbMin(i));
X(i) = factor * (x(i) - center);
t *= pow(factor, 1.0 / (double(dim)));
break;
}
case 3: // Map to the reference domain [0,1]^d.
{
double factor = 1.0 / (ConfigEuler.bbMax(i) - ConfigEuler.bbMin(i));
X(i) = factor * (x(i) - ConfigEuler.bbMin(i));
t *= pow(factor, 1.0 / (double(dim)));
break;
}
}
}
switch (ConfigEuler.ConfigNum)
{
case 0:
{
if (dim != 2) { MFEM_ABORT("Test case works only in 2D."); }
// Map to test case specific domain [-5,5]^d.
X *= 5.0;
t *= 5.0;
double beta = 5.0;
double r = X.Norml2();
double T0 = 1.0 - (SpHeatRatio - 1.0) * beta * beta
/ (8.0 * SpHeatRatio * M_PI * M_PI) * exp(1.0 - r*r);
u(0) = pow(T0, 1.0 / (SpHeatRatio - 1.0));
u(1) = (1.0 - beta / (2.0 * M_PI) * exp(0.5 * (1.0 - r*r)) * X(1)) * u(0);
u(2) = (1.0 + beta / (2.0 * M_PI) * exp(0.5 * (1.0 - r*r)) * X(0)) * u(0);
EvaluateEnergy(u, u(0) * T0);
break;
}
case 3:
{
if (dim != 2) { MFEM_ABORT("Test case works only in 2D."); }
// Map to test case specific domain [0,4] x [0,1].
X(0) = 4.0 * X(0);
t *= 2.0;
bool PostShock = X(0) < 1.0/6.0 + (X(1) + 20.0*t) / sqrt(3.0);
if (PostShock)
{
u(0) = 8.0;
u(1) = 66.0 * cos(M_PI / 6.0);
u(2) = -66.0 * sin(M_PI / 6.0);
EvaluateEnergy(u, 116.5);
}
else
{
u = 0.0;
u(0) = 1.4;
EvaluateEnergy(u, 1.0);
}
break;
}
case 5:
{
double r = X.Norml2();
if (r > t / 3.)
{
u(0) = 1.0 + t / r;
for (int l = 0; l < dim; l++) { u(l+1) = -X(l) / r * u(0); }
EvaluateEnergy(u, 1.0E-6);
}
else
{
u(0) = 1.0;
for (int l = 0; l < dim; l++) { u(l+1) = 0.0; }
EvaluateEnergy(u, 16.0 / 3.0);
}
break;
}
case 6:
{
if (dim != 2) { MFEM_ABORT("Test case works only in 2D."); }
double pressure = 3.0 + 4.0*log(2.0);
double r = X.Norml2();
u = 0.0;
u(0) = 1.0;
if (r < 0.2)
{
u(1) = -5.0 * X(1);
u(2) = 5.0 * X(0);
pressure = 5.0 + 12.5*r*r;
}
else if (r < 0.4)
{
u(1) = -(2.0 / r - 5.0) * X(1);
u(2) = (2.0 / r - 5.0) * X(0);
pressure = 9.0 + 4.0 * (log(r) - log(0.2)) + 12.5*r*r - 20.0*r;
}
EvaluateEnergy(u, pressure);
break;
}
default:
MFEM_ABORT("Analytical solution not known.");
}
}
void InitialConditionEuler(const Vector &x, Vector &u)
{
const int dim = x.Size();
Vector X(dim);
for (int i = 0; i < dim; i++)
{
switch (ConfigEuler.ConfigNum)
{
case 4: // Map to the reference domain [-1,1]^d.
{
double center = 0.5 * (ConfigEuler.bbMin(i) + ConfigEuler.bbMax(i));
double factor = 2.0 / (ConfigEuler.bbMax(i) - ConfigEuler.bbMin(i));
X(i) = factor * (x(i) - center);
break;
}
case 1:
case 2: // Map to the reference domain [0,1]^d.
{
double factor = 1.0 / (ConfigEuler.bbMax(i) - ConfigEuler.bbMin(i));
X(i) = factor * (x(i) - ConfigEuler.bbMin(i));
break;
}
}
}
switch (ConfigEuler.ConfigNum)
{
case 0:
case 3:
case 5:
case 6:
{
AnalyticalSolutionEuler(x, 0.0, u);
break;
}
case 1:
{
if (dim != 1) { MFEM_ABORT("Test case works only in 1D."); }
u = 0.0;
u(0) = X.Norml2() < 0.5 ? 1.0 : 0.125;
EvaluateEnergy(u, X.Norml2() < 0.5 ? 1.0 : 0.1);
break;
}
case 2:
{
if (dim != 1) { MFEM_ABORT("Test case works only in 1D."); }
u = 0.0;
u(0) = 1.0;
if (X(0) < 0.1)
{
EvaluateEnergy(u, 1000.);
}
else if (X(0) < 0.9)
{
EvaluateEnergy(u, 0.01);
}
else
{
EvaluateEnergy(u, 100.);
}
break;
}
case 4:
{
// Map to test case specific domain [-5,5]^d.
X *= 5.0;
u = 0.0;
u(0) = 1.0;
// TODO make sure that energy is essentially a delta distribution.
u(dim+1) = X.Norml2() < 1.0E-1 ? 1000.0 : 1.0E-8;
break;
}
case 7:
{
u = 0.0;
u(0) = 1.0;
u(1) = 1.0;
EvaluateEnergy(u, 0.1);
break;
}
}
}
void InflowFunctionEuler(const Vector &x, double t, Vector &u)
{
switch (ConfigEuler.ConfigNum)
{
case 0:
case 3:
case 5:
case 6:
{
AnalyticalSolutionEuler(x, t, u);
break;
}
case 7:
{
InitialConditionEuler(x, u);
break;
}
case 1:
case 2:
case 4: break; // No boundary conditions needed.
}
}
+30
View File
@@ -0,0 +1,30 @@
#ifndef HYPSYS_EULER
#define HYPSYS_EULER
#include "hyperbolic_system.hpp"
class Euler : public HyperbolicSystem
{
public:
explicit Euler(FiniteElementSpace *fes_, BlockVector &u_block,
Configuration &config_);
~Euler() { };
virtual double EvaluatePressure(const Vector &u) const;
virtual void EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
int e, int k, int i = -1) const;
virtual double GetGMS(const Vector &uL, const Vector &uR,
const Vector &normal) const override;
virtual double GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
int i) const;
virtual void CheckAdmissibility(const Vector &u) const override;
virtual void SetBdrCond(const Vector &y1, Vector &y2, const Vector &normal,
int attr) const override;
virtual void ComputeDerivedQuantities(const GridFunction &u, GridFunction &d1,
GridFunction &d2) const override;
virtual void ComputeErrors(Array<double> &errors, const GridFunction &u,
double DomainSize, double t) const override;
};
#endif
+140
View File
@@ -0,0 +1,140 @@
#ifndef HYPSYS_HYPERBOLIC_SYSTEM
#define HYPSYS_HYPERBOLIC_SYSTEM
#include "../lib/tools.hpp"
struct Configuration
{
int ConfigNum;
double tFinal;
Vector bbMin, bbMax;
};
class HyperbolicSystem
{
public:
explicit HyperbolicSystem(FiniteElementSpace *fes_, BlockVector &u_block,
int NumEq_, Configuration &config_,
VectorFunctionCoefficient BdrCond_) : fes(fes_), u0(fes_, u_block),
NumEq(NumEq_), BdrCond(BdrCond_)
{
ne = fes->GetNE();
nd = fes->GetFE(0)->GetDof();
dim = fes->GetMesh()->Dimension();
l2_fec = new L2_FECollection(fes->GetFE(0)->GetOrder(),
fes->GetMesh()->Dimension());
l2_fes = new FiniteElementSpace(fes->GetMesh(), l2_fec, NumEq,
Ordering::byNODES);
l2_proj = new GridFunction(l2_fes);
}
virtual ~HyperbolicSystem()
{
delete l2_proj;
delete l2_fes;
delete l2_fec;
}
virtual void EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
int e, int k, int i = -1) const = 0;
virtual double GetGMS(const Vector &uL, const Vector &uR,
const Vector &normal) const { } // TODO: if used "= 0"
virtual double GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
int i = -1) const = 0;
virtual void CheckAdmissibility(const Vector &u) const { };
virtual void SetBdrCond(const Vector &y1, Vector &y2, const Vector &normal,
int attr) const { };
virtual void ComputeDerivedQuantities(const GridFunction &u, GridFunction &d1,
GridFunction &d2) const { };
virtual void ComputeErrors(Array<double> &errors, const GridFunction &u,
double DomainSize, double t) const { };
virtual void WriteErrors(const Array<double> &errors) const
{
ofstream file("errors.txt", ios_base::app);
if (!file)
{
MFEM_ABORT("Error opening file.");
}
else
{
ostringstream strs;
for (int i = 0; i < errors.Size(); i++)
{
strs << errors[i] << " ";
}
strs << "\n";
string str = strs.str();
file << str;
file.close();
}
}
// L2 projection for scalar problems.
void L2_Projection(FunctionCoefficient fun, GridFunction &proj) const
{
l2_proj->ProjectCoefficient(fun);
proj.ProjectGridFunction(*l2_proj);
}
// L2 projection for systems.
void L2_Projection(VectorFunctionCoefficient fun, GridFunction &proj) const
{
l2_proj->ProjectCoefficient(fun);
proj.ProjectGridFunction(*l2_proj);
}
// Lumped L2 projection for general problems.
void LumpedL2_Projection(VectorFunctionCoefficient fun, GridFunction &proj) const
{
Vector LumpedMassMat;
Vector aux_vec(NumEq);
aux_vec = 1.0;
VectorConstantCoefficient ones(aux_vec);
BilinearForm ml(fes);
ml.AddDomainIntegrator(new LumpedIntegrator(new VectorMassIntegrator(ones)));
ml.Assemble();
ml.Finalize();
ml.SpMat().GetDiag(LumpedMassMat);
LinearForm rhs(fes);
rhs.AddDomainIntegrator(new VectorDomainLFIntegrator(fun));
rhs.Assemble();
for (int i = 0; i < LumpedMassMat.Size(); i++)
{
proj(i) = rhs.Elem(i) / LumpedMassMat(i);
}
}
int ne, nd, dim;
// 0: L2 projection,
// 1: Nodal values as GridFunction coefficients (only second order accurate).
int ProjType;
const int NumEq;
FiniteElementSpace *fes;
GridFunction u0;
// Auxiliary data needed for L2 projections
L2_FECollection *l2_fec;
FiniteElementSpace *l2_fes;
GridFunction *l2_proj;
mutable VectorFunctionCoefficient BdrCond;
string ProblemName, glvis_scale;
bool SolutionKnown;
bool SteadyState;
bool TimeDepBC;
// Currently only true for advection, due to spatially dependent flux.
bool DiscreteUpwinding = false;
DenseTensor VelNode;
};
#endif
+121
View File
@@ -0,0 +1,121 @@
#include "kpp.hpp"
Configuration ConfigKPP;
void InitialConditionKPP(const Vector &x, Vector &u);
void InflowFunctionKPP(const Vector &x, double t, Vector &u);
KPP::KPP(FiniteElementSpace *fes_, BlockVector &u_block,
Configuration &config_)
: HyperbolicSystem(fes_, u_block, 1, config_,
VectorFunctionCoefficient(1, InflowFunctionKPP))
{
ConfigKPP = config_;
VectorFunctionCoefficient ic(NumEq, InitialConditionKPP);
switch (ConfigKPP.ConfigNum)
{
case 1:
{
ProblemName = "KPP Equation - 2D Spiral";
glvis_scale = "on";
SolutionKnown = false;
SteadyState = false;
TimeDepBC = false;
ProjType = 1;
u0.ProjectCoefficient(ic);
break;
}
case 2:
{
ProblemName = "KPP Equation - 1D";
glvis_scale = "on";
SolutionKnown =
false; // There is a solution, but I don't have an analytical expression.
SteadyState = false;
TimeDepBC = false;
ProjType = 1;
u0.ProjectCoefficient(ic);
break;
}
default:
MFEM_ABORT("No such test case implemented.");
}
}
void KPP::EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
int e, int k, int i) const
{
if (dim==1)
{
double coef = u(0)*(1.0-u(0));
FluxEval(0,0) = u(0) < 0.5 ? (0.25*coef) : (0.1875 - 0.5*coef);
}
else if (dim==2)
{
FluxEval(0,0) = sin(u(0));
FluxEval(0,1) = cos(u(0));
}
else { MFEM_ABORT("Not implemented."); }
}
double KPP::GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
int i) const
{
return 1.0; // Tighter bound exists.
}
void InitialConditionKPP(const Vector &x, Vector &u)
{
const int dim = x.Size();
Vector X(dim);
for (int i = 0; i < dim; i++)
{
switch (ConfigKPP.ConfigNum)
{
case 1: // Map to the reference domain [-1,1]^d.
{
double center = 0.5 * (ConfigKPP.bbMin(i) + ConfigKPP.bbMax(i));
X(i) = 2.0 * (x(i) - center) / (ConfigKPP.bbMax(i) - ConfigKPP.bbMin(i));
break;
}
case 2: // Map to the reference domain [0,1]^d.
{
X(i) = (x(i) - ConfigKPP.bbMin(i)) / (ConfigKPP.bbMax(i) - ConfigKPP.bbMin(i));
break;
}
}
}
switch (ConfigKPP.ConfigNum)
{
case 1:
{
// Map to test case specific domain [-2,2] x [-2.5,1.5].
X *= 2.0;
X(1) -= 0.5;
u(0) = X.Norml2() <= 1. ? 3.5 * M_PI : 0.25 * M_PI;
break;
}
case 2:
{
u(0) = X.Norml2() <= 0.25 ? 0.0 :
1.0; // According to the original KPP paper, not Ern and Guermond.
break;
}
}
}
void InflowFunctionKPP(const Vector &x, double t, Vector &u)
{
switch (ConfigKPP.ConfigNum)
{
case 1: { u(0) = 0.25 * M_PI; break; }
// This definition is consistent with the problem and assures correct
// handling of inflow (left) and outflow (right) boundaries.
case 2: { u(0) = x(0); break; }
}
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef HYPSYS_KPP
#define HYPSYS_KPP
#include "hyperbolic_system.hpp"
class KPP : public HyperbolicSystem
{
public:
explicit KPP(FiniteElementSpace *fes_, BlockVector &u_block,
Configuration &config_);
~KPP() { };
virtual void EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
int e, int k, int i = -1) const;
virtual double GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
int i) const;
};
#endif
+11
View File
@@ -0,0 +1,11 @@
#ifndef HYPSYS_APPS_LIB
#define HYPSYS_APPS_LIB
#include "advection.hpp"
#include "burgers.hpp"
#include "kpp.hpp"
#include "buckley_leverett.hpp"
#include "shallowwater.hpp"
#include "euler.hpp"
#endif
+463
View File
@@ -0,0 +1,463 @@
#include "shallowwater.hpp"
Configuration ConfigSWE;
double GravConst;
double Depth;
void AnalyticalSolutionSWE(const Vector &x, double t, Vector &u);
void InitialConditionSWE(const Vector &x, Vector &u);
void InflowFunctionSWE(const Vector &x, double t, Vector &u);
ShallowWater::ShallowWater(FiniteElementSpace *fes_, BlockVector &u_block,
Configuration &config_)
: HyperbolicSystem(fes_, u_block, fes_->GetMesh()->Dimension() + 1, config_,
VectorFunctionCoefficient(fes_->GetMesh()->Dimension() + 1,
InflowFunctionSWE))
{
ConfigSWE = config_;
VectorFunctionCoefficient ic(NumEq, InitialConditionSWE);
switch (ConfigSWE.ConfigNum)
{
case 0:
{
// Periodic meshes must be used for this problem.
ProblemName = "Shallow Water Equations - Vorticity Advection";
glvis_scale = "on";
GravConst = 1.0;
Depth = 1.0;
SolutionKnown = true;
SteadyState = false;
TimeDepBC = false;
ProjType = 0;
L2_Projection(ic, u0);
break;
}
case 1:
{
ProblemName = "Shallow Water Equations - Dam Break";
glvis_scale = "on";
GravConst = 9.81;
Depth = 1.0;
SolutionKnown = true;
SteadyState = false;
TimeDepBC = false;
ProjType = 1;
L2_Projection(ic, u0);
break;
}
case 2:
{
ProblemName = "Shallow Water Equations - Radial Dam Break";
glvis_scale = "off valuerange 0.1 1";
GravConst = 9.81;
Depth = 0.1;
SolutionKnown = false;
SteadyState = false;
TimeDepBC = false;
ProjType = 1;
u0.ProjectCoefficient(ic);
break;
}
case 3:
{
ProblemName = "Shallow Water Equations - Constricted Channel";
glvis_scale = "on";
GravConst = 0.16;
Depth = 1.0;
SolutionKnown = false;
SteadyState = true;
TimeDepBC = false;
ProjType = 0;
u0.ProjectCoefficient(ic);
break;
}
case 4:
{
ProblemName = "Shallow Water Equations - MoST Gimmick";
glvis_scale = "on";
GravConst = 1.0;
SolutionKnown = false;
SteadyState = false;
TimeDepBC = false;
ProjType = 1;
Mesh *mesh = fes->GetMesh();
const int nd = fes->GetFE(0)->GetDof();
const int ne = fes->GetNE();
if (mesh->Dimension() != 2) { MFEM_ABORT("Test case works only in 2D."); }
u0 = 0.;
for (int e = 0; e < ne; e++)
{
int id = mesh->GetElement(e)->GetAttribute();
for (int j = 0; j < nd; j++)
{
switch (id)
{
case 1:
{
u0(e*nd+j) = 1.;
break;
}
case 2:
case 3:
case 4:
{
u0(e*nd+j) = 0.125;
break;
}
default:
MFEM_ABORT("Too many element IDs.");
}
}
}
break;
}
default:
MFEM_ABORT("No such test case implemented.");
}
}
void ShallowWater::EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
int e, int k, int i) const
{
CheckAdmissibility(u);
switch (dim)
{
case 1:
{
FluxEval(0,0) = u(1);
FluxEval(1,0) = u(1) * u(1) / u(0) + 0.5 * GravConst * u(0) * u(0);
break;
}
case 2:
{
double vx = u(1) / u(0);
double vy = u(2) / u(0);
double gravitation = 0.5 * GravConst * u(0) * u(0);
FluxEval(0,0) = u(1);
FluxEval(0,1) = u(2);
FluxEval(1,0) = u(1) * vx + gravitation;
FluxEval(1,1) = u(1) * vy;
FluxEval(2,0) = u(2) * vx;
FluxEval(2,1) = u(2) * vy + gravitation;
break;
}
default:
MFEM_ABORT("Invalid space dimension.");
}
}
double ShallowWater::GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
int i) const
{
CheckAdmissibility(u);
switch (u.Size())
{
case 2:
return abs( u(1)*n(0) / u(0) ) + sqrt(GravConst * u(0));
case 3:
return abs( (u(1)*n(0) + u(2)*n(1)) / u(0) ) + sqrt(GravConst * u(0));
}
}
void ShallowWater::CheckAdmissibility(const Vector &u) const
{
double HMin = 1.e-12;
if (u.Size() != NumEq) { MFEM_ABORT("Invalid solution vector."); }
if (u(0) < HMin)
{
ostringstream height_str;
height_str << u(0);
string err_msg = "Water height too small H = ";
MFEM_ABORT(err_msg << height_str.str() << ".");
}
}
void ShallowWater::SetBdrCond(const Vector &y1, Vector &y2,
const Vector &normal, int attr) const
{
switch (attr)
{
case -1: // Land boundary
{
if (normal.Size() == 1)
{
y2(0) = y1(0);
y2(1) = -y1(1);
}
else
{
double MomTimesNor = y1(1) * normal(0) + y1(2) * normal(1);
y2(0) = y1(0);
y2(1) = y1(1) - 2. * MomTimesNor * normal(0);
y2(2) = y1(2) - 2. * MomTimesNor * normal(1);
}
break;
}
case -2: // Radiation boundary
{
y2 = y1;
break;
}
case -3: // River boundary
{
break;
}
case -4: // Open sea boundary
{
double tmp = y2(0);
y2 = y1;
y2(0) = tmp;
break;
}
default:
MFEM_ABORT("Invalid boundary attribute.");
}
}
void ShallowWater::ComputeDerivedQuantities(const GridFunction &u,
GridFunction &d1, GridFunction &d2) const
{
double height, momentum;
const IntegrationRule ir = u.FESpace()->GetFE(0)->GetNodes();
for (int e = 0; e < ne; e++)
{
for (int i = 0; i < nd; i++)
{
const IntegrationPoint &ip = ir.IntPoint(i);
height = u.GetValue(e, ip, 1);
momentum = u.GetValue(e, ip, 2);
d1(e*nd + i) = pow(momentum / height, 2.0);
if (dim==2)
{
momentum = u.GetValue(e, ip, 3);
d1(e*nd + i) += pow(momentum / height, 2.0);
}
d1(e*nd + i) = sqrt(d1(e*nd + i));
}
}
}
void ShallowWater::ComputeErrors(Array<double> &errors, const GridFunction &u,
double DomainSize, double t) const
{
errors.SetSize(NumEq*3);
Vector component(dim+1);
VectorFunctionCoefficient uAnalytic(NumEq, AnalyticalSolutionSWE);
if (ConfigSWE.ConfigNum == 0) { uAnalytic.SetTime(0); }
else { uAnalytic.SetTime(t); }
component = 0.0;
component(0) = 1.0;
VectorConstantCoefficient weight1(component);
errors[0] = u.ComputeLpError(1.0, uAnalytic, NULL, &weight1) / DomainSize;
errors[1] = u.ComputeLpError(2.0, uAnalytic, NULL, &weight1) / DomainSize;
errors[2] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic,
NULL, &weight1);
component = 0.0;
component(1) = 1.0;
VectorConstantCoefficient weight2(component);
errors[3] = u.ComputeLpError(1.0, uAnalytic, NULL, &weight2) / DomainSize;
errors[4] = u.ComputeLpError(2.0, uAnalytic, NULL, &weight2) / DomainSize;
errors[5] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic,
NULL, &weight2);
if (dim == 2)
{
component = 0.0;
component(2) = 1.0;
VectorConstantCoefficient weight3(component);
errors[6] = u.ComputeLpError(1.0, uAnalytic, NULL, &weight3) / DomainSize;
errors[7] = u.ComputeLpError(2.0, uAnalytic, NULL, &weight3) / DomainSize;
errors[8] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic,
NULL, &weight3);
}
}
void AnalyticalSolutionSWE(const Vector &x, double t, Vector &u)
{
const int dim = x.Size();
Vector X(dim);
for (int i = 0; i < dim; i++)
{
switch (ConfigSWE.ConfigNum)
{
case 0: // Map to the reference domain [-1,1]^d.
{
double center = 0.5 * (ConfigSWE.bbMin(i) + ConfigSWE.bbMax(i));
double factor = 2.0 / (ConfigSWE.bbMax(i) - ConfigSWE.bbMin(i));
X(i) = factor * (x(i) - center);
t *= pow(factor, 1.0 / (double(dim)));
break;
}
case 1: // Map to the reference domain [0,1]^d.
{
double factor = 1.0 / (ConfigSWE.bbMax(i) - ConfigSWE.bbMin(i));
X(i) = factor * (x(i) - ConfigSWE.bbMin(i));
t *= pow(factor, 1.0 / (double(dim)));
break;
}
}
}
switch (ConfigSWE.ConfigNum)
{
case 0:
{
if (dim != 2) { MFEM_ABORT("Test case works only in 2D."); }
// Map to test case specific domain [-50,50].
X *= 50.;
t *= 50.;
double M = sqrt(2);
double c1 = -0.1;
double c2 = 0.005;
double a = M_PI / 4.0;
double x0 = 0.0;
double y0 = 0.0;
double f = -c2 * ( pow(X(0) - x0 - M*t*cos(a), 2.0)
+ pow(X(1) - y0 - M*t*sin(a), 2.0) );
u(0) = 1.0;
u(1) = M*cos(a) + c1 * (X(1) - y0 - M*t*sin(a)) * exp(f);
u(2) = M*sin(a) - c1 * (X(0) - x0 - M*t*cos(a)) * exp(f);
u *= Depth - c1*c1 / (4.0*c2*GravConst) * exp(2.0*f);
break;
}
case 1:
{
// Map to test case specific domain [0,1000]^d.
X *= 1000;
t *= 1000;
double r = X(0);
u = 0.;
if (t==0)
{
u(0) = r < 500.0 ? Depth + 9.0 : Depth;
return;
}
double cm = 6.23416;
double aux = sqrt(10.0 * GravConst);
double xA = 500.0 - t*aux;
double xB = 500.0 + t*(2.0*aux - 3.0*cm);
double xC = 500.0 + t*(2.0*cm*cm*(aux - cm))/(cm*cm - GravConst);
u(0) = 9.0 * (r<xA) + (4.0/(9.0*GravConst) * pow( aux - (r-500.0)/(2.0*t),
2.0 ) - 1.0) * (r>=xA) * (r<xB)
+ (cm*cm/GravConst - 1.) * (r>=xB) * (r<xC);
u(1) = 2.0/3.0 * ((r-500.0)/t + aux) * (r >= xA) * (r < xB) + 2.0 *
(aux - cm) * (r >= xB) * (r < xC);
u(0) += Depth;
u(1) *= u(0);
break;
}
case 3:
{
if (dim != 2) { MFEM_ABORT("Test case works only in 2D."); }
const double x1[2]= {-10., 0.}, x2[2]= {-10., 40.},
x3[2]= {53.8622, 5.5872}, x4[2]= {53.8622, 34.4128},
slope0=0.53886, slope1=0.79893;
int sign_top, sign_bot;
if (x(0)>x3[0])
{
sign_top = -(x(0)-x4[0])*slope1-(x(1)-x4[1])>0 ? 1 : -1;
sign_bot = (x(0)-x3[0])*slope1-(x(1)-x3[1])>0 ? 1 : -1;
u(0) = sign_top*sign_bot>0. ? 0.8350436: 0.5273361;
}
else
{
sign_top = -(x(0)-x2[0])*slope0-(x(1)-x2[1])>0 ? 1 : -1;
sign_bot = (x(0)-x1[0])*slope0-(x(1)-x1[1])>0 ? 1 : -1;
u(0) = sign_top*sign_bot>0. ? 0.250133 : (sign_top>0 ? 1. : 0.5273361);
}
u(0) += Depth;
break;
}
}
}
void InitialConditionSWE(const Vector &x, Vector &u)
{
const int dim = x.Size();
Vector X(dim);
// Map to the reference domain [-1,1]^d.
for (int i = 0; i < dim; i++)
{
double center = 0.5 * (ConfigSWE.bbMin(i) + ConfigSWE.bbMax(i));
double factor = 2.0 / (ConfigSWE.bbMax(i) - ConfigSWE.bbMin(i));
X(i) = factor * (x(i) - center);
}
switch (ConfigSWE.ConfigNum)
{
case 0:
case 1:
{
AnalyticalSolutionSWE(x, 0., u);
break;
}
case 2:
{
u = 0.0;
u(0) = X.Norml2() < 0.5 ? 0.9 : 0.0;
u(0) += Depth;
break;
}
case 3:
{
u(0) = Depth;
u(1) = Depth;
u(2) = 0.;
break;
}
}
}
void InflowFunctionSWE(const Vector &x, double t, Vector &u)
{
switch (ConfigSWE.ConfigNum)
{
case 0:
case 2:
{
// Do not impose inflow values in this setup.
break;
}
case 1:
{
AnalyticalSolutionSWE(x, 0., u);
break;
}
case 3:
{
InitialConditionSWE(x, u);
break;
}
}
}
+26
View File
@@ -0,0 +1,26 @@
#ifndef HYPSYS_SHALLOWWATER
#define HYPSYS_SHALLOWWATER
#include "hyperbolic_system.hpp"
class ShallowWater : public HyperbolicSystem
{
public:
explicit ShallowWater(FiniteElementSpace *fes_, BlockVector &u_block,
Configuration &config_);
~ShallowWater() { };
virtual void EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
int e, int k, int i = -1) const;
virtual double GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
int i) const;
virtual void CheckAdmissibility(const Vector &u) const override;
virtual void SetBdrCond(const Vector &y1, Vector &y2, const Vector &normal,
int attr) const override;
virtual void ComputeDerivedQuantities(const GridFunction &u, GridFunction &d1,
GridFunction &d2) const override;
virtual void ComputeErrors(Array<double> &errors, const GridFunction &u,
double DomainSize, double t) const override;
};
#endif
+115
View File
@@ -0,0 +1,115 @@
#include "template.hpp"
Configuration ConfigTEMPLATE;
void AnalyticalSolutionTEMPLATE(const Vector &x, double t, Vector &u);
void InitialConditionTEMPLATE(const Vector &x, Vector &u);
void InflowFunctionTEMPLATE(const Vector &x, double t, Vector &u);
TEMPLATE::TEMPLATE(FiniteElementSpace *fes_, BlockVector &u_block,
Configuration &config_)
: HyperbolicSystem(fes_, u_block, NUMEQ, config_,
VectorFunctionCoefficient(NUMEQ, InflowFunctionTEMPLATE))
{
ConfigTEMPLATE = config_;
VectorFunctionCoefficient ic(NumEq, InitialConditionTEMPLATE);
switch (ConfigTEMPLATE.ConfigNum)
{
case 0:
{
ProblemName = "TEMPLATE - ";
glvis_scale = "on";
SolutionKnown = ;
SteadyState = ;
TimeDepBC = ;
ProjType = 0;
L2_Projection(ic, u0);
break;
}
case 1:
{
ProblemName = "TEMPLATE - ";
glvis_scale = "off valuerange 0 1";
SolutionKnown = ;
SteadyState = ;
TimeDepBC = ;
ProjType = 1;
u0.ProjectCoefficient(ic);
break;
}
default:
MFEM_ABORT("No such test case implemented.");
}
}
void TEMPLATE::EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
int e, int k, int i) const
{
// TODO
}
double TEMPLATE::GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
int i) const
{
//TODO
return 0.;
}
void TEMPLATE::SetBdrCond(const Vector &y1, Vector &y2, const Vector &normal,
int attr) const
{
//TODO
}
void TEMPLATE::ComputeErrors(Array<double> &errors, const GridFunction &u,
double DomainSize, double t) const
{
errors.SetSize(3);
VectorFunctionCoefficient uAnalytic(NumEq, AnalyticalSolutionTEMPLATE);
uAnalytic.SetTime(t);
errors[0] = u.ComputeLpError(1., uAnalytic) / DomainSize;
errors[1] = u.ComputeLpError(2., uAnalytic) / DomainSize;
errors[2] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic);
}
void AnalyticalSolutionTEMPLATE(const Vector &x, double t, Vector &u)
{
const int dim = x.Size();
Vector X(dim);
for (int i = 0; i < dim; i++)
{
switch (ConfigTEMPLATE.ConfigNum)
{
case /* TODO */: // Map to the reference domain [-1,1]^d.
{
double center = 0.5 * (ConfigTEMPLATE.bbMin(i) + ConfigTEMPLATE.bbMax(i));
double factor = 2.0 / (ConfigTEMPLATE.bbMax(i) - ConfigTEMPLATE.bbMin(i));
X(i) = factor * (x(i) - center);
t *= pow(factor, 1.0 / (double(dim)));
break;
}
case /* TODO */: // Map to the reference domain [0,1]^d.
{
double factor = 1.0 / (ConfigTEMPLATE.bbMax(i) - ConfigTEMPLATE.bbMin(i));
X(i) = factor * (x(i) - ConfigTEMPLATE.bbMin(i));
t *= pow(factor, 1.0 / (double(dim)));
break;
}
}
}
// TODO
}
void InitialConditionTEMPLATE(const Vector &x, Vector &u)
{
// TODO
}
void InflowFunctionTEMPLATE(const Vector &x, double t, Vector &u)
{
// TODO
}
+24
View File
@@ -0,0 +1,24 @@
#ifndef HYPSYS_TEMPLATE
#define HYPSYS_TEMPLATE
#include "hyperbolic_system.hpp"
class TEMPLATE : public HyperbolicSystem
{
public:
explicit TEMPLATE(FiniteElementSpace *fes_, BlockVector &u_block,
Configuration &config_);
~TEMPLATE() { };
virtual void EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
int e, int k, int i = -1) const;
virtual double GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
int i) const;
virtual void SetBdrCond(const Vector &y1, Vector &y2, const Vector &normal,
int attr) const;
virtual void ComputeDerivedQuantities(const Vector &u) const { };
virtual void ComputeErrors(Array<double> &errors, const GridFunction &u,
double DomainSize, double t) const;
};
#endif
+32
View File
@@ -0,0 +1,32 @@
EXEC="mpirun -np 7 phypsys"
SCHEME=1
MESH="data/periodic-4segment.mesh"
MESH0="data/periodic-3segment.mesh"
CONFIG="-p 0 -c 4 -vf 100 -tf 1 -s 3 -dt 0.001 -m $MESH"
$EXEC $CONFIG -es $SCHEME -o 1 -r 5
$EXEC $CONFIG -es $SCHEME -o 3 -r 4
$EXEC $CONFIG -es $SCHEME -o 7 -r 3
# GRID CONVERGENCE TEST
ORDER=1
DT=0.0004
# ORDER=2
# DT=0.00025
# ORDER=3
# DT=0.0001
# ORDER=4
# DT=0.000025
CONFIG0="-p 0 -c 3 -vf 1000 -tf 1 -s 3 -dt $DT -m $MESH0 -o $ORDER"
CONFIG1="-p 0 -c 3 -vf 1000 -tf 1 -s 3 -dt $DT -m $MESH -o $ORDER"
# rm errors.txt
# $EXEC $CONFIG0 -r 4 -es $SCHEME
# $EXEC $CONFIG1 -r 4 -es $SCHEME
# $EXEC $CONFIG0 -r 5 -es $SCHEME
# $EXEC $CONFIG1 -r 5 -es $SCHEME
# $EXEC $CONFIG0 -r 6 -es $SCHEME
# $EXEC $CONFIG1 -r 6 -es $SCHEME
# $EXEC $CONFIG0 -r 7 -es $SCHEME
+43
View File
@@ -0,0 +1,43 @@
EXEC="mpirun -np 7 phypsys"
SCHEME=0
MESH=data/inline-4quad.mesh
CONFIG="-p 1 -c 1 -vf 100 -tf 0.5 -s 3 -dt 0.0005 -m $MESH"
$EXEC $CONFIG -es $SCHEME -o 0 -r 5
$EXEC $CONFIG -es $SCHEME -o 1 -r 4
SCHEME=1
$EXEC $CONFIG -es $SCHEME -o 1 -r 4
$EXEC $CONFIG -es $SCHEME -o 3 -r 3
$EXEC $CONFIG -es $SCHEME -o 7 -r 2
$EXEC $CONFIG -es $SCHEME -o 15 -r 1
# # GRID CONVERGENCE TEST
# SCHEME=1
ORDER=0
DT=0.002
# ORDER=1
# DT=0.0004
# # ORDER=2
# # DT=0.00016
# # ORDER=3
# # DT=-dt 0.0001
# # ORDER=4
# # DT=0.00005
# MESH="data/periodic-4segment.mesh"
# MESH0="data/periodic-3segment.mesh"
# CONFIG0="-p 1 -c 0 -vf 1000 -tf 0.1 -s 3 -dt $DT -m $MESH0 -o $ORDER"
# CONFIG1="-p 1 -c 0 -vf 1000 -tf 0.1 -s 3 -dt $DT -m $MESH -o $ORDER"
# rm errors.txt
# $EXEC $CONFIG0 -r 4 -es $SCHEME
# $EXEC $CONFIG1 -r 4 -es $SCHEME
# $EXEC $CONFIG0 -r 5 -es $SCHEME
# $EXEC $CONFIG1 -r 5 -es $SCHEME
# $EXEC $CONFIG0 -r 6 -es $SCHEME
# $EXEC $CONFIG1 -r 6 -es $SCHEME
# $EXEC $CONFIG0 -r 7 -es $SCHEME
# $EXEC $CONFIG1 -r 7 -es $SCHEME
+7
View File
@@ -0,0 +1,7 @@
MESH=data/wall-bdr-100segment.mesh
CONFIG="-p 3 -c 1 -vf 1000 -tf 0.02 -s 1 -m $MESH -r 0 -es 1"
./hypsys $CONFIG -o 3 -dt 0.00005
mv ultimate.gf cmp.gf
mpirun -np 3 phypsys $CONFIG -o 3 -dt 0.00005
meld ultimate.gf cmp.gf
+55
View File
@@ -0,0 +1,55 @@
EXEC="mpirun -np 7 phypsys"
SCHEME=1
MESH=data/wall-bdr-4segment.mesh
## SOD Shock tube
CONFIG="-p 5 -c 1 -vf 1000 -tf 0.231 -s 3 -m $MESH -es $SCHEME"
# # h-refinement
# $EXEC $CONFIG -o 1 -r 5 -dt 0.00064
# $EXEC $CONFIG -o 1 -r 6 -dt 0.00032
# $EXEC $CONFIG -o 1 -r 7 -dt 0.00016
# # p-refinement & h-coarsening
# $EXEC $CONFIG -r 5 -o 1 -dt 0.0004
# $EXEC $CONFIG -r 4 -o 3 -dt 0.0004
# $EXEC $CONFIG -r 3 -o 7 -dt 0.0004
# $EXEC $CONFIG -r 2 -o 15 -dt 0.0004
# $EXEC $CONFIG -r 1 -o 31 -dt 0.0004
## Woodward Colella
MESH=data/wall-bdr-100segment.mesh
CONFIG="-p 5 -c 2 -vf 1000 -tf 0.038 -s 3 -m $MESH -es $SCHEME"
$EXEC $CONFIG -o 1 -r 2 -dt 1e-6
# ## Double Mach reflection
# MESH=data/double-mach-quad.mesh
# CONFIG="-p 5 -c 3 -vf 1000 -tf 0.2 -s 3 -m $MESH -es $SCHEME"
# $EXEC $CONFIG -o 1 -r 3 -dt 5e-5
# ## Vortex advection
# SCHEME=0
# MESH3=data/periodic-3quad.mesh
# MESH4=data/periodic-4quad.mesh
# ORDER=1
# ODESOLVER=2
# DT=0.000625
# # ORDER=2
# # ODESOLVER=3
# # DT=0.0002
# # ORDER=3
# # ODESOLVER=3
# # DT=0.00032
# CONFIG="-p 5 -c 0 -vf 100 -tf 1 -s $ODESOLVER -dt $DT -o $ORDER -es $SCHEME"
# rm errors.txt
# $EXEC $CONFIG -m $MESH3 -r 3
# $EXEC $CONFIG -m $MESH4 -r 3
# $EXEC $CONFIG -m $MESH3 -r 4
# $EXEC $CONFIG -m $MESH4 -r 4
# $EXEC $CONFIG -m $MESH3 -r 5
+47
View File
@@ -0,0 +1,47 @@
SCHEME=0
## Advection
# Solid Body Roatation
# ./hypsys -r 0 -es $SCHEME
# ./phypsys -r 0 -es $SCHEME
# mpirun -np 4 ./phypsys -r 0 -es $SCHEME
# Steady Circular Convection
# ./hypsys -vf 1000 -m data/inline-4quad.mesh -dt 0.0001 -o 2 -s 1 -r 3 -c 0 -es $SCHEME
# ./phypsys -vf 1000 -m data/inline-4quad.mesh -dt 0.0001 -o 2 -s 1 -r 3 -c 0 -es $SCHEME
# mpirun -np 4 ./phypsys -vf 1000 -m data/inline-4quad.mesh -dt 0.0001 -o 2 -s 1 -r 3 -c 0 -es $SCHEME
# Translation
CONFIG="-p 0 -c 2 -vf 100 -tf 0.4 -s 3 -dt 0.002 -m data/periodic-3tri.mesh -o 2 -r 3 -es $SCHEME"
./hypsys $CONFIG
./phypsys $CONFIG
mpirun -np 4 phypsys $CONFIG
## Burgers
CONFIG="-p 1 -c 1 -vf 100 -tf 0.5 -s 3 -dt 0.004 -m data/inline-3quad.mesh -o 1 -r 3 -es $SCHEME"
./hypsys $CONFIG
./phypsys $CONFIG
mpirun -np 7 phypsys $CONFIG
## KPP
CONFIG="-p 2 -c 1 -vf 50 -tf 0.25 -s 3 -dt 0.005 -m data/inline-4tri.mesh -o 0 -r 4 -es 0"
./hypsys $CONFIG
./phypsys $CONFIG
mpirun -np 1 phypsys $CONFIG
## Shallow-Water
# Dam break
CONFIG="-p 4 -c 2 -vf 20 -tf 0.1 -s 3 -dt 0.0005 -m data/wall-bdr-4tri.mesh -o 1 -r 3 -es $SCHEME"
./hypsys $CONFIG
./phypsys $CONFIG
mpirun -np 2 phypsys $CONFIG
## Euler
# Smooth vortex
CONFIG="-p 5 -c 0 -vf 100 -tf 1 -s 3 -dt 0.00125 -m data/periodic-3quad.mesh -r 2 -es $SCHEME"
./hypsys $CONFIG
./phypsys $CONFIG
mpirun -np 4 phypsys $CONFIG
@@ -0,0 +1,12 @@
EXEC="mpirun -np 7 phypsys"
MESH=data/inline-4quad.mesh
# KPP
# $EXEC -p 2 -c 1 -vf 100 -tf 0.25 -s 3 -dt 0.00025 -r 9 -o 0 -m $MESH -es 0
$EXEC -p 2 -c 1 -vf 100 -tf 0.25 -s 3 -dt 0.002 -r 6 -o 0 -m $MESH -es 0
$EXEC -p 2 -c 1 -vf 100 -tf 0.25 -s 3 -dt 0.0008 -r 5 -o 1 -m $MESH -es 0
$EXEC -p 2 -c 1 -vf 100 -tf 0.25 -s 3 -dt 0.0008 -r 5 -o 1 -m $MESH -es 1
# Buckley-Leverett
$EXEC -p 3 -c 2 -vf 100 -tf 0.1666667 -s 3 -dt 0.0005 -r 5 -o 0 -m $MESH -es 0
$EXEC -p 3 -c 2 -vf 100 -tf 0.1666667 -s 3 -dt 0.0005 -r 4 -o 1 -m $MESH -es 1
+54
View File
@@ -0,0 +1,54 @@
EXEC="mpirun -np 7 phypsys"
## 1D Dam break
SCHEME=0
MESH=data/wall-bdr-4segment.mesh
CONFIG="-p 4 -c 1 -vf 1000 -tf 0.02 -s 3 -m $MESH -es $SCHEME"
# # h-refinement
# $EXEC $CONFIG -o 1 -r 5 -dt 0.0001
# $EXEC $CONFIG -o 1 -r 6 -dt 0.00005
# $EXEC $CONFIG -o 1 -r 7 -dt 0.000025
# $EXEC $CONFIG -o 1 -r 8 -dt 0.0000125
# # p-refinement & h-coarsening
# $EXEC $CONFIG -o 1 -r 5 -dt 0.000025
# $EXEC $CONFIG -o 3 -r 4 -dt 0.000025
# $EXEC $CONFIG -o 7 -r 3 -dt 0.000025
# ## Radial dambreak
# MESH=data/outflow-bdr-4quad.mesh
# CONFIG="-p 4 -c 2 -vf 50 -tf 0.06 -s 3 -m $MESH -es 1"
# # p-refinement & h-coarsening
# $EXEC $CONFIG -o 1 -r 5 -dt 0.0001
# $EXEC $CONFIG -o 3 -r 4 -dt 0.0001
# $EXEC $CONFIG -o 7 -r 3 -dt 0.0001
## Constricted channel
MESH=data/constricted-channel.mesh
CONFIG="-p 4 -c 3 -vf 100 -tf 1000 -s 1 -m $MESH -es $SCHEME"
$EXEC $CONFIG -r 1 -o 1 -dt 0.025
# ## Vortex advection
# SCHEME=0
# MESH3=data/periodic-3quad.mesh
# MESH4=data/periodic-4quad.mesh
# ORDER=1
# ODESOLVER=2
# DT=0.00064
# # ORDER=2
# # ODESOLVER=3
# # DT=0.0004
# # ORDER=3
# # ODESOLVER=3
# # DT=0.00025
# CONFIG="-p 4 -c 0 -vf 100 -tf 1 -s $ODESOLVER -dt $DT -o $ORDER -es $SCHEME"
# rm errors.txt
# $EXEC $CONFIG -m $MESH3 -r 3
# $EXEC $CONFIG -m $MESH4 -r 3
# $EXEC $CONFIG -m $MESH3 -r 4
# $EXEC $CONFIG -m $MESH4 -r 4
# $EXEC $CONFIG -m $MESH3 -r 5
@@ -0,0 +1,6 @@
EXEC="mpirun -np 7 phypsys"
MESH=data/periodic-4quad.mesh
SCHEME=1
$EXEC -p 0 -c 1 -vf 200 -tf 1 -s 3 -dt 0.00032 -m $MESH -r 4 -o 2 -es $SCHEME
+103
View File
@@ -0,0 +1,103 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
#
dimension
3
elements
8
1 5 0 1 10 9 18 19 28 27
1 5 1 2 11 10 19 20 29 28
1 5 2 3 12 11 20 21 30 29
1 5 3 4 13 12 21 22 31 30
2 5 4 5 14 13 22 23 32 31
2 5 5 6 15 14 23 24 33 32
2 5 6 7 16 15 24 25 34 33
2 5 7 8 17 16 25 26 35 34
boundary
34
3 3 9 10 1 0
3 3 0 1 19 18
3 3 10 9 27 28
1 3 9 0 18 27
3 3 18 19 28 27
3 3 10 11 2 1
3 3 1 2 20 19
3 3 11 10 28 29
3 3 19 20 29 28
3 3 11 12 3 2
3 3 2 3 21 20
3 3 12 11 29 30
3 3 20 21 30 29
3 3 12 13 4 3
3 3 3 4 22 21
3 3 13 12 30 31
3 3 21 22 31 30
3 3 13 14 5 4
3 3 4 5 23 22
3 3 14 13 31 32
3 3 22 23 32 31
3 3 14 15 6 5
3 3 5 6 24 23
3 3 15 14 32 33
3 3 23 24 33 32
3 3 15 16 7 6
3 3 6 7 25 24
3 3 16 15 33 34
3 3 24 25 34 33
3 3 16 17 8 7
3 3 7 8 26 25
2 3 8 17 35 26
3 3 17 16 34 35
3 3 25 26 35 34
vertices
36
3
0 0 0
1 0 0
2 0 0
3 0 0
4 0 0
5 0 0
6 0 0
7 0 0
8 0 0
0 1 0
1 1 0
2 1 0
3 1 0
4 1 0
5 1 0
6 1 0
7 1 0
8 1 0
0 0 1
1 0 1
2 0 1
3 0 1
4 0 1
5 0 1
6 0 1
7 0 1
8 0 1
0 1 1
1 1 1
2 1 1
3 1 1
4 1 1
5 1 1
6 1 1
7 1 1
8 1 1
+69
View File
@@ -0,0 +1,69 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
#
dimension
2
elements
8
1 3 0 1 10 9
1 3 1 2 11 10
1 3 2 3 12 11
1 3 3 4 13 12
2 3 4 5 14 13
2 3 5 6 15 14
2 3 6 7 16 15
2 3 7 8 17 16
boundary
18
3 1 0 1
3 1 1 2
3 1 2 3
3 1 3 4
3 1 4 5
3 1 5 6
3 1 6 7
3 1 7 8
3 1 10 9
3 1 11 10
3 1 12 11
3 1 13 12
3 1 14 13
3 1 15 14
3 1 16 15
3 1 17 16
1 1 9 0
2 1 8 17
vertices
18
2
0 0
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
0 1
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
+77
View File
@@ -0,0 +1,77 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
#
dimension
2
elements
16
1 2 10 0 1
1 2 0 10 9
1 2 11 1 2
1 2 1 11 10
1 2 12 2 3
1 2 2 12 11
1 2 13 3 4
1 2 3 13 12
2 2 14 4 5
2 2 4 14 13
2 2 15 5 6
2 2 5 15 14
2 2 16 6 7
2 2 6 16 15
2 2 17 7 8
2 2 7 17 16
boundary
18
3 1 0 1
3 1 1 2
3 1 2 3
3 1 3 4
3 1 4 5
3 1 5 6
3 1 6 7
3 1 7 8
3 1 10 9
3 1 11 10
3 1 12 11
3 1 13 12
3 1 14 13
3 1 15 14
3 1 16 15
3 1 17 16
1 1 9 0
2 1 8 17
vertices
18
2
0 0
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
0 1
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
File diff suppressed because it is too large Load Diff
+405
View File
@@ -0,0 +1,405 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
#
dimension
2
elements
144
1 3 0 1 26 25
1 3 25 26 51 50
1 3 26 27 52 51
1 3 1 2 27 26
1 3 2 3 28 27
1 3 27 28 53 52
1 3 52 53 78 77
1 3 77 78 103 102
1 3 76 77 102 101
1 3 51 52 77 76
1 3 50 51 76 75
1 3 75 76 101 100
1 3 100 101 126 125
1 3 125 126 151 150
1 3 126 127 152 151
1 3 101 102 127 126
1 3 102 103 128 127
1 3 127 128 153 152
1 3 128 129 154 153
1 3 103 104 129 128
1 3 104 105 130 129
1 3 129 130 155 154
1 3 130 131 156 155
1 3 105 106 131 130
1 3 80 81 106 105
1 3 55 56 81 80
1 3 54 55 80 79
1 3 79 80 105 104
1 3 78 79 104 103
1 3 53 54 79 78
1 3 28 29 54 53
1 3 3 4 29 28
1 3 4 5 30 29
1 3 29 30 55 54
1 3 30 31 56 55
1 3 5 6 31 30
1 3 6 7 32 31
1 3 31 32 57 56
1 3 32 33 58 57
1 3 7 8 33 32
1 3 8 9 34 33
1 3 33 34 59 58
1 3 58 59 84 83
1 3 83 84 109 108
1 3 82 83 108 107
1 3 57 58 83 82
1 3 56 57 82 81
1 3 81 82 107 106
1 3 106 107 132 131
1 3 131 132 157 156
1 3 132 133 158 157
1 3 107 108 133 132
1 3 108 109 134 133
1 3 133 134 159 158
1 3 134 135 160 159
1 3 109 110 135 134
1 3 110 111 136 135
1 3 135 136 161 160
1 3 136 137 162 161
1 3 111 112 137 136
1 3 86 87 112 111
1 3 61 62 87 86
1 3 60 61 86 85
1 3 85 86 111 110
1 3 84 85 110 109
1 3 59 60 85 84
1 3 34 35 60 59
1 3 9 10 35 34
1 3 10 11 36 35
1 3 35 36 61 60
1 3 36 37 62 61
1 3 11 12 37 36
1 3 12 13 38 37
1 3 37 38 63 62
1 3 38 39 64 63
1 3 13 14 39 38
1 3 14 15 40 39
1 3 39 40 65 64
1 3 64 65 90 89
1 3 89 90 115 114
1 3 88 89 114 113
1 3 63 64 89 88
1 3 62 63 88 87
1 3 87 88 113 112
1 3 112 113 138 137
1 3 137 138 163 162
1 3 138 139 164 163
1 3 113 114 139 138
1 3 114 115 140 139
1 3 139 140 165 164
1 3 140 141 166 165
1 3 115 116 141 140
1 3 116 117 142 141
1 3 141 142 167 166
1 3 142 143 168 167
1 3 117 118 143 142
1 3 92 93 118 117
1 3 67 68 93 92
1 3 66 67 92 91
1 3 91 92 117 116
1 3 90 91 116 115
1 3 65 66 91 90
1 3 40 41 66 65
1 3 15 16 41 40
1 3 16 17 42 41
1 3 41 42 67 66
1 3 42 43 68 67
1 3 17 18 43 42
1 3 18 19 44 43
1 3 43 44 69 68
1 3 44 45 70 69
1 3 19 20 45 44
1 3 20 21 46 45
1 3 45 46 71 70
1 3 70 71 96 95
1 3 95 96 121 120
1 3 94 95 120 119
1 3 69 70 95 94
1 3 68 69 94 93
1 3 93 94 119 118
1 3 118 119 144 143
1 3 143 144 169 168
1 3 144 145 170 169
1 3 119 120 145 144
1 3 120 121 146 145
1 3 145 146 171 170
1 3 146 147 172 171
1 3 121 122 147 146
1 3 122 123 148 147
1 3 147 148 173 172
1 3 148 149 174 173
1 3 123 124 149 148
1 3 98 99 124 123
1 3 73 74 99 98
1 3 72 73 98 97
1 3 97 98 123 122
1 3 96 97 122 121
1 3 71 72 97 96
1 3 46 47 72 71
1 3 21 22 47 46
1 3 22 23 48 47
1 3 47 48 73 72
1 3 48 49 74 73
1 3 23 24 49 48
boundary
60
3 1 0 1
1 1 1 2
1 1 2 3
1 1 3 4
1 1 4 5
1 1 5 6
1 1 6 7
1 1 7 8
1 1 8 9
1 1 9 10
1 1 10 11
1 1 11 12
1 1 12 13
1 1 13 14
1 1 14 15
1 1 15 16
1 1 16 17
1 1 17 18
1 1 18 19
1 1 19 20
1 1 20 21
1 1 21 22
1 1 22 23
1 1 23 24
3 1 151 150
3 1 152 151
3 1 153 152
3 1 154 153
3 1 155 154
3 1 156 155
3 1 157 156
3 1 158 157
3 1 159 158
3 1 160 159
3 1 161 160
3 1 162 161
3 1 163 162
3 1 164 163
3 1 165 164
3 1 166 165
3 1 167 166
3 1 168 167
3 1 169 168
3 1 170 169
3 1 171 170
3 1 172 171
3 1 173 172
3 1 174 173
3 1 25 0
3 1 50 25
3 1 75 50
3 1 100 75
3 1 125 100
3 1 150 125
2 1 24 49
2 1 49 74
2 1 74 99
2 1 99 124
2 1 124 149
2 1 149 174
vertices
175
2
0 0
0.16666666666666666 0
0.33333333333333333 0
0.5 0
0.66666666666666666 0
0.83333333333333333 0
1 0
1.1666666666666666 0
1.3333333333333333 0
1.5 0
1.6666666666666666 0
1.8333333333333333 0
2 0
2.1666666666666666 0
2.3333333333333333 0
2.5 0
2.6666666666666666 0
2.8333333333333333 0
3 0
3.1666666666666666 0
3.3333333333333333 0
3.5 0
3.6666666666666666 0
3.8333333333333333 0
4 0
0 0.16666666666666666
0.16666666666666666 0.16666666666666666
0.33333333333333333 0.16666666666666666
0.5 0.16666666666666666
0.66666666666666666 0.16666666666666666
0.83333333333333333 0.16666666666666666
1 0.16666666666666666
1.1666666666666666 0.16666666666666666
1.3333333333333333 0.16666666666666666
1.5 0.16666666666666666
1.6666666666666666 0.16666666666666666
1.8333333333333333 0.16666666666666666
2 0.16666666666666666
2.1666666666666666 0.16666666666666666
2.3333333333333333 0.16666666666666666
2.5 0.16666666666666666
2.6666666666666666 0.16666666666666666
2.8333333333333333 0.16666666666666666
3 0.16666666666666666
3.1666666666666666 0.16666666666666666
3.3333333333333333 0.16666666666666666
3.5 0.16666666666666666
3.6666666666666666 0.16666666666666666
3.8333333333333333 0.16666666666666666
4 0.16666666666666666
0 0.33333333333333333
0.16666666666666666 0.33333333333333333
0.33333333333333333 0.33333333333333333
0.5 0.33333333333333333
0.66666666666666666 0.33333333333333333
0.83333333333333333 0.33333333333333333
1 0.33333333333333333
1.1666666666666666 0.33333333333333333
1.3333333333333333 0.33333333333333333
1.5 0.33333333333333333
1.6666666666666666 0.33333333333333333
1.8333333333333333 0.33333333333333333
2 0.33333333333333333
2.1666666666666666 0.33333333333333333
2.3333333333333333 0.33333333333333333
2.5 0.33333333333333333
2.6666666666666666 0.33333333333333333
2.8333333333333333 0.33333333333333333
3 0.33333333333333333
3.1666666666666666 0.33333333333333333
3.3333333333333333 0.33333333333333333
3.5 0.33333333333333333
3.6666666666666666 0.33333333333333333
3.8333333333333333 0.33333333333333333
4 0.33333333333333333
0 0.5
0.16666666666666666 0.5
0.33333333333333333 0.5
0.5 0.5
0.66666666666666666 0.5
0.83333333333333333 0.5
1 0.5
1.1666666666666666 0.5
1.3333333333333333 0.5
1.5 0.5
1.6666666666666666 0.5
1.8333333333333333 0.5
2 0.5
2.1666666666666666 0.5
2.3333333333333333 0.5
2.5 0.5
2.6666666666666666 0.5
2.8333333333333333 0.5
3 0.5
3.1666666666666666 0.5
3.3333333333333333 0.5
3.5 0.5
3.6666666666666666 0.5
3.8333333333333333 0.5
4 0.5
0 0.66666666666666666
0.16666666666666666 0.66666666666666666
0.33333333333333333 0.66666666666666666
0.5 0.66666666666666666
0.66666666666666666 0.66666666666666666
0.83333333333333333 0.66666666666666666
1 0.66666666666666666
1.1666666666666666 0.66666666666666666
1.3333333333333333 0.66666666666666666
1.5 0.66666666666666666
1.6666666666666666 0.66666666666666666
1.8333333333333333 0.66666666666666666
2 0.66666666666666666
2.1666666666666666 0.66666666666666666
2.3333333333333333 0.66666666666666666
2.5 0.66666666666666666
2.6666666666666666 0.66666666666666666
2.8333333333333333 0.66666666666666666
3 0.66666666666666666
3.1666666666666666 0.66666666666666666
3.3333333333333333 0.66666666666666666
3.5 0.66666666666666666
3.6666666666666666 0.66666666666666666
3.8333333333333333 0.66666666666666666
4 0.66666666666666666
0 0.83333333333333333
0.16666666666666666 0.83333333333333333
0.33333333333333333 0.83333333333333333
0.5 0.83333333333333333
0.66666666666666666 0.83333333333333333
0.83333333333333333 0.83333333333333333
1 0.83333333333333333
1.1666666666666666 0.83333333333333333
1.3333333333333333 0.83333333333333333
1.5 0.83333333333333333
1.6666666666666666 0.83333333333333333
1.8333333333333333 0.83333333333333333
2 0.83333333333333333
2.1666666666666666 0.83333333333333333
2.3333333333333333 0.83333333333333333
2.5 0.83333333333333333
2.6666666666666666 0.83333333333333333
2.8333333333333333 0.83333333333333333
3 0.83333333333333333
3.1666666666666666 0.83333333333333333
3.3333333333333333 0.83333333333333333
3.5 0.83333333333333333
3.6666666666666666 0.83333333333333333
3.8333333333333333 0.83333333333333333
4 0.83333333333333333
0 1
0.16666666666666666 1
0.33333333333333333 1
0.5 1
0.66666666666666666 1
0.83333333333333333 1
1 1
1.1666666666666666 1
1.3333333333333333 1
1.5 1
1.6666666666666666 1
1.8333333333333333 1
2 1
2.1666666666666666 1
2.3333333333333333 1
2.5 1
2.6666666666666666 1
2.8333333333333333 1
3 1
3.1666666666666666 1
3.3333333333333333 1
3.5 1
3.6666666666666666 1
3.8333333333333333 1
4 1
+549
View File
@@ -0,0 +1,549 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
#
dimension
2
elements
288
1 2 0 26 25
1 2 26 0 1
1 2 1 27 26
1 2 27 1 2
1 2 2 28 27
1 2 28 2 3
1 2 3 29 28
1 2 29 3 4
1 2 4 30 29
1 2 30 4 5
1 2 5 31 30
1 2 31 5 6
1 2 6 32 31
1 2 32 6 7
1 2 7 33 32
1 2 33 7 8
1 2 8 34 33
1 2 34 8 9
1 2 9 35 34
1 2 35 9 10
1 2 10 36 35
1 2 36 10 11
1 2 11 37 36
1 2 37 11 12
1 2 12 38 37
1 2 38 12 13
1 2 13 39 38
1 2 39 13 14
1 2 14 40 39
1 2 40 14 15
1 2 15 41 40
1 2 41 15 16
1 2 16 42 41
1 2 42 16 17
1 2 17 43 42
1 2 43 17 18
1 2 18 44 43
1 2 44 18 19
1 2 19 45 44
1 2 45 19 20
1 2 20 46 45
1 2 46 20 21
1 2 21 47 46
1 2 47 21 22
1 2 22 48 47
1 2 48 22 23
1 2 23 49 48
1 2 49 23 24
1 2 25 51 50
1 2 51 25 26
1 2 26 52 51
1 2 52 26 27
1 2 27 53 52
1 2 53 27 28
1 2 28 54 53
1 2 54 28 29
1 2 29 55 54
1 2 55 29 30
1 2 30 56 55
1 2 56 30 31
1 2 31 57 56
1 2 57 31 32
1 2 32 58 57
1 2 58 32 33
1 2 33 59 58
1 2 59 33 34
1 2 34 60 59
1 2 60 34 35
1 2 35 61 60
1 2 61 35 36
1 2 36 62 61
1 2 62 36 37
1 2 37 63 62
1 2 63 37 38
1 2 38 64 63
1 2 64 38 39
1 2 39 65 64
1 2 65 39 40
1 2 40 66 65
1 2 66 40 41
1 2 41 67 66
1 2 67 41 42
1 2 42 68 67
1 2 68 42 43
1 2 43 69 68
1 2 69 43 44
1 2 44 70 69
1 2 70 44 45
1 2 45 71 70
1 2 71 45 46
1 2 46 72 71
1 2 72 46 47
1 2 47 73 72
1 2 73 47 48
1 2 48 74 73
1 2 74 48 49
1 2 50 76 75
1 2 76 50 51
1 2 51 77 76
1 2 77 51 52
1 2 52 78 77
1 2 78 52 53
1 2 53 79 78
1 2 79 53 54
1 2 54 80 79
1 2 80 54 55
1 2 55 81 80
1 2 81 55 56
1 2 56 82 81
1 2 82 56 57
1 2 57 83 82
1 2 83 57 58
1 2 58 84 83
1 2 84 58 59
1 2 59 85 84
1 2 85 59 60
1 2 60 86 85
1 2 86 60 61
1 2 61 87 86
1 2 87 61 62
1 2 62 88 87
1 2 88 62 63
1 2 63 89 88
1 2 89 63 64
1 2 64 90 89
1 2 90 64 65
1 2 65 91 90
1 2 91 65 66
1 2 66 92 91
1 2 92 66 67
1 2 67 93 92
1 2 93 67 68
1 2 68 94 93
1 2 94 68 69
1 2 69 95 94
1 2 95 69 70
1 2 70 96 95
1 2 96 70 71
1 2 71 97 96
1 2 97 71 72
1 2 72 98 97
1 2 98 72 73
1 2 73 99 98
1 2 99 73 74
1 2 75 101 100
1 2 101 75 76
1 2 76 102 101
1 2 102 76 77
1 2 77 103 102
1 2 103 77 78
1 2 78 104 103
1 2 104 78 79
1 2 79 105 104
1 2 105 79 80
1 2 80 106 105
1 2 106 80 81
1 2 81 107 106
1 2 107 81 82
1 2 82 108 107
1 2 108 82 83
1 2 83 109 108
1 2 109 83 84
1 2 84 110 109
1 2 110 84 85
1 2 85 111 110
1 2 111 85 86
1 2 86 112 111
1 2 112 86 87
1 2 87 113 112
1 2 113 87 88
1 2 88 114 113
1 2 114 88 89
1 2 89 115 114
1 2 115 89 90
1 2 90 116 115
1 2 116 90 91
1 2 91 117 116
1 2 117 91 92
1 2 92 118 117
1 2 118 92 93
1 2 93 119 118
1 2 119 93 94
1 2 94 120 119
1 2 120 94 95
1 2 95 121 120
1 2 121 95 96
1 2 96 122 121
1 2 122 96 97
1 2 97 123 122
1 2 123 97 98
1 2 98 124 123
1 2 124 98 99
1 2 100 126 125
1 2 126 100 101
1 2 101 127 126
1 2 127 101 102
1 2 102 128 127
1 2 128 102 103
1 2 103 129 128
1 2 129 103 104
1 2 104 130 129
1 2 130 104 105
1 2 105 131 130
1 2 131 105 106
1 2 106 132 131
1 2 132 106 107
1 2 107 133 132
1 2 133 107 108
1 2 108 134 133
1 2 134 108 109
1 2 109 135 134
1 2 135 109 110
1 2 110 136 135
1 2 136 110 111
1 2 111 137 136
1 2 137 111 112
1 2 112 138 137
1 2 138 112 113
1 2 113 139 138
1 2 139 113 114
1 2 114 140 139
1 2 140 114 115
1 2 115 141 140
1 2 141 115 116
1 2 116 142 141
1 2 142 116 117
1 2 117 143 142
1 2 143 117 118
1 2 118 144 143
1 2 144 118 119
1 2 119 145 144
1 2 145 119 120
1 2 120 146 145
1 2 146 120 121
1 2 121 147 146
1 2 147 121 122
1 2 122 148 147
1 2 148 122 123
1 2 123 149 148
1 2 149 123 124
1 2 125 151 150
1 2 151 125 126
1 2 126 152 151
1 2 152 126 127
1 2 127 153 152
1 2 153 127 128
1 2 128 154 153
1 2 154 128 129
1 2 129 155 154
1 2 155 129 130
1 2 130 156 155
1 2 156 130 131
1 2 131 157 156
1 2 157 131 132
1 2 132 158 157
1 2 158 132 133
1 2 133 159 158
1 2 159 133 134
1 2 134 160 159
1 2 160 134 135
1 2 135 161 160
1 2 161 135 136
1 2 136 162 161
1 2 162 136 137
1 2 137 163 162
1 2 163 137 138
1 2 138 164 163
1 2 164 138 139
1 2 139 165 164
1 2 165 139 140
1 2 140 166 165
1 2 166 140 141
1 2 141 167 166
1 2 167 141 142
1 2 142 168 167
1 2 168 142 143
1 2 143 169 168
1 2 169 143 144
1 2 144 170 169
1 2 170 144 145
1 2 145 171 170
1 2 171 145 146
1 2 146 172 171
1 2 172 146 147
1 2 147 173 172
1 2 173 147 148
1 2 148 174 173
1 2 174 148 149
boundary
60
3 1 0 1
1 1 1 2
1 1 2 3
1 1 3 4
1 1 4 5
1 1 5 6
1 1 6 7
1 1 7 8
1 1 8 9
1 1 9 10
1 1 10 11
1 1 11 12
1 1 12 13
1 1 13 14
1 1 14 15
1 1 15 16
1 1 16 17
1 1 17 18
1 1 18 19
1 1 19 20
1 1 20 21
1 1 21 22
1 1 22 23
1 1 23 24
3 1 151 150
3 1 152 151
3 1 153 152
3 1 154 153
3 1 155 154
3 1 156 155
3 1 157 156
3 1 158 157
3 1 159 158
3 1 160 159
3 1 161 160
3 1 162 161
3 1 163 162
3 1 164 163
3 1 165 164
3 1 166 165
3 1 167 166
3 1 168 167
3 1 169 168
3 1 170 169
3 1 171 170
3 1 172 171
3 1 173 172
3 1 174 173
3 1 25 0
3 1 50 25
3 1 75 50
3 1 100 75
3 1 125 100
3 1 150 125
2 1 24 49
2 1 49 74
2 1 74 99
2 1 99 124
2 1 124 149
2 1 149 174
vertices
175
2
0 0
0.1666666666666666 0
0.3333333333333333 0
0.5 0
0.6666666666666666 0
0.8333333333333333 0
1 0
1.1666667 0
1.333333333333333 0
1.5 0
1.666666666666666 0
1.8333333 0
2 0
2.1666667 0
2.333333333333333 0
2.5 0
2.666666666666666 0
2.8333333 0
3 0
3.1666667 0
3.333333333333333 0
3.5 0
3.666666666666666 0
3.8333333 0
4 0
0 0.1666666666666666
0.1666666666666666 0.1666666666666666
0.3333333333333333 0.1666666666666666
0.5 0.1666666666666666
0.6666666666666666 0.1666666666666666
0.8333333333333333 0.1666666666666666
1 0.1666666666666666
1.1666667 0.1666666666666666
1.333333333333333 0.1666666666666666
1.5 0.1666666666666666
1.666666666666666 0.1666666666666666
1.8333333 0.1666666666666666
2 0.1666666666666666
2.1666667 0.1666666666666666
2.333333333333333 0.1666666666666666
2.5 0.1666666666666666
2.666666666666666 0.1666666666666666
2.8333333 0.1666666666666666
3 0.1666666666666666
3.1666667 0.1666666666666666
3.333333333333333 0.1666666666666666
3.5 0.1666666666666666
3.666666666666666 0.1666666666666666
3.8333333 0.1666666666666666
4 0.1666666666666666
0 0.3333333333333333
0.1666666666666666 0.3333333333333333
0.3333333333333333 0.3333333333333333
0.5 0.3333333333333333
0.6666666666666666 0.3333333333333333
0.8333333333333333 0.3333333333333333
1 0.3333333333333333
1.1666667 0.3333333333333333
1.333333333333333 0.3333333333333333
1.5 0.3333333333333333
1.666666666666666 0.3333333333333333
1.8333333 0.3333333333333333
2 0.3333333333333333
2.1666667 0.3333333333333333
2.333333333333333 0.3333333333333333
2.5 0.3333333333333333
2.666666666666666 0.3333333333333333
2.8333333 0.3333333333333333
3 0.3333333333333333
3.1666667 0.3333333333333333
3.333333333333333 0.3333333333333333
3.5 0.3333333333333333
3.666666666666666 0.3333333333333333
3.8333333 0.3333333333333333
4 0.3333333333333333
0 0.5
0.1666666666666666 0.5
0.3333333333333333 0.5
0.5 0.5
0.6666666666666666 0.5
0.8333333333333333 0.5
1 0.5
1.1666667 0.5
1.333333333333333 0.5
1.5 0.5
1.666666666666666 0.5
1.8333333 0.5
2 0.5
2.1666667 0.5
2.333333333333333 0.5
2.5 0.5
2.666666666666666 0.5
2.8333333 0.5
3 0.5
3.1666667 0.5
3.333333333333333 0.5
3.5 0.5
3.666666666666666 0.5
3.8333333 0.5
4 0.5
0 0.6666666666666666
0.1666666666666666 0.6666666666666666
0.3333333333333333 0.6666666666666666
0.5 0.6666666666666666
0.6666666666666666 0.6666666666666666
0.8333333333333333 0.6666666666666666
1 0.6666666666666666
1.1666667 0.6666666666666666
1.333333333333333 0.6666666666666666
1.5 0.6666666666666666
1.666666666666666 0.6666666666666666
1.8333333 0.6666666666666666
2 0.6666666666666666
2.1666667 0.6666666666666666
2.333333333333333 0.6666666666666666
2.5 0.6666666666666666
2.666666666666666 0.6666666666666666
2.8333333 0.6666666666666666
3 0.6666666666666666
3.1666667 0.6666666666666666
3.333333333333333 0.6666666666666666
3.5 0.6666666666666666
3.666666666666666 0.6666666666666666
3.8333333 0.6666666666666666
4 0.6666666666666666
0 0.8333333333333333
0.1666666666666666 0.8333333333333333
0.3333333333333333 0.8333333333333333
0.5 0.8333333333333333
0.6666666666666666 0.8333333333333333
0.8333333333333333 0.8333333333333333
1 0.8333333333333333
1.1666667 0.8333333333333333
1.333333333333333 0.8333333333333333
1.5 0.8333333333333333
1.666666666666666 0.8333333333333333
1.8333333 0.8333333333333333
2 0.8333333333333333
2.1666667 0.8333333333333333
2.333333333333333 0.8333333333333333
2.5 0.8333333333333333
2.666666666666666 0.8333333333333333
2.8333333 0.8333333333333333
3 0.8333333333333333
3.1666667 0.8333333333333333
3.333333333333333 0.8333333333333333
3.5 0.8333333333333333
3.666666666666666 0.8333333333333333
3.8333333 0.8333333333333333
4 0.8333333333333333
0 1
0.1666666666666666 1
0.3333333333333333 1
0.5 1
0.6666666666666666 1
0.8333333333333333 1
1 1
1.1666667 1
1.333333333333333 1
1.5 1
1.666666666666666 1
1.8333333 1
2 1
2.1666667 1
2.333333333333333 1
2.5 1
2.666666666666666 1
2.8333333 1
3 1
3.1666667 1
3.333333333333333 1
3.5 1
3.666666666666666 1
3.8333333 1
4 1
+7
View File
@@ -0,0 +1,7 @@
MFEM INLINE mesh v1.0
type = quad
nx = 3
ny = 3
sx = 1.0
sy = 1.0
@@ -0,0 +1,5 @@
MFEM INLINE mesh v1.0
type = segment
nx = 3
sx = 1.0
+7
View File
@@ -0,0 +1,7 @@
MFEM INLINE mesh v1.0
type = tri
nx = 3
ny = 3
sx = 1.0
sy = 1.0
+7
View File
@@ -0,0 +1,7 @@
MFEM INLINE mesh v1.0
type = quad
nx = 4
ny = 4
sx = 1.0
sy = 1.0
@@ -0,0 +1,5 @@
MFEM INLINE mesh v1.0
type = segment
nx = 4
sx = 1.0
+7
View File
@@ -0,0 +1,7 @@
MFEM INLINE mesh v1.0
type = tri
nx = 4
ny = 4
sx = 1.0
sy = 1.0
+9
View File
@@ -0,0 +1,9 @@
MFEM INLINE mesh v1.0
type = hex
nx = 4
ny = 4
nz = 4
sx = 1.0
sy = 1.0
sz = 1.0
+83
View File
@@ -0,0 +1,83 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
#
dimension
2
elements
16
1 3 0 1 6 5
1 3 1 2 7 6
1 3 6 7 12 11
1 3 5 6 11 10
1 3 10 11 16 15
1 3 15 16 21 20
1 3 16 17 22 21
1 3 11 12 17 16
1 3 12 13 18 17
1 3 17 18 23 22
1 3 18 19 24 23
1 3 13 14 19 18
1 3 8 9 14 13
1 3 7 8 13 12
1 3 2 3 8 7
1 3 3 4 9 8
boundary
16
1 1 0 1
1 1 1 2
1 1 2 3
1 1 3 4
2 1 21 20
2 1 22 21
2 1 23 22
2 1 24 23
1 1 5 0
1 1 10 5
1 1 15 10
1 1 20 15
2 1 4 9
2 1 9 14
2 1 14 19
2 1 19 24
vertices
25
2
0 0
0.25 0
0.5 0
0.75 0
1 0
0 0.25
0.25 0.25
0.5 0.25
0.75 0.25
1 0.25
0 0.5
0.25 0.5
0.5 0.5
0.75 0.5
1 0.5
0 0.75
0.25 0.75
0.5 0.75
0.75 0.75
1 0.75
0 1
0.25 1
0.5 1
0.75 1
1 1
@@ -0,0 +1,83 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
#
dimension
2
elements
16
1 3 0 1 6 5
1 3 1 2 7 6
1 3 6 7 12 11
1 3 5 6 11 10
1 3 10 11 16 15
1 3 15 16 21 20
1 3 16 17 22 21
1 3 11 12 17 16
1 3 12 13 18 17
1 3 17 18 23 22
1 3 18 19 24 23
1 3 13 14 19 18
1 3 8 9 14 13
1 3 7 8 13 12
1 3 2 3 8 7
1 3 3 4 9 8
boundary
16
2 1 0 1
2 1 1 2
2 1 2 3
2 1 3 4
2 1 21 20
2 1 22 21
2 1 23 22
2 1 24 23
2 1 5 0
2 1 10 5
2 1 15 10
2 1 20 15
2 1 4 9
2 1 9 14
2 1 14 19
2 1 19 24
vertices
25
2
0 0
0.25 0
0.5 0
0.75 0
1 0
0 0.25
0.25 0.25
0.5 0.25
0.75 0.25
1 0.25
0 0.5
0.25 0.5
0.5 0.5
0.75 0.5
1 0.5
0 0.75
0.25 0.75
0.5 0.75
0.75 0.75
1 0.75
0 1
0.25 1
0.5 1
0.75 1
1 1
+88
View File
@@ -0,0 +1,88 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
#
dimension
2
# format: <attribute> <geometry type> <vertex 0> <vertex 1> ...
elements
9
1 3 0 1 4 3
2 3 1 2 5 4
3 3 2 0 3 5
4 3 3 4 7 6
5 3 4 5 8 7
6 3 5 3 6 8
7 3 6 7 1 0
8 3 7 8 2 1
9 3 8 6 0 2
boundary
0
vertices
9
nodes
FiniteElementSpace
FiniteElementCollection: L2_T1_2D_P1
VDim: 2
Ordering: 1
0 0
0.3333333333333333 0
0 0.3333333333333333
0.3333333333333333 0.3333333333333333
0.3333333333333333 0
0.6666666666666666 0
0.3333333333333333 0.3333333333333333
0.6666666666666666 0.3333333333333333
0.6666666666666666 0
1 0
0.6666666666666666 0.3333333333333333
1 0.3333333333333333
0 0.3333333333333333
0.3333333333333333 0.3333333333333333
0 0.6666666666666666
0.3333333333333333 0.6666666666666666
0.3333333333333333 0.3333333333333333
0.6666666666666666 0.3333333333333333
0.3333333333333333 0.6666666666666666
0.6666666666666666 0.6666666666666666
0.6666666666666666 0.3333333333333333
1 0.3333333333333333
0.6666666666666666 0.6666666666666666
1 0.6666666666666666
0 0.6666666666666666
0.3333333333333333 0.6666666666666666
0 1
0.3333333333333333 1
0.3333333333333333 0.6666666666666666
0.6666666666666666 0.6666666666666666
0.3333333333333333 1
0.6666666666666666 1
0.6666666666666666 0.6666666666666666
1 0.6666666666666666
0.6666666666666666 1
1 1
0.3333333333333333
0.6666666666666666
@@ -0,0 +1,38 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
#
dimension
1
# format: <attribute> <geometry type> <vertex 0> <vertex 1> ...
elements
3
1 1 0 1
1 1 1 2
1 1 2 0
boundary
0
vertices
3
nodes
FiniteElementSpace
FiniteElementCollection: L2_T1_1D_P1
VDim: 1
Ordering: 1
0.0000000000000000 0.3333333333333333
0.3333333333333333 0.6666666666666666
0.6666666666666666 1.0000000000000000
+121
View File
@@ -0,0 +1,121 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
#
dimension
2
# format: <attribute> <geometry type> <vertex 0> <vertex 1> ...
elements
18
1 2 0 1 4
1 2 0 4 3
1 2 1 2 5
1 2 1 5 4
1 2 2 0 3
1 2 2 3 5
1 2 3 4 7
1 2 3 7 6
1 2 4 5 8
1 2 4 8 7
1 2 5 3 6
1 2 5 6 8
1 2 6 7 1
1 2 6 1 0
1 2 7 8 2
1 2 7 2 1
1 2 8 6 0
1 2 8 0 2
boundary
0
vertices
9
nodes
FiniteElementSpace
FiniteElementCollection: L2_T1_2D_P1
VDim: 2
Ordering: 1
0.0000000000000000 0.0000000000000000
0.3333333333333333 0.0000000000000000
0.3333333333333333 0.3333333333333333
0.0000000000000000 0.0000000000000000
0.3333333333333333 0.3333333333333333
0.0000000000000000 0.3333333333333333
0.3333333333333333 0.0000000000000000
0.6666666666666666 0.0000000000000000
0.6666666666666666 0.3333333333333333
0.3333333333333333 0.0000000000000000
0.6666666666666666 0.3333333333333333
0.3333333333333333 0.3333333333333333
0.6666666666666666 0.0000000000000000
1.0000000000000000 0.0000000000000000
1.0000000000000000 0.3333333333333333
0.6666666666666666 0.0000000000000000
1.0000000000000000 0.3333333333333333
0.6666666666666666 0.3333333333333333
0.0000000000000000 0.3333333333333333
0.3333333333333333 0.3333333333333333
0.3333333333333333 0.6666666666666666
0.0000000000000000 0.3333333333333333
0.3333333333333333 0.6666666666666666
0.0000000000000000 0.6666666666666666
0.3333333333333333 0.3333333333333333
0.6666666666666666 0.3333333333333333
0.6666666666666666 0.6666666666666666
0.3333333333333333 0.3333333333333333
0.6666666666666666 0.6666666666666666
0.3333333333333333 0.6666666666666666
0.6666666666666666 0.3333333333333333
1.0000000000000000 0.3333333333333333
1.0000000000000000 0.6666666666666666
0.6666666666666666 0.3333333333333333
1.0000000000000000 0.6666666666666666
0.6666666666666666 0.6666666666666666
0.0000000000000000 0.6666666666666666
0.3333333333333333 0.6666666666666666
0.3333333333333333 1.0000000000000000
0.0000000000000000 0.6666666666666666
0.3333333333333333 1.0000000000000000
0.0000000000000000 1.0000000000000000
0.3333333333333333 0.6666666666666666
0.6666666666666666 0.6666666666666666
0.6666666666666666 1.0000000000000000
0.3333333333333333 0.6666666666666666
0.6666666666666666 1.0000000000000000
0.3333333333333333 1.0000000000000000
0.6666666666666666 0.6666666666666666
1.0000000000000000 0.6666666666666666
1.0000000000000000 1.0000000000000000
0.6666666666666666 0.6666666666666666
1.0000000000000000 1.0000000000000000
0.6666666666666666 1.0000000000000000
+127
View File
@@ -0,0 +1,127 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
#
dimension
2
# format: <attribute> <geometry type> <vertex 0> <vertex 1> ...
elements
16
1 3 0 1 5 4
2 3 1 2 6 5
3 3 2 3 7 6
4 3 3 0 4 7
5 3 4 5 9 8
6 3 5 6 10 9
7 3 6 7 11 10
8 3 7 4 8 11
9 3 8 9 13 12
10 3 9 10 14 13
11 3 10 11 15 14
12 3 11 8 12 15
13 3 12 13 1 0
14 3 13 14 2 1
15 3 14 15 3 2
16 3 15 12 0 3
boundary
0
vertices
16
nodes
FiniteElementSpace
FiniteElementCollection: L2_T1_2D_P1
VDim: 2
Ordering: 1
0 0
0.25 0
0 0.25
0.25 0.25
0.25 0
0.5 0
0.25 0.25
0.5 0.25
0.5 0
0.75 0
0.5 0.25
0.75 0.25
0.75 0
1 0
0.75 0.25
1 0.25
0 0.25
0.25 0.25
0 0.5
0.25 0.5
0.25 0.25
0.5 0.25
0.25 0.5
0.5 0.5
0.5 0.25
0.75 0.25
0.5 0.5
0.75 0.5
0.75 0.25
1 0.25
0.75 0.5
1 0.5
0 0.5
0.25 0.5
0 0.75
0.25 0.75
0.25 0.5
0.5 0.5
0.25 0.75
0.5 0.75
0.5 0.5
0.75 0.5
0.5 0.75
0.75 0.75
0.75 0.5
1 0.5
0.75 0.75
1 0.75
0 0.75
0.25 0.75
0 1
0.25 1
0.25 0.75
0.5 0.75
0.25 1
0.5 1
0.5 0.75
0.75 0.75
0.5 1
0.75 1
0.75 0.75
1 0.75
0.75 1
1 1
@@ -0,0 +1,40 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
#
dimension
1
# format: <attribute> <geometry type> <vertex 0> <vertex 1> ...
elements
4
1 1 0 1
1 1 1 2
1 1 2 3
1 1 3 0
boundary
0
vertices
4
nodes
FiniteElementSpace
FiniteElementCollection: L2_T1_1D_P1
VDim: 1
Ordering: 1
0 0.25
0.25 0.5
0.5 0.75
0.75 1
+191
View File
@@ -0,0 +1,191 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
#
dimension
2
# format: <attribute> <geometry type> <vertex 0> <vertex 1> ...
elements
32
1 2 0 1 5
1 2 0 5 4
1 2 1 2 6
1 2 1 6 5
1 2 2 3 7
1 2 2 7 6
1 2 3 0 4
1 2 3 4 7
1 2 4 5 9
1 2 4 9 8
1 2 5 6 10
1 2 5 10 9
1 2 6 7 11
1 2 6 11 10
1 2 7 4 8
1 2 7 8 11
1 2 8 9 13
1 2 8 13 12
1 2 9 10 14
1 2 9 14 13
1 2 10 11 15
1 2 10 15 14
1 2 11 8 12
1 2 11 12 15
1 2 12 13 1
1 2 12 1 0
1 2 13 14 2
1 2 13 2 1
1 2 14 15 3
1 2 14 3 2
1 2 15 12 0
1 2 15 0 3
boundary
0
vertices
16
nodes
FiniteElementSpace
FiniteElementCollection: L2_T1_2D_P1
VDim: 2
Ordering: 1
0 0
0.25 0
0.25 0.25
0 0
0.25 0.25
0 0.25
0.25 0
0.5 0
0.5 0.25
0.25 0
0.5 0.25
0.25 0.25
0.5 0
0.75 0
0.75 0.25
0.5 0
0.75 0.25
0.5 0.25
0.75 0
1 0
1 0.25
0.75 0
1 0.25
0.75 0.25
0 0.25
0.25 0.25
0.25 0.5
0 0.25
0.25 0.5
0 0.5
0.25 0.25
0.5 0.25
0.5 0.5
0.25 0.25
0.5 0.5
0.25 0.5
0.5 0.25
0.75 0.25
0.75 0.5
0.5 0.25
0.75 0.5
0.5 0.5
0.75 0.25
1 0.25
1 0.5
0.75 0.25
1 0.5
0.75 0.5
0 0.5
0.25 0.5
0.25 0.75
0 0.5
0.25 0.75
0 0.75
0.25 0.5
0.5 0.5
0.5 0.75
0.25 0.5
0.5 0.75
0.25 0.75
0.5 0.5
0.75 0.5
0.75 0.75
0.5 0.5
0.75 0.75
0.5 0.75
0.75 0.5
1 0.5
1 0.75
0.75 0.5
1 0.75
0.75 0.75
0 0.75
0.25 0.75
0.25 1
0 0.75
0.25 1
0 1
0.25 0.75
0.5 0.75
0.5 1
0.25 0.75
0.5 1
0.25 1
0.5 0.75
0.75 0.75
0.75 1
0.5 0.75
0.75 1
0.5 1
0.75 0.75
1 0.75
1 1
0.75 0.75
1 1
0.75 1
@@ -0,0 +1,37 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
#
dimension
1
elements
4
1 1 0 1
1 1 1 2
1 1 2 3
1 1 3 4
boundary
2
3 0 0
3 0 4
vertices
5
1
0
0.25
0.5
0.75
1
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,229 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
#
dimension
1
elements
100
1 1 0 1
1 1 1 2
1 1 2 3
1 1 3 4
1 1 4 5
1 1 5 6
1 1 6 7
1 1 7 8
1 1 8 9
1 1 9 10
1 1 10 11
1 1 11 12
1 1 12 13
1 1 13 14
1 1 14 15
1 1 15 16
1 1 16 17
1 1 17 18
1 1 18 19
1 1 19 20
1 1 20 21
1 1 21 22
1 1 22 23
1 1 23 24
1 1 24 25
1 1 25 26
1 1 26 27
1 1 27 28
1 1 28 29
1 1 29 30
1 1 30 31
1 1 31 32
1 1 32 33
1 1 33 34
1 1 34 35
1 1 35 36
1 1 36 37
1 1 37 38
1 1 38 39
1 1 39 40
1 1 40 41
1 1 41 42
1 1 42 43
1 1 43 44
1 1 44 45
1 1 45 46
1 1 46 47
1 1 47 48
1 1 48 49
1 1 49 50
1 1 50 51
1 1 51 52
1 1 52 53
1 1 53 54
1 1 54 55
1 1 55 56
1 1 56 57
1 1 57 58
1 1 58 59
1 1 59 60
1 1 60 61
1 1 61 62
1 1 62 63
1 1 63 64
1 1 64 65
1 1 65 66
1 1 66 67
1 1 67 68
1 1 68 69
1 1 69 70
1 1 70 71
1 1 71 72
1 1 72 73
1 1 73 74
1 1 74 75
1 1 75 76
1 1 76 77
1 1 77 78
1 1 78 79
1 1 79 80
1 1 80 81
1 1 81 82
1 1 82 83
1 1 83 84
1 1 84 85
1 1 85 86
1 1 86 87
1 1 87 88
1 1 88 89
1 1 89 90
1 1 90 91
1 1 91 92
1 1 92 93
1 1 93 94
1 1 94 95
1 1 95 96
1 1 96 97
1 1 97 98
1 1 98 99
1 1 99 100
boundary
2
1 0 0
1 0 100
vertices
101
1
0
0.01
0.02
0.03
0.04
0.05
0.06
0.07
0.08
0.09
0.10
0.11
0.12
0.13
0.14
0.15
0.16
0.17
0.18
0.19
0.20
0.21
0.22
0.23
0.24
0.25
0.26
0.27
0.28
0.29
0.30
0.31
0.32
0.33
0.34
0.35
0.36
0.37
0.38
0.39
0.40
0.41
0.42
0.43
0.44
0.45
0.46
0.47
0.48
0.49
0.50
0.51
0.52
0.53
0.54
0.55
0.56
0.57
0.58
0.59
0.60
0.61
0.62
0.63
0.64
0.65
0.66
0.67
0.68
0.69
0.70
0.71
0.72
0.73
0.74
0.75
0.76
0.77
0.78
0.79
0.80
0.81
0.82
0.83
0.84
0.85
0.86
0.87
0.88
0.89
0.90
0.91
0.92
0.93
0.94
0.95
0.96
0.97
0.98
0.99
1
+311
View File
@@ -0,0 +1,311 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
#
dimension
3
elements
64
1 5 0 1 6 5 25 26 31 30
1 5 25 26 31 30 50 51 56 55
1 5 26 27 32 31 51 52 57 56
1 5 1 2 7 6 26 27 32 31
1 5 6 7 12 11 31 32 37 36
1 5 31 32 37 36 56 57 62 61
1 5 30 31 36 35 55 56 61 60
1 5 5 6 11 10 30 31 36 35
1 5 10 11 16 15 35 36 41 40
1 5 11 12 17 16 36 37 42 41
1 5 16 17 22 21 41 42 47 46
1 5 15 16 21 20 40 41 46 45
1 5 40 41 46 45 65 66 71 70
1 5 41 42 47 46 66 67 72 71
1 5 36 37 42 41 61 62 67 66
1 5 35 36 41 40 60 61 66 65
1 5 60 61 66 65 85 86 91 90
1 5 61 62 67 66 86 87 92 91
1 5 66 67 72 71 91 92 97 96
1 5 65 66 71 70 90 91 96 95
1 5 90 91 96 95 115 116 121 120
1 5 91 92 97 96 116 117 122 121
1 5 86 87 92 91 111 112 117 116
1 5 85 86 91 90 110 111 116 115
1 5 80 81 86 85 105 106 111 110
1 5 75 76 81 80 100 101 106 105
1 5 50 51 56 55 75 76 81 80
1 5 55 56 61 60 80 81 86 85
1 5 56 57 62 61 81 82 87 86
1 5 51 52 57 56 76 77 82 81
1 5 76 77 82 81 101 102 107 106
1 5 81 82 87 86 106 107 112 111
1 5 82 83 88 87 107 108 113 112
1 5 77 78 83 82 102 103 108 107
1 5 52 53 58 57 77 78 83 82
1 5 57 58 63 62 82 83 88 87
1 5 58 59 64 63 83 84 89 88
1 5 53 54 59 58 78 79 84 83
1 5 78 79 84 83 103 104 109 108
1 5 83 84 89 88 108 109 114 113
1 5 88 89 94 93 113 114 119 118
1 5 87 88 93 92 112 113 118 117
1 5 92 93 98 97 117 118 123 122
1 5 93 94 99 98 118 119 124 123
1 5 68 69 74 73 93 94 99 98
1 5 67 68 73 72 92 93 98 97
1 5 62 63 68 67 87 88 93 92
1 5 63 64 69 68 88 89 94 93
1 5 38 39 44 43 63 64 69 68
1 5 37 38 43 42 62 63 68 67
1 5 42 43 48 47 67 68 73 72
1 5 43 44 49 48 68 69 74 73
1 5 18 19 24 23 43 44 49 48
1 5 17 18 23 22 42 43 48 47
1 5 12 13 18 17 37 38 43 42
1 5 13 14 19 18 38 39 44 43
1 5 8 9 14 13 33 34 39 38
1 5 33 34 39 38 58 59 64 63
1 5 32 33 38 37 57 58 63 62
1 5 7 8 13 12 32 33 38 37
1 5 2 3 8 7 27 28 33 32
1 5 27 28 33 32 52 53 58 57
1 5 28 29 34 33 53 54 59 58
1 5 3 4 9 8 28 29 34 33
boundary
96
1 3 0 5 6 1
1 3 1 6 7 2
1 3 2 7 8 3
1 3 3 8 9 4
1 3 5 10 11 6
1 3 6 11 12 7
1 3 7 12 13 8
1 3 8 13 14 9
1 3 10 15 16 11
1 3 11 16 17 12
1 3 12 17 18 13
1 3 13 18 19 14
1 3 15 20 21 16
1 3 16 21 22 17
1 3 17 22 23 18
1 3 18 23 24 19
1 3 100 101 106 105
1 3 101 102 107 106
1 3 102 103 108 107
1 3 103 104 109 108
1 3 105 106 111 110
1 3 106 107 112 111
1 3 107 108 113 112
1 3 108 109 114 113
1 3 110 111 116 115
1 3 111 112 117 116
1 3 112 113 118 117
1 3 113 114 119 118
1 3 115 116 121 120
1 3 116 117 122 121
1 3 117 118 123 122
1 3 118 119 124 123
1 3 0 25 30 5
1 3 5 30 35 10
1 3 10 35 40 15
1 3 15 40 45 20
1 3 25 50 55 30
1 3 30 55 60 35
1 3 35 60 65 40
1 3 40 65 70 45
1 3 50 75 80 55
1 3 55 80 85 60
1 3 60 85 90 65
1 3 65 90 95 70
1 3 75 100 105 80
1 3 80 105 110 85
1 3 85 110 115 90
1 3 90 115 120 95
1 3 4 9 34 29
1 3 9 14 39 34
1 3 14 19 44 39
1 3 19 24 49 44
1 3 29 34 59 54
1 3 34 39 64 59
1 3 39 44 69 64
1 3 44 49 74 69
1 3 54 59 84 79
1 3 59 64 89 84
1 3 64 69 94 89
1 3 69 74 99 94
1 3 79 84 109 104
1 3 84 89 114 109
1 3 89 94 119 114
1 3 94 99 124 119
1 3 0 1 26 25
1 3 25 26 51 50
1 3 50 51 76 75
1 3 75 76 101 100
1 3 1 2 27 26
1 3 26 27 52 51
1 3 51 52 77 76
1 3 76 77 102 101
1 3 2 3 28 27
1 3 27 28 53 52
1 3 52 53 78 77
1 3 77 78 103 102
1 3 3 4 29 28
1 3 28 29 54 53
1 3 53 54 79 78
1 3 78 79 104 103
1 3 20 45 46 21
1 3 45 70 71 46
1 3 70 95 96 71
1 3 95 120 121 96
1 3 21 46 47 22
1 3 46 71 72 47
1 3 71 96 97 72
1 3 96 121 122 97
1 3 22 47 48 23
1 3 47 72 73 48
1 3 72 97 98 73
1 3 97 122 123 98
1 3 23 48 49 24
1 3 48 73 74 49
1 3 73 98 99 74
1 3 98 123 124 99
vertices
125
3
0 0 0
0.25 0 0
0.5 0 0
0.75 0 0
1 0 0
0 0.25 0
0.25 0.25 0
0.5 0.25 0
0.75 0.25 0
1 0.25 0
0 0.5 0
0.25 0.5 0
0.5 0.5 0
0.75 0.5 0
1 0.5 0
0 0.75 0
0.25 0.75 0
0.5 0.75 0
0.75 0.75 0
1 0.75 0
0 1 0
0.25 1 0
0.5 1 0
0.75 1 0
1 1 0
0 0 0.25
0.25 0 0.25
0.5 0 0.25
0.75 0 0.25
1 0 0.25
0 0.25 0.25
0.25 0.25 0.25
0.5 0.25 0.25
0.75 0.25 0.25
1 0.25 0.25
0 0.5 0.25
0.25 0.5 0.25
0.5 0.5 0.25
0.75 0.5 0.25
1 0.5 0.25
0 0.75 0.25
0.25 0.75 0.25
0.5 0.75 0.25
0.75 0.75 0.25
1 0.75 0.25
0 1 0.25
0.25 1 0.25
0.5 1 0.25
0.75 1 0.25
1 1 0.25
0 0 0.5
0.25 0 0.5
0.5 0 0.5
0.75 0 0.5
1 0 0.5
0 0.25 0.5
0.25 0.25 0.5
0.5 0.25 0.5
0.75 0.25 0.5
1 0.25 0.5
0 0.5 0.5
0.25 0.5 0.5
0.5 0.5 0.5
0.75 0.5 0.5
1 0.5 0.5
0 0.75 0.5
0.25 0.75 0.5
0.5 0.75 0.5
0.75 0.75 0.5
1 0.75 0.5
0 1 0.5
0.25 1 0.5
0.5 1 0.5
0.75 1 0.5
1 1 0.5
0 0 0.75
0.25 0 0.75
0.5 0 0.75
0.75 0 0.75
1 0 0.75
0 0.25 0.75
0.25 0.25 0.75
0.5 0.25 0.75
0.75 0.25 0.75
1 0.25 0.75
0 0.5 0.75
0.25 0.5 0.75
0.5 0.5 0.75
0.75 0.5 0.75
1 0.5 0.75
0 0.75 0.75
0.25 0.75 0.75
0.5 0.75 0.75
0.75 0.75 0.75
1 0.75 0.75
0 1 0.75
0.25 1 0.75
0.5 1 0.75
0.75 1 0.75
1 1 0.75
0 0 1
0.25 0 1
0.5 0 1
0.75 0 1
1 0 1
0 0.25 1
0.25 0.25 1
0.5 0.25 1
0.75 0.25 1
1 0.25 1
0 0.5 1
0.25 0.5 1
0.5 0.5 1
0.75 0.5 1
1 0.5 1
0 0.75 1
0.25 0.75 1
0.5 0.75 1
0.75 0.75 1
1 0.75 1
0 1 1
0.25 1 1
0.5 1 1
0.75 1 1
1 1 1
+83
View File
@@ -0,0 +1,83 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
#
dimension
2
elements
16
1 3 0 1 6 5
1 3 1 2 7 6
1 3 6 7 12 11
1 3 5 6 11 10
1 3 10 11 16 15
1 3 15 16 21 20
1 3 16 17 22 21
1 3 11 12 17 16
1 3 12 13 18 17
1 3 17 18 23 22
1 3 18 19 24 23
1 3 13 14 19 18
1 3 8 9 14 13
1 3 7 8 13 12
1 3 2 3 8 7
1 3 3 4 9 8
boundary
16
1 1 0 1
1 1 1 2
1 1 2 3
1 1 3 4
1 1 21 20
1 1 22 21
1 1 23 22
1 1 24 23
1 1 5 0
1 1 10 5
1 1 15 10
1 1 20 15
1 1 4 9
1 1 9 14
1 1 14 19
1 1 19 24
vertices
25
2
0 0
0.25 0
0.5 0
0.75 0
1 0
0 0.25
0.25 0.25
0.5 0.25
0.75 0.25
1 0.25
0 0.5
0.25 0.5
0.5 0.5
0.75 0.5
1 0.5
0 0.75
0.25 0.75
0.5 0.75
0.75 0.75
1 0.75
0 1
0.25 1
0.5 1
0.75 1
1 1
@@ -0,0 +1,37 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
#
dimension
1
elements
4
1 1 0 1
1 1 1 2
1 1 2 3
1 1 3 4
boundary
2
1 0 0
1 0 4
vertices
5
1
0
0.25
0.5
0.75
1
+99
View File
@@ -0,0 +1,99 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
#
dimension
2
elements
32
1 2 0 6 5
1 2 6 0 1
1 2 1 7 6
1 2 7 1 2
1 2 2 8 7
1 2 8 2 3
1 2 3 9 8
1 2 9 3 4
1 2 5 11 10
1 2 11 5 6
1 2 6 12 11
1 2 12 6 7
1 2 7 13 12
1 2 13 7 8
1 2 8 14 13
1 2 14 8 9
1 2 10 16 15
1 2 16 10 11
1 2 11 17 16
1 2 17 11 12
1 2 12 18 17
1 2 18 12 13
1 2 13 19 18
1 2 19 13 14
1 2 15 21 20
1 2 21 15 16
1 2 16 22 21
1 2 22 16 17
1 2 17 23 22
1 2 23 17 18
1 2 18 24 23
1 2 24 18 19
boundary
16
1 1 0 1
1 1 1 2
1 1 2 3
1 1 3 4
1 1 21 20
1 1 22 21
1 1 23 22
1 1 24 23
1 1 5 0
1 1 10 5
1 1 15 10
1 1 20 15
1 1 4 9
1 1 9 14
1 1 14 19
1 1 19 24
vertices
25
2
0 0
0.25 0
0.5 0
0.75 0
1 0
0 0.25
0.25 0.25
0.5 0.25
0.75 0.25
1 0.25
0 0.5
0.25 0.5
0.5 0.5
0.75 0.5
1 0.5
0 0.75
0.25 0.75
0.5 0.75
0.75 0.75
1 0.75
0 1
0.25 1
0.5 1
0.75 1
1 1
+316
View File
@@ -0,0 +1,316 @@
#include "fe_evol.hpp"
FE_Evolution::FE_Evolution(FiniteElementSpace *fes_, HyperbolicSystem *hyp_,
DofInfo &dofs_)
: TimeDependentOperator(fes_->GetVSize()), fes(fes_), hyp(hyp_),
dofs(dofs_), z(fes_->GetVSize()), inflow(fes_),
xSizeMPI(dofs_.fes->GetVSize())
{
const char* fecol = fes->FEColl()->Name();
if (strncmp(fecol, "L2", 2))
{
MFEM_ABORT("FiniteElementSpace must be L2 conforming (DG).");
}
if (strncmp(fecol, "L2_T2", 5))
{
MFEM_ABORT("Shape functions must be represented in Bernstein basis.");
}
// Initialize member variables.
IntRuleElem = GetElementIntegrationRule(fes);
IntRuleFace = GetFaceIntegrationRule(fes);
IntRuleFaceWeights.SetSize(IntRuleFace->GetNPoints());
Mesh *mesh = fes->GetMesh();
const FiniteElement *el = fes->GetFE(0);
dim = mesh->Dimension();
nd = el->GetDof();
ne = mesh->GetNE();
nqe = IntRuleElem->GetNPoints();
nqf = IntRuleFace->GetNPoints();
ShapeEval.SetSize(nd,nqe);
DShapeEval.SetSize(nd,dim,nqe);
ShapeEvalFace.SetSize(dofs.NumBdrs, dofs.NumFaceDofs, nqf);
ElemInt.SetSize(dim, dim, ne*nqe);
BdrInt.SetSize(dofs.NumBdrs, nqf, ne);
OuterUnitNormals.SetSize(dim, nqf, ne*dofs.NumBdrs);
MassMat = new MassMatrixDG(fes);
InvMassMat = new InverseMassMatrixDG(MassMat);
Vector aux_vec(hyp->NumEq);
aux_vec = 1.0;
VectorConstantCoefficient ones(aux_vec);
BilinearForm ml(fes);
ml.AddDomainIntegrator(new LumpedIntegrator(new VectorMassIntegrator(ones)));
ml.Assemble();
ml.Finalize();
ml.SpMat().GetDiag(LumpedMassMat);
uElem.SetSize(nd);
uEval.SetSize(hyp->NumEq);
uNbrEval.SetSize(hyp->NumEq);
normal.SetSize(dim);
NumFlux.SetSize(hyp->NumEq);
Flux.SetSize(hyp->NumEq, dim);
FluxNbr.SetSize(hyp->NumEq, dim);
mat1.SetSize(dim, hyp->NumEq);
mat2.SetSize(nd, hyp->NumEq);
// Precompute data that is constant for the whole run.
Array <int> bdrs, orientation;
Vector shape(nd);
DenseMatrix dshape(nd,dim);
DenseMatrix adjJ(dim);
Array<IntegrationPoint> eip(nqf*dofs.NumBdrs);
// Fill eip, to be used for evaluation of shape functions on element faces.
if (dim==1) { mesh->GetElementVertices(0, bdrs); }
else if (dim==2) { mesh->GetElementEdges(0, bdrs, orientation); }
else if (dim==3) { mesh->GetElementFaces(0, bdrs, orientation); }
for (int i = 0; i < dofs.NumBdrs; i++)
{
FaceElementTransformations *help
= mesh->GetFaceElementTransformations(bdrs[i]);
if (help->Elem1No != 0)
{
// NOTE: If this error ever occurs, use neighbor element to
// obtain the correct quadrature points and weight.
MFEM_ABORT("First element has inward pointing normal.");
}
for (int k = 0; k < nqf; k++)
{
const IntegrationPoint &ip = IntRuleFace->IntPoint(k);
help->Loc1.Transform(ip, eip[i*nqf + k]);
}
}
// Precompute evaluations of shape functions on elements.
for (int k = 0; k < nqe; k++)
{
const IntegrationPoint &ip = IntRuleElem->IntPoint(k);
el->CalcShape(ip, shape);
el->CalcDShape(ip, dshape);
ShapeEval.SetCol(k, shape);
DShapeEval(k) = dshape;
}
// Precompute evaluations of shape functions on element faces.
for (int k = 0; k < nqf; k++)
{
const IntegrationPoint &ip = IntRuleFace->IntPoint(k);
IntRuleFaceWeights(k) = ip.weight;
if (dim==1) { mesh->GetElementVertices(0, bdrs); }
else if (dim==2) { mesh->GetElementEdges(0, bdrs, orientation); }
else if (dim==3) { mesh->GetElementFaces(0, bdrs, orientation); }
for (int i = 0; i < dofs.NumBdrs; i++)
{
FaceElementTransformations *facetrans =
mesh->GetFaceElementTransformations(bdrs[i]);
IntegrationPoint eip;
facetrans->Face->SetIntPoint(&ip);
facetrans->Loc1.Transform(ip, eip);
el->CalcShape(eip, shape);
for (int j = 0; j < dofs.NumFaceDofs; j++)
{
ShapeEvalFace(i,j,k) = shape(dofs.BdrDofs(j,i));
}
}
}
for (int e = 0; e < ne; e++)
{
ElementTransformation *eltrans = fes->GetElementTransformation(e);
for (int k = 0; k < nqe; k++)
{
const IntegrationPoint &ip = IntRuleElem->IntPoint(k);
eltrans->SetIntPoint(&ip);
CalcAdjugate(eltrans->Jacobian(), adjJ);
adjJ *= ip.weight;
ElemInt(e*nqe+k) = adjJ;
}
if (dim==1) { mesh->GetElementVertices(e, bdrs); }
else if (dim==2) { mesh->GetElementEdges(e, bdrs, orientation); }
else if (dim==3) { mesh->GetElementFaces(e, bdrs, orientation); }
for (int i = 0; i < dofs.NumBdrs; i++)
{
Vector nor(dim);
FaceElementTransformations *facetrans
= mesh->GetFaceElementTransformations(bdrs[i]);
for (int k = 0; k < nqf; k++)
{
const IntegrationPoint &ip = IntRuleFace->IntPoint(k);
facetrans->Face->SetIntPoint(&ip);
if (dim == 1)
{
IntegrationPoint aux;
facetrans->Loc1.Transform(ip, aux);
nor(0) = 2.*aux.x - 1.0;
}
else
{
CalcOrtho(facetrans->Face->Jacobian(), nor);
}
if (facetrans->Elem1No != e)
{
nor *= -1.;
}
nor /= nor.Norml2();
BdrInt(i,k,e) = facetrans->Face->Weight();
for (int l = 0; l < dim; l++)
{
OuterUnitNormals(l,k,e*dofs.NumBdrs+i) = nor(l);
}
}
}
}
if (!hyp->TimeDepBC)
{
if (!hyp->ProjType)
{
hyp->L2_Projection(hyp->BdrCond, inflow);
}
else
{
inflow.ProjectCoefficient(hyp->BdrCond);
}
}
}
void FE_Evolution::ElemEval(const Vector &uElem, Vector &uEval, int k) const
{
uEval = 0.;
for (int n = 0; n < hyp->NumEq; n++)
{
for (int j = 0; j < nd; j++)
{
uEval(n) += uElem(n * nd + j) * ShapeEval(j, k);
}
}
}
void FE_Evolution::FaceEval(const Vector &x, Vector &y1, Vector &y2,
const Vector &xMPI, const Vector &normal,
int e, int i, int k) const
{
y1 = y2 = 0.;
for (int n = 0; n < hyp->NumEq; n++)
{
for (int j = 0; j < dofs.NumFaceDofs; j++)
{
nbr = dofs.NbrDofs(i, j, e);
DofInd = n * ne * nd + e * nd + dofs.BdrDofs(j, i);
if (nbr < 0)
{
uNbr = inflow(DofInd);
}
else
{
// nbr in different MPI task?
uNbr = (nbr < xSizeMPI) ? x(n * ne * nd + nbr) : xMPI(int((
nbr - xSizeMPI) / nd) * nd * hyp->NumEq + n * nd + (nbr - xSizeMPI) % nd);
}
y1(n) += x(DofInd) * ShapeEvalFace(i, j, k);
y2(n) += uNbr * ShapeEvalFace(i, j, k);
}
}
if (nbr < 0) // TODO better distinction
{
hyp->SetBdrCond(y1, y2, normal, nbr);
}
}
void FE_Evolution::LaxFriedrichs(const Vector &x1, const Vector &x2,
const Vector &normal, Vector &y,
int e, int k, int i) const
{
hyp->EvaluateFlux(x1, Flux, e, k, i);
hyp->EvaluateFlux(x2, FluxNbr, e, k, i);
Flux += FluxNbr;
double ws = max(hyp->GetWaveSpeed(x1, normal, e, k, i),
hyp->GetWaveSpeed(x2, normal, e, k, i));
subtract(ws, x1, x2, y);
Flux.AddMult(normal, y);
y *= 0.5;
}
void FE_Evolution::HLL(const Vector &x1, const Vector &x2, const Vector &normal,
Vector &y, int e, int k, int i) const
{
MFEM_ABORT("TODO. Implement properly.");
hyp->EvaluateFlux(x1, Flux, e, k, i);
hyp->EvaluateFlux(x2, FluxNbr, e, k, i);
double v1 = (x1(1) * normal(0) + x1(2) * normal(1)) / x1(0);
double v2 = (x2(1) * normal(0) + x2(2) * normal(1)) / x2(0);
// Note: Hardcoded for 2D Euler
// double p1 = 0.4 * ( x1(3) - 0.5 * (x1(1)*x1(1) + x1(2)*x1(2)) / x1(0) );
// double p2 = 0.4 * ( x2(3) - 0.5 * (x2(1)*x2(1) + x2(2)*x2(2)) / x2(0) );
// double c1 = sqrt(1.4 * p1 / x1(0));
// double c2 = sqrt(1.4 * p2 / x2(0));
// Note: Hardcoded for 2D SWE
double c1 = sqrt(1.0 * x1(0));
double c2 = sqrt(1.0 * x2(0));
double s1 = min(v1, v2) - max(c1, c2);
double s2 = max(v1, v2) + min(c1, c2);
if (s1 > 0.0) { Flux.Mult(normal, y); }
else if (s2 < 0.0) { FluxNbr.Mult(normal, y); }
else
{
subtract(s1*s2, x2, x1, y);
Flux.AddMult_a(s2, normal, y);
FluxNbr.AddMult_a(-s1, normal, y);
y /= (s2 -s1);
}
}
double FE_Evolution::ConvergenceCheck(double dt, const Vector &u) const
{
z = u;
z -= uOld;
double res = 0.;
if (!hyp->SteadyState) // Use consistent mass matrix.
{
MassMat->Mult(z, uOld);
res = uOld.Norml2() / dt;
}
else // Use lumped mass matrix.
{
for (int i = 0; i < u.Size(); i++)
{
res += pow(LumpedMassMat(i) * z(i), 2.);
}
res = sqrt(res) / dt;
}
uOld = u;
return res;
}
+75
View File
@@ -0,0 +1,75 @@
#ifndef HYPSYS_FE_EVOL
#define HYPSYS_FE_EVOL
#include "../lib/lib.hpp"
#include "../apps/hyperbolic_system.hpp"
using namespace std;
using namespace mfem;
// Auxiliary, only used to pass a non-used reference as parameter.
static Vector serial;
class FE_Evolution : public TimeDependentOperator
{
public:
// General member variables.
FiniteElementSpace *fes;
const HyperbolicSystem *hyp;
const IntegrationRule *IntRuleElem; // TODO rm const, *
const IntegrationRule *IntRuleFace;
Vector IntRuleFaceWeights;
// Parameters that are needed repeatedly.
int dim, nd, ne, nqe, nqf;
const int xSizeMPI;
// Shape function evaluations.
DenseMatrix ShapeEval;
DenseTensor DShapeEval;
DenseTensor ShapeEvalFace;
// Element and boundary integrals evaluated in quadrature points.
DenseTensor ElemInt;
DenseTensor BdrInt;
DenseTensor OuterUnitNormals;
// DG mass matrices.
const MassMatrixDG *MassMat;
const InverseMassMatrixDG *InvMassMat;
Vector LumpedMassMat;
// Tools to compute the discrete time derivative, needed repeatedly.
mutable DofInfo dofs;
mutable Array<int> vdofs;
mutable Vector z, uOld, uElem, uEval, uNbrEval, NumFlux, normal;
mutable DenseMatrix Flux, FluxNbr, mat1, mat2;
mutable int DofInd, nbr;
mutable double uNbr;
mutable GridFunction inflow;
FE_Evolution(FiniteElementSpace *fes_, HyperbolicSystem *hyp_,
DofInfo &dofs_);
virtual ~FE_Evolution()
{
delete MassMat;
delete InvMassMat;
}
virtual void Mult(const Vector &x, Vector &y) const = 0;
virtual void ElemEval(const Vector &uElem, Vector &uEval, int k) const;
virtual void FaceEval(const Vector &x, Vector &y1, Vector &y2,
const Vector &xMPI, const Vector &normal,
int e, int i, int k) const;
virtual void LaxFriedrichs(const Vector &x1, const Vector &x2,
const Vector &normal,
Vector &y, int e, int k, int i) const;
virtual void HLL(const Vector &x1, const Vector &x2, const Vector &normal,
Vector &y, int e, int k, int i) const;
virtual double ConvergenceCheck(double dt, const Vector &u) const;
};
#endif
+73
View File
@@ -0,0 +1,73 @@
#include "galerkin.hpp"
GalerkinEvolution::GalerkinEvolution(FiniteElementSpace *fes_,
HyperbolicSystem *hyp_, DofInfo &dofs_)
: FE_Evolution(fes_, hyp_, dofs_)
{
// TODO
}
void GalerkinEvolution::Mult(const Vector &x, Vector &y) const
{
if (hyp->TimeDepBC)
{
hyp->BdrCond.SetTime(t);
if (!hyp->ProjType)
{
hyp->L2_Projection(hyp->BdrCond, inflow);
}
else
{
inflow.ProjectCoefficient(hyp->BdrCond);
}
}
z = 0.;
ComputeTimeDerivative(x, y);
}
void GalerkinEvolution::ComputeTimeDerivative(const Vector &x, Vector &y,
const Vector &xMPI) const
{
for (int e = 0; e < ne; e++)
{
fes->GetElementVDofs(e, vdofs);
x.GetSubVector(vdofs, uElem);
mat2 = 0.;
for (int k = 0; k < nqe; k++)
{
ElemEval(uElem, uEval, k);
hyp->EvaluateFlux(uEval, Flux, e, k);
MultABt(ElemInt(e * nqe + k), Flux, mat1);
AddMult(DShapeEval(k), mat1, mat2);
}
z.AddElementVector(vdofs, mat2.GetData());
// Here, the use of nodal basis functions is essential, i.e. shape
// functions must vanish on faces that their node is not associated with.
for (int i = 0; i < dofs.NumBdrs; i++)
{
for (int k = 0; k < nqf; k++)
{
OuterUnitNormals(e * dofs.NumBdrs + i).GetColumn(k, normal);
FaceEval(x, uEval, uNbrEval, xMPI, normal, e, i, k);
LaxFriedrichs(uEval, uNbrEval, normal, NumFlux, e, k, i);
NumFlux *= BdrInt(i, k, e) * IntRuleFaceWeights(k);
for (int n = 0; n < hyp->NumEq; n++)
{
for (int j = 0; j < dofs.NumFaceDofs; j++)
{
z(vdofs[n * nd + dofs.BdrDofs(j,i)]) -= ShapeEvalFace(i,j,k)
* NumFlux(n);
}
}
}
}
}
InvMassMat->Mult(z, y);
}
+23
View File
@@ -0,0 +1,23 @@
#ifndef HYPSYS_GALERKINEVOLUTION
#define HYPSYS_GALERKINEVOLUTION
#include "fe_evol.hpp"
using namespace std;
using namespace mfem;
class GalerkinEvolution : public FE_Evolution
{
public:
explicit GalerkinEvolution(FiniteElementSpace *fes_,
HyperbolicSystem *hyp_, DofInfo &dofs_);
virtual ~GalerkinEvolution() { }
void Mult(const Vector&x, Vector &y) const override;
void ComputeTimeDerivative(const Vector &x, Vector &y,
const Vector &xMPI = serial) const;
};
#endif
+9
View File
@@ -0,0 +1,9 @@
#ifndef HYPSYS_FE_EVOL_LIB
#define HYPSYS_FE_EVOL_LIB
#include "galerkin.hpp"
#include "monolithic_convex_limiting.hpp"
enum EvolutionScheme { Galerkin, MonolithicConvexLimiting };
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,47 @@
#ifndef HYPSYS_MCL_EVOLUTION
#define HYPSYS_MCL_EVOLUTION
#include "fe_evol.hpp"
using namespace std;
using namespace mfem;
class MCL_Evolution : public FE_Evolution
{
public:
FiniteElementSpace *fesH1;
double MassMatLumpedRef;
const double dt;
int NumLocNbr;
Vector DetJ;
DenseTensor PrecGradOp, GradProd, Adjugates;
DenseMatrix FaceMat, DistributionMatrix, MassMatLOR, Dof2LocNbr, MassMatRefInv;
Bounds *bounds;
mutable DenseTensor CTilde, CFull, NodalFluxes, uij/* , ufiMin, ufiMax */;
mutable DenseMatrix uFace, uNbrFace, mat3, DGFluxTerms, GalerkinRhs,
ElFlux, uDot, DTilde, ufi, BdrFlux, AntiDiffBdr,
uijMin, uijMax, LimitedBarState;
mutable Vector sif, vec1, diffusion, LimitedFluxState;
explicit MCL_Evolution(FiniteElementSpace *fes_, HyperbolicSystem *hyp_,
DofInfo &dofs_, double dt_);
virtual ~MCL_Evolution() { delete bounds; delete fesH1; }
void Mult(const Vector&x, Vector &y) const override;
virtual void GetNodeVal(const Vector &uElem, Vector &uEval, int ) const;
virtual void GetFaceVal(const Vector &x, const Vector &xMPI, int e,
int i) const;
void ComputeTimeDerivative(const Vector &x, Vector &y,
const Vector &xMPI = serial) const;
void ComputeDissipativeMatrix(int e, const Vector &uElem) const;
void ComputePrecGradOp();
void ComputeLORMassMatrix(DenseMatrix &RefMat, Geometry::Type gtype,
bool UseDiagonalNbrs);
};
#endif
+59
View File
@@ -0,0 +1,59 @@
#include "pgalerkin.hpp"
ParGalerkinEvolution::ParGalerkinEvolution(ParFiniteElementSpace *pfes_,
HyperbolicSystem *hyp_,
DofInfo &dofs_)
: GalerkinEvolution(pfes_, hyp_, dofs_), x_gf_MPI(pfes_) { }
void ParGalerkinEvolution::Mult(const Vector &x, Vector &y) const
{
x_gf_MPI = x;
x_gf_MPI.ExchangeFaceNbrData();
Vector &xMPI = x_gf_MPI.FaceNbrData();
if (hyp->TimeDepBC)
{
hyp->BdrCond.SetTime(t);
if (!hyp->ProjType)
{
hyp->L2_Projection(hyp->BdrCond, inflow);
}
else
{
inflow.ProjectCoefficient(hyp->BdrCond);
}
}
z = 0.;
ComputeTimeDerivative(x, y, xMPI);
}
double ParGalerkinEvolution::ConvergenceCheck(double dt, const Vector &u) const
{
z = u;
z -= uOld;
double res, resMPI = 0.;
if (!hyp->SteadyState) // Use consistent mass matrix.
{
MassMat->Mult(z, uOld);
for (int i = 0; i < u.Size(); i++)
{
resMPI += uOld(i) * uOld(i);
}
MPI_Allreduce(&resMPI, &res, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
res = sqrt(res) / dt;
}
else // Use lumped mass matrix.
{
for (int i = 0; i < u.Size(); i++)
{
resMPI += pow(LumpedMassMat(i) * z(i), 2.);
}
MPI_Allreduce(&resMPI, &res, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
res = sqrt(res) / dt;
}
uOld = u;
return res;
}
+24
View File
@@ -0,0 +1,24 @@
#ifndef HYPSYS_PARGALERKINEVOLUTION
#define HYPSYS_PARGALERKINEVOLUTION
#include "galerkin.hpp"
#include "../lib/plib.hpp"
using namespace std;
using namespace mfem;
class ParGalerkinEvolution : public GalerkinEvolution
{
public:
mutable ParGridFunction x_gf_MPI;
explicit ParGalerkinEvolution(ParFiniteElementSpace *pfes_,
HyperbolicSystem *hyp_, DofInfo &dofs_);
virtual ~ParGalerkinEvolution() { }
void Mult(const Vector&x, Vector &y) const override;
double ConvergenceCheck(double dt, const Vector &u) const override;
};
#endif
+9
View File
@@ -0,0 +1,9 @@
#ifndef HYPSYS_FE_EVOL_PLIB
#define HYPSYS_FE_EVOL_PLIB
#include "lib.hpp"
#include "../lib/ptools.hpp"
#include "pgalerkin.hpp"
#include "pmonolithic_convex_limiting.hpp"
#endif
@@ -0,0 +1,65 @@
#include "pmonolithic_convex_limiting.hpp"
ParMCL_Evolution::ParMCL_Evolution(ParFiniteElementSpace *pfes_,
HyperbolicSystem *hyp_,
DofInfo &dofs_, double dt_)
: MCL_Evolution(pfes_, hyp_, dofs_, dt_), x_gf_MPI(pfes_)
{
H1_FECollection fec(fes->GetFE(0)->GetOrder(), dim);
pfesH1 = new ParFiniteElementSpace(pfes_->GetParMesh(), &fec);
delete bounds; // Serial version is deleted.
bounds = new ParTightBounds(pfes_, pfesH1);
}
void ParMCL_Evolution::Mult(const Vector &x, Vector &y) const
{
x_gf_MPI = x;
x_gf_MPI.ExchangeFaceNbrData();
Vector &xMPI = x_gf_MPI.FaceNbrData();
if (hyp->TimeDepBC)
{
hyp->BdrCond.SetTime(t);
if (!hyp->ProjType)
{
hyp->L2_Projection(hyp->BdrCond, inflow);
}
else
{
inflow.ProjectCoefficient(hyp->BdrCond);
}
}
z = 0.;
ComputeTimeDerivative(x, y, xMPI);
}
double ParMCL_Evolution::ConvergenceCheck(double dt, const Vector &u) const
{
z = u;
z -= uOld;
double res, resMPI = 0.;
if (!hyp->SteadyState) // Use consistent mass matrix.
{
MassMat->Mult(z, uOld);
for (int i = 0; i < u.Size(); i++)
{
resMPI += uOld(i) * uOld(i);
}
MPI_Allreduce(&resMPI, &res, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
res = sqrt(res) / dt;
}
else // Use lumped mass matrix.
{
for (int i = 0; i < u.Size(); i++)
{
resMPI += pow(LumpedMassMat(i) * z(i), 2.);
}
MPI_Allreduce(&resMPI, &res, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
res = sqrt(res) / dt;
}
uOld = u;
return res;
}
@@ -0,0 +1,26 @@
#ifndef HYPSYS_PARMCL_EVOLUTION
#define HYPSYS_PARMCL_EVOLUTION
#include "monolithic_convex_limiting.hpp"
#include "../lib/plib.hpp"
using namespace std;
using namespace mfem;
class ParMCL_Evolution : public MCL_Evolution
{
public:
ParFiniteElementSpace *pfesH1;
mutable ParGridFunction x_gf_MPI;
explicit ParMCL_Evolution(ParFiniteElementSpace *pfes_,
HyperbolicSystem *hyp_, DofInfo &dofs_, double dt_);
virtual ~ParMCL_Evolution() { delete pfesH1; }
void Mult(const Vector&x, Vector &y) const override;
double ConvergenceCheck(double dt, const Vector &u) const override;
};
#endif
+60
View File
@@ -0,0 +1,60 @@
#include "ptemplate.hpp"
PARTEMPLATE::PARTEMPLATE(ParFiniteElementSpace *pfes_,
HyperbolicSystem *hyp_,
DofInfo &dofs_)
: PARTEMPLATE(pfes_, hyp_, dofs_), x_gf_MPI(pfes_) { }
void PARTEMPLATE::Mult(const Vector &x, Vector &y) const
{
x_gf_MPI = x;
x_gf_MPI.ExchangeFaceNbrData();
Vector &xMPI = x_gf_MPI.FaceNbrData();
if (hyp->TimeDepBC)
{
hyp->BdrCond.SetTime(t);
if (!hyp->ProjType)
{
hyp->L2_Projection(hyp->BdrCond, inflow);
}
else
{
inflow.ProjectCoefficient(hyp->BdrCond);
}
}
z = 0.;
ComputeTimeDerivative(x, y, xMPI);
}
double PARTEMPLATE::ConvergenceCheck(double dt, double tol,
const Vector &u) const
{
z = u;
z -= uOld;
double res, resMPI = 0.;
if (!hyp->SteadyState) // Use consistent mass matrix.
{
MassMat->Mult(z, uOld);
for (int i = 0; i < u.Size(); i++)
{
resMPI += uOld(i) * uOld(i);
}
MPI_Allreduce(&resMPI, &res, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
res = sqrt(res) / dt;
}
else // Use lumped mass matrix.
{
for (int i = 0; i < u.Size(); i++)
{
resMPI += pow(LumpedMassMat(i) * z(i), 2.);
}
MPI_Allreduce(&resMPI, &res, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
res = sqrt(res) / dt;
}
uOld = u;
return res;
}
+25
View File
@@ -0,0 +1,25 @@
#ifndef HYPSYS_PARTEMPLATE_EVOLUTION
#define HYPSYS_PARTEMPLATE_EVOLUTION
#include "template.hpp"
#include "../lib/plib.hpp"
using namespace std;
using namespace mfem;
class PARTEMPLATE : public TEMPLATE
{
public:
mutable ParGridFunction x_gf_MPI;
explicit PARTEMPLATE(ParFiniteElementSpace *pfes_,
HyperbolicSystem *hyp_,
DofInfo &dofs_);
virtual ~PARTEMPLATE() { }
void Mult(const Vector&x, Vector &y) const override;
double ConvergenceCheck(double dt, double tol, const Vector &u) const override;
};
#endif
+33
View File
@@ -0,0 +1,33 @@
#include "template.hpp"
TEMPLATE::TEMPLATE(FiniteElementSpace *fes_, HyperbolicSystem *hyp_,
DofInfo &dofs_)
: FE_Evolution(fes_, hyp_, dofs_)
{
// TODO
}
void TEMPLATE::Mult(const Vector &x, Vector &y) const
{
if (hyp->TimeDepBC)
{
hyp->BdrCond.SetTime(t);
if (!hyp->ProjType)
{
hyp->L2_Projection(hyp->BdrCond, inflow);
}
else
{
inflow.ProjectCoefficient(hyp->BdrCond);
}
}
z = 0.;
ComputeTimeDerivative(x, y);
}
void TEMPLATE::ComputeTimeDerivative(const Vector &x, Vector &y,
const Vector &xMPI) const
{
// TODO
}
+22
View File
@@ -0,0 +1,22 @@
#ifndef HYPSYS_TEMPLATE_EVOLUTION
#define HYPSYS_TEMPLATE_EVOLUTION
#include "fe_evol.hpp"
using namespace std;
using namespace mfem;
class TEMPLATE : public FE_Evolution
{
public:
explicit TEMPLATE(FiniteElementSpace *fes_, HyperbolicSystem *hyp_,
DofInfo &dofs_);
virtual ~TEMPLATE() { }
void Mult(const Vector&x, Vector &y) const override;
void ComputeTimeDerivative(const Vector &x, Vector &y,
const Vector &xMPI = serial) const;
};
#endif
+295
View File
@@ -0,0 +1,295 @@
#include "lib/lib.hpp"
#include "fe_evol/lib.hpp"
#include "apps/lib.hpp"
int main(int argc, char *argv[])
{
Configuration config;
int ProblemNum = 0;
config.ConfigNum = 1;
int VisSteps = 100;
config.tFinal = 1.;
int odeSolverType = 3;
double dt = 0.001;
const char *MeshFile = "data/inline-4quad.mesh";
int order = 3;
int refinements = 1;
EvolutionScheme scheme = MonolithicConvexLimiting;
const char *OutputDir = "."; // Directory has to exist to produce output.
bool TransOutput = false; // Use this to produce output for videos.
bool VisualizeDerived = false;
int precision = 8;
cout.precision(precision);
OptionsParser args(argc, argv);
args.AddOption(&ProblemNum, "-p", "--problem",
"Hyperbolic system of equations to solve.");
args.AddOption(&config.ConfigNum, "-c", "--configuration",
"Problem setup to use.");
args.AddOption(&VisSteps, "-vf", "--visualization-frequency",
"Visualize every n-th timestep.");
args.AddOption(&config.tFinal, "-tf", "--final-time",
"Final time; start time is 0.");
args.AddOption(&odeSolverType, "-s", "--ode-solver",
"ODE solver: 1 - Forward Euler,\n\t"
" 2 - RK2 SSP, 3 - RK3 SSP, 4 - RK4, 6 - RK6.");
args.AddOption(&dt, "-dt", "--time-step", "Time step.");
args.AddOption(&MeshFile, "-m", "--mesh", "Mesh file to use.");
args.AddOption(&order, "-o", "--order",
"Order (polynomial degree) of the finite element space.");
args.AddOption(&refinements, "-r", "--refinements",
"Number of times to refine the mesh uniformly.");
args.AddOption((int*)(&scheme), "-es", "--evolution-scheme",
"Scheme: 0 - Galerkin Finite Element Approximation,\n\t"
" 1 - Monolithic Convex Limiting.");
args.AddOption(&OutputDir, "-out", "--output-directory", "Output directory.");
args.AddOption(&TransOutput, "-t", "--transitional-output", "-no-t",
"--no-transitional-output", "Print transitional output files.");
args.Parse();
if (!args.Good())
{
args.PrintUsage(cout);
return -1;
}
args.PrintOptions(cout);
if (order == 0)
{
scheme = Galerkin;
}
ODESolver *odeSolver = NULL;
switch (odeSolverType)
{
case 1: odeSolver = new ForwardEulerSolver; break;
case 2: odeSolver = new RK2Solver(1.0); break;
case 3: odeSolver = new RK3SSPSolver; break;
case 4: odeSolver = new RK4Solver; break;
case 6: odeSolver = new RK6Solver; break;
default:
cout << "Unknown ODE solver type: " << odeSolverType << endl;
return -1;
}
if (odeSolverType > 3)
{
MFEM_WARNING("Non-SSP odeSolver: Maximum principles may be violated.");
}
Mesh mesh(MeshFile, 1, 1);
const int dim = mesh.Dimension();
for (int lev = 0; lev < refinements; lev++)
{
mesh.UniformRefinement();
}
if (mesh.NURBSext)
{
mesh.SetCurvature(max(order, 1));
}
mesh.GetBoundingBox(config.bbMin, config.bbMax, max(order, 1));
int NumEq;
switch (ProblemNum)
{
case 0:
case 1:
case 2:
case 3: { NumEq = 1; VisualizeDerived = false; break; }
case 4: NumEq = 1 + dim; break;
case 5: NumEq = 2 + dim; break;
default:
cout << "Unknown hyperbolic system: " << ProblemNum << endl;
delete odeSolver;
return -1;
}
// Create Bernstein Finite Element Space.
const int btype = BasisType::Positive;
L2_FECollection fec(order, dim, btype);
FiniteElementSpace fes(&mesh, &fec);
FiniteElementSpace vfes(&mesh, &fec, NumEq, Ordering::byNODES);
Array<int> offsets(NumEq + 1);
for (int k = 0; k <= NumEq; k++) { offsets[k] = k * fes.GetNDofs(); }
BlockVector u_block(offsets);
const int ProblemSize = vfes.GetVSize();
cout << "Number of unknowns: " << ProblemSize << endl;
DofInfo dofs(&fes);
bool NodalQuadRule = false;
if (scheme == MonolithicConvexLimiting)
{
NodalQuadRule = true;
}
HyperbolicSystem *hyp;
switch (ProblemNum)
{
case 0: { hyp = new Advection(&vfes, u_block, config, NodalQuadRule); break; }
case 1: { hyp = new Burgers(&vfes, u_block, config); break; }
case 2: { hyp = new KPP(&vfes, u_block, config); break; }
case 3: { hyp = new BuckleyLeverett(&vfes, u_block, config); break; }
case 4: { hyp = new ShallowWater(&vfes, u_block, config); break; }
case 5: { hyp = new Euler(&vfes, u_block, config); break; }
default:
return -1;
}
if (odeSolverType != 1 && hyp->SteadyState)
{
MFEM_WARNING("Better use forward Euler pseudo time stepping for steady state simulations.");
}
GridFunction u(&vfes, u_block);
u = hyp->u0;
// The main is variable is visualized, printed, and used to check for mass leaks or violation of maximum principles.
GridFunction main(&fes, u_block.GetBlock(0));
ostringstream MeshName, InitName;
MeshName << OutputDir << "/grid.mesh";
InitName << OutputDir << "/initial.gf";
ofstream omesh(MeshName.str().c_str());
omesh.precision(precision);
mesh.Print(omesh);
ofstream initial(InitName.str().c_str());
initial.precision(precision);
main.Save(initial);
socketstream sout;
char vishost[] = "localhost";
int visport = 19916;
VisualizeField(sout, vishost, visport, hyp->ProblemName, main,
hyp->glvis_scale);
FE_Evolution *evol;
switch (scheme)
{
case Galerkin: { evol = new GalerkinEvolution(&vfes, hyp, dofs); break; }
case MonolithicConvexLimiting: { evol = new MCL_Evolution(&vfes, hyp, dofs, dt); break; }
default:
MFEM_ABORT("Unknown evolution scheme");
}
Vector LumpedMassMat(fes.GetVSize());
BilinearForm ml(&fes);
ml.AddDomainIntegrator(new LumpedIntegrator(new MassIntegrator()));
ml.Assemble();
ml.Finalize();
ml.SpMat().GetDiag(LumpedMassMat);
double InitialMass = LumpedMassMat * main;
odeSolver->Init(*evol);
if (hyp->SteadyState)
{
evol->uOld.SetSize(ProblemSize);
evol->uOld = 0.;
}
int TransStep = 1;
double dtLast, res, t = 0., tol = 1.e-12;
bool done = t >= config.tFinal;
tic_toc.Clear();
tic_toc.Start();
cout << "Preprocessing done. Entering time stepping loop.\n";
for (int ti = 0; !done;)
{
dtLast = min(dt, config.tFinal - t);
odeSolver->Step(u, t, dtLast);
ti++;
done = (t >= config.tFinal - 1.e-8 * dt);
if (hyp->SteadyState)
{
res = evol->ConvergenceCheck(dt, u);
if (res < tol)
{
done = true;
u = evol->uOld;
}
}
if (done || ti % VisSteps == 0)
{
if (hyp->SteadyState)
{
cout << "time step: " << ti << ", time: " << t <<
", residual: " << res << endl;
}
else
{
cout << "time step: " << ti << ", time: " << t << endl;
}
VisualizeField(sout, vishost, visport, hyp->ProblemName, main,
hyp->glvis_scale);
if (TransOutput)
{
ostringstream TransName;
TransName << OutputDir << "/trans" << TransStep << ".gf";
ofstream trans(TransName.str().c_str());
trans.precision(precision);
main.Save(trans);
TransStep++;
}
}
}
tic_toc.Stop();
cout << "Time stepping loop done in " << tic_toc.RealTime() << " seconds.\n\n";
double DomainSize = LumpedMassMat.Sum();
if (hyp->SolutionKnown)
{
Array<double> errors;
hyp->ComputeErrors(errors, u, DomainSize, t);
cout << "L1 error: " << errors[0] << endl;
hyp->WriteErrors(errors);
}
cout << "Min of primary field: " << main.Min() << endl
<< "Max of primary field: " << main.Max() << endl
<< "Difference in solution mass: "
<< abs(InitialMass - LumpedMassMat * main) / DomainSize << "\n\n";
ostringstream FinalName;
FinalName << OutputDir << "/ultimate.gf";
ofstream ultimate(FinalName.str().c_str());
ultimate.precision(precision);
main.Save(ultimate);
if (VisualizeDerived)
{
GridFunction v(&fes), p(&fes);
hyp->ComputeDerivedQuantities(u, v, p);
ostringstream VelocityName;
VelocityName << OutputDir << "/velocity.gf";
ofstream velocity(VelocityName.str().c_str());
velocity.precision(precision);
v.Save(velocity);
if (ProblemNum == 5)
{
ostringstream PressureName;
PressureName << OutputDir << "/pressure.gf";
ofstream pressure(PressureName.str().c_str());
pressure.precision(precision);
p.Save(pressure);
}
}
delete evol;
delete hyp;
delete odeSolver;
return 0;
}
+416
View File
@@ -0,0 +1,416 @@
#include "bounds.hpp"
Bounds::Bounds(FiniteElementSpace *fes_, FiniteElementSpace *fesH1_)
: fes(fes_), fesH1(fesH1_), x_min(fesH1_),
x_max(fesH1_) //, y_min(fesH1_), y_max(fesH1_)
{
Mesh *mesh = fes->GetMesh();
const FiniteElement *el = fes->GetFE(0);
nd = el->GetDof();
ne = mesh->GetNE();
NumEq = fes->GetVSize() / (ne*nd);
xi_min.SetSize(NumEq*ne*nd);
xi_max.SetSize(NumEq*ne*nd);
// yi_min.SetSize(NumEq*ne*nd);
// yi_max.SetSize(NumEq*ne*nd);
FillDofMap();
}
void Bounds::FillDofMap()
{
const FiniteElement *el = fes->GetFE(0);
if (el->GetGeomType() != Geometry::TRIANGLE)
{
const TensorBasisElement *TensorElem =
dynamic_cast<const TensorBasisElement *>(fesH1->GetFE(0));
DofMapH1 = TensorElem->GetDofMap();
return;
}
const int p = el->GetOrder();
const int nd = (p+1)*(p+2) / 2;
DofMapH1.SetSize(nd);
// Corners
DofMapH1[0] = 0;
DofMapH1[p] = 1;
DofMapH1[nd-1] = 2;
int ctr1 = 2*p;
int ctr2 = nd-3;
// Element edges
for (int i = 1; i < p; i++)
{
DofMapH1[i] = 2+i;
DofMapH1[ctr1] = 2+i+p-1;
DofMapH1[ctr2] = 2+i+2*(p-1);
ctr1 += (p-i);
ctr2 -= 2+i;
}
ctr1 = p+2;
ctr2 = 3*p;
// Element interior
for (int j = 1; j < p-1; j++)
{
for (int i = 1; i < p-j; i++)
{
DofMapH1[ctr1] = ctr2;
ctr1++;
ctr2++;
}
ctr1 += 2;
}
}
void Bounds::ComputeBounds(const Vector &x)
{
x_min = std::numeric_limits<double>::infinity();
x_max = -std::numeric_limits<double>::infinity();
// y_min = std::numeric_limits<double>::infinity();
// y_max = -std::numeric_limits<double>::infinity();
for (int e = 0; e < ne; e++)
{
fesH1->GetElementDofs(e, eldofs);
ComputeElementBounds(0, e, x);
}
for (int e = 0; e < ne; e++)
{
fesH1->GetElementDofs(e, eldofs);
for (int j = 0; j < nd; j++)
{
xi_min(e*nd + j) = x_min(eldofs[DofMapH1[j]]);
xi_max(e*nd + j) = x_max(eldofs[DofMapH1[j]]);
// yi_min(e*nd + j) = y_min(eldofs[DofMapH1[j]]);
// yi_max(e*nd + j) = y_max(eldofs[DofMapH1[j]]);
}
}
for (int n = 1; n < NumEq; n++)
{
x_min = std::numeric_limits<double>::infinity();
x_max = -std::numeric_limits<double>::infinity();
// y_min = std::numeric_limits<double>::infinity();
// y_max = -std::numeric_limits<double>::infinity();
for (int e = 0; e < ne; e++)
{
fesH1->GetElementDofs(e, eldofs);
ComputeSequentialBounds(n, e, x);
}
for (int e = 0; e < ne; e++)
{
fesH1->GetElementDofs(e, eldofs);
for (int j = 0; j < nd; j++)
{
xi_min(n*ne*nd + e*nd + j) = x_min(eldofs[DofMapH1[j]]);
xi_max(n*ne*nd + e*nd + j) = x_max(eldofs[DofMapH1[j]]);
// yi_min(n*ne*nd + e*nd + j) = y_min(eldofs[DofMapH1[j]]);
// yi_max(n*ne*nd + e*nd + j) = y_max(eldofs[DofMapH1[j]]);
}
}
}
}
TightBounds::TightBounds(FiniteElementSpace *fes_, FiniteElementSpace *fesH1_)
: Bounds(fes_, fesH1_)
{
FillClosestNbrs(fes->GetFE(0), ClosestNbrs);
}
void TightBounds::ComputeElementBounds(int n, int e, const Vector &x)
{
for (int i = 0; i < nd; i++)
{
const int I = eldofs[DofMapH1[i]];
x_min(I) = min(x_min(I), xi_min(n*ne*nd + e*nd + i));
x_max(I) = max(x_max(I), xi_max(n*ne*nd + e*nd + i));
// y_min(I) = min(y_min(I), yi_min(n*ne*nd + e*nd + i)); // not used for now
// y_max(I) = max(y_max(I), yi_max(n*ne*nd + e*nd + i)); // not used for now
for (int j = 0; j < ClosestNbrs.Width(); j++)
{
if (ClosestNbrs(i,j) == -1) { break; }
const int J = n*ne*nd + e*nd + ClosestNbrs(i,j);
x_min(I) = min(x_min(I), x(J));
x_max(I) = max(x_max(I), x(J));
}
}
}
void TightBounds::ComputeSequentialBounds(int n, int e, const Vector &x)
{
for (int i = 0; i < nd; i++)
{
const int I = eldofs[DofMapH1[i]];
x_min(I) = min(x_min(I), xi_min(n*ne*nd + e*nd + i));
x_max(I) = max(x_max(I), xi_max(n*ne*nd + e*nd + i));
// y_min(I) = min(y_min(I), yi_min(n*ne*nd + e*nd + i));
// y_max(I) = max(y_max(I), yi_max(n*ne*nd + e*nd + i));
// for (int j = 0; j < ClosestNbrs.Width(); j++)
// {
// if (ClosestNbrs(i,j) == -1) { break; }
// const int J = n*ne*nd + e*nd + ClosestNbrs(i,j);
// x_min(I) = min(x_min(I), x(J) / x(e*nd + ClosestNbrs(i,j)));
// x_max(I) = max(x_max(I), x(J) / x(e*nd + ClosestNbrs(i,j)));
// }
}
}
LooseBounds::LooseBounds(FiniteElementSpace *fes_, FiniteElementSpace *fesH1_)
: Bounds(fes_, fesH1_) { }
void LooseBounds::ComputeElementBounds(int n, int e, const Vector &x)
{
double xe_min = std::numeric_limits<double>::infinity();
double xe_max = -std::numeric_limits<double>::infinity();
for (int j = 0; j < nd; j++)
{
xe_min = min(xe_min, x(n*ne*nd + e*nd+j));
xe_max = max(xe_max, x(n*ne*nd + e*nd+j));
}
for (int j = 0; j < nd; j++)
{
int I = eldofs[DofMapH1[j]];
x_min(I) = min(x_min(I), xe_min);
x_max(I) = max(x_max(I), xe_max);
}
}
void LooseBounds::ComputeSequentialBounds(int n, int e, const Vector &x)
{
for (int i = 0; i < nd; i++)
{
const int I = eldofs[DofMapH1[i]];
x_min(I) = min(x_min(I), xi_min(n*ne*nd + e*nd + i));
x_max(I) = max(x_max(I), xi_max(n*ne*nd + e*nd + i));
}
}
void FillClosestNbrs(const FiniteElement *el, DenseMatrix &ClosestNbrs)
{
const int nd = el->GetDof();
const int p = el->GetOrder();
Geometry::Type gtype = el->GetGeomType();
switch (gtype)
{
case Geometry::SEGMENT:
{
ClosestNbrs.SetSize(nd, p==1 ? 2 : 3);
ClosestNbrs = -1;
ClosestNbrs(0,0) = 0;
ClosestNbrs(0,1) = 1;
for (int i = 1; i < p; i++)
{
ClosestNbrs(i,0) = i-1;
ClosestNbrs(i,1) = i;
ClosestNbrs(i,2) = i+1;
}
ClosestNbrs(p,0) = p-1;
ClosestNbrs(p,1) = p;
break;
}
case Geometry::TRIANGLE:
{
ClosestNbrs.SetSize(nd, p==1 ? 3 : (p==2 ? 5 : 7));
ClosestNbrs = -1;
ClosestNbrs(0,0) = 0;
ClosestNbrs(0,1) = 1;
ClosestNbrs(0,2) = p+1;
for (int i = 1; i < p; i++)
{
ClosestNbrs(i,0) = i-1;
ClosestNbrs(i,1) = i;
ClosestNbrs(i,2) = i+1;
ClosestNbrs(i,3) = p+i;
ClosestNbrs(i,4) = p+i+1;
}
ClosestNbrs(p,0) = p-1;
ClosestNbrs(p,1) = p;
ClosestNbrs(p,2) = 2*p;
int ctr = p+1;
for (int j = 1; j < p; j++)
{
int lower = (j-1)*(p+2) - (j-1)*j/2;
int upper = lower + 2*(p-j) + 3;
ClosestNbrs(ctr,0) = lower;
ClosestNbrs(ctr,1) = lower+1;
ClosestNbrs(ctr,2) = ctr;
ClosestNbrs(ctr,3) = ctr+1;
ClosestNbrs(ctr,4) = upper;
ctr++;
for (int i = 1; i < p-j; i++)
{
ClosestNbrs(ctr,0) = lower+i;
ClosestNbrs(ctr,1) = lower+i+1;
ClosestNbrs(ctr,2) = ctr-1;
ClosestNbrs(ctr,3) = ctr;
ClosestNbrs(ctr,4) = ctr+1;
ClosestNbrs(ctr,5) = upper+i-1;
ClosestNbrs(ctr,6) = upper+i;
ctr++;
}
ClosestNbrs(ctr,0) = lower + p-j;
ClosestNbrs(ctr,1) = lower + p-j+1;
ClosestNbrs(ctr,2) = ctr-1;
ClosestNbrs(ctr,3) = ctr;
ClosestNbrs(ctr,4) = upper+p-j-1;
ctr++;
}
ClosestNbrs(nd-1,0) = nd-3;
ClosestNbrs(nd-1,1) = nd-2;
ClosestNbrs(nd-1,2) = nd-1;
break;
}
case Geometry::SQUARE:
{
ClosestNbrs.SetSize(nd, p == 1 ? 4: 9);
ClosestNbrs = -1;
for (int i = 0; i < nd; i++)
{
int ctr = 0;
// lower neighbors
if (i > p)
{
if (i % (p+1) != 0) { ClosestNbrs(i,ctr) = i-p-2; ctr++; }
ClosestNbrs(i,ctr) = i-p-1; ctr++;
if ((i+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = i-p; ctr++; }
}
// horizontal neighbors
if (i % (p+1) != 0) { ClosestNbrs(i,ctr) = i-1; ctr++; }
ClosestNbrs(i,ctr) = i; ctr++;
if ((i+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = i+1; ctr++; }
// upper neighbors
if (i < p*(p+1))
{
if (i % (p+1) != 0) { ClosestNbrs(i,ctr) = i+p; ctr++; }
ClosestNbrs(i,ctr) = i+p+1; ctr++;
if ((i+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = i+p+2; ctr++; }
}
}
break;
}
case Geometry::CUBE:
{
ClosestNbrs.SetSize(nd, p==1 ? 8 : 27);
ClosestNbrs = -1;
for (int i = 0; i < nd; i++)
{
int ctr = 0;
if (i >= (p+1)*(p+1)) // There is a lower plane
{
int k = i - (p+1)*(p+1); // lower neighbor in z direction
int j = k % ((p+1)*(p+1));
// lower neighbors in y direction
if (j > p)
{
if (j % (p+1) != 0) { ClosestNbrs(i,ctr) = k-p-2; ctr++; }
ClosestNbrs(i,ctr) = k-p-1; ctr++;
if ((j+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = k-p; ctr++; }
}
// horizontal neighbors
if (j % (p+1) != 0) { ClosestNbrs(i,ctr) = k-1; ctr++; }
ClosestNbrs(i,ctr) = k; ctr++;
if ((j+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = k+1; ctr++; }
// upper neighbors
if (j < p*(p+1))
{
if (j % (p+1) != 0) { ClosestNbrs(i,ctr) = k+p; ctr++; }
ClosestNbrs(i,ctr) = k+p+1; ctr++;
if ((j+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = k+p+2; ctr++; }
}
}
int j = i % ((p+1)*(p+1));
// lower neighbors
if (j > p)
{
if (j % (p+1) != 0) { ClosestNbrs(i,ctr) = i-p-2; ctr++; }
ClosestNbrs(i,ctr) = i-p-1; ctr++;
if ((j+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = i-p; ctr++; }
}
// horizontal neighbors
if (j % (p+1) != 0) { ClosestNbrs(i,ctr) = i-1; ctr++; }
ClosestNbrs(i,ctr) = i; ctr++;
if ((j+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = i+1; ctr++; }
// upper neighbors
if (j < p*(p+1))
{
if (j % (p+1) != 0) { ClosestNbrs(i,ctr) = i+p; ctr++; }
ClosestNbrs(i,ctr) = i+p+1; ctr++;
if ((j+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = i+p+2; ctr++; }
}
if (i < p*(p+1)*(p+1)) // There is an upper plane
{
int k = i + (p+1)*(p+1); // upper neighbor in z direction
int j = k % ((p+1)*(p+1));
// lower neighbors in y direction
if (j > p)
{
if (j % (p+1) != 0) { ClosestNbrs(i,ctr) = k-p-2; ctr++; }
ClosestNbrs(i,ctr) = k-p-1; ctr++;
if ((j+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = k-p; ctr++; }
}
// horizontal neighbors
if (j % (p+1) != 0) { ClosestNbrs(i,ctr) = k-1; ctr++; }
ClosestNbrs(i,ctr) = k; ctr++;
if ((j+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = k+1; ctr++; }
// upper neighbors
if (j < p*(p+1))
{
if (j % (p+1) != 0) { ClosestNbrs(i,ctr) = k+p; ctr++; }
ClosestNbrs(i,ctr) = k+p+1; ctr++;
if ((j+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = k+p+2; ctr++; }
}
}
}
}
}
}
+55
View File
@@ -0,0 +1,55 @@
#ifndef HYPSYS_BOUNDS
#define HYPSYS_BOUNDS
#include "mfem.hpp"
using namespace std;
using namespace mfem;
class Bounds
{
public:
FiniteElementSpace *fes, *fesH1;
GridFunction x_min, x_max; // element bounds for each H1 dof
// GridFunction y_min, y_max; // element bounds for each H1 dof
Vector xi_min, xi_max; // element bounds for each L2 dof
// Vector yi_min, yi_max; // flux term bounds for each L2 dof
Array<int> eldofs, DofMapH1;
int nd, ne, NumEq;
Bounds(FiniteElementSpace *fes_, FiniteElementSpace *fesH1_);
virtual ~Bounds() { }
void FillDofMap();
virtual void ComputeBounds(const Vector &x);
virtual void ComputeElementBounds(int n, int e, const Vector &x) = 0;
virtual void ComputeSequentialBounds(int n, int e, const Vector &x) = 0;
};
class TightBounds : public Bounds
{
public:
DenseMatrix ClosestNbrs;
TightBounds(FiniteElementSpace *fes_, FiniteElementSpace *fesH1_);
~TightBounds() { }
virtual void ComputeElementBounds(int n, int e, const Vector &x) override;
virtual void ComputeSequentialBounds(int n, int e, const Vector &x) override;
};
class LooseBounds : public Bounds
{
public:
LooseBounds(FiniteElementSpace *fes_, FiniteElementSpace *fesH1_);
~LooseBounds() { }
virtual void ComputeElementBounds(int n, int e, const Vector &x) override;
virtual void ComputeSequentialBounds(int n, int e, const Vector &x) override;
};
void FillClosestNbrs(const FiniteElement *el, DenseMatrix &ClosestNbrs);
#endif
+847
View File
@@ -0,0 +1,847 @@
#include "dofs.hpp"
DofInfo::DofInfo(FiniteElementSpace *fes_)
: mesh(fes_->GetMesh()), fes(fes_)
{
dim = mesh->Dimension();
FillBdrDofs();
NumFaceDofs = BdrDofs.Height();
NumBdrs = BdrDofs.Width();
FillNeighborDofs();
FillSubcell2CellDof();
FillLoc2Multiindex();
}
void DofInfo::FillLoc2Multiindex()
{
const FiniteElement *el = fes->GetFE(0);
if (el->GetGeomType() != Geometry::TRIANGLE) { return; }
const int p = el->GetOrder();
const int nd = (p+1)*(p+2)/2;
Loc2Multiindex.SetSize(nd,3);
Vector a(3);
a = 0.;
a(0) = p;
int ctr = 0;
for (int j = 0; j <= p; j++)
{
for (int i = 0; i <= p-j; i++)
{
Loc2Multiindex.SetRow(ctr,a);
ctr = ctr+1;
a(0)--;
a(1)++;
}
a(0) = p-1-j;
a(1) = 0;
a(2)++;
if (a.Sum() != p)
{
MFEM_ABORT("Invalid Multiindex");
}
}
}
int DofInfo::GetLocFromMultiindex(int p, const Vector &a) const
{
if (a.Sum() != p || a.Min() < 0 || a.Size() != 3)
{
MFEM_ABORT("Invalid Multiindex");
}
return (p+1)*a(2) - a(2)*(a(2)-1)/2 + a(1);
}
void DofInfo::FillNeighborDofs()
{
// Use the first mesh element as indicator.
const FiniteElement &el = *fes->GetFE(0);
int i, j, e, nbr, ne = mesh->GetNE();
int nd = el.GetDof(), p = el.GetOrder();
Array <int> bdrs, orientation;
FaceElementTransformations *Trans;
Table *face_to_el = mesh->GetFaceToElementTable();
NbrDofs.SetSize(NumBdrs, NumFaceDofs, ne);
// Permutations of BdrDofs, taking into account all possible orientations.
// Assumes BdrDofs are ordered in xyz order, which is true for 3D hexes,
// but it isn't true for 2D quads.
int orient_cnt = 1;
if (dim == 2) { orient_cnt = 2; }
if (dim == 3) { orient_cnt = 8; }
const int dof1D_cnt = p+1;
DenseTensor fdof_ids(NumFaceDofs, NumBdrs, orient_cnt);
for (int ori = 0; ori < orient_cnt; ori++)
{
for (int face_id = 0; face_id < NumBdrs; face_id++)
{
for (int fdof_id = 0; fdof_id < NumFaceDofs; fdof_id++)
{
// Index of fdof_id in the current orientation.
const int ori_fdof_id = GetLocalFaceDofIndex(dim, face_id, ori,
fdof_id, dof1D_cnt);
fdof_ids(ori)(ori_fdof_id, face_id) = BdrDofs(fdof_id, face_id);
}
}
}
for (e = 0; e < ne; e++)
{
if (dim==1)
{
mesh->GetElementVertices(e, bdrs);
for (i = 0; i < NumBdrs; i++)
{
const int nbr_cnt = face_to_el->RowSize(bdrs[i]);
if (nbr_cnt == 1)
{
// No neighbor element.
NbrDofs(i,0,e) = -1;
continue;
}
int el1_id, el2_id, nbr_id;
mesh->GetFaceElements(bdrs[i], &el1_id, &el2_id);
if (el2_id < 0)
{
// This element is in a different mpi task.
el2_id = -1 - el2_id + ne;
}
nbr_id = (el1_id == e) ? el2_id : el1_id;
NbrDofs(i,0,e) = nbr_id*nd + BdrDofs(0,(i+1)%2);
}
}
else if (dim==2)
{
mesh->GetElementEdges(e, bdrs, orientation);
for (i = 0; i < NumBdrs; i++)
{
const int nbr_cnt = face_to_el->RowSize(bdrs[i]);
if (nbr_cnt == 1)
{
// No neighbor element.
for (j = 0; j < NumFaceDofs; j++) { NbrDofs(i,j,e) = -1; }
continue;
}
int el1_id, el2_id, nbr_id;
mesh->GetFaceElements(bdrs[i], &el1_id, &el2_id);
if (el2_id < 0)
{
// This element is in a different mpi task.
el2_id = -1 - el2_id + ne;
}
nbr_id = (el1_id == e) ? el2_id : el1_id;
int el1_info, el2_info;
mesh->GetFaceInfos(bdrs[i], &el1_info, &el2_info);
const int face_id_nbr = (nbr_id == el1_id) ? el1_info / 64
: el2_info / 64;
for (j = 0; j < NumFaceDofs; j++)
{
// Here it is utilized that the orientations of the face for
// the two elements are opposite of each other.
NbrDofs(i,j,e) = nbr_id*nd + BdrDofs(NumFaceDofs - 1 - j,
face_id_nbr);
}
}
}
else if (dim==3)
{
mesh->GetElementFaces(e, bdrs, orientation);
for (int f = 0; f < NumBdrs; f++)
{
const int nbr_cnt = face_to_el->RowSize(bdrs[f]);
if (nbr_cnt == 1)
{
// No neighbor element.
for (j = 0; j < NumFaceDofs; j++) { NbrDofs(f,j,e) = -1; }
continue;
}
int el1_id, el2_id, nbr_id;
mesh->GetFaceElements(bdrs[f], &el1_id, &el2_id);
if (el2_id < 0)
{
// This element is in a different mpi task.
el2_id = -1 - el2_id + ne;
}
nbr_id = (el1_id == e) ? el2_id : el1_id;
// Local index and orientation of the face, when considered in
// the neighbor element.
int el1_info, el2_info;
mesh->GetFaceInfos(bdrs[f], &el1_info, &el2_info);
const int face_id_nbr = (nbr_id == el1_id) ? el1_info / 64
: el2_info / 64;
const int face_or_nbr = (nbr_id == el1_id) ? el1_info % 64
: el2_info % 64;
for (j = 0; j < NumFaceDofs; j++)
{
// What is the index of the j-th dof on the face, given its
// orientation.
const int loc_face_dof_id =
GetLocalFaceDofIndex(dim, face_id_nbr, face_or_nbr,
j, dof1D_cnt);
// What is the corresponding local dof id on the element,
// given the face orientation.
const int nbr_dof_id =
fdof_ids(face_or_nbr)(loc_face_dof_id, face_id_nbr);
NbrDofs(f,j,e) = nbr_id*nd + nbr_dof_id;
}
}
}
}
for (e = 0; e < fes->GetNBE(); e++)
{
const int bdr_attr = mesh->GetBdrAttribute(e);
FaceElementTransformations *tr = mesh->GetBdrFaceTransformations(e);
if (tr != NULL)
{
const int el = tr->Elem1No;
if (dim == 1) { mesh->GetElementVertices(el, bdrs); }
else if (dim == 2) { mesh->GetElementEdges(el, bdrs, orientation); }
else if (dim == 3) { mesh->GetElementFaces(el, bdrs, orientation); }
for (i = 0; i < NumBdrs; i++)
{
if (bdrs[i] == mesh->GetBdrElementEdgeIndex(e))
{
for (j = 0; j < NumFaceDofs; j++)
{
NbrDofs(i, j, el) = -bdr_attr;
}
continue;
}
}
}
else
{
MFEM_ABORT("Something went wrong.");
}
}
delete face_to_el;
}
void DofInfo::FillSubcell2CellDof()
{
const FiniteElement &el = *fes->GetFE(0);
int j, m, aux, p = el.GetOrder();
Geometry::Type gtype = el.GetGeomType();
if (dim==1)
{
numSubcells = p;
numDofsSubcell = 2;
}
else if (dim==2)
{
if (gtype == Geometry::TRIANGLE)
{
numSubcells = 1;
numDofsSubcell = 3;
for (int i = 1; i < p; i++)
{
numSubcells += 2*i+1;
}
}
else if (gtype == Geometry::SQUARE)
{
numSubcells = p*p;
numDofsSubcell = 4;
}
}
else if (dim==3)
{
numSubcells = p*p*p;
numDofsSubcell = 8;
}
Sub2Ind.SetSize(numSubcells, numDofsSubcell);
if (gtype == Geometry::TRIANGLE)
{
int nd = (p+1)*(p+2) / 2;
int ctr = numSubcells - 1;
int node = nd - 1;
int old;
aux = 1;
for (int iy = p; iy > 0; iy--)
{
old = node;
Sub2Ind(ctr,2) = node;
Sub2Ind(ctr,1) = node - aux;
Sub2Ind(ctr,0) = node - aux - 1;
ctr--;
for (int ix = p - iy; ix > 0; ix--)
{
Sub2Ind(ctr,2) = node;
Sub2Ind(ctr,1) = node - aux - 1;
Sub2Ind(ctr,0) = node - 1;
ctr--;
node--;
Sub2Ind(ctr,2) = node;
Sub2Ind(ctr,1) = node - aux;
Sub2Ind(ctr,0) = node - aux - 1;
ctr--;
}
node = old - aux;
aux++;
}
return;
}
for (m = 0; m < numSubcells; m++)
{
for (j = 0; j < numDofsSubcell; j++)
{
if (dim == 1) { Sub2Ind(m,j) = m + j; }
else if (dim == 2 && gtype == Geometry::SQUARE)
{
aux = m + m/p;
switch (j)
{
case 0: Sub2Ind(m,j) = aux; break;
case 1: Sub2Ind(m,j) = aux + 1; break;
case 2: Sub2Ind(m,j) = aux + p+1; break;
case 3: Sub2Ind(m,j) = aux + p+2; break;
}
}
else if (dim == 3 && gtype == Geometry::CUBE)
{
aux = m + m/p + (p+1)*(m/(p*p));
switch (j)
{
case 0: Sub2Ind(m,j) = aux; break;
case 1: Sub2Ind(m,j) = aux + 1; break;
case 2: Sub2Ind(m,j) = aux + p+1; break;
case 3: Sub2Ind(m,j) = aux + p+2; break;
case 4: Sub2Ind(m,j) = aux + (p+1)*(p+1); break;
case 5: Sub2Ind(m,j) = aux + (p+1)*(p+1)+1; break;
case 6: Sub2Ind(m,j) = aux + (p+1)*(p+1)+p+1; break;
case 7: Sub2Ind(m,j) = aux + (p+1)*(p+1)+p+2; break;
}
}
else
{
MFEM_ABORT("Tetraheadra are not supported.");
}
}
}
}
void DofInfo::FillBdrDofs()
{
const FiniteElement *el = fes->GetFE(0);
Geometry::Type gtype = el->GetGeomType();
int p = el->GetOrder();
switch (gtype)
{
case Geometry::SEGMENT:
{
BdrDofs.SetSize(1,2);
BdrDofs(0,0) = 0;
BdrDofs(0,1) = p;
break;
}
case Geometry::TRIANGLE:
{
int ctr = 0;
BdrDofs.SetSize(p+1, 3);
for (int i = 0; i <= p; i++)
{
BdrDofs(i,0) = i;
BdrDofs(i,1) = ctr + p;
BdrDofs(p-i,2) = ctr + i;
ctr += p - i;
}
break;
}
case Geometry::SQUARE:
{
BdrDofs.SetSize(p+1,4);
for (int i = 0; i <= p; i++)
{
BdrDofs(i,0) = i;
BdrDofs(i,1) = i*(p+1) + p;
BdrDofs(i,2) = (p+1)*(p+1) - 1 - i;
BdrDofs(i,3) = (p-i)*(p+1);
}
break;
}
case Geometry::TETRAHEDRON:
{
int ctr;
BdrDofs.SetSize((p+1)*(p+2)/2, 4);
for (int bdrID = 0; bdrID < 4; bdrID++)
{
int o = 0;
switch (bdrID)
{
case 0:
ctr = p;
for (int i = 0; i <= p; i++)
{
for (int j = 0; j <= p - i; j++)
{
BdrDofs(o++,bdrID) = ctr;
ctr += p - i - j;
}
ctr += p - i;
}
break;
case 1:
ctr = 0;
for (int i = 0; i <= p; i++)
{
for (int j = 0; j <= p - i; j++)
{
BdrDofs(o++,bdrID) = ctr;
ctr += p + 1 - i - j;
}
}
break;
case 2:
ctr = 0;
for (int i = 0; i <= p; i++)
{
for (int j = 0; j <= p - i; j++)
{
BdrDofs(o++,bdrID) = ctr++;
}
ctr += - p + i - 1 + (p-i+1)*(p-i+2)/2;
}
break;
case 3:
for (int i = 0; i < (p+1)*(p+2)/2; i++)
{
BdrDofs(o++,bdrID) = i;
}
break;
}
}
break;
}
case Geometry::CUBE:
{
BdrDofs.SetSize((p+1)*(p+1), 6);
for (int bdrID = 0; bdrID < 6; bdrID++)
{
int o(0);
switch (bdrID)
{
case 0:
for (int i = 0; i < (p+1)*(p+1); i++)
{
BdrDofs(o++,bdrID) = i;
}
break;
case 1:
for (int i = 0; i <= p*(p+1)*(p+1); i+=(p+1)*(p+1))
for (int j = 0; j < p+1; j++)
{
BdrDofs(o++,bdrID) = i+j;
}
break;
case 2:
for (int i = p; i < (p+1)*(p+1)*(p+1); i+=p+1)
{
BdrDofs(o++,bdrID) = i;
}
break;
case 3:
for (int i = 0; i <= p*(p+1)*(p+1); i+=(p+1)*(p+1))
for (int j = p*(p+1); j < (p+1)*(p+1); j++)
{
BdrDofs(o++,bdrID) = i+j;
}
break;
case 4:
for (int i = 0; i <= (p+1)*((p+1)*(p+1)-1); i+=p+1)
{
BdrDofs(o++,bdrID) = i;
}
break;
case 5:
for (int i = p*(p+1)*(p+1); i < (p+1)*(p+1)*(p+1); i++)
{
BdrDofs(o++,bdrID) = i;
}
break;
}
}
break;
}
default: MFEM_ABORT("Geometry not implemented.");
}
}
int DofInfo::GetLocalFaceDofIndex3D(int loc_face_id, int face_orient,
int face_dof_id, int face_dof1D_cnt)
{
int k1, k2;
const int kf1 = face_dof_id % face_dof1D_cnt;
const int kf2 = face_dof_id / face_dof1D_cnt;
switch (loc_face_id)
{
case 0://BOTTOM
switch (face_orient)
{
case 0://{0, 1, 2, 3}
k1 = kf1;
k2 = face_dof1D_cnt-1-kf2;
break;
case 1://{0, 3, 2, 1}
k1 = face_dof1D_cnt-1-kf2;
k2 = kf1;
break;
case 2://{1, 2, 3, 0}
k1 = face_dof1D_cnt-1-kf2;
k2 = face_dof1D_cnt-1-kf1;
break;
case 3://{1, 0, 3, 2}
k1 = face_dof1D_cnt-1-kf1;
k2 = face_dof1D_cnt-1-kf2;
break;
case 4://{2, 3, 0, 1}
k1 = face_dof1D_cnt-1-kf1;
k2 = kf2;
break;
case 5://{2, 1, 0, 3}
k1 = kf2;
k2 = face_dof1D_cnt-1-kf1;
break;
case 6://{3, 0, 1, 2}
k1 = kf2;
k2 = kf1;
break;
case 7://{3, 2, 1, 0}
k1 = kf1;
k2 = kf2;
break;
default:
mfem_error("This orientation does not exist in 3D");
break;
}
break;
case 1://SOUTH
switch (face_orient)
{
case 0://{0, 1, 2, 3}
k1 = kf1;
k2 = kf2;
break;
case 1://{0, 3, 2, 1}
k1 = kf2;
k2 = kf1;
break;
case 2://{1, 2, 3, 0}
k1 = kf2;
k2 = face_dof1D_cnt-1-kf1;
break;
case 3://{1, 0, 3, 2}
k1 = face_dof1D_cnt-1-kf1;
k2 = kf2;
break;
case 4://{2, 3, 0, 1}
k1 = face_dof1D_cnt-1-kf1;
k2 = face_dof1D_cnt-1-kf2;
break;
case 5://{2, 1, 0, 3}
k1 = face_dof1D_cnt-1-kf2;
k2 = face_dof1D_cnt-1-kf1;
break;
case 6://{3, 0, 1, 2}
k1 = face_dof1D_cnt-1-kf2;
k2 = kf1;
break;
case 7://{3, 2, 1, 0}
k1 = kf1;
k2 = face_dof1D_cnt-1-kf2;
break;
default:
mfem_error("This orientation does not exist in 3D");
break;
}
break;
case 2://EAST
switch (face_orient)
{
case 0://{0, 1, 2, 3}
k1 = kf1;
k2 = kf2;
break;
case 1://{0, 3, 2, 1}
k1 = kf2;
k2 = kf1;
break;
case 2://{1, 2, 3, 0}
k1 = kf2;
k2 = face_dof1D_cnt-1-kf1;
break;
case 3://{1, 0, 3, 2}
k1 = face_dof1D_cnt-1-kf1;
k2 = kf2;
break;
case 4://{2, 3, 0, 1}
k1 = face_dof1D_cnt-1-kf1;
k2 = face_dof1D_cnt-1-kf2;
break;
case 5://{2, 1, 0, 3}
k1 = face_dof1D_cnt-1-kf2;
k2 = face_dof1D_cnt-1-kf1;
break;
case 6://{3, 0, 1, 2}
k1 = face_dof1D_cnt-1-kf2;
k2 = kf1;
break;
case 7://{3, 2, 1, 0}
k1 = kf1;
k2 = face_dof1D_cnt-1-kf2;
break;
default:
mfem_error("This orientation does not exist in 3D");
break;
}
break;
case 3://NORTH
switch (face_orient)
{
case 0://{0, 1, 2, 3}
k1 = face_dof1D_cnt-1-kf1;
k2 = kf2;
break;
case 1://{0, 3, 2, 1}
k1 = kf2;
k2 = face_dof1D_cnt-1-kf1;
break;
case 2://{1, 2, 3, 0}
k1 = kf2;
k2 = kf1;
break;
case 3://{1, 0, 3, 2}
k1 = kf1;
k2 = kf2;
break;
case 4://{2, 3, 0, 1}
k1 = kf1;
k2 = face_dof1D_cnt-1-kf2;
break;
case 5://{2, 1, 0, 3}
k1 = face_dof1D_cnt-1-kf2;
k2 = kf1;
break;
case 6://{3, 0, 1, 2}
k1 = face_dof1D_cnt-1-kf2;
k2 = face_dof1D_cnt-1-kf1;
break;
case 7://{3, 2, 1, 0}
k1 = face_dof1D_cnt-1-kf1;
k2 = face_dof1D_cnt-1-kf2;
break;
default:
mfem_error("This orientation does not exist in 3D");
break;
}
break;
case 4://WEST
switch (face_orient)
{
case 0://{0, 1, 2, 3}
k1 = face_dof1D_cnt-1-kf1;
k2 = kf2;
break;
case 1://{0, 3, 2, 1}
k1 = kf2;
k2 = face_dof1D_cnt-1-kf1;
break;
case 2://{1, 2, 3, 0}
k1 = kf2;
k2 = kf1;
break;
case 3://{1, 0, 3, 2}
k1 = kf1;
k2 = kf2;
break;
case 4://{2, 3, 0, 1}
k1 = kf1;
k2 = face_dof1D_cnt-1-kf2;
break;
case 5://{2, 1, 0, 3}
k1 = face_dof1D_cnt-1-kf2;
k2 = kf1;
break;
case 6://{3, 0, 1, 2}
k1 = face_dof1D_cnt-1-kf2;
k2 = face_dof1D_cnt-1-kf1;
break;
case 7://{3, 2, 1, 0}
k1 = face_dof1D_cnt-1-kf1;
k2 = face_dof1D_cnt-1-kf2;
break;
default:
mfem_error("This orientation does not exist in 3D");
break;
}
break;
case 5://TOP
switch (face_orient)
{
case 0://{0, 1, 2, 3}
k1 = kf1;
k2 = kf2;
break;
case 1://{0, 3, 2, 1}
k1 = kf2;
k2 = kf1;
break;
case 2://{1, 2, 3, 0}
k1 = kf2;
k2 = face_dof1D_cnt-1-kf1;
break;
case 3://{1, 0, 3, 2}
k1 = face_dof1D_cnt-1-kf1;
k2 = kf2;
break;
case 4://{2, 3, 0, 1}
k1 = face_dof1D_cnt-1-kf1;
k2 = face_dof1D_cnt-1-kf2;
break;
case 5://{2, 1, 0, 3}
k1 = face_dof1D_cnt-1-kf2;
k2 = face_dof1D_cnt-1-kf1;
break;
case 6://{3, 0, 1, 2}
k1 = face_dof1D_cnt-1-kf2;
k2 = kf1;
break;
case 7://{3, 2, 1, 0}
k1 = kf1;
k2 = face_dof1D_cnt-1-kf2;
break;
default:
mfem_error("This orientation does not exist in 3D");
break;
}
break;
default: MFEM_ABORT("This face_id does not exist in 3D");
}
return k1 + face_dof1D_cnt * k2;
}
int DofInfo::GetLocalFaceDofIndex(int dim, int loc_face_id, int face_orient,
int face_dof_id, int face_dof1D_cnt)
{
switch (dim)
{
case 1: return face_dof_id;
case 2:
if (loc_face_id <= 1)
{
// SOUTH or EAST (canonical ordering)
return face_dof_id;
}
else
{
// NORTH or WEST (counter-canonical ordering)
return face_dof1D_cnt - 1 - face_dof_id;
}
case 3: return GetLocalFaceDofIndex3D(loc_face_id, face_orient,
face_dof_id, face_dof1D_cnt);
default: MFEM_ABORT("Dimension too high!"); return 0;
}
}
void DofInfo::FillSubcellCross()
{
const FiniteElement &el = *fes->GetFE(0);
Geometry::Type gtype = el.GetGeomType();
switch (gtype)
{
case Geometry::SEGMENT:
{
SubcellCross.SetSize(2,1);
SubcellCross(0,0) = 1;
SubcellCross(1,0) = 0;
break;
}
case Geometry::TRIANGLE:
{
SubcellCross.SetSize(3,2);
SubcellCross(0,0) = 1;
SubcellCross(0,1) = 2;
SubcellCross(1,0) = 0;
SubcellCross(1,1) = 2;
SubcellCross(2,0) = 0;
SubcellCross(2,1) = 1;
break;
}
case Geometry::SQUARE:
{
SubcellCross.SetSize(4,2);
SubcellCross(0,0) = 1;
SubcellCross(0,1) = 2;
SubcellCross(1,0) = 0;
SubcellCross(1,1) = 3;
SubcellCross(2,0) = 0;
SubcellCross(2,1) = 3;
SubcellCross(3,0) = 1;
SubcellCross(3,1) = 2;
break;
}
case Geometry::CUBE:
{
SubcellCross.SetSize(8,3);
SubcellCross(0,0) = 1;
SubcellCross(0,1) = 2;
SubcellCross(0,2) = 4;
SubcellCross(1,0) = 0;
SubcellCross(1,1) = 3;
SubcellCross(1,2) = 5;
SubcellCross(2,0) = 0;
SubcellCross(2,1) = 3;
SubcellCross(2,2) = 6;
SubcellCross(3,0) = 1;
SubcellCross(3,1) = 2;
SubcellCross(3,2) = 7;
SubcellCross(4,0) = 0;
SubcellCross(4,1) = 5;
SubcellCross(4,2) = 6;
SubcellCross(5,0) = 1;
SubcellCross(5,1) = 4;
SubcellCross(5,2) = 7;
SubcellCross(6,0) = 2;
SubcellCross(6,1) = 4;
SubcellCross(6,2) = 7;
SubcellCross(7,0) = 3;
SubcellCross(7,1) = 5;
SubcellCross(7,2) = 6;
break;
}
default:
MFEM_ABORT("Other gemoetries are not supported.");
}
}
+45
View File
@@ -0,0 +1,45 @@
#ifndef HYPSYS_DOFS
#define HYPSYS_DOFS
#include "mfem.hpp"
using namespace std;
using namespace mfem;
// NOTE: The mesh is assumed to consist of segments, triangles quads or hexes.
class DofInfo
{
public:
Mesh *mesh;
FiniteElementSpace *fes;
DenseMatrix BdrDofs, Sub2Ind, SubcellCross, Loc2Multiindex;
DenseTensor NbrDofs; // Negative values correspond to the boundary attributes.
int dim, NumBdrs, NumFaceDofs, numSubcells, numDofsSubcell;
Array<int> DofMapH1;
DofInfo(FiniteElementSpace *fes_);
virtual ~DofInfo() { }
// NOTE: This approach will not work for meshes with hanging h- or p-nodes.
void FillNeighborDofs();
void FillBdrDofs();
void FillSubcell2CellDof();
void FillSubcellCross();
// The following two routines work only for TRIANGLES.
void FillLoc2Multiindex();
int GetLocFromMultiindex(int p, const Vector &a) const;
// Auxiliary routines.
int GetLocalFaceDofIndex3D(int loc_face_id, int face_orient,
int face_dof_id, int face_dof1D_cnt);
int GetLocalFaceDofIndex(int dim, int loc_face_id, int face_orient,
int face_dof_id, int face_dof1D_cnt);
};
#endif
+9
View File
@@ -0,0 +1,9 @@
#ifndef HYPSYS_LIB_LIB
#define HYPSYS_LIB_LIB
#include "massmat.hpp"
#include "dofs.hpp"
#include "bounds.hpp"
#include "tools.hpp"
#endif
+65
View File
@@ -0,0 +1,65 @@
#include "massmat.hpp"
MassMatrixDG::MassMatrixDG(const FiniteElementSpace *fes_) : fes(fes_)
{
const int nd = fes->GetFE(0)->GetDof();
M.SetSize(nd, nd, fes->GetNE());
MassIntegrator mi;
for (int e = 0; e < fes->GetNE(); e++)
{
mi.AssembleElementMatrix(*fes->GetFE(e),
*fes->GetElementTransformation(e),
M(e));
}
}
void MassMatrixDG::Mult(const Vector &x, Vector &y) const
{
Array<int> vdofs;
const int nd = fes->GetFE(0)->GetDof();
DenseMatrix xel, yel;
for (int e = 0; e < fes->GetNE(); e++)
{
fes->GetElementVDofs(e, vdofs);
int nc = vdofs.Size()/nd;
xel.SetSize(nd, nc);
yel.SetSize(nd, nc);
x.GetSubVector(vdofs, xel.Data());
mfem::Mult(M(e), xel, yel);
y.SetSubVector(vdofs, yel.Data());
}
}
InverseMassMatrixDG::InverseMassMatrixDG(const MassMatrixDG *mass_)
: mass(mass_),
fes(mass->fes)
{
const int nd = fes->GetFE(0)->GetDof();
Minv.SetSize(nd, nd, fes->GetNE());
DenseMatrix Me(nd);
DenseMatrixInverse MeInv(&Me);
for (int e = 0; e < fes->GetNE(); e++)
{
Me = mass->M(e);
MeInv.Factor();
MeInv.GetInverseMatrix(Minv(e));
}
}
void InverseMassMatrixDG::Mult(const Vector &x, Vector &y) const
{
Array<int> vdofs;
const int nd = fes->GetFE(0)->GetDof();
DenseMatrix xel, yel;
for (int e = 0; e < fes->GetNE(); e++)
{
fes->GetElementVDofs(e, vdofs);
int nc = vdofs.Size()/nd;
xel.SetSize(nd, nc);
yel.SetSize(nd, nc);
x.GetSubVector(vdofs, xel.Data());
mfem::Mult(Minv(e), xel, yel);
y.SetSubVector(vdofs, yel.Data());
}
}
+35
View File
@@ -0,0 +1,35 @@
#ifndef HYPSYS_MASSMAT
#define HYPSYS_MASSMAT
#include "mfem.hpp"
using namespace mfem;
class MassMatrixDG : public Operator
{
friend class InverseMassMatrixDG;
const FiniteElementSpace *fes;
public:
DenseTensor M;
MassMatrixDG(const FiniteElementSpace *fes_);
~MassMatrixDG() {};
void Mult(const Vector &x, Vector &y) const;
};
class InverseMassMatrixDG : public Operator
{
const MassMatrixDG *mass;
const FiniteElementSpace *fes;
public:
DenseTensor Minv;
InverseMassMatrixDG(const MassMatrixDG *mass_);
~InverseMassMatrixDG() { };
virtual void Mult(const Vector &x, Vector &y) const;
};
#endif
+133
View File
@@ -0,0 +1,133 @@
#include "pbounds.hpp"
ParBounds::ParBounds(ParFiniteElementSpace *pfes_,
ParFiniteElementSpace *pfesH1_)
: Bounds(pfes_, pfesH1_), pfes(pfes_), pfesH1(pfesH1_), px_min(pfesH1_),
px_max(pfesH1_) { /* mom_min.SetSize(2*ne*nd); mom_max.SetSize(2*ne*nd); */ }
void ParBounds::ComputeBounds(const Vector &x)
{
GroupCommunicator &gcomm = pfesH1->GroupComm();
px_min = std::numeric_limits<double>::infinity();
px_max = -std::numeric_limits<double>::infinity();
for (int e = 0; e < ne; e++)
{
pfesH1->GetElementDofs(e, eldofs);
ComputeElementBounds(0, e, x);
}
Array<double> minvals(px_min.GetData(), px_min.Size()),
maxvals(px_max.GetData(), px_max.Size());
gcomm.Reduce<double>(minvals, GroupCommunicator::Min);
gcomm.Bcast(minvals);
gcomm.Reduce<double>(maxvals, GroupCommunicator::Max);
gcomm.Bcast(maxvals);
for (int e = 0; e < ne; e++)
{
pfesH1->GetElementDofs(e, eldofs);
for (int j = 0; j < nd; j++)
{
xi_min(e*nd + j) = px_min(eldofs[DofMapH1[j]]);
xi_max(e*nd + j) = px_max(eldofs[DofMapH1[j]]);
}
}
for (int n = 1; n < NumEq; n++)
{
px_min = std::numeric_limits<double>::infinity();
px_max = -std::numeric_limits<double>::infinity();
for (int e = 0; e < ne; e++)
{
pfesH1->GetElementDofs(e, eldofs);
ComputeSequentialBounds(n, e, x);
}
Array<double> minvals2(px_min.GetData(), px_min.Size()),
maxvals2(px_max.GetData(), px_max.Size());
gcomm.Reduce<double>(minvals2, GroupCommunicator::Min);
gcomm.Bcast(minvals2);
gcomm.Reduce<double>(maxvals2, GroupCommunicator::Max);
gcomm.Bcast(maxvals2);
for (int e = 0; e < ne; e++)
{
pfesH1->GetElementDofs(e, eldofs);
for (int j = 0; j < nd; j++)
{
xi_min(n*ne*nd + e*nd + j) = px_min(eldofs[DofMapH1[j]]);
xi_max(n*ne*nd + e*nd + j) = px_max(eldofs[DofMapH1[j]]);
}
}
}
}
ParTightBounds::ParTightBounds(ParFiniteElementSpace *pfes_,
ParFiniteElementSpace *pfesH1_)
: ParBounds(pfes_, pfesH1_)
{
FillClosestNbrs(pfes->GetFE(0), ClosestNbrs);
}
void ParTightBounds::ComputeElementBounds(int n, int e, const Vector &x)
{
for (int i = 0; i < nd; i++)
{
const int I = eldofs[DofMapH1[i]];
px_min(I) = min(px_min(I), xi_min(n*ne*nd + e*nd + i));
px_max(I) = max(px_max(I), xi_max(n*ne*nd + e*nd + i));
for (int j = 0; j < ClosestNbrs.Width(); j++)
{
if (ClosestNbrs(i,j) == -1) { break; }
const int J = n*ne*nd + e*nd + ClosestNbrs(i,j);
px_min(I) = min(px_min(I), x(J));
px_max(I) = max(px_max(I), x(J));
}
}
}
void ParTightBounds::ComputeSequentialBounds(int n, int e, const Vector &x)
{
for (int i = 0; i < nd; i++)
{
const int I = eldofs[DofMapH1[i]];
px_min(I) = min(px_min(I), xi_min(n*ne*nd + e*nd + i));
px_max(I) = max(px_max(I), xi_max(n*ne*nd + e*nd + i));
}
}
ParLooseBounds::ParLooseBounds(ParFiniteElementSpace *pfes_,
ParFiniteElementSpace *pfesH1_)
: ParBounds(pfes_, pfesH1_) { }
void ParLooseBounds::ComputeElementBounds(int n, int e, const Vector &x)
{
double xe_min = std::numeric_limits<double>::infinity();
double xe_max = -std::numeric_limits<double>::infinity();
for (int j = 0; j < nd; j++)
{
xe_min = min(xe_min, x(n*ne*nd + e*nd+j));
xe_max = max(xe_max, x(n*ne*nd + e*nd+j));
}
for (int j = 0; j < nd; j++)
{
int I = eldofs[DofMapH1[j]];
px_min(I) = min(px_min(I), xe_min);
px_max(I) = max(px_max(I), xe_max);
}
}
void ParLooseBounds::ComputeSequentialBounds(int n, int e, const Vector &x)
{
// TODO
}
+45
View File
@@ -0,0 +1,45 @@
#ifndef HYPSYS_PBOUNDS
#define HYPSYS_PBOUNDS
#include "bounds.hpp"
using namespace std;
using namespace mfem;
class ParBounds : public Bounds
{
public:
ParFiniteElementSpace *pfes, *pfesH1;
ParGridFunction px_min, px_max; // min max values for each H1 dof.
// Vector mom_min, mom_max;
ParBounds(ParFiniteElementSpace *pfes_, ParFiniteElementSpace *pfesH1_);
virtual ~ParBounds() { }
virtual void ComputeBounds(const Vector &x) override;
};
class ParTightBounds : public ParBounds
{
public:
DenseMatrix ClosestNbrs;
ParTightBounds(ParFiniteElementSpace *pfes_, ParFiniteElementSpace *pfesH1_);
~ParTightBounds() { }
virtual void ComputeElementBounds(int n, int e, const Vector &x) override;
virtual void ComputeSequentialBounds(int n, int e, const Vector &x) override;
};
class ParLooseBounds : public ParBounds
{
public:
ParLooseBounds(ParFiniteElementSpace *pfes_, ParFiniteElementSpace *pfesH1_);
~ParLooseBounds() { }
virtual void ComputeElementBounds(int n, int e, const Vector &x) override;
virtual void ComputeSequentialBounds(int n, int e, const Vector &x) override;
};
#endif
+189
View File
@@ -0,0 +1,189 @@
#include "pdofs.hpp"
ParDofInfo::ParDofInfo(ParFiniteElementSpace *pfes_)
: DofInfo(pfes_), pmesh(pfes_->GetParMesh()), pfes(pfes_)
{
FillNeighborDofs();
}
void ParDofInfo::FillNeighborDofs()
{
// Use the first mesh element as indicator.
const FiniteElement &el = *pfes->GetFE(0);
int i, j, e, nbr, ne = pmesh->GetNE();
int nd = el.GetDof(), p = el.GetOrder();
Array <int> bdrs, orientation;
FaceElementTransformations *Trans;
pmesh->ExchangeFaceNbrData();
Table *face_to_el = pmesh->GetFaceToAllElementTable();
NbrDofs.SetSize(NumBdrs, NumFaceDofs, ne);
// Permutations of BdrDofs, taking into account all possible orientations.
// Assumes BdrDofs are ordered in xyz order, which is true for 3D hexes,
// but it isn't true for 2D quads.
int orient_cnt = 1;
if (dim == 2) { orient_cnt = 2; }
if (dim == 3) { orient_cnt = 8; }
const int dof1D_cnt = p+1;
DenseTensor fdof_ids(NumFaceDofs, NumBdrs, orient_cnt);
for (int ori = 0; ori < orient_cnt; ori++)
{
for (int face_id = 0; face_id < NumBdrs; face_id++)
{
for (int fdof_id = 0; fdof_id < NumFaceDofs; fdof_id++)
{
// Index of fdof_id in the current orientation.
const int ori_fdof_id = GetLocalFaceDofIndex(dim, face_id, ori,
fdof_id, dof1D_cnt);
fdof_ids(ori)(ori_fdof_id, face_id) = BdrDofs(fdof_id, face_id);
}
}
}
for (e = 0; e < ne; e++)
{
if (dim==1)
{
pmesh->GetElementVertices(e, bdrs);
for (i = 0; i < NumBdrs; i++)
{
const int nbr_cnt = face_to_el->RowSize(bdrs[i]);
if (nbr_cnt == 1)
{
// No neighbor element.
NbrDofs(i,0,e) = -1;
continue;
}
int el1_id, el2_id, nbr_id;
pmesh->GetFaceElements(bdrs[i], &el1_id, &el2_id);
if (el2_id < 0)
{
// This element is in a different mpi task.
el2_id = -1 - el2_id + ne;
}
nbr_id = (el1_id == e) ? el2_id : el1_id;
NbrDofs(i,0,e) = nbr_id*nd + BdrDofs(0,(i+1)%2);
}
}
else if (dim==2)
{
pmesh->GetElementEdges(e, bdrs, orientation);
for (i = 0; i < NumBdrs; i++)
{
const int nbr_cnt = face_to_el->RowSize(bdrs[i]);
if (nbr_cnt == 1)
{
// No neighbor element.
for (j = 0; j < NumFaceDofs; j++) { NbrDofs(i,j,e) = -1; }
continue;
}
int el1_id, el2_id, nbr_id;
pmesh->GetFaceElements(bdrs[i], &el1_id, &el2_id);
if (el2_id < 0)
{
// This element is in a different mpi task.
el2_id = -1 - el2_id + ne;
}
nbr_id = (el1_id == e) ? el2_id : el1_id;
int el1_info, el2_info;
pmesh->GetFaceInfos(bdrs[i], &el1_info, &el2_info);
const int face_id_nbr = (nbr_id == el1_id) ? el1_info / 64
: el2_info / 64;
for (j = 0; j < NumFaceDofs; j++)
{
// Here it is utilized that the orientations of the face for
// the two elements are opposite of each other.
NbrDofs(i,j,e) = nbr_id*nd + BdrDofs(NumFaceDofs - 1 - j,
face_id_nbr);
}
}
}
else if (dim==3)
{
pmesh->GetElementFaces(e, bdrs, orientation);
for (int f = 0; f < NumBdrs; f++)
{
const int nbr_cnt = face_to_el->RowSize(bdrs[f]);
if (nbr_cnt == 1)
{
// No neighbor element.
for (j = 0; j < NumFaceDofs; j++) { NbrDofs(f,j,e) = -1; }
continue;
}
int el1_id, el2_id, nbr_id;
pmesh->GetFaceElements(bdrs[f], &el1_id, &el2_id);
if (el2_id < 0)
{
// This element is in a different mpi task.
el2_id = -1 - el2_id + ne;
}
nbr_id = (el1_id == e) ? el2_id : el1_id;
// Local index and orientation of the face, when considered in
// the neighbor element.
int el1_info, el2_info;
pmesh->GetFaceInfos(bdrs[f], &el1_info, &el2_info);
const int face_id_nbr = (nbr_id == el1_id) ? el1_info / 64
: el2_info / 64;
const int face_or_nbr = (nbr_id == el1_id) ? el1_info % 64
: el2_info % 64;
for (j = 0; j < NumFaceDofs; j++)
{
// What is the index of the j-th dof on the face, given its
// orientation.
const int loc_face_dof_id =
GetLocalFaceDofIndex(dim, face_id_nbr, face_or_nbr,
j, dof1D_cnt);
// What is the corresponding local dof id on the element,
// given the face orientation.
const int nbr_dof_id =
fdof_ids(face_or_nbr)(loc_face_dof_id, face_id_nbr);
NbrDofs(f,j,e) = nbr_id*nd + nbr_dof_id;
}
}
}
}
for (e = 0; e < pfes->GetNBE(); e++)
{
const int bdr_attr = mesh->GetBdrAttribute(e);
FaceElementTransformations *tr = mesh->GetBdrFaceTransformations(e);
if (tr != NULL)
{
const int el = tr->Elem1No;
if (dim == 1) { mesh->GetElementVertices(el, bdrs); }
else if (dim == 2) { mesh->GetElementEdges(el, bdrs, orientation); }
else if (dim == 3) { mesh->GetElementFaces(el, bdrs, orientation); }
for (i = 0; i < NumBdrs; i++)
{
if (bdrs[i] == mesh->GetBdrElementEdgeIndex(e))
{
for (j = 0; j < NumFaceDofs; j++)
{
NbrDofs(i, j, el) = -bdr_attr;
}
continue;
}
}
}
else
{
MFEM_ABORT("Something went wrong.");
}
}
delete face_to_el;
}
+23
View File
@@ -0,0 +1,23 @@
#ifndef HYPSYS_PDOFS
#define HYPSYS_PDOFS
#include "dofs.hpp"
using namespace std;
using namespace mfem;
class ParDofInfo : public DofInfo
{
public:
ParMesh *pmesh;
ParFiniteElementSpace *pfes;
ParDofInfo(ParFiniteElementSpace *pfes_);
~ParDofInfo() { }
// NOTE: This approach will not work for meshes with hanging h- or p-nodes.
void FillNeighborDofs();
};
#endif
+8
View File
@@ -0,0 +1,8 @@
#ifndef HYPSYS_LIB_PLIB
#define HYPSYS_LIB_PLIB
#include "pbounds.hpp"
#include "pdofs.hpp"
#include "ptools.hpp"
#endif
+39
View File
@@ -0,0 +1,39 @@
#include "ptools.hpp"
void ParVisualizeField(socketstream &sock, const char *vishost, int visport,
string ProblemName, ParGridFunction &gf, string glvis_scale, bool vec)
{
ParMesh &pmesh = *gf.ParFESpace()->GetParMesh();
MPI_Comm comm = pmesh.GetComm();
int myid;
MPI_Comm_rank(comm, &myid);
bool newly_opened = false;
if (myid == 0)
{
if (!sock.is_open() && sock)
{
sock.open(vishost, visport);
sock.precision(8);
newly_opened = true;
}
sock << "solution\n";
}
pmesh.PrintAsOne(sock);
gf.SaveAsOne(sock);
if (myid == 0 && newly_opened)
{
sock << "window_title '" << ProblemName << "'\n"
<< "window_geometry "
<< 0 << " " << 0 << " " << 1080 << " " << 1080 << "\n"
<< "autoscale " << glvis_scale << "\n"
<< "keys mcjlppppppppppppppppppppppppppp66666666666666666666666"
<< "66666666666666666666666666666666666666666666666662222222222";
if ( vec ) { sock << "vvv"; }
sock << endl;
}
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef HYPSYS_PTOOLS
#define HYPSYS_PTOOLS
#include <fstream>
#include <iostream>
#include "mfem.hpp"
using namespace std;
using namespace mfem;
void ParVisualizeField(socketstream &sock, const char *vishost, int visport,
string ProblemName, ParGridFunction &gf, string glvis_scale, bool vec = false);
#endif
+15
View File
@@ -0,0 +1,15 @@
#ifndef HYPSYS_LIB_TEMPLATE
#define HYPSYS_LIB_TEMPLATE
#include "mfem.hpp"
using namespace std;
using namespace mfem;
class TEMPLATE
{
public:
};
#endif
+77
View File
@@ -0,0 +1,77 @@
#include "tools.hpp"
const IntegrationRule* GetElementIntegrationRule(FiniteElementSpace *fes,
bool NodalQuadRule)
{
const FiniteElement *el = fes->GetFE(0);
if (NodalQuadRule)
{
return &(el->GetNodes());
}
ElementTransformation *eltrans = fes->GetElementTransformation(0);
int order = eltrans->OrderGrad(el) + eltrans->Order() + el->GetOrder();
return &IntRules.Get(el->GetGeomType(), order);
}
const IntegrationRule *GetFaceIntegrationRule(FiniteElementSpace *fes,
bool NodalQuadRule)
{
int i, order;
// Use the first mesh face and element as indicator.
const FaceElementTransformations *Trans =
fes->GetMesh()->GetFaceElementTransformations(0);
if (NodalQuadRule)
{
return &IntRules.Get(Trans->FaceGeom, 1);
}
const FiniteElement *el = fes->GetFE(0);
if (Trans->Elem2No >= 0)
{
order = min(Trans->Elem1->OrderW(), Trans->Elem2->OrderW())
+ 2*el->GetOrder();
}
else
{
order = Trans->Elem1->OrderW() + 2*el->GetOrder();
}
if (el->Space() == FunctionSpace::Pk)
{
order++;
}
return &IntRules.Get(Trans->FaceGeom, order);
}
void VisualizeField(socketstream &sock, const char *vishost, int visport,
string ProblemName, GridFunction &gf, string glvis_scale, bool vec)
{
Mesh &mesh = *gf.FESpace()->GetMesh();
bool newly_opened = false;
if (!sock.is_open() && sock)
{
sock.open(vishost, visport);
sock.precision(8);
newly_opened = true;
}
sock << "solution\n";
mesh.Print(sock);
gf.Save(sock);
if (newly_opened)
{
sock << "window_title '" << ProblemName << "'\n"
<< "window_geometry "
<< 0 << " " << 0 << " " << 1080 << " " << 1080 << "\n"
<< "autoscale " << glvis_scale << "\n"
<< "keys mcjlppppppppppppppppppppppppppp66666666666666666666666"
<< "66666666666666666666666666666666666666666666666662222222222";
if ( vec ) { sock << "vvv"; }
sock << endl;
}
}
+21
View File
@@ -0,0 +1,21 @@
#ifndef HYPSYS_TOOLS
#define HYPSYS_TOOLS
#include <fstream>
#include <iostream>
#include "mfem.hpp"
using namespace std;
using namespace mfem;
const IntegrationRule* GetElementIntegrationRule(FiniteElementSpace *fes,
bool NodalQuadRule = false);
// Appropriate quadrature rule for faces according to DGTraceIntegrator.
const IntegrationRule *GetFaceIntegrationRule(FiniteElementSpace *fes,
bool NodalQuadRule = false);
void VisualizeField(socketstream &sock, const char *vishost, int visport,
string ProblemName, GridFunction &gf, string glvis_scale, bool vec = false);
#endif
+109
View File
@@ -0,0 +1,109 @@
# Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at the
# Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights reserved.
# See file COPYRIGHT for details.
#
# This file is part of the MFEM library. For more information and source code
# availability see http://mfem.org.
#
# MFEM is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License (as published by the Free
# Software Foundation) version 2.1 dated February 1999.
# Use the MFEM build directory
MFEM_DIR ?= ../..
CONFIG_MK = $(MFEM_DIR)/config/config.mk
MFEM_LIB_FILE = mfem_is_not_built
-include $(CONFIG_MK)
# Code directories in logical order
APP_DIR = apps
BLD_DIR = build
EVL_DIR = fe_evol
LIB_DIR = lib
OUT_DIR = output
DIRS = $(APP_DIR) $(EVL_DIR) $(LIB_DIR)
LIB_FILES = $(BLD_DIR)/massmat.o $(BLD_DIR)/dofs.o $(BLD_DIR)/tools.o $(BLD_DIR)/bounds.o
EVL_FILES = $(BLD_DIR)/fe_evol.evl $(BLD_DIR)/galerkin.evl $(BLD_DIR)/monolithic_convex_limiting.evl
APP_FILES = $(BLD_DIR)/advection.app $(BLD_DIR)/burgers.app $(BLD_DIR)/kpp.app $(BLD_DIR)/buckley_leverett.app # scalar problems
APP_FILES+= $(BLD_DIR)/shallowwater.app $(BLD_DIR)/euler.app # hyperbolic systems
MAIN_FILES = hypsys
ifeq ($(MFEM_USE_MPI), YES)
MAIN_FILES += phypsys
PLIB_FILES += $(BLD_DIR)/pdofs.o
PLIB_FILES += $(BLD_DIR)/ptools.o
PLIB_FILES += $(BLD_DIR)/pbounds.o
PEVL_FILES += $(BLD_DIR)/pgalerkin.evl
PEVL_FILES += $(BLD_DIR)/pmonolithic_convex_limiting.evl
endif
# valgrind-test setup
PROBLEM = 0
VALGRIND-CONFIG = -tf 0.001 -dt 0.001 -p $(PROBLEM) -e 0
## Makefile rules. #############################################################
# Keywords that are not associated with files (by default, all are).
.PHONY: all library hypsys phypsys clean valgrind-test grid-convergence-test sytle
# Delete the default suffixes.
.SUFFIXES:
# Define suffixes.
.SUFFIXES: .c .cpp
# Replace the default implicit rule for *.cpp files
%: %.cpp $(CONFIG_MK)
$(MFEM_CXX) $(MFEM_FLAGS) $< -o $@ $(LIB_FILES) $(APP_FILES) $(MFEM_LIBS)
%.o: ../$(LIB_DIR)/%.cpp
$(MFEM_CXX) $(MFEM_FLAGS) -c $^ -o $@
%.evl: ../$(EVL_DIR)/%.cpp
$(MFEM_CXX) $(MFEM_FLAGS) -c $^ -o $@
%.app: ../$(APP_DIR)/%.cpp
$(MFEM_CXX) $(MFEM_FLAGS) -c $^ -o $@
all: $(MAIN_FILES)
library: $(LIB_FILES) $(PLIB_FILES) $(EVL_FILES) $(PEVL_FILES) $(APP_FILES)
hypsys: library
$(MFEM_CXX) $(MFEM_FLAGS) hypsys.cpp -o $@ $(LIB_FILES) $(EVL_FILES) $(APP_FILES) $(MFEM_LIBS)
phypsys: library
$(MFEM_CXX) $(MFEM_FLAGS) phypsys.cpp -o $@ $(LIB_FILES) $(PLIB_FILES) $(EVL_FILES) $(PEVL_FILES) $(APP_FILES) $(MFEM_LIBS)
clean:
@rm -f hypsys phypsys errors.txt *gf* grid* $(OUT_DIR)/* $(BLD_DIR)/*
valgrind-serial:
valgrind ./hypsys $(VALGRIND-CONFIG) -c 1 -m data/inline-4segment.mesh -r 4 -o 1
valgrind ./hypsys $(VALGRIND-CONFIG) -c 0 -m data/periodic-square.mesh -r 2 -o 2 -s 1
valgrind ./hypsys $(VALGRIND-CONFIG) -c 0 -m data/beam-quad.mesh -r 1 -o 3
valgrind ./hypsys $(VALGRIND-CONFIG) -c 1 -m data/wall-bdr-4hex.mesh -r 0 -o 2
# TODO does not work yet
valgrind-parallel:
# mpirun -np 2 valgrind --leak-check=yes ./par-hypsys -tf 0.1 -r 0
# valgrind --gen-suppressions=yes phypsys $(VALGRIND-CONFIG)
# valgrind --suppressions=$(MPI_HOME)/share/openmpi/openmpi-valgrind.supp phypsys $(VALGRIND-CONFIG)
valgrind --suppressions=./my-mpi-suppressions.supp phypsys $(VALGRIND-CONFIG)
$(MFEM_LIB_FILE):
$(error The MFEM library is not built)
ASTYLE = ~/astyle --options=$(MFEM_DIR)/config/mfem.astylerc
FORMAT_FILES = $(foreach dir,$(DIRS),"$(dir)/*.?pp")
FORMAT_FILES += hypsys.cpp
FORMAT_FILES += phypsys.cpp
style:
@if ! $(ASTYLE) $(FORMAT_FILES) | grep Formatted; then\
echo "No source files were changed.";\
fi
+61
View File
@@ -0,0 +1,61 @@
ATTENTION
DEBUG
ROADMAP
-euler w-c benchmark shows problem with mcl low order method
-Change quadrature rules - read up on it/use int rules as in different operators in mfem. Hexes seem off as well.
CLEANUP
-lib: check quadrature orders - other than that *tools* *lib.hpp is done
TODO: (p-) bounds, dofs, massmat
-fe_evol
TODO
Minor Tasks
Check if it is actually possible to make Gresho vortex converge to steady state (with galerkin first)
Check apps/bl.cpp for correctness
High Priority:
Discrepancy to results in paper :( - already in 1D low order method, Woodward-Colella breaks
Cleanup
Efficiency
Medium Priority:
Advection - NodalQuadRule
Low Priority:
Test GMS for Euler, remove if unnecessary
Try to run MCL on curved geometries
Vector output as arrows
Desirable:
-Euler: Implement subsonic in- and outflow.
-Sedov setup
-Theoretically, double-mach requires a subsonic outlet at the short edge before wall boundaries
-Noh problem: zero verlocity part of bdr: wall, rest: supersonic outflow (east, north)
and supersonic inflow (south, east), i.e. bdr type changes in time
-Expression for momentum in narrowing channel
-If possible: Try to distinguish boundary types by considering eigenvalues of systems
next steps
-Pressure fix: Required for Woodward-Colella, double-mach, Sedov, Noh
If possible: try to make advection with non-constant velocity and MCL work
minor tasks:
-C++ type cleanup, e.g for DofInfo classes
-Maybe move stuff thats not needed within main routines (e.g. dofs) into fe_evol.cpp
-If difficult, move bound computation to MCL Evolution.
-Use mfem::Mult for matrix multiplication
-Since MCL works only for elements with constant Jacobians, maybe use Vector of size ne
-Restructure galerkin, fe_evol and mcl (constructors)
future tasks
-Entropy fixes
-Smoothness indicator
+344
View File
@@ -0,0 +1,344 @@
#include "lib/lib.hpp"
#include "fe_evol/plib.hpp"
#include "apps/lib.hpp"
int main(int argc, char *argv[])
{
MPI_Session mpi(argc, argv);
const int myid = mpi.WorldRank();
Configuration config;
int ProblemNum = 0;
config.ConfigNum = 1;
int VisSteps = 100;
config.tFinal = 1.;
int odeSolverType = 3;
double dt = 0.001;
const char *MeshFile = "data/inline-4quad.mesh";
int order = 3;
int refinements = 1;
int prefinements = 0;
EvolutionScheme scheme = MonolithicConvexLimiting;
const char *OutputDir = "output"; // Directory has to exist to produce output.
bool TransOutput = false; // Use this to produce output for videos.
bool VisualizeDerived = false;
int precision = 8;
cout.precision(precision);
OptionsParser args(argc, argv);
args.AddOption(&ProblemNum, "-p", "--problem",
"Hyperbolic system of equations to solve.");
args.AddOption(&config.ConfigNum, "-c", "--configuration",
"Problem setup to use.");
args.AddOption(&VisSteps, "-vf", "--visualization-frequency",
"Visualize every n-th timestep.");
args.AddOption(&config.tFinal, "-tf", "--final-time",
"Final time; start time is 0.");
args.AddOption(&odeSolverType, "-s", "--ode-solver",
"ODE solver: 1 - Forward Euler,\n\t"
" 2 - RK2 SSP, 3 - RK3 SSP, 4 - RK4, 6 - RK6.");
args.AddOption(&dt, "-dt", "--time-step", "Time step.");
args.AddOption(&MeshFile, "-m", "--mesh", "Mesh file to use.");
args.AddOption(&order, "-o", "--order",
"Order (polynomial degree) of the finite element space.");
args.AddOption(&refinements, "-r", "--serial-refinements",
"Number of times to refine the mesh uniformly in serial.");
args.AddOption(&prefinements, "-pr", "--parallel-refinements",
"Number of times to refine the mesh uniformly in parallel.");
args.AddOption((int*)(&scheme), "-es", "--evolution-scheme",
"Scheme: 0 - Galerkin Finite Element Approximation,\n\t"
" 1 - Monolithic Convex Limiting.");
args.AddOption(&OutputDir, "-out", "--output-directory", "Output directory.");
args.AddOption(&TransOutput, "-t", "--transitional-output", "-no-t",
"--no-transitional-output", "Print transitional output files.");
args.Parse();
if (!args.Good())
{
if (myid == 0) { args.PrintUsage(cout); }
return -1;
}
if (myid == 0) { args.PrintOptions(cout); }
if (order == 0)
{
scheme = Galerkin;
}
ODESolver *odeSolver = NULL;
switch (odeSolverType)
{
case 1: odeSolver = new ForwardEulerSolver; break;
case 2: odeSolver = new RK2Solver(1.0); break;
case 3: odeSolver = new RK3SSPSolver; break;
case 4: odeSolver = new RK4Solver; break;
case 6: odeSolver = new RK6Solver; break;
default:
cout << "Unknown ODE solver type: " << odeSolverType << endl;
return -1;
}
if (myid == 0 && odeSolverType > 3)
{
MFEM_WARNING("Non-SSP odeSolver: Maximum principles may be violated.");
}
// Read the serial mesh from the given mesh file on all processors.
Mesh *mesh = new Mesh(MeshFile, 1, 1);
const int dim = mesh->Dimension();
for (int lev = 0; lev < refinements; lev++)
{
mesh->UniformRefinement();
}
mesh->GetBoundingBox(config.bbMin, config.bbMax, max(order, 1));
// Parallel partitioning of the mesh.
ParMesh pmesh(MPI_COMM_WORLD, *mesh);
delete mesh;
for (int lev = 0; lev < prefinements; lev++)
{
pmesh.UniformRefinement();
}
if (pmesh.NURBSext)
{
pmesh.SetCurvature(max(order, 1));
}
MPI_Comm comm = pmesh.GetComm();
int NumEq;
switch (ProblemNum)
{
case 0:
case 1:
case 2:
case 3: {NumEq = 1; VisualizeDerived = false; break; }
case 4: NumEq = 1 + dim; break;
case 5: NumEq = 2 + dim; break;
default:
cout << "Unknown hyperbolic system: " << ProblemNum << endl;
delete odeSolver;
return -1;
}
// Create Bernstein Finite Element Space.
const int btype = BasisType::Positive;
L2_FECollection fec(order, dim, btype);
ParFiniteElementSpace pfes(&pmesh, &fec);
ParFiniteElementSpace vfes(&pmesh, &fec, NumEq, Ordering::byNODES);
Array<int> offsets(NumEq + 1);
for (int k = 0; k <= NumEq; k++) { offsets[k] = k * pfes.GetNDofs(); }
BlockVector u_block(offsets);
const int ProblemSize = vfes.GlobalVSize();
if (myid == 0)
{
cout << "Number of unknowns: " << ProblemSize << endl;
}
ParDofInfo pdofs(&pfes);
bool NodalQuadRule = false;
if (scheme == MonolithicConvexLimiting)
{
NodalQuadRule = true;
}
HyperbolicSystem *hyp;
switch (ProblemNum)
{
case 0: { hyp = new Advection(&vfes, u_block, config, NodalQuadRule); break; }
case 1: { hyp = new Burgers(&vfes, u_block, config); break; }
case 2: { hyp = new KPP(&vfes, u_block, config); break; }
case 3: { hyp = new BuckleyLeverett(&vfes, u_block, config); break; }
case 4: { hyp = new ShallowWater(&vfes, u_block, config); break; }
case 5: { hyp = new Euler(&vfes, u_block, config); break; }
default:
return -1;
}
if (odeSolverType != 1 && hyp->SteadyState && myid == 0)
{
MFEM_WARNING("Better use forward Euler pseudo time stepping for steady state simulations.");
}
ParGridFunction u(&vfes, u_block);
u = hyp->u0;
// The main is variable is visualized, printed, and used to check for mass leaks or violation of maximum principles.
ParGridFunction main(&pfes, u_block.GetBlock(0));
ostringstream MeshName, InitName;
MeshName << OutputDir << "/grid-mesh." << setfill('0') << setw(6) << myid;
InitName << OutputDir << "/initial-gf." << setfill('0') << setw(6) << myid;
ofstream omesh(MeshName.str().c_str());
omesh.precision(precision);
pmesh.Print(omesh);
ofstream initial(InitName.str().c_str());
initial.precision(precision);
main.Save(initial);
socketstream sout;
char vishost[] = "localhost";
int visport = 19916;
{
// Make sure all MPI ranks have sent their 'v' solution before initiating
// another set of GLVis connections (one from each rank):
MPI_Barrier(comm);
ParVisualizeField(sout, vishost, visport, hyp->ProblemName, main,
hyp->glvis_scale);
}
FE_Evolution *evol;
switch (scheme)
{
case Galerkin: { evol = new ParGalerkinEvolution(&vfes, hyp, pdofs); break; }
case MonolithicConvexLimiting: { evol = new ParMCL_Evolution(&vfes, hyp, pdofs, dt); break; }
default:
MFEM_ABORT("Unknown evolution scheme");
}
Vector LumpedMassMat(pfes.GetVSize());
ParBilinearForm ml(&pfes);
ml.AddDomainIntegrator(new LumpedIntegrator(new MassIntegrator()));
ml.Assemble();
ml.Finalize();
ml.SpMat().GetDiag(LumpedMassMat);
double InitialMass, MassMPI = LumpedMassMat * main;
MPI_Allreduce(&MassMPI, &InitialMass, 1, MPI_DOUBLE, MPI_SUM, comm);
odeSolver->Init(*evol);
if (hyp->SteadyState)
{
evol->uOld.SetSize(ProblemSize);
evol->uOld = 0.;
}
int TransStep = 1;
double dtLast, res, t = 0., tol = 1.e-12;
bool done = t >= config.tFinal;
tic_toc.Clear();
tic_toc.Start();
if (myid == 0)
{
cout << "Preprocessing done. Entering time stepping loop.\n";
}
for (int ti = 0; !done;)
{
dtLast = min(dt, config.tFinal - t);
odeSolver->Step(u, t, dtLast);
ti++;
done = (t >= config.tFinal - 1.e-8 * dt);
if (hyp->SteadyState)
{
res = evol->ConvergenceCheck(dt, u);
if (res < tol)
{
done = true;
u = evol->uOld;
}
}
if (done || ti % VisSteps == 0)
{
if (myid == 0)
{
if (hyp->SteadyState)
{
cout << "time step: " << ti << ", time: " << t << ", residual: " << res << endl;
}
else
{
cout << "time step: " << ti << ", time: " << t << endl;
}
}
ParVisualizeField(sout, vishost, visport, hyp->ProblemName, main,
hyp->glvis_scale);
if (TransOutput)
{
ostringstream TransName;
TransName << OutputDir << "/trans-gf-" << TransStep << "."
<< setfill('0') << setw(6) << myid;
ofstream trans(TransName.str().c_str());
trans.precision(precision);
main.Save(trans);
TransStep++;
}
}
}
tic_toc.Stop();
if (myid == 0)
{
cout << "Time stepping loop done in " << tic_toc.RealTime() << " seconds.\n\n";
}
double FinalMass, DomainSize, DomainSizeMPI = LumpedMassMat.Sum();
MPI_Allreduce(&DomainSizeMPI, &DomainSize, 1, MPI_DOUBLE, MPI_SUM, comm);
if (hyp->SolutionKnown)
{
Array<double> errors;
hyp->ComputeErrors(errors, u, DomainSize, t);
if (myid == 0)
{
cout << "L1 error: " << errors[0] << endl;
hyp->WriteErrors(errors);
}
}
double mainMin, mainMax, mainLoc = main.Min();
MPI_Allreduce(&mainLoc, &mainMin, 1, MPI_DOUBLE, MPI_MIN, comm);
mainLoc = main.Max();
MPI_Allreduce(&mainLoc, &mainMax, 1, MPI_DOUBLE, MPI_MAX, comm);
MassMPI = LumpedMassMat * main;
MPI_Allreduce(&MassMPI, &FinalMass, 1, MPI_DOUBLE, MPI_SUM, comm);
if (myid == 0)
{
cout << "Min of primary field: " << mainMin << endl
<< "Max of primary field: " << mainMax << endl
<< "Difference in solution mass: "
<< abs(InitialMass - FinalMass) / DomainSize << "\n\n";
}
ostringstream FinalName;
FinalName << OutputDir << "/ultimate-gf." << setfill('0') << setw(6) << myid;
ofstream ultimate(FinalName.str().c_str());
ultimate.precision(precision);
main.Save(ultimate);
if (VisualizeDerived)
{
ParGridFunction v(&pfes), p(&pfes);
hyp->ComputeDerivedQuantities(u, v, p);
ostringstream VelocityName;
VelocityName << OutputDir << "/velocity-gf." << setfill('0') << setw(6) << myid;
ofstream velocity(VelocityName.str().c_str());
velocity.precision(precision);
v.Save(velocity);
if (ProblemNum == 5)
{
ostringstream PressureName;
PressureName << OutputDir << "/pressure-gf." << setfill('0') << setw(6) << myid;
ofstream pressure(PressureName.str().c_str());
pressure.precision(precision);
p.Save(pressure);
}
}
delete evol;
delete hyp;
delete odeSolver;
return 0;
}
+52
View File
@@ -0,0 +1,52 @@
# Plot specifications for my benchmarks
# Advection - Solid Body Rotation: side view
# keys lmj6666666666666666666666666666666666666666666666666666666666666666666666662222222222
valuerange 0 1
# TODO TRIM
# Burgers Equation - Riemann Problem
glvis -fn -20
keys lRjmc*******
valuerange -1 0.8
TRIM=1116x1018+576+20
# KPP Equation - 2D Spiral: top view
keys laammjR*************
valuerange 0.7854 11
# TODO TRIM
# KPP Equation - 2D Spiral: side view
keys RRRR44444444444444444444444444444422222222222222222222************** # 5 times Ctrl + UP
valuerange 0.7854 11
# TODO TRIM
# Shallow Water Equations - Constricted Channel
# run in serial to plot boundary
keys lRjmmb*************************
valuerange 1 1.85
TRIM=1886x838+17+121
# TODO choice of isolines
# Shallow Water Equations - Radial Dam Break
keys mjRRRR222222222222222222222222jmblttt**************** # 4 times Ctrl + UP
valuerange 0.1 1
TRIM=1096x881+412+191
# TODO choice of isolines
# Euler Equations of Gas dynamics - Double Mach Reflection
keys aajlmmR***************************
valuerange 1.375 23
TRIM=1886x472+17+304
ISOLINES: 1.375 23 24
# Euler Equations of Gas dynamics - Double Mach Reflection: Zoom
keys jlmmR******************************************************** # 50 times Ctrl + RIGHT, 22 time Ctrl + UP
valuerange 1.375 23
TRIM=1353x1057+0+0
ISOLINES: 4 14 24
@@ -0,0 +1,49 @@
function cmpRiemannSolvers()
ul = 0;
ur = 1;
n = 1/sqrt(2)*[1 1];
problem = 1;
fl = flux(ul, n, problem);
fr = flux(ur, n, problem);
sl = wavespeed(ul, n, problem);
sr = wavespeed(ur, n, problem);
LF = 0.5 * (dot(fl + fr, n) + max(abs(sl),abs(sr)) * (ul - ur))
if 0 < sl
HLL = dot(fl, n);
elseif 0 > sr
HLL = dot(fr, n);
else
HLL = (dot(sr*fl - sl*fr, n) + sl*sr*(ur-ul)) / (sr-sl);
end
HLL
end
function f = flux(u, n, problem)
switch problem
case 0
f = velocity * u;
case 1
f = u*u/2 * [1; 1];
end
end
function s = wavespeed(u, n, problem)
switch problem
case 0
s = dot(velocity, n);
case 1
s = u * sum(n);
end
end
function v = velocity()
v=[1; -0.5];
end
+69
View File
@@ -0,0 +1,69 @@
function createTable()
q = 1; % q=1: L1, q=2: L2, q=3 LInf errors
domainSize = 2;
numElPerDim = [48 64 96 128 192 256 384]' / domainSize;
numLvls = length(numElPerDim);
maxOrd = 4;
data = zeros(numLvls, maxOrd);
eoc = zeros(numLvls-1, 3);
for j = 1:maxOrd
file = fopen([num2str(j) '.txt'], 'r');
for i = 1:numLvls+1-j
aux = str2num(fgets(file));
data(i,j) = aux(q);
end
fclose(file);
end
tab = [];
for i=1:maxOrd
eoc(:,i) = log(data(2:end,i) ./ data(1:end-1,i)) ./ log(numElPerDim(1:end-1) ./ numElPerDim(2:end));
tab = [tab data(2:end,i), eoc(:,i)];
end
% tab
% return
file = fopen('table.txt','wt');
fprintf(file, '\\begin{table}[ht!]\n\\centering\n\\begin{tabular}{||c||c|c||c|c||c|c||c|c||}\n\\hline\n$1/h$ & $p=1$ & EOC & $p=2$ & EOC & $p=3$ & EOC & $p=4$ & EOC\\\\\n\\hline\n');
fprintf(file, '%d & %1.2E & & %1.2E & & %1.2E & & %1.2E & \\\\\n', numElPerDim(1), data(1,:));
for i = 2 : numLvls
switch i
case {2,3,4}
if numElPerDim(i) < 100
fprintf(file, '%d & %1.2E & %1.2f & %1.2E & %1.2f & %1.2E & %1.2f & %1.2E & %1.2f \\\\\n', numElPerDim(i), tab(i-1,:));
else
fprintf(file, '%d & %1.2E & %1.2f & %1.2E & %1.2f & %1.2E & %1.2f & %1.2E & %1.2f \\\\\n', numElPerDim(i), tab(i-1,:));
end
case 5
if numElPerDim(i) < 100
fprintf(file, '%d & %1.2E & %1.2f & %1.2E & %1.2f & %1.2E & %1.2f &&\\\\\n', numElPerDim(i), tab(i-1,1:end-2));
else
fprintf(file, '%d & %1.2E & %1.2f & %1.2E & %1.2f & %1.2E & %1.2f &&\\\\\n', numElPerDim(i), tab(i-1,1:end-2));
end
case 6
if numElPerDim(i) < 100
fprintf(file, '%d & %1.2E & %1.2f & %1.2E & %1.2f &&&&\\\\\n', numElPerDim(i), tab(i-1,1:end-4));
else
fprintf(file, '%d & %1.2E & %1.2f & %1.2E & %1.2f &&&&\\\\\n', numElPerDim(i), tab(i-1,1:end-4));
end
case 7
if numElPerDim(i) < 100
fprintf(file, '%d & %1.2E & %1.2f &&&&&&\\\\\n', numElPerDim(i), tab(i-1,1:end-6));
else
fprintf(file, '%d & %1.2E & %1.2f &&&&&&\\\\\n', numElPerDim(i), tab(i-1,1:end-6));
end
otherwise
error('Change of configuration requires modification of output formatting.');
end
end
e = num2str(q);
if q==3
e = '\\infty';
end
fprintf(file, ['\\hline\n\\end{tabular}\n\\caption{The $\\|\\cdot\\|_{L^' e '(\\Omega)}$~errors and corresponding EOC of ...$\\mathbb Q_p$, $p \\in \\{1,\\hdots,4\\}$ solutions to the 1D ... equation with initial condition ...}\\label{tab:}\n\\end{table}']);
fclose(file);
end
@@ -0,0 +1,89 @@
// This file is part of BLAST - a high-order finite element hydrocode
//
// MFEM has to be compiled in serial, then compile this with
//
// g++ -O3 -std=c++11 -I<MFEM_DIR> gridfunc-scatter.cpp -o gridfunc-scatter -L<MFEM_DIR> -lmfem -lrt
//
// where <MFEM_DIR> has to be replaced with the absolute path of the mfem directory.
#include <fstream>
#include "mfem.hpp"
using namespace mfem;
using namespace std;
int main(int argc, char *argv[])
{
if (argc != 3)
{
cout << "usage: " << argv[0]
<< " in_mesh_file in_gf_file" << endl;
return 1;
}
Mesh *mesh;
{
ifstream imesh (argv[1]);
if (!imesh)
{
cout << "can not open mesh file: " << argv[1] << endl;
return 2;
}
mesh = new Mesh (imesh, 1, 1);
}
int dim = mesh -> Dimension();
cout << "mesh dimension: " << dim << endl;
//////////////////////////////////
ofstream scatter_file("scatter.dat");
int sd = 4;
RefinedGeometry *RefG;
Vector values;
DenseMatrix pointmat, vec_values;
const IntegrationRule *ir;
int points_percell=sd;
cout << "Enter subdivision factor : " << flush;
cin >> sd;
cout << "Enter subdivisions per cell : " << flush;
cin >> points_percell;
points_percell--;
scatter_file.precision(8);
for (int lev = 0; lev < sd; lev++)
mesh->UniformRefinement();
GridFunction *gf;
{
ifstream igf(argv[2]);
gf = new GridFunction(mesh, igf);
}
for (int i = 0; i < mesh->GetNE(); i++)
{
RefG = GlobGeometryRefiner.Refine(mesh->GetElementBaseGeometry(i), points_percell, 1);
ir = &(RefG->RefPts);
// GET VALUES
gf->GetValues(i, *ir, values, pointmat);
for (int j = 0; j < pointmat.Width(); j++) //num of points per element
{
scatter_file << pointmat(0, j) << ' ';
//cout << pointmat(0,j) << ' ';
scatter_file << values(j) << '\n';
//cout << values(j) << endl;
}
//abort();
}
scatter_file.close();
//////////////////////////////////
delete gf;
delete mesh;
return 0;
}
@@ -0,0 +1,116 @@
# -*- text -*-
#
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
# University Research and Technology
# Corporation. All rights reserved.
# Copyright (c) 2004-2005 The University of Tennessee and The University
# of Tennessee Research Foundation. All rights
# reserved.
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
###############################################################
#
# OPAL suppressions
#
###############################################################
# weirdness in init routines on Gentoo
{
linux_pthread_init
Memcheck:Leak
fun:calloc
fun:allocate_dtv
fun:_dl_allocate_tls_storage
fun:_dl_allocate_tls
}
{
linux_pthread_init2
Memcheck:Leak
fun:calloc
fun:_dl_tls_setup
fun:__pthread_initialize_minimal
}
{
linux_pthread_init3
Memcheck:Leak
fun:memalign
fun:_dl_allocate_tls_storage
fun:_dl_allocate_tls
fun:__pthread_initialize_minimal
}
# The event library leaves some blocks in use that we should clean up,
# but it would require much changing of the event library, so it
# really isn't worth it...
{
event_lib_poll
Memcheck:Leak
fun:malloc
fun:realloc
fun:opal_realloc
fun:poll_dispatch
}
###############################################################
#
# ORTE suppressions
#
###############################################################
# inet_ntoa on linux mallocs a static buffer. We can't free
# it, so we have to live with it
{
linux_inet_ntoa
Memcheck:Leak
fun:malloc
fun:inet_ntoa
}
{
linux_inet_ntoa_thread
Memcheck:Leak
fun:calloc
fun:pthread_setspecific
fun:inet_ntoa
}
###############################################################
#
# OMPI suppressions
#
###############################################################
{
tcp_send
Memcheck:Param
writev(vector[...])
fun:writev
fun:mca_btl_tcp_frag_send
fun:mca_btl_tcp_endpoint_send
}
###############################################################
#
# Suppressions for various commonly-used packages
#
###############################################################
# Portals reference implementation has a read from invalid issue
{
portals_send
Memcheck:Param
socketcall.send(msg)
fun:send
fun:utcp_sendbytes
fun:utcp_sendto
fun:utcp_msg_wait
}
+42
View File
@@ -0,0 +1,42 @@
import numpy as np
from matplotlib import pyplot as plt
# exact
x=np.linspace(0,1,1000)
y=(x>=0.4)*(x<=0.6)
plt.plot(x,y,'--k',lw=1)
# # Order 0
# data = np.genfromtxt("scatter0.dat")
# index = np.argsort(data[:,0])
# plt.plot(data[index,0],data[index,1],'-m',lw=2)
# Order 1
data = np.genfromtxt("scatter1.dat")
index = np.argsort(data[:,0])
plt.plot(data[index,0],data[index,1],'-k',lw=2)
# Order 3
data = np.genfromtxt("scatter2.dat")
index = np.argsort(data[:,0])
plt.plot(data[index,0],data[index,1],'-b',lw=2)
# Order 7
data = np.genfromtxt("scatter3.dat")
index = np.argsort(data[:,0])
plt.plot(data[index,0],data[index,1],'-c',lw=2)
# Order 15
data = np.genfromtxt("scatter4.dat")
index = np.argsort(data[:,0])
plt.plot(data[index,0],data[index,1],'-g',lw=2)
# Order 31
data = np.genfromtxt("scatter5.dat")
index = np.argsort(data[:,0])
plt.plot(data[index,0],data[index,1],'-r',lw=2)
plt.ylim([-0.01,1.01])
plt.axis('off')
plt.legend(['p=1','p=3','p=7','p=15','p=31'])
plt.savefig('img.png')
+37
View File
@@ -0,0 +1,37 @@
function printEOC(data)
if nargin == 0
filename = '../errors.txt';
file = fopen(filename, 'r');
data = zeros(0,3);
while true
aux = fgets(file);
if aux == -1
break;
end
data(end+1,:) = str2num(aux);
end
fclose(file);
end
numElPerDim = [48 64 96 128 192 256 384 512]';
% numElPerDim = [4 8 16 32 64 128 256]';
numElPerDim = numElPerDim(1:size(data,1));
numLvls = length(numElPerDim)-1;
eoc = zeros(numLvls, 3);
for i=1:3
eoc(:,i) = log(data(2:end,i) ./ data(1:end-1,i)) ./ log(numElPerDim(1:end-1) ./ numElPerDim(2:end));
end
tab = [data(2:end,1), eoc(:,1), data(2:end,2), eoc(:,2), data(2:end,3), eoc(:,3)];
fprintf('\n1/%d & %1.2E & & %1.2E & & %1.2E & \\\\\n', numElPerDim(1), data(1,:));
for i = 2:length(numElPerDim)
if numElPerDim(i) < 100
fprintf('1/%d & %1.2E & %1.2f & %1.2E & %1.2f & %1.2E & %1.2f \\\\\n', numElPerDim(i), tab(i-1,:));
else
fprintf('1/%d & %1.2E & %1.2f & %1.2E & %1.2f & %1.2E & %1.2f \\\\\n', numElPerDim(i), tab(i-1,:));
end
end
fprintf('\n');
end

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