Compare commits

..
Author SHA1 Message Date
Christina Migliore 6ea1f4f9e5 Adds in capability to read in 1D discrete data+cleans code. 2026-08-07 07:35:47 -07:00
Christina Migliore 37959936d6 Fixes major bug with Dirichlet BCs in Stix DH code. 2026-07-02 07:15:04 -07:00
Christina Migliore 98c67ab6ab Fixes minor bug with 2D dissipation output. 2026-04-23 06:33:51 -07:00
Christina Migliore 5b09076d11 Cleans up code and minor bug. 2026-04-02 17:38:18 -07:00
Christina Migliore a0e5b9b7d0 Allows to toggle between PML and vacuum mu 2026-04-02 17:20:43 -07:00
Christina Migliore 63a64f368e Cleans up thermal dielectric components. 2026-03-31 10:43:47 -07:00
Christina Migliore 36eec78dd2 Merge branch 'dh-sheath-bc-dev' of https://github.com/mfem/mfem into dh-sheath-bc-dev 2026-03-31 10:41:20 -07:00
Christina Migliore cf3a47d35e Fixes major bug in thermal dielectric kperp, cleans up code. 2026-03-31 10:38:08 -07:00
christinamigliore a5dd257a0d Add files via upload 2026-03-26 15:28:14 -04:00
Christina Migliore 81ab73f759 Fixes major bug in alfven speed calc. 2026-03-24 07:57:31 -07:00
Christina Migliore c04c89f875 Minor changes relating to debugging PML. 2026-03-24 05:25:25 -07:00
Christina Migliore d7a9accdab Fixes bug in PML, add 1/R dependence to K_par in 3D, cleans up code. 2026-03-19 08:10:55 -07:00
migliore d22404ee2c Fixes major bug with new thermal dielectric 2026-03-13 10:07:22 -04:00
migliore 799301678a Adds in n=0 thermal dielectric terms + cleans up how the dielectric tensor is done. 2026-03-06 13:17:04 -05:00
migliore cd5c566d62 Allows stix 3D to read in outside interpolated data, allows to toggle between coords in 3D. 2026-02-27 15:03:58 -05:00
migliore 6c72aa90f4 Updates global power calculation to account for 2D simulation 2026-02-26 13:12:49 -05:00
migliore a7af8fcb0e Adds flag to command line to toggle between cold plasma and warm plasma. 2026-02-25 08:34:50 -05:00
migliore 7e0b8b6a15 Adds capability of visit files for thermal dielectric 2026-02-20 09:46:26 -05:00
migliore 82b2da7af7 Adds in option to toggle between warm and cold dielectrics 2026-02-20 09:37:50 -05:00
migliore 2905cb50b9 Cleans up codes + starts addition on more thermal effects 2026-02-20 09:32:02 -05:00
migliore 1d8f2468ea Adds visuals for dielectric matrix components for debugging 2026-02-18 10:47:33 -05:00
migliore 732b07f675 Uncomments out absorbing BC. 2026-02-11 07:14:06 -05:00
migliore 8ecee546f8 Updates DH port BC in 3D + updates PML for all Stix codes. 2026-02-10 11:34:46 -05:00
migliore d562333da7 Cleans up codes. 2026-02-09 12:09:02 -05:00
migliore 43e9084bf3 Fixes deprecated compile error. 2026-02-06 14:01:52 -05:00
migliore 233ab7734c Cleans up code. 2026-02-06 13:52:03 -05:00
migliore 100c6749a9 Cleans up main code. 2026-02-06 13:20:48 -05:00
migliore fc9ef84533 Fixes bug when reading in port bc values from textfile. 2026-02-06 06:42:52 -05:00
migliore e67a60b1e6 Fixes minor bug in Port BC + updates DH Stix to have Port BC. 2026-02-04 12:37:57 -05:00
migliore 89cc5548b6 Updates Port BC to have arguments read in from txt file. 2026-02-03 10:11:58 -05:00
migliore 3efb592f2c Adds Cartesian PML to EB Stix formulation. 2026-01-26 14:06:05 -05:00
migliore 225ddcb010 Fixes bug with power absorption by species 2025-07-22 15:41:32 -04:00
migliore b9848db6f5 Updates thermal stix coefs. 2025-07-21 10:19:55 -04:00
migliore a4357eeec9 Adds power absorption by species, (slight bug that will be fixed soon) 2025-07-21 10:16:59 -04:00
migliore 8c44565676 Adds dimensionality to plasma profiles 2025-06-12 14:30:12 -04:00
migliore cbc349ec68 Adds 3D coordinates for L mode profile. 2025-05-06 10:49:03 -04:00
migliore aa4d28f5dc Comments out power calculation for SOL and Core. 2025-05-05 09:35:48 -04:00
migliore 3cdae7b80a Fixes issue of having negative temperatures. 2025-05-01 11:58:51 -04:00
migliore 3136c96164 Cleans up reading in outside density and temperature data 2025-05-01 11:30:07 -04:00
migliore 878bc6155f Generalizes plasma profiles to be 2D and 3D 2025-05-01 11:22:06 -04:00
migliore 5717258b60 Fixes capability of having multiple port BCs. 2025-04-30 10:36:10 -04:00
migliore 692a3acbcf Fixes coax cable's exact solutions. 2025-04-25 13:52:57 -04:00
migliore feb360dfce Updates MPI. 2025-04-25 13:27:29 -04:00
migliore 9b9b81df3b Adds interpolation class. 2025-04-25 12:13:00 -04:00
migliore c25500b833 Updates Stix3D EB and adds port BCs. 2025-04-25 12:05:55 -04:00
migliore 5f034cacad Updates all the versions of Stix 2025-03-07 13:34:58 -05:00
migliore b31f6b94eb Fixes 3D antenna sources. 2025-02-11 13:58:18 -05:00
migliore 6c8f6a9009 Fixes Lmode SOL density. 2025-01-15 12:34:10 -05:00
migliore 8c6a8e1454 Updates EB stix and fixes power dissipation calculation in DH stix. 2025-01-15 11:59:18 -05:00
migliore c7be05fab5 Adds negative sign to sigma. 2024-12-26 10:47:35 -05:00
migliore a96e5bcb74 Fixes density profiles in poloidal SOL. 2024-12-20 16:22:29 -05:00
migliore 5daa0e9148 Fixes power dissipation calculation 2024-12-20 12:36:25 -05:00
migliore 52b849fc12 Adds units to printed power dissipation. 2024-12-16 13:49:00 -05:00
migliore 4f85e8a213 Adds SOL and Core power dissipation calculation. 2024-12-16 13:45:48 -05:00
migliore e16969bcc8 Fixes dug in core density parameterization 2024-12-12 10:57:31 -05:00
migliore 545362d345 Adds new density profile for L mode cases. 2024-12-12 08:35:29 -05:00
migliore e9719f5988 Allows electron temp to be changed from command line, updates EQDSK to include fluxfactor. 2024-12-11 09:19:37 -05:00
migliore 45223f0c24 Adds command line input to poloidal core density profiles. 2024-12-10 10:58:13 -05:00
migliore 88111ecbdb Cleans up 3D antenna source. 2024-11-15 10:27:54 -05:00
migliore 280b59a449 Prints norm of current density. 2024-11-08 09:45:45 -05:00
migliore 3f03210a4f Prints out the norm of the antenna current. 2024-11-07 12:59:14 -05:00
migliore 508c255b84 Fixes kparallel default value if kparallel is 0. 2024-11-07 10:10:33 -05:00
migliore 496b515d16 Deletes dummpy kparallel variable. 2024-11-07 09:49:50 -05:00
migliore c38c987c3c Fixes stix1d and stix2d so that they can build. 2024-11-07 09:39:10 -05:00
migliore 15099a4a21 Fixes stix1d and stiz2d so that they can build. 2024-11-07 09:38:16 -05:00
migliore cf2b55bccf Cleans up code. 2024-11-07 09:08:29 -05:00
migliore 7d73a863ac Updates the 3D volumetric current sources. 2024-10-24 15:04:20 -04:00
migliore 472122bd3e Updates the 3D EB formulation of Stix by adding 3D volumetric sources and proper mesh extrusion. 2024-10-24 15:03:33 -04:00
migliore 1cfe1efe29 Updates the 3D Stix code 2024-04-22 12:34:25 -04:00
christinamigliore a4e4e2451a Adds mesh for example case 2024-02-29 08:10:37 -05:00
migliore ebb5d60c6a Adds mesh for test case. 2024-02-29 08:08:22 -05:00
migliore a5432ab18b Cleans up code. 2024-02-29 08:04:06 -05:00
migliore 83bbc0f257 Adds RF sheath power dissipation and global power dissipation calculations. 2023-12-06 15:16:59 -05:00
migliore 3a562eb225 Adds sheath power dissipation calculation. 2023-11-27 15:30:53 -05:00
migliore 378854101f Adds non-symmetric SOL density and lowers sbcs GMRES error. 2023-10-12 13:47:42 -04:00
migliore 4e01b443a7 Enables non-symmetric collisionality for cutoffs 2023-09-27 14:44:44 -04:00
migliore a6046cd2f4 Resolved merge conflict by incorporating both suggestions. 2023-09-27 14:15:53 -04:00
Stowell, Mark L 53a420ec98 Swapping direction of phi transformation to maintain a right-handed coordinate system 2023-09-14 13:55:20 -07:00
migliore 514daedd0e Minor changes to the artificial collisionality 2023-09-12 18:09:58 -04:00
Stowell, Mark L 9f8a15dcdb Adding screen output to indicate proper program termination 2023-08-30 14:44:51 -07:00
Stowell, Mark L 5b32039d2e Removing temporary debugging code 2023-08-30 14:44:08 -07:00
Stowell, Mark L 1c994892cc Fixing phase vector treatment 2023-08-30 10:13:44 -07:00
Stowell, Mark L a8cbdb1ae8 Trying to improve curve_param_ size checks 2023-08-30 10:13:13 -07:00
Stowell, Mark L 606a0ad22d Setting default vector values in plane wave classes 2023-08-30 09:35:53 -07:00
Stowell, Mark L 3215ee8736 make style 2023-08-29 19:55:33 -07:00
Stowell, Mark L 8eeb7ca5fd Fixing deprecated calls to (double*)Vector 2023-08-29 19:54:38 -07:00
Stowell, Mark L 1b2a63136f Updating MPI class usage 2023-08-29 19:52:01 -07:00
Stowell, Mark L ca45fac72c Updating MUMPS constructor calls 2023-08-29 19:43:58 -07:00
Stowell, Mark L 59b354a22c Merge remote-tracking branch 'origin/master' into dh-sheath-bc-dev
# Conflicts:
#	doc/CodeDocumentation.dox
#	makefile
2023-08-29 19:27:03 -07:00
migliore db00961301 Fixes minor bug in volumetric current sources. 2023-08-24 14:33:33 -04:00
migliore 162dd6ec83 Adds back cold plasma dielectric (temporary). 2023-08-23 12:49:28 -04:00
migliore b6fb2b181b Updates all files. 2023-08-21 11:22:37 -04:00
migliore fa632d6380 Adds thermal effects to cold plasma tensor, adds 2 antenna volumetric sources. 2023-08-14 10:20:37 -04:00
migliore 6f670d490c Adds E+ and E- polarization calculations. 2023-03-03 14:22:34 -05:00
migliore 2273116df2 Adds kinetic effects into the Stix P coefs, adds option for minority temperature profile, adds beginnings of calculating E+ and E- polarizations. 2023-03-03 12:40:58 -05:00
migliore 45cf3b733d Adds effective mass of electrons back into S and D coefs. 2023-02-24 12:10:14 -05:00
migliore 62e2aed452 Adds piece-wise temperature profile capability and SOL/Core indiviual PlasmaProfiles. 2023-02-24 11:47:32 -05:00
Stowell, Mark L d918de52fa Adding support for piecewise PlasmaProfile 2023-02-23 15:25:31 -08:00
migliore f8243d35d1 Adds hot plasma correction to D Stix coef. 2023-02-23 10:35:39 -05:00
migliore 6e9034953a Fixes the Z function. 2023-02-22 13:45:32 -05:00
migliore ff841d2852 Adds a hot plasma implementation to the S Stix coef (currently commented out) and adds a script to calculate the error function analytically. 2023-02-21 10:23:12 -05:00
migliore e58ea5a564 Adds temperature profile for core. 2023-02-17 12:42:06 -05:00
migliore ddcc22e8e5 Updates curve current source and adds SOL param. 2023-01-30 14:30:43 -05:00
Stowell, Mark L 1228e0c43d Fixing command line recording of new vector-valued options 2023-01-27 17:39:53 -05:00
Stowell, Mark L 0fbdd7dbed Adding resonance limiter to the Stix coefs L, S, and D 2023-01-27 17:39:26 -05:00
Stowell, Mark L 0f300a6b64 Adding integer labels to documentation of profile cases for easier lookup 2023-01-23 14:08:53 -05:00
Stowell, Mark L 23d44353db make style 2023-01-23 14:08:14 -05:00
Stowell, Mark L e0b5d2fbaf Adding visualization of ion collisional profile 2023-01-23 14:08:01 -05:00
Stowell, Mark L 145f469995 Fixing k vector in cylindrical coordinates 2023-01-23 14:07:16 -05:00
migliore 34dd6e34e0 Fixes minor spelling bug. 2023-01-23 13:35:56 -05:00
Stowell, Mark L a867ea7fa7 Updating "rod" and "slab" current sources for cylindrical symmetry support 2023-01-20 12:05:54 -05:00
Stowell, Mark L fed9f4c07e Adding visualization of phase shift vector 2023-01-20 10:43:20 -05:00
Stowell, Mark L 136eede0ea Switching to direct solver for E 2023-01-20 10:43:01 -05:00
Stowell, Mark L 8164bcfc58 Adding absolute tolerance option to some linear solvers 2023-01-20 10:42:25 -05:00
Stowell, Mark L df55e54d59 Switching phi component of phase shift to radians/radian rather than radians/meter 2023-01-20 10:41:36 -05:00
Stowell, Mark L b7ddfdfc9c Bug fix in cylindrical version of new current sources 2023-01-20 10:39:15 -05:00
Stowell, Mark L 43ee87e771 Adding profile and source for SPARC 2ant simulation 2023-01-19 16:55:32 -05:00
Stowell, Mark L 4b8eab22ab Lowering default mesh order in stix2d 2023-01-18 17:33:50 -05:00
Stowell, Mark L 8cdbece15d Adjusting VisIt output in stix2d_dh to capture initial Stix coefs 2023-01-18 17:33:28 -05:00
Stowell, Mark L 4e601f2112 Curve current source incorrectly required 2D space 2023-01-18 14:10:35 -05:00
Stowell, Mark L 66eea20441 Bug fix in cylindrical current 2023-01-18 14:09:54 -05:00
Stowell, Mark L fea5fc2400 Changing default mesh order to 1 (sufficient for small angle extrusions) 2023-01-18 14:09:18 -05:00
Stowell, Mark L b4aa85dfa4 Modifying "curve" current source to support cylindrical symmetry 2023-01-17 10:50:03 -05:00
Stowell, Mark L f377c589c2 make style 2023-01-17 10:09:05 -05:00
Stowell, Mark L 3bf6c8d474 Adding phase shift support for cylindrical symmetry 2023-01-17 10:08:01 -05:00
Stowell, Mark L 2324650087 Adding Cylindrical symmetry support to BFieldProfile 2023-01-17 09:44:45 -05:00
Stowell, Mark L c43ebefafb Adding Cylindrical symmetry support to PlasmaProfile 2023-01-17 09:44:01 -05:00
Stowell, Mark L fd4e99a5c0 Adding cylindrical mesh extrusion to Stix 2d codes 2023-01-17 09:40:36 -05:00
migliore 526f456047 Includes resonances for high field case 2023-01-13 14:48:02 -05:00
migliore 41779256cb Updates EQDSK reader, add curved volumetric current source, adds high field core density and magnetic field profiles. 2023-01-13 11:02:05 -05:00
migliore 2c88cd2315 Adds MUMPS 2022-12-13 13:33:17 -05:00
Stowell, Mark L ff0b85731c make style 2022-12-06 15:00:05 -08:00
Stowell, Mark L a1d4161431 make style 2022-12-06 14:58:59 -08:00
Stowell, Mark L dfa3dffc6c Merge branch 'dh-sheath-bc-dev' of github.com:mfem/mfem into dh-sheath-bc-dev 2022-12-06 14:42:03 -08:00
Stowell, Mark L 9328627684 Retaining zeros in Maxwell equation sesquilinear forms 2022-12-06 14:41:08 -08:00
migliore bfb04b39f6 Brings the EB formulation of Stix up to date with the DH formualtion of Stix. In addition, the CMod density is updated. 2022-07-20 16:35:00 -04:00
migliore d73ddcf7e2 Refines the plasma profiles needed for the CMOD case. 2022-05-27 11:49:21 -04:00
migliore 6b893b3125 Refines the plasma profiles needed for the CMOD case. 2022-05-27 11:48:56 -04:00
Stowell, Mark L aa7578ccc4 Adding ion collisionality to all five Stix coefficients 2022-05-20 11:32:19 -07:00
Stowell, Mark L 6dba843400 Adding AMR loop focused on Stix S parameter 2022-05-18 17:52:56 -07:00
Stowell, Mark L 45fbc47666 Adding L2 error estimator for complex valued fields 2022-05-18 17:51:07 -07:00
Stowell, Mark L 935267dabc Adding ParVectorOperator class 2022-05-04 11:48:09 -07:00
migliore 9d2fa1b123 Fixes ion collisional profile. 2022-04-28 15:44:37 -04:00
migliore 7991f0a096 Adds capability of ion collisional profile. 2022-04-28 15:05:04 -04:00
migliore 05f9aa9e11 Adds new profiles for CMod density and collisional profiles. 2022-04-28 08:28:28 -04:00
migliore 31e505a0b6 Adds the BField angle to be written out. 2022-04-07 09:09:06 -04:00
migliore c0e7bfc7dd Reduces the rectified potential to only a real valued field (no longer complex). 2022-04-05 10:01:01 -04:00
Stowell, Mark L df0d830f98 Bringing up to date with stix-r2d-dev 2022-03-29 22:27:30 -07:00
Stowell, Mark L 81ca1b8f69 make style 2022-03-28 20:19:17 -07:00
Stowell, Mark L 8969cc8983 Switching to new EQDSK implementation in stix2d_dh 2022-03-28 20:18:56 -07:00
Stowell, Mark L febfa384ef Updating copyright statement 2022-03-28 20:17:53 -07:00
Stowell, Mark L 7a250f3d71 Moving EQDSK classes to separate source and header files 2022-03-28 20:17:25 -07:00
Stowell, Mark L fc2a129a7c Merge remote-tracking branch 'origin/master' into dh-sheath-bc-dev
# Conflicts:
#	.binder/environment.yml
#	.gitignore
#	.gitlab/configs/corona-config.yml
#	.gitlab/configs/report-build-and-test.yml
#	.gitlab/configs/setup-baseline.yml
#	.gitlab/configs/setup-build-and-test.yml
#	.gitlab/quartz-baseline.yml
#	CONTRIBUTING.md
#	INSTALL
#	examples/CMakeLists.txt
#	examples/ex30.cpp
#	examples/ex30p.cpp
#	examples/makefile
#	fem/bilininteg.cpp
#	fem/bilininteg_dgtrace_pa.cpp
#	fem/bilininteg_hcurl.cpp
#	fem/datacollection.cpp
#	fem/doftrans.cpp
#	fem/fe/fe_base.cpp
#	fem/fe/fe_base.hpp
#	fem/fe/fe_fixed_order.cpp
#	fem/fe/fe_nd.cpp
#	fem/fe/fe_nd.hpp
#	fem/fe/fe_rt.cpp
#	fem/fe/fe_rt.hpp
#	fem/gridfunc.cpp
#	fem/tmop.cpp
#	fem/tmop.hpp
#	fem/tmop_amr.cpp
#	fem/tmop_amr.hpp
#	general/hash.hpp
#	makefile
#	mesh/mesh.hpp
#	mesh/ncmesh.hpp
#	mesh/pmesh.hpp
#	mesh/vtk.hpp
#	miniapps/autodiff/par_example.cpp
#	miniapps/meshing/mesh-optimizer.cpp
#	miniapps/meshing/pmesh-optimizer.cpp
#	miniapps/navier/navier_tgv.cpp
#	miniapps/parelag/MultilevelHcurlHdivSolver.cpp
#	miniapps/parelag/README
#	miniapps/performance/ex1p.cpp
#	miniapps/shifted/diffusion.cpp
#	miniapps/shifted/extrapolate.cpp
#	miniapps/shifted/extrapolator.cpp
#	miniapps/shifted/extrapolator.hpp
#	miniapps/shifted/sbm_aux.hpp
#	miniapps/solvers/block-solvers.cpp
#	miniapps/solvers/plor_solvers.cpp
#	tests/gitlab/reproduce-ci-jobs-interactively.md
#	tests/unit/fem/test_fe.cpp
#	tests/unit/fem/test_pa_kernels.cpp
2022-03-25 17:35:14 -07:00
Stowell, Mark L 6ff3181c5c merge master into dh-sheath-bc-dev 2022-03-25 17:22:12 -07:00
Stowell, Mark L bc405e7830 Adding EQDSK support to BFieldProfile 2022-03-25 17:09:09 -07:00
Stowell, Mark L 7183341c2a make style 2022-03-25 17:08:14 -07:00
migliore 781b6506e1 Adds eqdsk reader into Stix. 2022-03-25 15:23:54 -04:00
Stowell, Mark L b02c616e57 Adding record of command line 2022-03-07 12:29:41 -08:00
Stowell, Mark L ae601a14ca Merge branch 'dh-sheath-bc-dev' of github.com:mfem/mfem into dh-sheath-bc-dev
# Conflicts:
#	miniapps/plasma/cold_plasma_dielectric_coefs.cpp
#	miniapps/plasma/cold_plasma_dielectric_coefs.hpp
2022-03-07 10:25:21 -08:00
migliore ec22215a0b Includes new formulation of collisional profile types. 2022-01-20 10:11:05 -05:00
migliore cc21a03635 Includes new formulation of collisional profile types. 2022-01-20 10:10:45 -05:00
migliore 7d71795148 Includes writing out collisional profile. Collisional profile is adapted to follow density and temperature profiles types. 2022-01-20 10:10:01 -05:00
Stowell, Mark L 678a62b589 Adding PEDESTAL to the plasma profiles 2022-01-11 14:26:14 -08:00
migliore e6f828a13d Updates. 2022-01-11 16:00:25 -05:00
migliore e41928879d Updates sheath impedance calc and the dielectric collisional frequency. 2022-01-11 16:00:10 -05:00
migliore da5e221804 Updates sheath impedance calc and the dielectric collisional frequency. 2022-01-11 15:59:32 -05:00
migliore df1517f0d1 Updates plasma profiles. 2022-01-11 15:59:05 -05:00
migliore cc327d9a9f Adds multi-strap antenna implemention. 2021-10-26 10:14:23 -04:00
Stowell, Mark L 0ecf471f5f Updating Neumann BC implementation 2021-09-01 11:40:07 -07:00
Stowell, Mark L 660446e81e Fixing perpendicular projection 2021-08-30 15:46:12 -07:00
Stowell, Mark L ee4e891b21 Switching e_perp to a vector field 2021-08-30 15:45:49 -07:00
Stowell, Mark L 1ca6143f2c Merge remote-tracking branch 'origin/sheath-bc-dev' into dh-sheath-bc-dev
# Conflicts:
#	miniapps/plasma/cold_plasma_dielectric_coefs.cpp
#	miniapps/plasma/cold_plasma_dielectric_coefs.hpp
#	miniapps/plasma/cold_plasma_dielectric_solver.cpp
#	miniapps/plasma/cold_plasma_dielectric_solver.hpp
#	miniapps/plasma/stix1d.cpp
#	miniapps/plasma/stix2d.cpp
#	miniapps/plasma/stix3d.cpp
2021-08-06 17:16:04 -07:00
Stowell, Mark L 7c91bbeed9 Switching to trivial Array types 2021-08-06 15:12:15 -07:00
Stowell, Mark L adbca86b20 Merge remote-tracking branch 'origin/stix-dev' into sheath-bc-dev
# Conflicts:
#	miniapps/plasma/cold_plasma_dielectric_coefs.cpp
#	miniapps/plasma/cold_plasma_dielectric_coefs.hpp
#	miniapps/plasma/cold_plasma_dielectric_solver.cpp
#	miniapps/plasma/cold_plasma_dielectric_solver.hpp
#	miniapps/plasma/stix1d.cpp
#	miniapps/plasma/stix2d.cpp
2021-08-06 14:46:26 -07:00
Stowell, Mark L 5aec9b1422 Switching to trivial Array types 2021-08-06 14:26:40 -07:00
Stowell, Mark L 89370f8d23 Merge remote-tracking branch 'origin/master' into stix-dev
# Conflicts:
#	.gitignore
#	makefile
2021-08-06 14:14:14 -07:00
Stowell, Mark L 14b7733853 Adding BFieldProfile, minority species, etc. 2021-08-06 14:11:55 -07:00
Stowell, Mark L fefe75deed style fixes 2021-05-24 15:21:47 -07:00
Stowell, Mark L bfe34bc00c Fixing old vs. new parameterization issues 2021-05-24 15:21:35 -07:00
Stowell, Mark L b7cbb00346 Removing default value for realPart argument 2021-05-24 15:20:20 -07:00
Stowell, Mark L 5dee441363 Adding parameter for collision profile 2021-05-24 15:19:23 -07:00
Stowell, Mark L 6268d57a45 Removing unused variable 2021-05-24 15:15:50 -07:00
psocratis bf961046ca linalg/mumps.cpp 2021-05-19 10:06:55 -07:00
Stowell, Mark L a300a7eaae Updating EB formulation of sheath BC 2021-04-14 16:44:23 -07:00
Stowell, Mark L ff5d435373 make style 2021-04-13 20:46:55 -07:00
Stowell, Mark L d7178d30dd Fixing D and P implementations 2021-04-13 20:46:41 -07:00
Stowell, Mark L 5143130079 Fixing error with clang compilers 2021-04-13 09:45:34 -07:00
migliore aae304888c Adds negative sign to the exponential. 2021-04-13 12:32:24 -04:00
migliore c368ff5554 Adds Kohno's collisional damping profile from 2017 paper. 2021-04-13 10:44:37 -04:00
migliore 76d832b122 Adds argument "-slab-prof" to command line that specifies whether antenna profile is constant (0) or sin func (1). 2021-04-13 10:33:41 -04:00
migliore c433de42cd Fixes compiling error. 2021-04-13 10:18:27 -04:00
migliore df17928b1d Adds Jim's old sheath impedance parameterization from Kohno et al 2017. 2021-04-13 10:12:31 -04:00
migliore 82baa09b0f Adds Jim Myra's old sheath impedance parameterization from Kohno et al 2017. 2021-04-13 10:10:30 -04:00
migliore e94383da0c Fixes effective mass to be only electron dependent rather than electron and ion dependent. 2021-04-13 10:05:45 -04:00
migliore 072711705c Adds line to stop potential iteration if the difference is < 1e-3. 2021-04-13 09:58:09 -04:00
Stowell, Mark L 2cc37f3f1a Bringing EB and DH formulations into agreement 2021-04-12 20:58:33 -07:00
Stowell, Mark L 1cfdf95765 Updating older stix miniapps so that they compile 2021-04-07 18:38:30 -07:00
Stowell, Mark L 5cee9b241c Moving informational messages and fixing a small indexing bug 2021-04-07 09:19:33 -07:00
Stowell, Mark L 0a59a414af Force a particular "=" operator 2021-04-06 19:26:27 -07:00
Stowell, Mark L 123bb77551 Bringing stix2d up to date with stix2d_dh 2021-04-06 19:05:11 -07:00
Stowell, Mark L 2ac45124b6 Cleaning up admittance/impedance code 2021-04-06 19:03:36 -07:00
Stowell, Mark L 0b37ce6e5f Accidentally swapped banners 2021-04-06 13:52:55 -07:00
Stowell, Mark L 613e447ccf Adding DH miniapps to make systems 2021-04-06 13:24:03 -07:00
Stowell, Mark L 1945666d32 Cleaning up stix1d_dh 2021-04-06 13:13:15 -07:00
Stowell, Mark L d8cc605593 Cleaning up banners 2021-04-06 13:12:44 -07:00
Stowell, Mark L 3489d624f5 make style 2021-03-25 20:04:55 -07:00
Stowell, Mark L 3f75bec941 Propagating the complex operator convention to the sheath BC opderators 2021-03-25 20:04:34 -07:00
Stowell, Mark L d06f450843 Adding test meshes 2021-03-24 13:12:14 -07:00
Stowell, Mark L 29e9a443ae Fixing sign error in sheath BC 2021-03-11 15:26:31 -08:00
Stowell, Mark L d4a03965c8 Expanding stix2d_dh comments 2021-03-11 15:26:10 -08:00
Stowell, Mark L 7cc83e9193 Adding kz phase shift to sheath BC 2021-03-11 09:33:50 -08:00
Stowell, Mark L ce1c4699e6 Adding comments and fixing phase of animation 2021-03-10 16:39:30 -08:00
Stowell, Mark L 7c4e1f4fbc Fixing sheath BC phase and amplitude 2021-02-17 22:46:47 -08:00
Stowell, Mark L aa99a05f10 Adjusting tolerances and increasing iteration count 2021-02-17 22:45:48 -08:00
Stowell, Mark L c0559bf3b6 Fixing AMR support 2021-01-22 14:24:29 -08:00
Stowell, Mark L a2a6c22711 Applying phase shift vector to current density 2021-01-22 10:08:47 -08:00
Stowell, Mark L 448bf35e9d Reverting to current density from Kohno paper 2021-01-22 10:07:49 -08:00
Stowell, Mark L cef989ad49 Adding support for complex current sources 2021-01-21 15:01:58 -08:00
Stowell, Mark L 2f56bd77a6 Fixing phase shift in non-plane-wave case 2020-12-21 09:16:01 -08:00
Stowell, Mark L be96aa0d7f Adding comment regarding automatically set plane wave phase shift 2020-12-20 12:11:36 -08:00
Stowell, Mark L 93e10fd209 Changing color palette for electric field visualization 2020-12-20 12:08:00 -08:00
Stowell, Mark L b59b9e738d Fixing plane wave solutions 2020-12-20 12:06:33 -08:00
Stowell, Mark L 581143b702 Fixing phase shift coefficients in PDE 2020-12-20 12:05:48 -08:00
Stowell, Mark L 68b894cb25 Fixing non-portable DBL_MAX 2020-12-18 14:50:19 -08:00
Stowell, Mark L 78a9fe3702 make style 2020-12-18 14:36:53 -08:00
Stowell, Mark L 6caff297a5 Adding support for complex valued phase shifts 2020-12-18 14:36:25 -08:00
Stowell, Mark L d71717e430 Adding a complex phase coefficient 2020-12-18 14:35:48 -08:00
Stowell, Mark L b8f252cf26 Updating plane wave solutions in Stix2d_DH 2020-12-17 17:20:44 -08:00
Stowell, Mark L 47ae518b6f Removing dead code 2020-12-17 17:20:18 -08:00
Stowell, Mark L a99512ce31 New banner for Stix2D_DH 2020-12-15 14:14:59 -08:00
Stowell, Mark L fb176b85f9 Activating Neumann BCs in stix2d_dh 2020-12-15 10:13:26 -08:00
Stowell, Mark L 6958f0f570 Added loop for non-linear sheath bc in the DH formulation of Stix solver 2020-12-01 00:16:46 -08:00
Stowell, Mark L 70d2cab198 Adding Schur compliment solve to CPDSolverDH for sheath BC 2020-11-30 20:33:21 -08:00
Stowell, Mark L d99b7b7a12 Adding class hierarchy to BC container classes 2020-11-30 20:32:35 -08:00
Stowell, Mark L de507a2928 Adding Schur compliment solver 2020-11-30 20:30:43 -08:00
Stowell, Mark L a7bf98e81e Adding ParMixedSesquilinearForm::FormRectangularSystemMatrix 2020-11-30 20:30:16 -08:00
Stowell, Mark L eeac6da33c Small memory leak 2020-11-25 11:57:45 -08:00
Stowell, Mark L 20354d42ac Cleaning up memcheck issues 2020-11-25 11:40:29 -08:00
Stowell, Mark L 6f9ec4e3cd Adding support for kz phase shift in stix2d_dh.cpp 2020-11-23 17:16:56 -08:00
Stowell, Mark L 19f381f423 Adding 1D DH formulation stix solver 2020-11-23 14:07:12 -08:00
Stowell, Mark L 500c02014e Adding exact solutions for testing 2020-11-20 17:14:57 -08:00
Stowell, Mark L d0effbdcd2 Activating ABCs and computation of E from D 2020-11-18 19:38:08 -08:00
Stowell, Mark L 921bf6e084 Adding separate E and H error computations 2020-11-18 19:35:35 -08:00
Stowell, Mark L 02333230c8 Changing sign convention in output fields 2020-11-18 19:34:15 -08:00
Stowell, Mark L 572db64855 Fixing stix1d sample runs to match new standard 2020-11-18 18:22:34 -08:00
Stowell, Mark L db46770f95 Bringing new DielectricTensor into agreement with standard set in Stix text 2020-11-18 18:21:46 -08:00
Stowell, Mark L eb08eddc7c Adding Mult method to ParMixedSesquilinearForm 2020-11-16 19:56:49 -08:00
Stowell, Mark L 6518eb6bb8 Adding rectangular parallel sesquilinear forms 2020-11-16 19:43:35 -08:00
Stowell, Mark L f00740bce5 Fixing E field solve and GLViz output 2020-11-16 19:02:54 -08:00
Stowell, Mark L f9ecd96839 Non-functional DH formulation of stix2d which compiles 2020-11-15 11:51:05 -08:00
Stowell, Mark L 94835c4820 Adding InverseDielectricTensor class 2020-11-15 10:09:43 -08:00
Stowell, Mark L 96a2ceb3e6 Removing fudge factor from sheath impedance coef 2020-11-13 16:45:05 -08:00
Stowell, Mark L 03f045701d Removing fudge factor from sheath impedance coef 2020-11-13 16:44:07 -08:00
Stowell, Mark L aef7c54004 Adding b-aligned dielectric tensor 2020-11-13 16:42:49 -08:00
Stowell, Mark L a08fa8bcde Changing Dielectric tensor to use normalized B vector 2020-11-13 16:23:43 -08:00
Stowell, Mark L 188cd5dc35 Starting a DH formulation of stix2d 2020-11-13 15:13:54 -08:00
Stowell, Mark L 7d1c7158b8 Updating density and temperature in stix1d 2020-11-12 11:17:20 -08:00
Stowell, Mark L 60a8baf5cd Setting vector size in MatrixVectorProductCoefficient 2020-11-12 10:47:35 -08:00
Stowell, Mark L e3b19a704a Updating coefs from sheth-bc-dev 2020-11-12 10:46:58 -08:00
Stowell, Mark L ca9ee8e207 Generalizing MassIntegrator to support INTEGRAL basis functions 2020-11-12 10:40:54 -08:00
Stowell, Mark L 3fc6078960 Merge remote-tracking branch 'origin/master' into stix-dev 2020-11-12 10:29:28 -08:00
Stowell, Mark L 8da8085663 Adding B^T Eps B / |B|^2 to VisIt output 2020-11-05 19:34:29 -08:00
Stowell, Mark L 905f6fa431 Bugfix in MatrixVectorProductCoefficient 2020-11-05 19:33:45 -08:00
Stowell, Mark L f81cdde992 Adding Stix coefficients to VisIt output 2020-11-05 17:34:44 -08:00
Stowell, Mark L 9026627b90 make style 2020-11-05 15:54:19 -08:00
Stowell, Mark L 0911b3c849 Adding coefficient classes to compute Stix coefficients S, D, and P 2020-11-05 15:54:01 -08:00
Stowell, Mark L b30e2fa27b Adding sinusoidal current source similar to Kohno paper 2020-11-05 11:47:16 -08:00
Stowell, Mark L c67ff82b8b Adding \hat{B} to VisIt output 2020-11-05 11:46:27 -08:00
christinamigliore da1c41ddf4 Put back unit comments on the cylotron and plasma frequency
calculations.
2020-11-05 16:46:07 +00:00
christinamigliore 51ba95f842 Fixes volt_norm input to be magnitude of zero-to-peak complex potential. 2020-11-05 16:39:10 +00:00
christinamigliore 5e805fb90e Deletes extra conversion of temperature. 2020-11-05 15:26:27 +00:00
christinamigliore 36d72442c9 Updates expression for z (SI). 2020-11-05 14:29:52 +00:00
Stowell, Mark L 8696431789 Experimental rescaling of sheath impedance 2020-11-04 16:49:24 -08:00
Stowell, Mark L ef47085638 Reimplementing the inner iteration to compute the sheath potential 2020-11-04 16:48:50 -08:00
Stowell, Mark L e2e20ec9d3 Simplifying sheath impedance implementations slightly (and fixed a small bug in yi) 2020-11-04 14:20:52 -08:00
Stowell, Mark L 16dfcff444 Adding comments containing units for various things in the Sheath impedance calculation 2020-11-03 16:34:54 -08:00
Stowell, Mark L 68a4eaf36f make style 2020-11-03 14:53:39 -08:00
Stowell, Mark L c05d1d76a7 Fixing z-dependence in sheath potential solve 2020-11-03 14:16:38 -08:00
christinamigliore 435ac7ce0c Changes to implementing non-linear BC. 2020-11-02 21:51:22 +00:00
Stowell, Mark L 9d7c4891c4 Initializing solution vectors before iterative solves to avoid NaNs 2020-10-15 15:50:44 -07:00
Stowell, Mark L 1287f0a287 Different argument signature 2020-10-15 14:29:05 -07:00
Stowell, Mark L b791744109 Switching MassIntegrator to use CalcPhysShape 2020-10-15 14:27:29 -07:00
christinamigliore b40eb9298e Making sure everything is up to date. 2020-10-14 21:34:11 +00:00
christinamigliore ea69fc3f87 Making sure everything is up to date. 2020-10-14 21:33:52 +00:00
christinamigliore 02c060f94d Fixes bug regarding the assembly of the imepdance matrix. 2020-10-14 20:34:05 +00:00
christinamigliore 6a8d31365d Merge branch 'sheath-bc-dev' of https://github.com/mfem/mfem into sheath-bc-dev 2020-10-14 18:26:37 +00:00
christinamigliore f51f565399 Adds bhat calculation. 2020-10-14 18:05:07 +00:00
christinamigliore c07c9b6874 Adds commented out fixed sheath width. 2020-10-14 18:00:52 +00:00
christinamigliore 3aa47dcbb7 Small changes to what is printed and saved. 2020-10-14 17:59:29 +00:00
Stowell, Mark L d5210c1ee6 Adding command line options to access the Neumann BCs in stix2d 2020-10-09 09:44:10 -07:00
Stowell, Mark L 7f31086842 make style 2020-10-05 20:12:42 -07:00
Stowell, Mark L 0419347790 Adding graded meshing near boundary in simple_antenna.cpp 2020-10-05 20:12:33 -07:00
christinamigliore 284115026d Commenting out rectPot_ definition. 2020-10-02 19:42:44 +00:00
christinamigliore b24c51e610 Fixing a few minor issues. 2020-10-01 20:34:58 +00:00
Stowell, Mark L b939a14bd1 Fixing grid function copies 2020-09-25 09:45:35 -07:00
Stowell, Mark L 3ef21c6019 make style 2020-09-25 09:45:14 -07:00
christinamigliore adc823f916 Fixing inner potential loop within solver. 2020-09-25 16:14:40 +00:00
christinamigliore 7e8e36a065 Fxing inner potential loop within solver. 2020-09-25 16:14:05 +00:00
christinamigliore 8c17c7c0b3 Deleting cold code and fixing sbcs to represent sheath impedance. 2020-09-25 13:49:24 +00:00
christinamigliore a917a079aa Deleting old code and fixing sbcs to represent sheath impedance. 2020-09-25 13:48:41 +00:00
Stowell, Mark L 4421d197a7 Adding partial copy constructors 2020-09-22 15:45:57 -07:00
Mark L. Stowell b1b65b4f86 Merge pull request #1770 from mfem/stix1d-analytic-dev
Updating analytic solutions to support collisional losses [stix1d-analytic-dev]
2020-09-22 12:57:39 -07:00
Stowell, Mark L 2e72abff11 Removing unused member data to avoid compiler warning 2020-09-22 11:30:23 -07:00
Stowell, Mark L fc1a071390 Avoiding compiler warning 2020-09-22 10:49:52 -07:00
Stowell, Mark L b8d5af15e6 Checking magnetic field alignment in stix1d 2020-09-22 10:07:21 -07:00
Mark L. Stowell 14fcb640cc Merge pull request #1777 from mfem/rect-pot-coef-dev
Rectified sheath potential coefficient [rect-pot-coef-dev]
2020-09-22 09:55:30 -07:00
Stowell, Mark L 573bfdbaba Fixing compiler warning 2020-09-21 20:09:28 -07:00
Stowell, Mark L d3f2b2eefa Resolving build errors 2020-09-21 16:44:26 -07:00
Stowell, Mark L 59985d9225 Creating RectifiedSheathPotential coefficient from SheathImpedance coefficient 2020-09-21 15:26:27 -07:00
Stowell, Mark L 4de2a23879 Potential no longer being passed to SheathImpedance objects via constructor 2020-09-21 15:25:33 -07:00
Stowell, Mark L 6c7fde1b1a make style 2020-09-21 15:24:50 -07:00
christinamigliore 75f11014e2 Commenting out the E_parallel dot B visualization. 2020-09-21 21:02:20 +00:00
christinamigliore 22cd65c032 Implemenatation of the non-linearity of the sheath BC. 2020-09-21 20:58:44 +00:00
christinamigliore acad697d65 Implementaton of the non-linearity of sheath BC. 2020-09-21 20:57:48 +00:00
christinamigliore 85d81aa958 Changes to how the potential is passed into the SheathImpedance class. 2020-09-21 20:57:20 +00:00
christinamigliore 07a065b685 Changes to how the potential is passed into SheathImpedance class. 2020-09-21 20:56:50 +00:00
Stowell, Mark L 273095461e Reporting expected wavelengths and skin depths resulting from complex-valued S, D, and P. 2020-09-18 12:11:53 -07:00
Stowell, Mark L 95d5bb3934 Implementing support for different PlasmaProfiles for each ion species. 2020-09-18 12:11:01 -07:00
Stowell, Mark L d5adba7621 Implementing stix1d exact solutions for complex-valued S, D, and P. 2020-09-18 12:08:57 -07:00
Stowell, Mark L 084a2a7b65 Removing dead code from stix1d 2020-09-18 12:08:05 -07:00
Stowell, Mark L 58ba96553f Tuning sample runs in stix1d 2020-09-18 12:05:32 -07:00
Stowell, Mark L 48e844e16d Switching DielectricTensor implementation to use standard spherical coordinate representation of magnetic field vector (internally) 2020-09-18 12:05:05 -07:00
Stowell, Mark L 5ccb10f0f2 Adding default constructor to PlasmaProfile class 2020-09-18 12:02:44 -07:00
Stowell, Mark L d73a102f7c Changing space for current density to improve visualization 2020-09-18 12:01:45 -07:00
christinamigliore 97762a7451 Fixes error with pulling out values of the potential. 2020-09-14 22:05:32 +00:00
christinamigliore c740cf379d Changes potential from being a BlockVector to instead being a GridFunction. 2020-09-14 01:26:20 +00:00
christinamigliore bff492dcbc Changes potential from being a BlockVector to instead being a gridfunction. 2020-09-14 01:22:50 +00:00
christinamigliore d36c757b58 Adding option to export global L2 error needed for convergence testing. 2020-08-25 14:04:50 +00:00
christinamigliore 69815d66af Adding analytic solutions of both the real and imaginary electric field to the saved VisIt file. 2020-08-14 19:15:29 +00:00
Stefan Henneking e41c197dd0 Merge pull request #1690 from mfem/sheath-bc-dev-gpu
GPU support for sheath-bc in stix miniapp
2020-08-12 16:00:12 -05:00
christinamigliore fa6119b906 Fixes error with namespace of MakePeriodicMesh. 2020-08-12 19:21:49 +00:00
stefanhenneking b6b55361fb Adding TODO statements for PA support. 2020-08-06 15:44:26 -05:00
stefanhenneking 4e58a53e99 Using MFEM_CONTRACT_VAR to avoid unused private fields. 2020-08-06 13:50:30 -05:00
stefanhenneking 1667c89a4f Use MFEM_VERIFY to avoid unused private field without debug mode. 2020-08-06 13:39:10 -05:00
stefanhenneking 2cfc57a6a8 Avoid line continuation in comment. 2020-08-06 13:36:53 -05:00
stefanhenneking 2baf7cf15c Minor fix to remove unused private field warnings. 2020-08-06 11:35:56 -05:00
stefanhenneking 4388133c48 Reorder fields correctly in initialization. 2020-08-06 11:13:31 -05:00
stefanhenneking 704f730f9b Merging stix-dev into feature branch (including support for GPU computation). 2020-08-05 15:44:13 -05:00
stefanhenneking e6fb165c96 Merge branch 'master' of github.com:mfem/mfem into stix-dev 2020-08-05 15:21:41 -05:00
Stefan Henneking e203aba91b Merge pull request #1598 from mfem/stix-dev-gpu
GPU support for stix miniapp
2020-08-05 15:14:35 -05:00
stefanhenneking 8e8d50502f Improve error handling for untested/unimplemented PA cases. 2020-08-03 14:55:42 -05:00
stefanhenneking bfeb8aa1ec Simplifying SyncAlias statements. 2020-08-03 14:44:03 -05:00
stefanhenneking 0fdbada96e Merge branch 'complex-operator-gpu' of github.com:mfem/mfem into stix-dev-gpu 2020-08-03 14:39:29 -05:00
stefanhenneking 2e0d196752 Set assembly level directly for sesquilinear form. 2020-07-31 15:06:40 -05:00
stefanhenneking 46dc158355 Merge branch 'stix-dev' of github.com:mfem/mfem into stix-dev-gpu 2020-07-31 13:45:10 -05:00
stefanhenneking e737b7a416 Merged master into feature branch 2020-07-31 13:44:09 -05:00
stefanhenneking 09e169cbe8 Merge branch 'master' of github.com:mfem/mfem into stix-dev-gpu 2020-07-31 13:41:12 -05:00
Stefan Henneking 93989b5ab5 Merge branch 'mem-dangling-aliases-fix' of github.com:mfem/mfem into stix-dev-gpu 2020-07-27 08:12:01 -07:00
stefanhenneking 9bda1db360 Merging complex-operator-gpu into feature branch. 2020-07-23 12:23:02 -05:00
stefanhenneking b11a0df5f9 Merge branch 'bugfix/dof-marker-gpu' of github.com:mfem/mfem into stix-dev-gpu 2020-07-21 16:58:59 -05:00
stefanhenneking 64c8c7dcf3 Merge branch 'complex-operator-gpu' of github.com:mfem/mfem into stix-dev-gpu 2020-07-21 16:58:41 -05:00
stefanhenneking bfcfb2e4ee Merging stix-dev into feature branch. 2020-07-20 14:04:44 -05:00
Stowell, Mark L 0c5049e38a Separating high order L2 FESpace 2020-07-20 11:56:32 -07:00
Stowell, Mark L a81ac4d1c9 Fixing offsets in Update functions 2020-07-20 11:54:28 -07:00
Stowell, Mark L d992275b61 make style 2020-07-20 11:54:13 -07:00
Stowell, Mark L 04b6f9f9bb Fixing offsets in Update functions 2020-07-20 11:43:42 -07:00
Mark L. Stowell 71fded08f8 Separate high order L2 FESpace 2020-07-20 11:37:23 -07:00
Stowell, Mark L 926715c87e Updating new potential variables alongside density and temperature 2020-07-17 14:19:32 -07:00
Stowell, Mark L 79a93a6fb8 make style 2020-07-17 14:18:49 -07:00
Stowell, Mark L dcbd06c994 Adding sheath BC updates to stix1d and stix3d 2020-07-16 10:53:51 -07:00
stefanhenneking e1f2fc6c52 cleanup 2020-07-15 15:55:07 -05:00
Stefan Henneking a17451e66c Merge branch 'complex-operator-gpu' of github.com:mfem/mfem into stix-dev-gpu 2020-07-15 13:19:06 -07:00
stefanhenneking ff3f4a1c03 Merging matrix coefficient support for H(curl) PA from feature branch. 2020-07-15 15:09:36 -05:00
stefanhenneking 1cc053d006 Merge branch 'abs-mult-dev' of github.com:mfem/mfem into stix-dev-gpu 2020-07-15 14:57:42 -05:00
stefanhenneking 5391448485 Merge branch 'abs-mult-dev' of github.com:mfem/mfem into stix-dev-gpu 2020-07-15 13:55:33 -05:00
stefanhenneking ada59068da Merge branch 'abs-mult-dev' of github.com:mfem/mfem into stix-dev-gpu 2020-07-15 10:41:54 -05:00
Stowell, Mark L dd3ce3241c Reinterpret essential vdofs as a marker array (oops!) 2020-07-14 19:36:14 -07:00
stefanhenneking 1d74c1d154 Merge branch 'abs-mult-dev' of github.com:mfem/mfem into stix-dev-gpu 2020-07-14 19:30:59 -05:00
stefanhenneking db423a5206 Merge branch 'complex-operator-gpu' of github.com:mfem/mfem into stix-dev-gpu 2020-07-14 19:23:44 -05:00
stefanhenneking e4be88b510 Merge branch 'blockop_cuda' of github.com:mfem/mfem into stix-dev-gpu 2020-07-14 18:35:43 -05:00
stefanhenneking 7c28433560 Merge branch 'complex-operator-gpu' of github.com:mfem/mfem into stix-dev-gpu 2020-07-14 18:35:29 -05:00
Stowell, Mark L 203f0b79dd Switching to RecoverFEMSolution 2020-07-14 15:44:34 -07:00
Stowell, Mark L da82f1fbd6 Adding sheath potential with sheath impedance 2020-07-14 15:17:29 -07:00
Stowell, Mark L c656c15102 Adding sheath impedance coefficients on behalf of Christina Migliore 2020-07-14 15:16:47 -07:00
Stowell, Mark L 7da6cf3045 make style 2020-07-14 15:16:09 -07:00
stefanhenneking e92825a477 Merge branch 'master' of github.com:mfem/mfem into stix-dev-gpu 2020-07-10 11:38:29 -05:00
stefanhenneking b9d707fb85 Merging complex-operator-gpu features into stix-dev-gpu branch. 2020-07-08 14:59:43 -05:00
stefanhenneking ea62996f7a Minor style changes. 2020-07-08 09:39:22 -05:00
Stefan Henneking 1f7106eceb Enable PA for electric flux computation. 2020-07-06 14:23:27 -07:00
Stefan Henneking 5787f34b11 Makefile change needed for nvcc to work. 2020-07-06 10:26:42 -07:00
Stefan Henneking 7b2b28b87a Merge branch 'blockop_cuda' of github.com:mfem/mfem into stix-dev-gpu
Merging blockoperator gpu support from feature branch.
2020-07-02 14:29:24 -07:00
stefanhenneking e29e18871e Minor style changes. 2020-07-02 09:40:21 -05:00
stefanhenneking 7b0f400a94 Adding PA and device option to stix2d. 2020-07-01 17:34:24 -05:00
stefanhenneking 52a8339fed Changing sample run default to standard solver. 2020-07-01 17:29:15 -05:00
stefanhenneking ccf7870426 Merge branch 'matcoefpa' of github.com:mfem/mfem into stix-dev-gpu
Merging matrix coefficient PA support from feature branch.
2020-07-01 14:14:52 -05:00
stefanhenneking 962ddfa256 Adding PA option to plasma solver. 2020-06-30 14:34:58 -05:00
stefanhenneking ecd2c36006 Adding PA and device option to stix1D miniapp. 2020-06-29 18:08:07 -05:00
stefanhenneking f4c758c39d Merge branch 'matcoefpa' of github.com:mfem/mfem into stix-dev-gpu 2020-06-29 17:14:20 -05:00
stefanhenneking a899c1b101 Merge branch 'complex-operator-gpu' of github.com:mfem/mfem into stix-dev-gpu
Merging GPU feature branch.
2020-06-29 16:02:27 -05:00
stefanhenneking e0ad629839 Merge branch 'complex-operator-gpu' of github.com:mfem/mfem into stix-dev-gpu
Merging feature branch to get device support for complex operator.
2020-06-29 15:44:23 -05:00
Stowell, Mark L 58d444f68e Re-adding PhaseCoefficient 2020-06-29 13:41:20 -07:00
Stowell, Mark L 0dd4d531a3 Fixing issue with virtual GetVectorValue functions 2020-06-29 13:41:03 -07:00
Stowell, Mark L e06eb31481 Merge remote-tracking branch 'origin/master' into stix-dev
# Conflicts:
#	fem/coefficient.cpp
#	fem/coefficient.hpp
2020-06-29 13:40:24 -07:00
Stowell, Mark L c210d4d1bd Merge remote-tracking branch 'origin/master' into stix-dev 2020-06-15 09:56:43 -07:00
Mark L. Stowell 2880a5cc0f Merge pull request #1543 from mfem/bugfix/stix-dev
Fixing uninitialized vector offset [bugfix/stix-dev]
2020-06-15 09:48:11 -07:00
Stowell, Mark L a2bd065b95 Including std headers to avoid compiler warnings/errors 2020-06-13 21:05:50 -07:00
Stowell, Mark L 470cdace7e Putting in dummy tests for stix miniapps 2020-06-13 20:27:56 -07:00
Stowell, Mark L eb7590a450 Typo in .gitignore 2020-06-13 20:17:40 -07:00
Stowell, Mark L df6d03c386 Adding stix miniapps to .gitignore and cmake files 2020-06-13 20:03:12 -07:00
Stowell, Mark L 649a03a485 make style 2020-06-13 20:00:06 -07:00
Stowell, Mark L 52052ac74c Temporary hack to make Dirichlet BCs work 2020-06-13 19:01:59 -07:00
Stowell, Mark L ae7a551961 Fixing uninitialized vector offset 2020-06-13 12:04:58 -07:00
Stowell, Mark L 2c44d01aa1 Clarifying an error message 2020-06-13 12:04:23 -07:00
Stowell, Mark L 0e53af26d0 Adding debugging comments 2020-06-13 11:36:20 -07:00
Stowell, Mark L 5d86ba5fe8 Adding D=epsilon E computation to stix miniapps 2020-06-13 10:12:32 -07:00
Stowell, Mark L c86c973ed8 Temporary BC work-around 2020-06-10 19:05:03 -07:00
Stowell, Mark L 1cd5e75598 Removing debugging comment 2020-06-10 19:04:33 -07:00
Stowell, Mark L 2789a40187 make style 2020-06-10 14:40:42 -07:00
Stowell, Mark L 36c846b00c Changing namespace miniapps to common 2020-06-10 14:40:02 -07:00
Stowell, Mark L 91f7a623f3 Merge remote-tracking branch 'origin/master' into stix-dev
# Conflicts:
#	fem/coefficient.hpp
#	makefile
#	miniapps/common/mesh_extras.cpp
#	miniapps/common/mesh_extras.hpp
2020-06-10 14:35:18 -07:00
Stowell, Mark L b0a250a18d Improving the documentation block in stix2d 2020-01-08 11:11:58 -08:00
Stowell, Mark L 3f3d35895a Moving stix miniapps into a separate branch 2020-01-08 10:47:26 -08:00
266 changed files with 280468 additions and 13147 deletions
@@ -1,6 +1,7 @@
name: "Docker"
on:
# Always have a base image ready to go - this is a nightly build
schedule:
- cron: 0 3 * * *
@@ -25,6 +26,7 @@ jobs:
strategy:
fail-fast: false
matrix:
# Dockerfiles to build, a matrix supports future expanded builds
container: [["config/docker/Dockerfile.base", "ghcr.io/mfem/mfem-ubuntu-base"],
["config/docker/Dockerfile", "ghcr.io/mfem/mfem-ubuntu"]]
@@ -32,20 +34,15 @@ jobs:
runs-on: ubuntu-latest
name: Build
steps:
- name: Run Actions Cleaner
uses: easimon/maximize-build-space@v8
with:
overprovision-lvm: 'true'
remove-dotnet: 'true'
remove-android: 'true'
remove-haskell: 'true'
remove-codeql: 'true'
remove-docker-images: 'true'
- name: Checkout
uses: actions/checkout@v3
# It's easier to reference named variables than indexes of the matrix
- name: Make Space For Build
run: |
sudo rm -rf /usr/share/dotnet
sudo rm -rf /opt/ghc
# It's easier to reference named variables than indexes of the matrix
- name: Set Environment
env:
dockerfile: ${{ matrix.container[0] }}
+157 -165
View File
@@ -65,7 +65,7 @@ jobs:
# - Add a new combination.
# 'build-system: cmake' and 'hypre-target: int64'
#
# Note: we will gather coverage info for any non-debug run except the
# note: we will gather coverage info for any non-debug run except the
# CMake build.
include:
- target: dbg
@@ -101,189 +101,181 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
# This external action allows to interrupt a workflow already running on
# the same branch to save resources.
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.11.0
with:
access_token: ${{ github.token }}
# This external action allows to interrupt a workflow already running on
# the same branch to save resource
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.11.0
with:
access_token: ${{ github.token }}
# Fix 'No space left on device' errors for Ubuntu builds.
- name: Run Actions Cleaner
if: matrix.os == 'ubuntu-latest'
uses: easimon/maximize-build-space@v8
with:
overprovision-lvm: 'true'
remove-android: 'true'
# Checkout MFEM in "mfem" subdirectory. Final path:
# /home/runner/work/mfem/mfem/mfem
# Note: Done now to access "install-hypre" and "install-metis" actions.
- name: checkout mfem
uses: actions/checkout@v3
with:
path: ${{ env.MFEM_TOP_DIR }}
# Fetch the complete history for codecov to access commits ID
fetch-depth: 0
# Checkout MFEM in "mfem" subdirectory. Final path:
# /home/runner/work/mfem/mfem/mfem
# Note: Done now to access "install-hypre" and "install-metis" actions.
- name: checkout mfem
uses: actions/checkout@v3
with:
path: ${{ env.MFEM_TOP_DIR }}
# Fetch the complete history for codecov to access commits ID
fetch-depth: 0
# Only get MPI if defined for the job.
# TODO: It would be nice to have only one step, e.g. with a dedicated
# action, but I (@adrienbernede) don't see how at the moment.
- name: get MPI (Linux)
if: matrix.mpi == 'par' && matrix.os == 'ubuntu-latest'
run: |
sudo apt-get install mpich libmpich-dev
# Only get MPI if defined for the job.
# TODO: It would be nice to have only one step, e.g. with a dedicated
# action, but I (@adrienbernede) don't see how at the moment.
- name: get MPI (Linux)
if: matrix.mpi == 'par' && matrix.os == 'ubuntu-latest'
run: |
sudo apt-get install mpich libmpich-dev
- name: get lcov (Linux)
if: matrix.codecov == 'YES' && matrix.os == 'ubuntu-latest'
run: |
sudo apt-get install lcov
- name: get lcov (Linux)
if: matrix.codecov == 'YES' && matrix.os == 'ubuntu-latest'
run: |
sudo apt-get install lcov
# Keep the following section in case we need it again in the future,
# see: https://github.com/mfem/mfem/pull/3385#discussion_r1058013032
# - name: Set up Homebrew
# if: ( matrix.mpi == 'par' || matrix.codecov == 'YES' ) && matrix.os == 'macos-latest'
# uses: Homebrew/actions/setup-homebrew@master
# Keep the following section in case we need it again in the future,
# see: https://github.com/mfem/mfem/pull/3385#discussion_r1058013032
# - name: Set up Homebrew
# if: ( matrix.mpi == 'par' || matrix.codecov == 'YES' ) && matrix.os == 'macos-latest'
# uses: Homebrew/actions/setup-homebrew@master
- name: get MPI (MacOS)
if: matrix.mpi == 'par' && matrix.os == 'macos-latest'
run: |
export HOMEBREW_NO_INSTALL_CLEANUP=1
brew install openmpi
- name: get MPI (MacOS)
if: matrix.mpi == 'par' && matrix.os == 'macos-latest'
run: |
export HOMEBREW_NO_INSTALL_CLEANUP=1
brew install openmpi
- name: get lcov (MacOS)
if: matrix.codecov == 'YES' && matrix.os == 'macos-latest'
run: |
export HOMEBREW_NO_INSTALL_CLEANUP=1
brew install lcov
- name: get lcov (MacOS)
if: matrix.codecov == 'YES' && matrix.os == 'macos-latest'
run: |
export HOMEBREW_NO_INSTALL_CLEANUP=1
brew install lcov
- name: get MPI (Windows)
if: matrix.mpi == 'par' && matrix.os == 'windows-latest'
uses: mpi4py/setup-mpi@v1.1.4
- name: get MPI (Windows)
if: matrix.mpi == 'par' && matrix.os == 'windows-latest'
uses: mpi4py/setup-mpi@v1.1.4
# Get Hypre through cache, or build it.
# Install will only run on cache miss.
- name: cache hypre
id: hypre-cache
if: matrix.mpi == 'par'
uses: actions/cache@v3
with:
path: ${{ env.HYPRE_TOP_DIR }}
key: ${{ runner.os }}-build-${{ env.HYPRE_TOP_DIR }}-${{ matrix.hypre-target }}-v2.2
# Get Hypre through cache, or build it.
# Install will only run on cache miss.
- name: cache hypre
id: hypre-cache
if: matrix.mpi == 'par'
uses: actions/cache@v3
with:
path: ${{ env.HYPRE_TOP_DIR }}
key: ${{ runner.os }}-build-${{ env.HYPRE_TOP_DIR }}-${{ matrix.hypre-target }}-v2.2
- name: get hypre
if: matrix.mpi == 'par' && steps.hypre-cache.outputs.cache-hit != 'true' && matrix.os != 'windows-latest'
uses: mfem/github-actions/build-hypre@v2.4
with:
archive: ${{ env.HYPRE_ARCHIVE }}
dir: ${{ env.HYPRE_TOP_DIR }}
target: ${{ matrix.hypre-target }}
build-system: make
- name: get hypre
if: matrix.mpi == 'par' && steps.hypre-cache.outputs.cache-hit != 'true' && matrix.os != 'windows-latest'
uses: mfem/github-actions/build-hypre@v2.4
with:
archive: ${{ env.HYPRE_ARCHIVE }}
dir: ${{ env.HYPRE_TOP_DIR }}
target: ${{ matrix.hypre-target }}
build-system: make
- name: get hypre (Windows)
if: matrix.mpi == 'par' && steps.hypre-cache.outputs.cache-hit != 'true' && matrix.os == 'windows-latest'
uses: mfem/github-actions/build-hypre@v2.4
with:
archive: ${{ env.HYPRE_ARCHIVE }}
dir: ${{ env.HYPRE_TOP_DIR }}
target: ${{ matrix.hypre-target }}
build-system: cmake
- name: get hypre (Windows)
if: matrix.mpi == 'par' && steps.hypre-cache.outputs.cache-hit != 'true' && matrix.os == 'windows-latest'
uses: mfem/github-actions/build-hypre@v2.4
with:
archive: ${{ env.HYPRE_ARCHIVE }}
dir: ${{ env.HYPRE_TOP_DIR }}
target: ${{ matrix.hypre-target }}
build-system: cmake
# Get Metis through cache, or build it.
# Install will only run on cache miss.
- name: cache metis
id: metis-cache
if: matrix.mpi == 'par' && matrix.os != 'windows-latest'
uses: actions/cache@v3
with:
path: ${{ env.METIS_TOP_DIR }}
key: ${{ runner.os }}-build-${{ env.METIS_TOP_DIR }}-v2.2
# Get Metis through cache, or build it.
# Install will only run on cache miss.
- name: cache metis
id: metis-cache
if: matrix.mpi == 'par' && matrix.os != 'windows-latest'
uses: actions/cache@v3
with:
path: ${{ env.METIS_TOP_DIR }}
key: ${{ runner.os }}-build-${{ env.METIS_TOP_DIR }}-v2.2
- name: install metis
if: matrix.mpi == 'par' && matrix.os != 'windows-latest' && steps.metis-cache.outputs.cache-hit != 'true'
uses: mfem/github-actions/build-metis@v2.4
with:
archive: ${{ env.METIS_ARCHIVE }}
dir: ${{ env.METIS_TOP_DIR }}
- name: install metis
if: matrix.mpi == 'par' && matrix.os != 'windows-latest' && steps.metis-cache.outputs.cache-hit != 'true'
uses: mfem/github-actions/build-metis@v2.4
with:
archive: ${{ env.METIS_ARCHIVE }}
dir: ${{ env.METIS_TOP_DIR }}
- name: cache vcpkg (Windows)
id: vcpkg-cache
if: matrix.os == 'windows-latest'
uses: actions/cache@v3
with:
path: vcpkg_cache
key: ${{ runner.os }}-${{ matrix.mpi }}-vcpkg-v1
- name: cache vcpkg (Windows)
id: vcpkg-cache
if: matrix.os == 'windows-latest'
uses: actions/cache@v3
with:
path: vcpkg_cache
key: ${{ runner.os }}-${{ matrix.mpi }}-vcpkg-v1
- name: prepare vcpkg binary cache location (Windows)
if: matrix.os == 'windows-latest' && steps.vcpkg-cache.outputs.cache-hit != 'true'
run: |
mkdir -p vcpkg_cache
- name: prepare vcpkg binary cache location (Windows)
if: matrix.os == 'windows-latest' && steps.vcpkg-cache.outputs.cache-hit != 'true'
run: |
mkdir -p vcpkg_cache
- name: install metis (Windows)
if: matrix.mpi == 'par' && matrix.os == 'windows-latest'
env:
VCPKG_DEFAULT_BINARY_CACHE: ${{ github.workspace }}/vcpkg_cache
run: |
vcpkg install metis-mfem --triplet=x64-windows-static --overlay-ports=${{ env.MFEM_TOP_DIR }}/config/vcpkg/ports
- name: install metis (Windows)
if: matrix.mpi == 'par' && matrix.os == 'windows-latest'
env:
VCPKG_DEFAULT_BINARY_CACHE: ${{ github.workspace }}/vcpkg_cache
run: |
vcpkg install metis-mfem --triplet=x64-windows-static --overlay-ports=${{ env.MFEM_TOP_DIR }}/config/vcpkg/ports
# MFEM build and test
- name: build
uses: mfem/github-actions/build-mfem@v2.4
env:
VCPKG_DEFAULT_BINARY_CACHE: ${{ github.workspace }}/vcpkg_cache
with:
os: ${{ matrix.os }}
target: ${{ matrix.target }}
codecov: ${{ matrix.codecov }}
mpi: ${{ matrix.mpi }}
build-system: ${{ matrix.build-system }}
hypre-dir: ${{ env.HYPRE_TOP_DIR }}
metis-dir: ${{ env.METIS_TOP_DIR }}
mfem-dir: ${{ env.MFEM_TOP_DIR }}
config-options: ${{ matrix.config-opts }}
library-only: ${{ matrix.target == 'dbg' && matrix.os != 'ubuntu-latest' }}
# MFEM build and test
- name: build
uses: mfem/github-actions/build-mfem@v2.4
env:
VCPKG_DEFAULT_BINARY_CACHE: ${{ github.workspace }}/vcpkg_cache
with:
os: ${{ matrix.os }}
target: ${{ matrix.target }}
codecov: ${{ matrix.codecov }}
mpi: ${{ matrix.mpi }}
build-system: ${{ matrix.build-system }}
hypre-dir: ${{ env.HYPRE_TOP_DIR }}
metis-dir: ${{ env.METIS_TOP_DIR }}
mfem-dir: ${{ env.MFEM_TOP_DIR }}
config-options: ${{ matrix.config-opts }}
library-only: ${{ matrix.target == 'dbg' && matrix.os != 'ubuntu-latest' }}
# Run checks (and only checks) on debug targets
- name: checks
if: matrix.build-system == 'make' && matrix.target == 'dbg'
run: |
cd ${{ env.MFEM_TOP_DIR }} && make check
# Run checks (and only checks) on debug targets
- name: checks
if: matrix.build-system == 'make' && matrix.target == 'dbg'
run: |
cd ${{ env.MFEM_TOP_DIR }} && make check
# Note: 'tests' include the unit tests
- name: tests
if: matrix.build-system == 'make' && (matrix.target == 'opt' || matrix.os == 'ubuntu-latest')
run: |
cd ${{ env.MFEM_TOP_DIR }} && make test
# Note: 'tests' include the unit tests
- name: tests
if: matrix.build-system == 'make' && (matrix.target == 'opt' || matrix.os == 'ubuntu-latest')
run: |
cd ${{ env.MFEM_TOP_DIR }} && make test
- name: cmake checks
if: matrix.build-system == 'cmake' && matrix.target == 'dbg'
run: |
CTEST_CONFIG="Debug"
cd ${{ env.MFEM_TOP_DIR }} && cmake --build build --target check --config ${CTEST_CONFIG}
shell: bash
- name: cmake checks
if: matrix.build-system == 'cmake' && matrix.target == 'dbg'
run: |
CTEST_CONFIG="Debug"
cd ${{ env.MFEM_TOP_DIR }} && cmake --build build --target check --config ${CTEST_CONFIG}
shell: bash
- name: cmake unit tests (Ubuntu)
if: matrix.build-system == 'cmake' && matrix.target == 'opt' && matrix.os == 'ubuntu-latest'
run: |
CTEST_CONFIG="Release"
[[ ${{ matrix.target }} == 'dbg' ]] && CTEST_CONFIG="Debug"
cd ${{ env.MFEM_TOP_DIR }}/build/tests/unit && ctest --output-on-failure -C ${CTEST_CONFIG}
shell: bash
- name: cmake unit tests (Ubuntu)
if: matrix.build-system == 'cmake' && matrix.target == 'opt' && matrix.os == 'ubuntu-latest'
run: |
CTEST_CONFIG="Release"
[[ ${{ matrix.target }} == 'dbg' ]] && CTEST_CONFIG="Debug"
cd ${{ env.MFEM_TOP_DIR }}/build/tests/unit && ctest --output-on-failure -C ${CTEST_CONFIG}
shell: bash
- name: cmake tests
if: matrix.build-system == 'cmake' && matrix.target == 'opt' && matrix.os != 'ubuntu-latest'
run: |
CTEST_CONFIG="Release"
cd ${{ env.MFEM_TOP_DIR }}/build && \
ctest --output-on-failure -C ${CTEST_CONFIG} || \
ctest --rerun-failed --output-on-failure -C ${CTEST_CONFIG}
shell: bash
- name: cmake tests
if: matrix.build-system == 'cmake' && matrix.target == 'opt' && matrix.os != 'ubuntu-latest'
run: |
CTEST_CONFIG="Release"
cd ${{ env.MFEM_TOP_DIR }}/build && \
ctest --output-on-failure -C ${CTEST_CONFIG} || \
ctest --rerun-failed --output-on-failure -C ${CTEST_CONFIG}
shell: bash
# Code coverage (process and upload reports)
- name: codecov
if: matrix.codecov == 'YES'
uses: mfem/github-actions/upload-coverage@v2.4
with:
name: ${{ matrix.os }}-${{ matrix.build-system }}-${{ matrix.target }}-${{ matrix.mpi }}-${{ matrix.hypre-target }}
project_dir: ${{ env.MFEM_TOP_DIR }}
directories: "fem general linalg mesh"
# Code coverage (process and upload reports)
- name: codecov
if: matrix.codecov == 'YES'
uses: mfem/github-actions/upload-coverage@v2.4
with:
name: ${{ matrix.os }}-${{ matrix.build-system }}-${{ matrix.target }}-${{ matrix.mpi }}-${{ matrix.hypre-target }}
project_dir: ${{ env.MFEM_TOP_DIR }}
directories: "fem general linalg mesh"
+28 -27
View File
@@ -13,10 +13,10 @@ name: "Static Analysis"
on:
push:
branches: ["master", "next"]
branches: [ "master", "next"]
pull_request:
# The branches below must be a subset of the branches above
branches: ["master"]
branches: [ "master" ]
jobs:
analyze:
@@ -35,35 +35,36 @@ jobs:
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
+55 -55
View File
@@ -34,67 +34,67 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.11.0
with:
access_token: ${{ github.token }}
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.11.0
with:
access_token: ${{ github.token }}
- name: checkout MFEM
uses: actions/checkout@v3
with:
path: mfem
- name: checkout MFEM
uses: actions/checkout@v3
with:
path: mfem
- name: Get MPI (Linux)
run: |
sudo apt-get install mpich libmpich-dev
- name: Get MPI (Linux)
run: |
sudo apt-get install mpich libmpich-dev
- name: Cache Hypre Install
id: hypre-cache
uses: actions/cache@v3
with:
path: ${{ env.HYPRE_TOP_DIR }}
key: ${{ runner.os }}-build-${{ env.HYPRE_TOP_DIR }}-v2.2
- name: Cache Hypre Install
id: hypre-cache
uses: actions/cache@v3
with:
path: ${{ env.HYPRE_TOP_DIR }}
key: ${{ runner.os }}-build-${{ env.HYPRE_TOP_DIR }}-v2.2
- name: Get Hypre
if: steps.hypre-cache.outputs.cache-hit != 'true'
uses: mfem/github-actions/build-hypre@v2.4
with:
archive: ${{ env.HYPRE_ARCHIVE }}
dir: ${{ env.HYPRE_TOP_DIR }}
target: int32
- name: Get Hypre
if: steps.hypre-cache.outputs.cache-hit != 'true'
uses: mfem/github-actions/build-hypre@v2.4
with:
archive: ${{ env.HYPRE_ARCHIVE }}
dir: ${{ env.HYPRE_TOP_DIR }}
target: int32
- name: Cache Metis Install
id: metis-cache
uses: actions/cache@v3
with:
path: ${{ env.METIS_TOP_DIR }}
key: ${{ runner.os }}-build-${{ env.METIS_TOP_DIR }}-v2.2
- name: Cache Metis Install
id: metis-cache
uses: actions/cache@v3
with:
path: ${{ env.METIS_TOP_DIR }}
key: ${{ runner.os }}-build-${{ env.METIS_TOP_DIR }}-v2.2
- name: Install Metis
if: steps.metis-cache.outputs.cache-hit != 'true'
uses: mfem/github-actions/build-metis@v2.4
with:
archive: ${{ env.METIS_ARCHIVE }}
dir: ${{ env.METIS_TOP_DIR }}
- name: Install Metis
if: steps.metis-cache.outputs.cache-hit != 'true'
uses: mfem/github-actions/build-metis@v2.4
with:
archive: ${{ env.METIS_ARCHIVE }}
dir: ${{ env.METIS_TOP_DIR }}
# MFEM build and test
- name: build-mfem
uses: mfem/github-actions/build-mfem@v2.4
with:
os: ${{ runner.os }}
target: opt
codecov: NO
mpi: par
build-system: make
hypre-dir: ${{ env.HYPRE_TOP_DIR }}
metis-dir: ${{ env.METIS_TOP_DIR }}
mfem-dir: mfem
# MFEM build and test
- name: build-mfem
uses: mfem/github-actions/build-mfem@v2.4
with:
os: ${{ runner.os }}
target: opt
codecov: NO
mpi: par
build-system: make
hypre-dir: ${{ env.HYPRE_TOP_DIR }}
metis-dir: ${{ env.METIS_TOP_DIR }}
mfem-dir: mfem
- name: test (no clean)
run: |
cd mfem && make test-noclean
- name: test (no clean)
run: |
cd mfem && make test-noclean
- name: gitignore
run: |
cd mfem/tests/scripts
./runtest gitignore
- name: gitignore
run: |
cd mfem/tests/scripts
./runtest gitignore
+37 -37
View File
@@ -27,44 +27,44 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.11.0
with:
access_token: ${{ github.token }}
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.11.0
with:
access_token: ${{ github.token }}
- name: MFEM Checkout
uses: actions/checkout@v3
with:
path: mfem
- name: MFEM Checkout
uses: actions/checkout@v3
with:
path: mfem
- name: MFEM Build
uses: mfem/github-actions/build-mfem@v2.4
with:
os: ${{ runner.os }}
target: opt
mpi: seq
hypre-dir: unused-hypre-dir
metis-dir: unused-metis-dir
mfem-dir: mfem
build-system: make
library-only: false
config-options:
CXX="clang++-14"
CXXFLAGS="-g -O1 -std=c++11
-fsanitize=address
-fno-omit-frame-pointer
-fsanitize-address-use-after-scope"
- name: MFEM Build
uses: mfem/github-actions/build-mfem@v2.4
with:
os: ${{ runner.os }}
target: opt
mpi: seq
hypre-dir: unused-hypre-dir
metis-dir: unused-metis-dir
mfem-dir: mfem
build-system: make
library-only: false
config-options:
CXX="clang++-14"
CXXFLAGS="-g -O1 -std=c++11
-fsanitize=address
-fno-omit-frame-pointer
-fsanitize-address-use-after-scope"
- name: MFEM Info
working-directory: mfem
run: make info
- name: MFEM Info
working-directory: mfem
run: make info
- name: MFEM Sanitize
working-directory: mfem
run:
ASAN_OPTIONS="detect_leaks=1,
strict_init_order=1,
strict_string_checks=1,
check_initialization_order=1,
detect_stack_use_after_return=1"
make test
- name: MFEM Sanitize
working-directory: mfem
run:
ASAN_OPTIONS="detect_leaks=1,
strict_init_order=1,
strict_string_checks=1,
check_initialization_order=1,
detect_stack_use_after_return=1"
make test
+70 -70
View File
@@ -33,49 +33,49 @@ jobs:
(github.event_name == 'push' ||
github.event.pull_request.head.repo.full_name != github.repository)
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.11.0
with:
access_token: ${{ github.token }}
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.11.0
with:
access_token: ${{ github.token }}
- name: checkout mfem
uses: actions/checkout@v3
- name: checkout mfem
uses: actions/checkout@v3
- name: copyright check
id: copyright
run: |
./config/githooks/pre-push --copyright
- name: copyright check
id: copyright
run: |
./config/githooks/pre-push --copyright
continue-on-error: true
continue-on-error: true
- name: license check
id: license
run: |
./config/githooks/pre-push --license
continue-on-error: true
- name: license check
id: license
run: |
./config/githooks/pre-push --license
continue-on-error: true
- name: release check
id: release
run: |
./config/githooks/pre-push --release
continue-on-error: true
- name: release check
id: release
run: |
./config/githooks/pre-push --release
continue-on-error: true
- name: wrap-up
if: |
steps.copyright.outcome != 'success' ||
steps.license.outcome != 'success' ||
steps.release.outcome != 'success'
run: |
if [[ "${{ steps.copyright.outcome }}" != "success" ]]; then
echo "copyright check failed, unroll log for details"
fi
if [[ "${{ steps.license.outcome }}" != "success" ]]; then
echo "license check failed, unroll log for details"
fi
if [[ "${{ steps.release.outcome }}" != "success" ]]; then
echo "release check failed, unroll log for details"
fi
exit 1
- name: wrap-up
if: |
steps.copyright.outcome != 'success' ||
steps.license.outcome != 'success' ||
steps.release.outcome != 'success'
run: |
if [[ "${{ steps.copyright.outcome }}" != "success" ]]; then
echo "copyright check failed, unroll log for details"
fi
if [[ "${{ steps.license.outcome }}" != "success" ]]; then
echo "license check failed, unroll log for details"
fi
if [[ "${{ steps.release.outcome }}" != "success" ]]; then
echo "release check failed, unroll log for details"
fi
exit 1
code-style:
runs-on: ubuntu-latest
@@ -83,16 +83,16 @@ jobs:
(github.event_name == 'push' ||
github.event.pull_request.head.repo.full_name != github.repository)
steps:
- name: checkout mfem
uses: actions/checkout@v3
- name: checkout mfem
uses: actions/checkout@v3
- name: get astyle
run: |
sudo apt-get install astyle
- name: get astyle
run: |
sudo apt-get install astyle
- name: style check
run: |
./config/githooks/pre-push --style
- name: style check
run: |
./config/githooks/pre-push --style
documentation:
runs-on: ubuntu-latest
@@ -100,22 +100,22 @@ jobs:
(github.event_name == 'push' ||
github.event.pull_request.head.repo.full_name != github.repository)
steps:
- name: checkout mfem
uses: actions/checkout@v3
- name: checkout mfem
uses: actions/checkout@v3
- name: get doxygen and graphviz
run: |
sudo apt-get install doxygen graphviz
- name: get doxygen and graphviz
run: |
sudo apt-get install doxygen graphviz
- name: update doxygen config file
run: |
cd doc
doxygen -u CodeDocumentation.conf.in
- name: update doxygen config file
run: |
cd doc
doxygen -u CodeDocumentation.conf.in
- name: build documentation
run: |
cd tests/scripts
./runtest documentation
- name: build documentation
run: |
cd tests/scripts
./runtest documentation
branch-history:
if: |
@@ -125,16 +125,16 @@ jobs:
github.event.pull_request.head.repo.full_name != github.repository)
runs-on: ubuntu-latest
steps:
- name: checkout mfem
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: checkout mfem
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: branch-history
run: |
# We override origin to make sure we point to the main repo.
# This is to have consistent test results on PRs from forks.
git remote remove origin
git remote add origin https://github.com/mfem/mfem.git
git checkout -b gh-actions-branch-history
./config/githooks/pre-push --history
- name: branch-history
run: |
# We override origin to make sure we point to the main repo.
# This is to have consistent test results on PRs from forks.
git remote remove origin
git remote add origin https://github.com/mfem/mfem.git
git checkout -b gh-actions-branch-history
./config/githooks/pre-push --history
-6
View File
@@ -213,7 +213,6 @@ miniapps/meshing/twist
miniapps/meshing/mesh-explorer
miniapps/meshing/shaper
miniapps/meshing/extruder
miniapps/meshing/fit-node-position
miniapps/meshing/trimmer
miniapps/meshing/reflector
miniapps/meshing/mesh-optimizer
@@ -266,7 +265,6 @@ miniapps/navier/*_output
miniapps/nurbs/nurbs_ex1
miniapps/nurbs/nurbs_ex1p
miniapps/nurbs/nurbs_ex11p
miniapps/nurbs/nurbs_printfunc
miniapps/nurbs/nurbs_patch_ex1
miniapps/nurbs/nurbs_curveint
miniapps/nurbs/refined.mesh
@@ -302,10 +300,6 @@ miniapps/tools/plor-transfer
miniapps/tools/get-values
miniapps/tools/check-tmop-metric
miniapps/tools/tmop-metric-magnitude
miniapps/tools/nodal-transfer
miniapps/tools/ParaView
miniapps/tools/gridfunc_*
miniapps/tools/mesh_*
miniapps/toys/automata
miniapps/toys/life
+179 -114
View File
@@ -8,148 +8,111 @@
https://mfem.org
Version 4.6.1 (development)
Version 4.5.3 (development)
===========================
Discretization improvements
---------------------------
- Introduced support for higher order non conformal Nedelec elements on
simplices in ParMesh.
Miscellaneous
-------------
- The ReadCubit Genesis mesh importer has been rewritten to improve readability.
Version 4.6, released on September 27, 2023
===========================================
- MFEM is now available in Homebrew and can be installed on a Mac with just
"brew install mfem". See https://formulae.brew.sh/formula/mfem.
Meshing improvements
--------------------
- Added asymptotically-balanced TMOP compound metrics 90, 94, 328, 338. A new
tool, tmop-metric-magnitude, can be used to track how metrics change under
geometric perturbations. See miniapps/tools.
- Several NURBS meshing improvements:
* Support for free connectivity of NURBS patches allowing for more complex
patch configurations such as C-meshes.
* New methods to set and get attributes on NURBS patches and patch boundaries.
* The edge to knot map for NURBS meshes can be determined automatically. It is
no longer needed to specify this in the NURBS mesh.
* Added curve interpolation method for NURBS.
* Added new small miniapp for printing of shape functions of a KnotVector
* See miniapps/nurbs for example meshes and miniapps.
Discretization improvements
---------------------------
- SubMesh and ParSubMesh have been extended to support the transfer of
Nedelec and Raviart-Thomas finite element spaces.
- Added support for partial assembly on NURBS patches, and NURBS-patch sparse
matrix assembly. Patch matrix assembly includes the option to use reduced
approximate integration rules, computed by the newly implemented non-negative
least-squares (NNLS) solver.
- Support for parallel transfer of H1 fields using the low-order refined (LOR)
transfer operators in L2ProjectionGridTransfer
- Added KDTree class for 2D/3D set of points, which is then utilized in the new
KDTreeNodalProjection class to project a function defined on an arbitrary set
of points onto an MFEM grid function. This functionality is demonstrated in
the nodal-transfer miniapp. The current implementation is serial only. Further
extensions can include search in arbitrary dimensional spaces.
- Added support for p-refined meshes in GSLIB-FindPoints.
- Device kernels can now access device-specific DOF and quadrature limits using
the DofQuadLimits structure, allowing increased limits when executing on CPU.
The limits for the runtime selected device can be accessed in host code using
DeviceDofQuadLimits::Get(). The global constants MAX_D1D and MAX_Q1D are no
longer available.
- Face restriction operators for Nedelec and Raviart-Thomas finite element
spaces are now supported through the ConformingFaceRestriction class.
- VectorFEBoundaryFluxLFIntegrator is now supported on device/GPU.
Linear and nonlinear solvers
----------------------------
- Updated the MUMPS interface to support multiple right-hand sides, block
low-rank compression, builds using 64-bit integers, and other improvements.
- Added an interface to the MKL Pardiso sparse direct solver developed by Intel.
The interface provides a serial (OpenMP shared memory) version of Pardiso for
use with SparseMatrix. This complements the existing parallel (MPI distributed
memory) version already available through the CPardiso MFEM integration.
- Added HIP support to the PETSc and SUNDIALS interfaces.
- Added curve interpolation method for NURBS.
New and updated examples and miniapps
-------------------------------------
- Added a new H(div) solver miniapp demonstrating the use of a matrix-free
saddle-point solver methodology, suitable for high-order discretizations and
for GPU acceleration. Examples illustrating the solution of Darcy and grad-div
problems are included. See miniapps/hdiv-linear-solver.
- Added a new example code, Example 36/36p, to demonstrate the solution of
the obstacle problem with a new finite element method.
- Added a new miniapp, Mesh Quality, for evaluating mesh quality using size,
skewness, and aspect-ratio computed from the Jacobian of the transformation.
- Added a new miniapp for interface and boundary fitting to implicit domains
defined using level-set functions. See miniapps/meshing/pmesh-fitting.cpp
- Added new Discontinuous Petrov-Galerkin (DPG) miniapp which includes serial
and parallel examples for diffusion, convection-diffusion, acoustics and
Maxwell equations. The miniapp includes new classes such as (Par)DPGWeakForm,
(Par)ComplexDPGWeakForm and (Complex)BlockStaticCondensation. Three new
integrators are added in support of DPG systems: TraceIntegrator,
NormalTraceIntegrator and TangentTraceIntegrator. See miniapps/dpg.
NormalTraceIntegrator and TangentTraceIntegrator.
- Added a new miniapp that implements the SPDE method for generating Gaussian
random fields of Matern covariance. The resulting random field can be used,
e.g., to model material uncertainties. See miniapps/spde.
- Added new SubMesh examples demonstrating source terms and boundary conditions
transferred from SubMesh objects.
- Added a new parallel LOR transfer miniapp, plor-transfer, which mirrors the
functionality of the serial LOR transfer miniapp. See miniapps/tools.
- Added a miniapp for interpolation of NURBS.
- New serial miniapp, nodal-transfer, demonstrating the use of KDTree to map a
parallel grid function to a different parallel partitioning of the same mesh.
- Added 3 additional TMOP miniapps in miniapps/meshing:
* Mesh-Quality evaluates quality using size, skewness, and aspect-ratio
computed from the Jacobian of the transformation.
* Mesh-Fitting can be used for interface and boundary fitting to implicit
domains defined using level-set functions.
* Fit-Node-Position fits selected mesh nodes to specified positions, while
maintaining overall mesh quality.
- Added 4 new example codes:
* Example 34/34p solves a simple magnetostatic problem where source terms and
boundary conditions are transferred with SubMesh objects.
* Example 35p implements H1, H(curl) and H(div) variants of a damped harmonic
oscillator with field transfer using SubMesh objects.
* Example 36/36p demonstrates the solution of the obstacle problem with a new
finite element method (proximal Galerkin).
* Example 37/37p demonstrates topology optimization with MFEM.
- Added a new H(div) solvers miniapp in miniapps/hdiv-linear-solver,
demonstrating the use of a matrix-free saddle-point solver methodology,
suitable for high-order discretizations and for GPU acceleration. Examples
illustrating the solution of Darcy and grad-div problems are included.
- Added a random refinement option to the mesh-explorer miniapp to assist users
in experimenting with nonconforming meshes.
- Moved the distance solver methods from miniapps/shifted to miniapps/common.
- Added a new parallel LOR transfer miniapp, miniapps/tools/plor-transfer, which
mirrors the functionality of the serial LOR transfer miniapp,
miniapps/tools/lor-transfer
Meshing improvements
--------------------
- Added support for free connectivity of NURBS patches allowing for more complex
patch configurations such as C-meshes. This is demonstrated in a new NURBS
miniapp.
- The edge to knot map for NURBS meshes can be determined automatically. It is no
longer needed to specify this in the NURBS mesh. A mesh in the NURBS miniapp
demonstrates this.
- Added new methods in the Mesh class to set and get attributes on NURBS patches
and patch boundaries.
- Added HIP support to the SUNDIALS interface.
- TMOP improvement: added asymptotically-balanced compound metrics 90, 94, 328,
338. Added the tmop-metric-magnitude tool for tracking how metrics change
under geometric perturbations.
Discretization improvements
---------------------------
- Face restriction operators for Nedelec and Raviart-Thomas finite element
spaces are now supported through the ConformingFaceRestriction class.
- SubMesh and ParSubMesh have been extended to support the transfer of
Nedelec and Raviart-Thomas finite element spaces.
- VectorFEBoundaryFluxLFIntegrator is now supported on device/GPU.
- Added support for partial assembly on NURBS patches and NURBS patch sparse
matrix assembly. Patch matrix assembly includes the option to use reduced
approximate integration rules, computed by the newly implemented non-negative
least-squares (NNLS) solver.
- Added support for p-refined meshes in FindPointsGSLIB.
- Support for parallel transfer of H1 fields using the low-order refined (LOR)
transfer operators in L2ProjectionGridTransfer
Linear and nonlinear solvers
----------------------------
- Updated interface to MUMPS direct solver to support multiple right-hand
sides, block low-rank compression, builds using 64-bit integers, and other
improvements.
- Added an interface to the MKL Pardiso sparse direct solver developed by Intel.
This interface provides a serial (OpenMP shared memory) version of Pardiso for
use with SparseMatrix. This complements the existing parallel (MPI distributed
memory) version already available through the CPardiso MFEM integration.
Integrations, testing and documentation
---------------------------------------
- Added an address sanitizer GitHub action for a serial build/test on Ubuntu,
based on Clang/LLVM (https://clang.llvm.org/docs/AddressSanitizer.html).
Miscellaneous
-------------
- Improved lambda body debugging with the addition of mfem::forall functions.
These functions can take the place of the MFEM_FORALL macros, which have been
preserved for backwards compatibility.
- Added an address sanitizer GitHub action for a serial build/test on Ubuntu,
based on Clang/LLVM (https://clang.llvm.org/docs/AddressSanitizer.html).
- Reorganized files for bilinear form, linear form, and nonlinear form integrators
in the fem/integ/ subdirectory.
- FiniteElementSpace::GetFE has been updated to abort instead of returning NULL for
an empty partition.
- Various other simplifications, extensions, and bugfixes in the code.
Version 4.5.2, released on March 23, 2023
=========================================
@@ -349,6 +312,102 @@ Miscellaneous
- Various other simplifications, extensions, and bugfixes in the code.
- Added PA support for MixedScalarCurlIntegrator in 2D and
MixedVectorGradientIntegrator in 2D and 3D, as well as their transposes.
- Added hipSPARSE support for sparse mat-vec multiplications.
- Added support for using the HYPRE library built with HIP support. Similar to
the HYPRE + CUDA support added earlier, most of the MFEM examples and miniapps
work transparently with HYPRE + HIP builds. This includes the BoomerAMG, AMS,
and ADS solvers.
- More explicit and consistent formating of the output of iterative solvers
with the new IterativeSolver::PrintLevel options. See linalg/solvers.hpp.
- Added a miniapp for PDE-based extrapolation of finite element functions. See
miniapps/shifted/extrapolate.cpp.
- Added support for automatic differentiation. Users can select between native
implementation and external library implementation during configuration. One
parallel and two serial examples are implemented in the miniapps/autodiff/
directory.
- GridFunctionCoefficient (and the related vector, gradient, divergence, and
curl classes) now work properly with LORDiscretization and LORSolver.
- Added support for mesh preprocessing to resolve fine scale problem data
before simulation. This feature uses adaptive mesh refinement to control the
associated data oscillation error. See the new Example 30/30p.
- Switched from Artistic Style (astyle) version 2.05.1 to version 3.1 for code
formatting. See the "make style" target.
- Split the fem/fe.?pp files into separate files in the new fem/fe/ directory
to simplify and clarify the organization of FiniteElement classes.
- Added support for hr-adaptivity using TMOP-based error estimator.
- Coefficient::SetTime now propagates the new time into internally stored
Coefficient objects.
- Added initial support for google-benchmarks in the tests/benchmarks directory.
It can be enabled with MFEM_USE_BENCHMARK=YES.
- Added Binder (mybinder.org) configuration files for C++ MFEM Jupyter Notebooks
with inline GLVis visualization as well as a new examples/jupyter/ directory
with a sample notebook based on Example 1. Implementation based on xeus-cling,
github.com/jupyter-xeus/xeus-cling + xeus-glvis, github.com/GLVis/xeus-glvis.
- Added 'double' atomicAdd implementation for previous versions of CUDA.
- Adding lowest order Nedelec and Raviart-Thomas basis functions on wedge
shaped elements.
- Added initial support for meshes with pyramidal elements, including several
pyramidal meshes in the data/ directory and support for the lowest order H1,
Nedelec, Raviart-Thomas, and L2 basis functions on pyramids.
- Updated the hypre interface according to changes in hypre-2.22.1. The ADS
solver is now fully working on GPUs.
- Tetrahedral meshes no longer need to be reordered to support high order
Nedelec basis functions. This will allow future support for Nedelec basis
functions on wedges and pyramids which are not amenable to reordering. The
ReorientTetMesh method of the Mesh and ParMesh classes has been deprecated.
- Gmsh meshes where all elements have zero physical tag (the default Gmsh
output format if no physical groups are defined) are now successfully loaded,
and elements are reassigned attribute number 1.
- Added new miniapps that use the ParELAG library, its hybrid smoothers, and the
hierarchy of spaces created by the element-based AMG (AMGe) methodology in
ParELAG to build multigrid solvers for H(curl) and H(div) forms. See the
miniapps/parelag directory for more details.
- Fixed several MinGW build issues on Windows.
- Remove the 'u' flag in the ar command, to update all files in the archive,
avoiding file name collisions from different subdirectories.
- Added initial TMOP-based capabilities for surface fitting and tangential
relaxation in the mesh-optimizer and pmesh-optimizer miniapps.
- Added ParMesh Adjaceny Set (adjset) creation support to the Conduit Mesh
Blueprint MFEM wrapper functions in ConduitDataCollection.
- `HypreParVector` and `Vector` now support move semantics, and the copy
constructor for `HypreParVector` now copies the local vector data.
- The HPC versions of ex1 and ex1p (in miniapps/performance) now support
runtime selection of either 2D or 3D meshes.
- Added arbitrary order Nedelec and Raviart-Thomas basis functions for
wedge-shaped elements.
- Added ParaView visualization of `QuadratureFunction` fields, through both
`QuadratureFunction::SaveVTU` and `ParaViewDataCollection::RegisterQField`.
Version 4.4, released on March 21, 2022
=======================================
@@ -530,6 +589,12 @@ Discretization improvements
- Added support for nonscalar coefficient with VectorDiffusionIntegrator.
- Added support for Partial Assembly and Element Assembly with Discontinuous
Galerkin methods on nonconforming meshes.
- Added a simpler interface to request face information: see
`Mesh::FaceInformation` and `Mesh::GetFaceInformation`.
Linear and nonlinear solvers
----------------------------
- Added support for AMG preconditioners on GPUs based on the hypre library
+2 -2
View File
@@ -57,7 +57,7 @@ project(mfem NONE)
# Current version of MFEM, see also `makefile`.
# mfem_VERSION = (string)
# MFEM_VERSION = (int) [automatically derived from mfem_VERSION]
set(${PROJECT_NAME}_VERSION 4.6.1)
set(${PROJECT_NAME}_VERSION 4.5.3)
# Prohibit in-source build
if (${PROJECT_SOURCE_DIR} STREQUAL ${PROJECT_BINARY_DIR})
@@ -138,7 +138,7 @@ if (MFEM_USE_CUDA)
set(CUDA_FLAGS "-ccbin=${CMAKE_CXX_COMPILER} ${CUDA_FLAGS}")
set(CMAKE_CUDA_HOST_LINK_LAUNCHER ${CMAKE_CXX_COMPILER})
endif()
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} ${CUDA_FLAGS}")
set(CMAKE_CUDA_FLAGS ${CMAKE_CUDA_FLAGS} ${CUDA_FLAGS})
set(CUSPARSE_FOUND TRUE)
set(CUSPARSE_LIBRARIES "cusparse")
set(CUBLAS_FOUND TRUE)
-2
View File
@@ -135,7 +135,6 @@ The MFEM source code has the following structure:
│ ├── adjoint
│ ├── autodiff
│ ├── common
│ ├── dpg
│ ├── electromagnetics
│ ├── gslib
│ ├── hdiv-linear-solver
@@ -149,7 +148,6 @@ The MFEM source code has the following structure:
│ ├── performance
│ ├── shifted
│ ├── solvers
│ ├── spde
│ ├── tools
│ └── toys
└── tests
+2 -5
View File
@@ -699,15 +699,12 @@ The specific libraries and their options are:
PETSc has been cloned on the same level as mfem and hypre:
./configure --download-fblaslapack=yes --download-scalapack=yes \
--download-mumps=yes --download-suitesparse=yes \
--with-hypre-dir=../hypre/src/hypre \
--with-hypre-dir=../hypre-2.10.0b/src/hypre \
--with-shared-libraries=0
When building PETSc with HIP, one may need to add a flag like -std=c2x to
CFLAGS to allow proper parsing of the hipsparse header under C.
URL: https://www.mcs.anl.gov/petsc
Options: PETSC_OPT, PETSC_LIB.
Versions: PETSc >= 3.8.0 (PETSc build without CUDA/HIP)
Versions: PETSc >= 3.8.0 (PETSc build without CUDA)
PETSc >= 3.15.0 (PETSc built with CUDA)
PETSc >= 3.19.0 (PETSc built with HIP, older versions may work too)
- SLEPc (optional), used when MFEM_USE_SLEPC = YES. SLEPc depends on PETSc and
uses some of the PETSc options when compiled.
+5 -20
View File
@@ -331,30 +331,16 @@ STRUMPACK_OPT = -I$(STRUMPACK_DIR)/include $(SCOTCH_OPT)
STRUMPACK_LIB = -L$(STRUMPACK_DIR)/lib -lstrumpack $(MPI_FORTRAN_LIB)\
$(SCOTCH_LIB) $(SCALAPACK_LIB)
# Ginkgo library configuration
# Ginkgo library configuration (currently not needed)
GINKGO_DIR = @MFEM_DIR@/../ginkgo/install
GINKGO_SEARCH_DIR = $(subst @MFEM_DIR@,$(MFEM_DIR),$(GINKGO_DIR))
GINKGO_BUILD_TYPE=Release
ifeq ($(MFEM_USE_GINKGO),YES)
BASE_FLAGS = -std=c++14
endif
GINKGO_OPT = -isystem $(GINKGO_DIR)/include
GINKGO_LIB_DIR = $(sort $(dir $(wildcard\
$(GINKGO_SEARCH_DIR)/lib*/libginkgo*.a\
$(GINKGO_SEARCH_DIR)/lib*/libginkgo*.so\
$(GINKGO_SEARCH_DIR)/lib*/libginkgo*.dylib\
$(GINKGO_SEARCH_DIR)/lib*/libginkgo*.dll)))
GINKGO_LINK_LIB_DIR = $(GINKGO_DIR)$(subst $(GINKGO_SEARCH_DIR),,$(GINKGO_LIB_DIR))
ALL_GINKGO_LIBS_DEBUG = $(notdir $(basename $(wildcard\
$(GINKGO_SEARCH_DIR)/lib*/libginkgo*d.a\
$(GINKGO_SEARCH_DIR)/lib*/libginkgo*d.so\
$(GINKGO_SEARCH_DIR)/lib*/libginkgo*d.dylib\
$(GINKGO_SEARCH_DIR)/lib*/libginkgo*d.dll)))
ALL_GINKGO_LIBS = $(notdir $(basename $(wildcard\
$(GINKGO_SEARCH_DIR)/lib*/libginkgo*.a\
$(GINKGO_SEARCH_DIR)/lib*/libginkgo*.so\
$(GINKGO_SEARCH_DIR)/lib*/libginkgo*.dylib\
$(GINKGO_SEARCH_DIR)/lib*/libginkgo*.dll)))
GINKGO_LIB_DIR = $(sort $(dir $(wildcard $(GINKGO_DIR)/lib*/libginkgo*.a $(GINKGO_DIR)/lib*/libginkgo*.so $(GINKGO_DIR)/lib*/libginkgo*.dylib $(GINKGO_DIR)/lib*/libginkgo*.dll)))
ALL_GINKGO_LIBS_DEBUG = $(notdir $(basename $(wildcard $(GINKGO_DIR)/lib*/libginkgo*d.a $(GINKGO_DIR)/lib*/libginkgo*d.so $(GINKGO_DIR)/lib*/libginkgo*d.dylib $(GINKGO_DIR)/lib*/libginkgo*d.dll)))
ALL_GINKGO_LIBS = $(notdir $(basename $(wildcard $(GINKGO_DIR)/lib*/libginkgo*.a $(GINKGO_DIR)/lib*/libginkgo*.so $(GINKGO_DIR)/lib*/libginkgo*.dylib $(GINKGO_DIR)/lib*/libginkgo*.dll)))
ALL_GINKGO_LIBS_RELEASE = $(filter-out $(ALL_GINKGO_LIBS_DEBUG),$(ALL_GINKGO_LIBS))
GINKGO_LINK = $(subst libginkgo,-lginkgo,$(ALL_GINKGO_LIBS_RELEASE))
ifeq ($(GINKGO_BUILD_TYPE),Debug)
@@ -363,8 +349,7 @@ ifeq ($(GINKGO_BUILD_TYPE),Debug)
endif
else
endif
GINKGO_LIB = $(XLINKER)-rpath,$(GINKGO_LINK_LIB_DIR) -L$(GINKGO_LINK_LIB_DIR)\
$(GINKGO_LINK)
GINKGO_LIB = $(XLINKER)-rpath,$(GINKGO_LIB_DIR) -L$(GINKGO_LIB_DIR) $(GINKGO_LINK)
# AmgX library configuration
AMGX_DIR = @MFEM_DIR@/../amgx
-37
View File
@@ -1,37 +0,0 @@
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
2 0 4
vertices
5
2
0 0
0.25 0.25
0.50 0.50
0.75 0.75
1 1
-37
View File
@@ -1,37 +0,0 @@
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
2 0 4
vertices
5
3
0 0 0
0.25 0.25 0.25
0.50 0.50 0.50
0.75 0.75 0.75
1 1 1
+1 -1
View File
@@ -38,7 +38,7 @@ PROJECT_NAME = "MFEM"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = v4.6.1
PROJECT_NUMBER = v4.5.3
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
-5
View File
@@ -105,13 +105,8 @@ namespace mfem {
* - <a class="el" href="ex32p_8cpp_source.html">Example 32p</a>: parallel anisotropic Maxwell eigensolver
* - <a class="el" href="ex33_8cpp_source.html">Example 33</a>: nodal H1 FEM for the fractional Laplacian problem
* - <a class="el" href="ex33p_8cpp_source.html">Example 33p</a>: parallel nodal H1 FEM for the fractional Laplacian problem
* - <a class="el" href="ex34_8cpp_source.html">Example 34</a>: multi-domain magnetostatics
* - <a class="el" href="ex34p_8cpp_source.html">Example 34p</a>: parallel multi-domain magnetostatics
* - <a class="el" href="ex35p_8cpp_source.html">Example 35p</a>: parallel multi-domain damped harmonic oscillators
* - <a class="el" href="ex36_8cpp_source.html">Example 36</a>: Proximal Galerkin FEM for the obstacle problem
* - <a class="el" href="ex36p_8cpp_source.html">Example 36p</a>: parallel Proximal Galerkin FEM for the obstacle problem
* - <a class="el" href="ex37_8cpp_source.html">Example 37</a>: Topology optimization
* - <a class="el" href="ex37p_8cpp_source.html">Example 37p</a>: parallel topology optimization
*
* <H4>AmgX Examples</H4>
* - Variants of Examples
-4
View File
@@ -42,7 +42,6 @@ list(APPEND ALL_EXE_SRCS
ex33.cpp
ex34.cpp
ex36.cpp
ex37.cpp
)
if (MFEM_USE_MPI)
@@ -83,7 +82,6 @@ if (MFEM_USE_MPI)
ex34p.cpp
ex35p.cpp
ex36p.cpp
ex37p.cpp
)
endif()
@@ -109,8 +107,6 @@ if (MFEM_ENABLE_TESTING)
list(APPEND THIS_TEST_OPTIONS "-e" "1")
elseif(${TEST_NAME} MATCHES "ex27p*")
list(APPEND THIS_TEST_OPTIONS "-dg")
elseif(${TEST_NAME} MATCHES "ex37p*")
list(APPEND THIS_TEST_OPTIONS "-mi" "3")
endif()
if (NOT (${TEST_NAME} MATCHES ".*p$"))
-9
View File
@@ -5,7 +5,6 @@
// Sample runs: mpirun -np 4 ex13p -m ../data/star.mesh
// mpirun -np 4 ex13p -m ../data/square-disc.mesh -o 2 -n 4
// mpirun -np 4 ex13p -m ../data/beam-tet.mesh
// mpirun -np 4 ex13p -m ../data/beam-tet.mesh -nc -o 2 -rs 1
// mpirun -np 4 ex13p -m ../data/beam-hex.mesh
// mpirun -np 4 ex13p -m ../data/escher.mesh
// mpirun -np 4 ex13p -m ../data/fichera.mesh
@@ -55,7 +54,6 @@ int main(int argc, char *argv[])
int par_ref_levels = 1;
int order = 1;
int nev = 5;
bool nc = false;
bool visualization = 1;
const char *device_config = "cpu";
@@ -71,9 +69,6 @@ int main(int argc, char *argv[])
" isoparametric space.");
args.AddOption(&nev, "-n", "--num-eigs",
"Number of desired eigenmodes.");
args.AddOption(&nc, "-nc", "--non-conforming", "-c",
"--conforming",
"Mark the mesh as nonconforming before partitioning.");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
@@ -103,10 +98,6 @@ int main(int argc, char *argv[])
// and volume meshes with the same code.
Mesh *mesh = new Mesh(mesh_file, 1, 1);
int dim = mesh->Dimension();
if (nc)
{
mesh->EnsureNCMesh(true);
}
// 5. Refine the serial mesh on all processors to increase the resolution. In
// this example we do 'ref_levels' of uniform refinement (2 by default, or
-1
View File
@@ -13,7 +13,6 @@
// mpirun -np 4 ex15p -m ../data/square-disc-nurbs.mesh
// mpirun -np 4 ex15p -m ../data/disc-nurbs.mesh
// mpirun -np 4 ex15p -m ../data/fichera.mesh -tf 0.5
// mpirun -np 4 ex15p -m ../data/fichera-mixed.mesh -tf 0.5
// mpirun -np 4 ex15p -m ../data/ball-nurbs.mesh -tf 0.5
// mpirun -np 4 ex15p -m ../data/mobius-strip.mesh
// mpirun -np 4 ex15p -m ../data/amr-quad.mesh
-9
View File
@@ -63,7 +63,6 @@ int main(int argc, char *argv[])
int order = 1;
bool static_cond = false;
bool pa = false;
bool nc = false;
const char *device_config = "cpu";
bool visualization = 1;
@@ -78,9 +77,6 @@ int main(int argc, char *argv[])
"--no-static-condensation", "Enable static condensation.");
args.AddOption(&pa, "-pa", "--partial-assembly", "-no-pa",
"--no-partial-assembly", "Enable Partial Assembly.");
args.AddOption(&nc, "-nc", "--non-conforming", "-c",
"--conforming",
"Mark the mesh as nonconforming before partitioning.");
args.AddOption(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
@@ -106,11 +102,6 @@ int main(int argc, char *argv[])
Mesh *mesh = new Mesh(mesh_file, 1, 1);
dim = mesh->Dimension();
int sdim = mesh->SpaceDimension();
if (nc)
{
// Can set to false to use conformal refinement for simplices.
mesh->EnsureNCMesh(true);
}
// 4. Refine the mesh to increase the resolution. In this example we do
// 'ref_levels' of uniform refinement. We choose 'ref_levels' to be the
+25 -24
View File
@@ -267,9 +267,9 @@ int main(int argc, char *argv[])
<< "window_geometry 400 0 400 350" << flush;
}
// 7. Define a parallel finite element space on the full mesh. Here we use
// the H(curl) finite elements for the vector potential and H(div) for the
// current density.
// 7. Define a parallel finite element space on the full mesh. Here we
// use the H(curl) finite elements for the vector potential and H(div)
// for the current density.
ND_FECollection fec_nd(order, dim);
RT_FECollection fec_rt(order - 1, dim);
FiniteElementSpace fespace_nd(&mesh, &fec_nd);
@@ -292,10 +292,10 @@ int main(int argc, char *argv[])
}
// 8. Determine the list of true (i.e. parallel conforming) essential
// boundary dofs. In this example, the boundary conditions are defined by
// marking all the boundary attributes except for those on a symmetry
// plane as essential (Dirichlet) and converting them to a list of true
// dofs.
// boundary dofs. In this example, the boundary conditions are defined
// by marking all the boundary attributes except for those on a symmetry
// plane as essential (Dirichlet) and converting them to a list of
// true dofs.
Array<int> ess_tdof_list;
Array<int> ess_bdr;
if (mesh.bdr_attributes.Size())
@@ -324,13 +324,14 @@ int main(int argc, char *argv[])
GridFunction x(&fespace_nd);
x = 0.0;
// 11. Set up the parallel bilinear form corresponding to the EM diffusion
// operator curl muinv curl + delta I, by adding the curl-curl and the
// mass domain integrators. For standard magnetostatics equations choose
// delta << 1. Larger values of delta should make the linear system
// easier to solve at the expense of resembling a diffusive quasistatic
// magnetic field. A reasonable balance must be found whenever the mesh
// or problem setup is altered.
// 11. Set up the parallel bilinear form corresponding to the EM
// diffusion operator curl muinv curl + delta I, by adding the
// curl-curl and the mass domain integrators. For standard
// magnetostatics equations choose delta << 1. Larger values of
// delta should make the linear system easier to solve at the
// expense of resembling a diffusive quasistatic magnetic field.
// A reasonable balance must be found whenever the mesh or problem
// setup is altered.
ConstantCoefficient muinv(1.0);
ConstantCoefficient delta(delta_const);
BilinearForm a(&fespace_nd);
@@ -422,8 +423,8 @@ int main(int argc, char *argv[])
GridFunction dx(&fespace_rt);
curl.Mult(x, dx);
// 18. Save the curl of the solution in parallel. This output can be viewed
// later using GLVis: "glvis -np <np> -m mesh -g dsol".
// 18. Save the curl of the solution in parallel. This output can
// be viewed later using GLVis: "glvis -np <np> -m mesh -g dsol".
{
ostringstream dsol_name;
dsol_name << "dsol.gf";
@@ -455,18 +456,18 @@ void ComputeCurrentDensityOnSubMesh(int order,
const Array<int> &jn_zero_attr,
GridFunction &j_cond)
{
// Extract the finite element space and mesh on which j_cond is defined
// Exract the finite element space and mesh on which j_cond is defined
FiniteElementSpace &fes_cond_rt = *j_cond.FESpace();
Mesh &mesh_cond = *fes_cond_rt.GetMesh();
int dim = mesh_cond.Dimension();
// Define a parallel finite element space on the SubMesh. Here we use the H1
// finite elements for the electrostatic potential.
// Define a parallel finite element space on the SubMesh. Here we use the
// H1 finite elements for the electrostatic potential.
H1_FECollection fec_h1(order, dim);
FiniteElementSpace fes_cond_h1(&mesh_cond, &fec_h1);
// Define the conductivity coefficient and the boundaries associated with the
// fixed potentials phi0 and phi1 which will drive the current.
// Define the conductivity coefficient and the boundaries associated with
// the fixed potentials phi0 and phi1 which will drive the current.
ConstantCoefficient sigmaCoef(1.0);
Array<int> ess_bdr_phi(mesh_cond.bdr_attributes.Max());
Array<int> ess_bdr_j(mesh_cond.bdr_attributes.Max());
@@ -577,9 +578,9 @@ void ComputeCurrentDensityOnSubMesh(int order,
<< "window_geometry 0 0 400 350" << flush;
}
// Solve for the current density J = -sigma Grad phi with boundary conditions
// J.n = 0 on the walls of the conductor but not on the ports where phi=0 and
// phi=1.
// Solve for the current density J = -sigma Grad phi with boundary
// conditions J.n = 0 on the walls of the conductor but not on the
// ports where phi=0 and phi=1.
// J will be computed in H(div) so we need an RT mass matrix
BilinearForm m_rt(&fes_cond_rt);
+17 -16
View File
@@ -302,9 +302,9 @@ int main(int argc, char *argv[])
<< "window_geometry 400 0 400 350" << flush;
}
// 8. Define a parallel finite element space on the full mesh. Here we use
// the H(curl) finite elements for the vector potential and H(div) for the
// current density.
// 8. Define a parallel finite element space on the full mesh. Here we
// use the H(curl) finite elements for the vector potential and H(div)
// for the current density.
ND_FECollection fec_nd(order, dim);
RT_FECollection fec_rt(order - 1, dim);
ParFiniteElementSpace fespace_nd(&pmesh, &fec_nd);
@@ -360,13 +360,14 @@ int main(int argc, char *argv[])
ParGridFunction x(&fespace_nd);
x = 0.0;
// 12. Set up the parallel bilinear form corresponding to the EM diffusion
// operator curl muinv curl + delta I, by adding the curl-curl and the
// mass domain integrators. For standard magnetostatics equations choose
// delta << 1. Larger values of delta should make the linear system
// easier to solve at the expense of resembling a diffusive quasistatic
// magnetic field. A reasonable balance must be found whenever the mesh
// or problem setup is altered.
// 12. Set up the parallel bilinear form corresponding to the EM
// diffusion operator curl muinv curl + delta I, by adding the
// curl-curl and the mass domain integrators. For standard
// magnetostatics equations choose delta << 1. Larger values of
// delta should make the linear system easier to solve at the
// expense of resembling a diffusive quasistatic magnetic field.
// A reasonable balance must be found whenever the mesh or problem
// setup is altered.
ConstantCoefficient muinv(1.0);
ConstantCoefficient delta(delta_const);
ParBilinearForm a(&fespace_nd);
@@ -503,7 +504,7 @@ void ComputeCurrentDensityOnSubMesh(int order,
const Array<int> &jn_zero_attr,
ParGridFunction &j_cond)
{
// Extract the finite element space and mesh on which j_cond is defined
// Exract the finite element space and mesh on which j_cond is defined
ParFiniteElementSpace &fes_cond_rt = *j_cond.ParFESpace();
ParMesh &pmesh_cond = *fes_cond_rt.GetParMesh();
int myid = fes_cond_rt.GetMyRank();
@@ -514,8 +515,8 @@ void ComputeCurrentDensityOnSubMesh(int order,
H1_FECollection fec_h1(order, dim);
ParFiniteElementSpace fes_cond_h1(&pmesh_cond, &fec_h1);
// Define the conductivity coefficient and the boundaries associated with the
// fixed potentials phi0 and phi1 which will drive the current.
// Define the conductivity coefficient and the boundaries associated with
// the fixed potentials phi0 and phi1 which will drive the current.
ConstantCoefficient sigmaCoef(1.0);
Array<int> ess_bdr_phi(pmesh_cond.bdr_attributes.Max());
Array<int> ess_bdr_j(pmesh_cond.bdr_attributes.Max());
@@ -598,9 +599,9 @@ void ComputeCurrentDensityOnSubMesh(int order,
<< "window_geometry 0 0 400 350" << flush;
}
// Solve for the current density J = -sigma Grad phi with boundary conditions
// J.n = 0 on the walls of the conductor but not on the ports where phi=0 and
// phi=1.
// Solve for the current density J = -sigma Grad phi with boundary
// conditions J.n = 0 on the walls of the conductor but not on the
// ports where phi=0 and phi=1.
// J will be computed in H(div) so we need an RT mass matrix
ParBilinearForm m_rt(&fes_cond_rt);
+25 -22
View File
@@ -35,10 +35,10 @@
// conductivity, sigma = c. The user can specify these constants
// using either set of names.
//
// This example demonstrates how to transfer fields computed on a
// boundary generated SubMesh to the full mesh and apply them as
// boundary conditions. The default mesh and corresponding
// boundary attributes were chosen to verify proper behavior on
// This example demonstrates how to transfer fields computed on
// a boundary generated SubMesh to the full mesh and apply them
// as boundary conditions. The default mesh and corresponding
// boundary attriburtes were chosen to verify proper behavior on
// both triangular and quadrilateral faces of tetrahedral,
// wedge-shaped, and hexahedral elements.
//
@@ -420,6 +420,7 @@ int main(int argc, char *argv[])
//
// 2) A vector H(Div) field
// -Grad(a Div) - omega^2 b + i omega c
//
ParBilinearForm pcOp(&fespace);
if (pa) { pcOp.SetAssemblyLevel(AssemblyLevel::PARTIAL); }
switch (prob)
@@ -444,8 +445,8 @@ int main(int argc, char *argv[])
pcOp.Assemble();
// 14b. Define and apply a parallel FGMRES solver for AU=B with a block
// diagonal preconditioner based on the appropriate multigrid
// preconditioner from hypre.
// diagonal preconditioner based on the appropriate multigrid
// preconditioner from hypre.
Array<int> blockTrueOffsets;
blockTrueOffsets.SetSize(3);
blockTrueOffsets[0] = 0;
@@ -608,9 +609,10 @@ int main(int argc, char *argv[])
}
/**
Solves the eigenvalue problem -Div(Grad x) = lambda x with homogeneous
Dirichlet boundary conditions on the boundary of the domain. Returns mode
number "mode" (counting from zero) in the ParGridFunction "x".
Solves the eigenvalue problem -Div(Grad x) = lambda x with
homogeneous Dirichlet boundary conditions on the boundary of the
domain. Returns mode number "mode" (counting from zero) in the
ParGridFunction "x".
*/
void ScalarWaveGuide(int mode, ParGridFunction &x)
{
@@ -665,10 +667,10 @@ void ScalarWaveGuide(int mode, ParGridFunction &x)
}
/**
Solves the eigenvalue problem -Curl(Curl x) = lambda x with homogeneous
Dirichlet boundary conditions, on the tangential component of x, on the
boundary of the domain. Returns mode number "mode" (counting from zero) in
the ParGridFunction "x".
Solves the eigenvalue problem -Curl(Curl x) = lambda x with
homogeneous Dirichlet boundary conditions, on the tangential
component of x, on the boundary of the domain. Returns mode number
"mode" (counting from zero) in the ParGridFunction "x".
*/
void VectorWaveGuide(int mode, ParGridFunction &x)
{
@@ -721,12 +723,13 @@ void VectorWaveGuide(int mode, ParGridFunction &x)
}
/**
Solves the eigenvalue problem -Div(Grad x) = lambda x with homogeneous
Neumann boundary conditions on the boundary of the domain. Returns mode
number "mode" (counting from zero) in the ParGridFunction "x_l2". Note that
mode 0 is a constant field so higher mode numbers are often more
interesting. The eigenmode is solved using continuous H1 basis of the
appropriate order and then projected onto the L2 basis and returned.
Solves the eigenvalue problem -Div(Grad x) = lambda x with
homogeneous Neumann boundary conditions on the boundary of the
domain. Returns mode number "mode" (counting from zero) in the
ParGridFunction "x_l2". Note that mode 0 is a constant field so
higher mode numbers are often more interesting. The eigenmode is
solved using continuous H1 basis of the appropriate order and then
projected onto the L2 basis and returned.
*/
void PseudoScalarWaveGuide(int mode, ParGridFunction &x_l2)
{
@@ -788,9 +791,9 @@ void PseudoScalarWaveGuide(int mode, ParGridFunction &x_l2)
delete M;
}
// Compute eigenmode "mode" of either a Dirichlet or Neumann Laplacian or of a
// Dirichlet curl curl operator based on the problem type and dimension of the
// domain.
// Compute eigenmode "mode" of either a Dirichlet or Neumann Laplacian
// or of a Dirichlet curl curl operator based on the problem type and
// dimension of the domain.
void SetPortBC(int prob, int dim, int mode, ParGridFunction &port_bc)
{
switch (prob)
+7 -3
View File
@@ -1,10 +1,12 @@
// MFEM Example 36
//
//
// Compile with: make ex36
//
// Sample runs: ex36 -o 2
// ex36 -o 2 -r 4
//
//
// Description: This example code demonstrates the use of MFEM to solve the
// bound-constrained energy minimization problem
//
@@ -26,10 +28,12 @@
// order solutions to variation inequality problems and
// showcases how to set up and solve nonlinear mixed methods.
//
//
// [1] Keith, B. and Surowiec, T. (2023) Proximal Galerkin: A structure-
// preserving finite element method for pointwise bound constraints.
// arXiv:2307.12444 [math.NA]
#include "mfem.hpp"
#include <fstream>
#include <iostream>
@@ -59,7 +63,7 @@ public:
class ExponentialGridFunctionCoefficient : public Coefficient
{
protected:
GridFunction *u;
GridFunction *u; // grid function
Coefficient *obstacle;
double min_val;
double max_val;
@@ -84,7 +88,7 @@ int main(int argc, char *argv[])
OptionsParser args(argc, argv);
args.AddOption(&order, "-o", "--order",
"Finite element order (polynomial degree).");
"Finite element order (polynomial degree)");
args.AddOption(&ref_levels, "-r", "--refs",
"Number of h-refinements.");
args.AddOption(&max_it, "-mi", "--max-it",
@@ -194,7 +198,7 @@ int main(int argc, char *argv[])
u_gf.ProjectCoefficient(IC_coef);
u_old_gf = u_gf;
// 9. Initialize the slack variable ψₕ = ln(uₕ)
// 9. Initialize the slack variable ψₕ = exp(uₕ)
LogarithmGridFunctionCoefficient ln_u(u_gf, obstacle);
psi_gf.ProjectCoefficient(ln_u);
psi_old_gf = psi_gf;
+8 -3
View File
@@ -1,10 +1,12 @@
// MFEM Example 36 - Parallel Version
// MFEM Example 36 - Parallel Version
//
//
// Compile with: make ex36p
//
// Sample runs: mpirun -np 4 ex36p -o 2
// mpirun -np 4 ex36p -o 2 -r 4
//
//
// Description: This example code demonstrates the use of MFEM to solve the
// bound-constrained energy minimization problem
//
@@ -26,10 +28,12 @@
// order solutions to variation inequality problems and
// showcases how to set up and solve nonlinear mixed methods.
//
//
// [1] Keith, B. and Surowiec, T. (2023) Proximal Galerkin: A structure-
// preserving finite element method for pointwise bound constraints.
// arXiv:2307.12444 [math.NA]
#include "mfem.hpp"
#include <fstream>
#include <iostream>
@@ -59,7 +63,7 @@ public:
class ExponentialGridFunctionCoefficient : public Coefficient
{
protected:
GridFunction *u;
GridFunction *u; // grid function
Coefficient *obstacle;
double min_val;
double max_val;
@@ -216,6 +220,7 @@ int main(int argc, char *argv[])
u_old_gf = 0.0;
psi_old_gf = 0.0;
// 8. Define the function coefficients for the solution and use them to
// initialize the initial guess
FunctionCoefficient exact_coef(exact_solution_obstacle);
@@ -226,7 +231,7 @@ int main(int argc, char *argv[])
u_gf.ProjectCoefficient(IC_coef);
u_old_gf = u_gf;
// 9. Initialize the slack variable ψₕ = ln(uₕ)
// 9. Initialize the slack variable ψₕ = exp(uₕ)
LogarithmGridFunctionCoefficient ln_u(u_gf, obstacle);
psi_gf.ProjectCoefficient(ln_u);
psi_old_gf = psi_gf;
-466
View File
@@ -1,466 +0,0 @@
// MFEM Example 37
//
// Compile with: make ex37
//
// Sample runs:
// ex37 -alpha 10
// ex37 -alpha 10 -pv
// ex37 -lambda 0.1 -mu 0.1
// ex37 -o 2 -alpha 5.0 -mi 50 -vf 0.4 -ntol 1e-5
// ex37 -r 6 -o 1 -alpha 25.0 -epsilon 0.02 -mi 50 -ntol 1e-5
//
// Description: This example code demonstrates the use of MFEM to solve a
// density-filtered [3] topology optimization problem. The
// objective is to minimize the compliance
//
// minimize ∫_Ω f⋅u dx over u ∈ [H¹(Ω)]² and ρ ∈ L¹(Ω)
//
// subject to
//
// -Div(r(ρ̃)Cε(u)) = f in Ω + BCs
// -ϵ²Δρ̃ + ρ̃ = ρ in Ω + Neumann BCs
// 0 ≤ ρ ≤ 1 in Ω
// ∫_Ω ρ dx = θ vol(Ω)
//
// Here, r(ρ̃) = ρ₀ + ρ̃³ (1-ρ₀) is the solid isotropic material
// penalization (SIMP) law, C is the elasticity tensor for an
// isotropic linearly elastic material, ϵ > 0 is the design
// length scale, and 0 < θ < 1 is the volume fraction.
//
// The problem is discretized and gradients are computing using
// finite elements [1]. The design is optimized using an entropic
// mirror descent algorithm introduced by Keith and Surowiec [2]
// that is tailored to the bound constraint 0 ≤ ρ ≤ 1.
//
// This example highlights the ability of MFEM to deliver high-
// order solutions to inverse design problems and showcases how
// to set up and solve PDE-constrained optimization problems
// using the so-called reduced space approach.
//
// [1] Andreassen, E., Clausen, A., Schevenels, M., Lazarov, B. S., & Sigmund, O.
// (2011). Efficient topology optimization in MATLAB using 88 lines of
// code. Structural and Multidisciplinary Optimization, 43(1), 1-16.
// [2] Keith, B. and Surowiec, T. (2023) Proximal Galerkin: A structure-
// preserving finite element method for pointwise bound constraints.
// arXiv:2307.12444 [math.NA]
// [3] Lazarov, B. S., & Sigmund, O. (2011). Filters in topology optimization
// based on Helmholtztype differential equations. International Journal
// for Numerical Methods in Engineering, 86(6), 765-781.
#include "mfem.hpp"
#include <iostream>
#include <fstream>
#include "ex37.hpp"
using namespace std;
using namespace mfem;
/**
* @brief Bregman projection of ρ = sigmoid(ψ) onto the subspace
* ∫_Ω ρ dx = θ vol(Ω) as follows:
*
* 1. Compute the root of the R → R function
* f(c) = ∫_Ω sigmoid(ψ + c) dx - θ vol(Ω)
* 2. Set ψ ← ψ + c.
*
* @param psi a GridFunction to be updated
* @param target_volume θ vol(Ω)
* @param tol Newton iteration tolerance
* @param max_its Newton maximum iteration number
* @return double Final volume, ∫_Ω sigmoid(ψ)
*/
double proj(GridFunction &psi, double target_volume, double tol=1e-12,
int max_its=10)
{
MappedGridFunctionCoefficient sigmoid_psi(&psi, sigmoid);
MappedGridFunctionCoefficient der_sigmoid_psi(&psi, der_sigmoid);
LinearForm int_sigmoid_psi(psi.FESpace());
int_sigmoid_psi.AddDomainIntegrator(new DomainLFIntegrator(sigmoid_psi));
LinearForm int_der_sigmoid_psi(psi.FESpace());
int_der_sigmoid_psi.AddDomainIntegrator(new DomainLFIntegrator(
der_sigmoid_psi));
bool done = false;
for (int k=0; k<max_its; k++) // Newton iteration
{
int_sigmoid_psi.Assemble(); // Recompute f(c) with updated ψ
const double f = int_sigmoid_psi.Sum() - target_volume;
int_der_sigmoid_psi.Assemble(); // Recompute df(c) with updated ψ
const double df = int_der_sigmoid_psi.Sum();
const double dc = -f/df;
psi += dc;
if (abs(dc) < tol) { done = true; break; }
}
if (!done)
{
mfem_warning("Projection reached maximum iteration without converging. "
"Result may not be accurate.");
}
int_sigmoid_psi.Assemble();
return int_sigmoid_psi.Sum();
}
/**
* ---------------------------------------------------------------
* ALGORITHM PREAMBLE
* ---------------------------------------------------------------
*
* The Lagrangian for this problem is
*
* L(u,ρ,ρ̃,w,w̃) = (f,u) - (r(ρ̃) C ε(u),ε(w)) + (f,w)
* - (ϵ² ∇ρ̃,∇w̃) - (ρ̃,w̃) + (ρ,w̃)
*
* where
*
* r(ρ̃) = ρ₀ + ρ̃³ (1 - ρ₀) (SIMP rule)
*
* ε(u) = (∇u + ∇uᵀ)/2 (symmetric gradient)
*
* C e = λtr(e)I + 2μe (isotropic material)
*
* NOTE: The Lame parameters can be computed from Young's modulus E
* and Poisson's ratio ν as follows:
*
* λ = E ν/((1+ν)(1-2ν)), μ = E/(2(1+ν))
*
* ---------------------------------------------------------------
*
* Discretization choices:
*
* u ∈ V ⊂ (H¹)ᵈ (order p)
* ψ ∈ L² (order p - 1), ρ = sigmoid(ψ)
* ρ̃ ∈ H¹ (order p)
* w ∈ V (order p)
* w̃ ∈ H¹ (order p)
*
* ---------------------------------------------------------------
* ALGORITHM
* ---------------------------------------------------------------
*
* Update ρ with projected mirror descent via the following algorithm.
*
* 1. Initialize ψ = inv_sigmoid(vol_fraction) so that ∫ sigmoid(ψ) = θ vol(Ω)
*
* While not converged:
*
* 2. Solve filter equation ∂_w̃ L = 0; i.e.,
*
* (ϵ² ∇ ρ̃, ∇ v ) + (ρ̃,v) = (ρ,v) ∀ v ∈ H¹.
*
* 3. Solve primal problem ∂_w L = 0; i.e.,
*
* (λ r(ρ̃) ∇⋅u, ∇⋅v) + (2 μ r(ρ̃) ε(u), ε(v)) = (f,v) ∀ v ∈ V.
*
* NB. The dual problem ∂_u L = 0 is the negative of the primal problem due to symmetry.
*
* 4. Solve for filtered gradient ∂_ρ̃ L = 0; i.e.,
*
* (ϵ² ∇ w̃ , ∇ v ) + (w̃ ,v) = (-r'(ρ̃) ( λ |∇⋅u|² + 2 μ |ε(u)|²),v) ∀ v ∈ H¹.
*
* 5. Project the gradient onto the discrete latent space; i.e., solve
*
* (G,v) = (w̃,v) ∀ v ∈ L².
*
* 6. Bregman proximal gradient update; i.e.,
*
* ψ ← ψ - αG + c,
*
* where α > 0 is a step size parameter and c ∈ R is a constant ensuring
*
* ∫_Ω sigmoid(ψ - αG + c) dx = θ vol(Ω).
*
* end
*/
int main(int argc, char *argv[])
{
// 1. Parse command-line options.
int ref_levels = 5;
int order = 2;
double alpha = 1.0;
double epsilon = 0.01;
double vol_fraction = 0.5;
int max_it = 1e3;
double itol = 1e-1;
double ntol = 1e-4;
double rho_min = 1e-6;
double lambda = 1.0;
double mu = 1.0;
bool glvis_visualization = true;
bool paraview_output = false;
OptionsParser args(argc, argv);
args.AddOption(&ref_levels, "-r", "--refine",
"Number of times to refine the mesh uniformly.");
args.AddOption(&order, "-o", "--order",
"Order (degree) of the finite elements.");
args.AddOption(&alpha, "-alpha", "--alpha-step-length",
"Step length for gradient descent.");
args.AddOption(&epsilon, "-epsilon", "--epsilon-thickness",
"Length scale for ρ.");
args.AddOption(&max_it, "-mi", "--max-it",
"Maximum number of gradient descent iterations.");
args.AddOption(&ntol, "-ntol", "--rel-tol",
"Normalized exit tolerance.");
args.AddOption(&itol, "-itol", "--abs-tol",
"Increment exit tolerance.");
args.AddOption(&vol_fraction, "-vf", "--volume-fraction",
"Volume fraction for the material density.");
args.AddOption(&lambda, "-lambda", "--lambda",
"Lamé constant λ.");
args.AddOption(&mu, "-mu", "--mu",
"Lamé constant μ.");
args.AddOption(&rho_min, "-rmin", "--psi-min",
"Minimum of density coefficient.");
args.AddOption(&glvis_visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.AddOption(&paraview_output, "-pv", "--paraview", "-no-pv",
"--no-paraview",
"Enable or disable ParaView output.");
args.Parse();
if (!args.Good())
{
args.PrintUsage(mfem::out);
return 1;
}
args.PrintOptions(mfem::out);
Mesh mesh = Mesh::MakeCartesian2D(3, 1, mfem::Element::Type::QUADRILATERAL,
true, 3.0, 1.0);
int dim = mesh.Dimension();
// 2. Set BCs.
for (int i = 0; i<mesh.GetNBE(); i++)
{
Element * be = mesh.GetBdrElement(i);
Array<int> vertices;
be->GetVertices(vertices);
double * coords1 = mesh.GetVertex(vertices[0]);
double * coords2 = mesh.GetVertex(vertices[1]);
Vector center(2);
center(0) = 0.5*(coords1[0] + coords2[0]);
center(1) = 0.5*(coords1[1] + coords2[1]);
if (abs(center(0) - 0.0) < 1e-10)
{
// the left edge
be->SetAttribute(1);
}
else
{
// all other boundaries
be->SetAttribute(2);
}
}
mesh.SetAttributes();
// 3. Refine the mesh.
for (int lev = 0; lev < ref_levels; lev++)
{
mesh.UniformRefinement();
}
// 4. Define the necessary finite element spaces on the mesh.
H1_FECollection state_fec(order, dim); // space for u
H1_FECollection filter_fec(order, dim); // space for ρ̃
L2_FECollection control_fec(order-1, dim,
BasisType::GaussLobatto); // space for ψ
FiniteElementSpace state_fes(&mesh, &state_fec,dim);
FiniteElementSpace filter_fes(&mesh, &filter_fec);
FiniteElementSpace control_fes(&mesh, &control_fec);
int state_size = state_fes.GetTrueVSize();
int control_size = control_fes.GetTrueVSize();
int filter_size = filter_fes.GetTrueVSize();
mfem::out << "Number of state unknowns: " << state_size << std::endl;
mfem::out << "Number of filter unknowns: " << filter_size << std::endl;
mfem::out << "Number of control unknowns: " << control_size << std::endl;
// 5. Set the initial guess for ρ.
GridFunction u(&state_fes);
GridFunction psi(&control_fes);
GridFunction psi_old(&control_fes);
GridFunction rho_filter(&filter_fes);
u = 0.0;
rho_filter = vol_fraction;
psi = inv_sigmoid(vol_fraction);
psi_old = inv_sigmoid(vol_fraction);
// ρ = sigmoid(ψ)
MappedGridFunctionCoefficient rho(&psi, sigmoid);
// Interpolation of ρ = sigmoid(ψ) in control fes (for ParaView output)
GridFunction rho_gf(&control_fes);
// ρ - ρ_old = sigmoid(ψ) - sigmoid(ψ_old)
DiffMappedGridFunctionCoefficient succ_diff_rho(&psi, &psi_old, sigmoid);
// 6. Set-up the physics solver.
int maxat = mesh.bdr_attributes.Max();
Array<int> ess_bdr(maxat);
ess_bdr = 0;
ess_bdr[0] = 1;
ConstantCoefficient one(1.0);
ConstantCoefficient lambda_cf(lambda);
ConstantCoefficient mu_cf(mu);
LinearElasticitySolver * ElasticitySolver = new LinearElasticitySolver();
ElasticitySolver->SetMesh(&mesh);
ElasticitySolver->SetOrder(state_fec.GetOrder());
ElasticitySolver->SetupFEM();
Vector center(2); center(0) = 2.9; center(1) = 0.5;
Vector force(2); force(0) = 0.0; force(1) = -1.0;
double r = 0.05;
VolumeForceCoefficient vforce_cf(r,center,force);
ElasticitySolver->SetRHSCoefficient(&vforce_cf);
ElasticitySolver->SetEssentialBoundary(ess_bdr);
// 7. Set-up the filter solver.
ConstantCoefficient eps2_cf(epsilon*epsilon);
DiffusionSolver * FilterSolver = new DiffusionSolver();
FilterSolver->SetMesh(&mesh);
FilterSolver->SetOrder(filter_fec.GetOrder());
FilterSolver->SetDiffusionCoefficient(&eps2_cf);
FilterSolver->SetMassCoefficient(&one);
Array<int> ess_bdr_filter;
if (mesh.bdr_attributes.Size())
{
ess_bdr_filter.SetSize(mesh.bdr_attributes.Max());
ess_bdr_filter = 0;
}
FilterSolver->SetEssentialBoundary(ess_bdr_filter);
FilterSolver->SetupFEM();
BilinearForm mass(&control_fes);
mass.AddDomainIntegrator(new InverseIntegrator(new MassIntegrator(one)));
mass.Assemble();
SparseMatrix M;
Array<int> empty;
mass.FormSystemMatrix(empty,M);
// 8. Define the Lagrange multiplier and gradient functions.
GridFunction grad(&control_fes);
GridFunction w_filter(&filter_fes);
// 9. Define some tools for later.
ConstantCoefficient zero(0.0);
GridFunction onegf(&control_fes);
onegf = 1.0;
GridFunction zerogf(&control_fes);
zerogf = 0.0;
LinearForm vol_form(&control_fes);
vol_form.AddDomainIntegrator(new DomainLFIntegrator(one));
vol_form.Assemble();
double domain_volume = vol_form(onegf);
const double target_volume = domain_volume * vol_fraction;
// 10. Connect to GLVis. Prepare for VisIt output.
char vishost[] = "localhost";
int visport = 19916;
socketstream sout_r;
if (glvis_visualization)
{
sout_r.open(vishost, visport);
sout_r.precision(8);
}
mfem::ParaViewDataCollection paraview_dc("ex37", &mesh);
if (paraview_output)
{
rho_gf.ProjectCoefficient(rho);
paraview_dc.SetPrefixPath("ParaView");
paraview_dc.SetLevelsOfDetail(order);
paraview_dc.SetDataFormat(VTKFormat::BINARY);
paraview_dc.SetHighOrderOutput(true);
paraview_dc.SetCycle(0);
paraview_dc.SetTime(0.0);
paraview_dc.RegisterField("displacement",&u);
paraview_dc.RegisterField("density",&rho_gf);
paraview_dc.RegisterField("filtered_density",&rho_filter);
paraview_dc.Save();
}
// 11. Iterate:
for (int k = 1; k <= max_it; k++)
{
if (k > 1) { alpha *= ((double) k) / ((double) k-1); }
mfem::out << "\nStep = " << k << std::endl;
// Step 1 - Filter solve
// Solve (ϵ^2 ∇ ρ̃, ∇ v ) + (ρ̃,v) = (ρ,v)
FilterSolver->SetRHSCoefficient(&rho);
FilterSolver->Solve();
rho_filter = *FilterSolver->GetFEMSolution();
// Step 2 - State solve
// Solve (λ r(ρ̃) ∇⋅u, ∇⋅v) + (2 μ r(ρ̃) ε(u), ε(v)) = (f,v)
SIMPInterpolationCoefficient SIMP_cf(&rho_filter,rho_min, 1.0);
ProductCoefficient lambda_SIMP_cf(lambda_cf,SIMP_cf);
ProductCoefficient mu_SIMP_cf(mu_cf,SIMP_cf);
ElasticitySolver->SetLameCoefficients(&lambda_SIMP_cf,&mu_SIMP_cf);
ElasticitySolver->Solve();
u = *ElasticitySolver->GetFEMSolution();
// Step 3 - Adjoint filter solve
// Solve (ϵ² ∇ w̃, ∇ v) + (w̃ ,v) = (-r'(ρ̃) ( λ |∇⋅u|² + 2 μ |ε(u)|²),v)
StrainEnergyDensityCoefficient rhs_cf(&lambda_cf,&mu_cf,&u, &rho_filter,
rho_min);
FilterSolver->SetRHSCoefficient(&rhs_cf);
FilterSolver->Solve();
w_filter = *FilterSolver->GetFEMSolution();
// Step 4 - Compute gradient
// Solve G = M⁻¹w̃
GridFunctionCoefficient w_cf(&w_filter);
LinearForm w_rhs(&control_fes);
w_rhs.AddDomainIntegrator(new DomainLFIntegrator(w_cf));
w_rhs.Assemble();
M.Mult(w_rhs,grad);
// Step 5 - Update design variable ψ ← proj(ψ - αG)
psi.Add(-alpha, grad);
const double material_volume = proj(psi, target_volume);
// Compute ||ρ - ρ_old|| in control fes.
double norm_increment = zerogf.ComputeL1Error(succ_diff_rho);
double norm_reduced_gradient = norm_increment/alpha;
psi_old = psi;
double compliance = (*(ElasticitySolver->GetLinearForm()))(u);
mfem::out << "norm of the reduced gradient = " << norm_reduced_gradient <<
std::endl;
mfem::out << "norm of the increment = " << norm_increment << endl;
mfem::out << "compliance = " << compliance << std::endl;
mfem::out << "volume fraction = " << material_volume / domain_volume <<
std::endl;
if (glvis_visualization)
{
GridFunction r_gf(&filter_fes);
r_gf.ProjectCoefficient(SIMP_cf);
sout_r << "solution\n" << mesh << r_gf
<< "window_title 'Design density r(ρ̃)'" << flush;
}
if (paraview_output)
{
rho_gf.ProjectCoefficient(rho);
paraview_dc.SetCycle(k);
paraview_dc.SetTime((double)k);
paraview_dc.Save();
}
if (norm_reduced_gradient < ntol && norm_increment < itol)
{
break;
}
}
delete ElasticitySolver;
delete FilterSolver;
return 0;
}
-748
View File
@@ -1,748 +0,0 @@
// MFEM Example 37 - Serial/Parallel Shared Code
#include "mfem.hpp"
#include <fstream>
#include <iostream>
#include <functional>
namespace mfem
{
/// @brief Inverse sigmoid function
double inv_sigmoid(double x)
{
double tol = 1e-12;
x = std::min(std::max(tol,x),1.0-tol);
return std::log(x/(1.0-x));
}
/// @brief Sigmoid function
double sigmoid(double x)
{
if (x >= 0)
{
return 1.0/(1.0+std::exp(-x));
}
else
{
return std::exp(x)/(1.0+std::exp(x));
}
}
/// @brief Derivative of sigmoid function
double der_sigmoid(double x)
{
double tmp = sigmoid(-x);
return tmp - std::pow(tmp,2);
}
/// @brief Returns f(u(x)) where u is a scalar GridFunction and f:R → R
class MappedGridFunctionCoefficient : public GridFunctionCoefficient
{
protected:
std::function<double(const double)> fun; // f:R → R
public:
MappedGridFunctionCoefficient()
:GridFunctionCoefficient(),
fun([](double x) {return x;}) {}
MappedGridFunctionCoefficient(const GridFunction *gf,
std::function<double(const double)> fun_,
int comp=1)
:GridFunctionCoefficient(gf, comp),
fun(fun_) {}
virtual double Eval(ElementTransformation &T,
const IntegrationPoint &ip)
{
return fun(GridFunctionCoefficient::Eval(T, ip));
}
void SetFunction(std::function<double(const double)> fun_) { fun = fun_; }
};
/// @brief Returns f(u(x)) - f(v(x)) where u, v are scalar GridFunctions and f:R → R
class DiffMappedGridFunctionCoefficient : public GridFunctionCoefficient
{
protected:
const GridFunction *OtherGridF;
GridFunctionCoefficient OtherGridF_cf;
std::function<double(const double)> fun; // f:R → R
public:
DiffMappedGridFunctionCoefficient()
:GridFunctionCoefficient(),
OtherGridF(nullptr),
OtherGridF_cf(),
fun([](double x) {return x;}) {}
DiffMappedGridFunctionCoefficient(const GridFunction *gf,
const GridFunction *other_gf,
std::function<double(const double)> fun_,
int comp=1)
:GridFunctionCoefficient(gf, comp),
OtherGridF(other_gf),
OtherGridF_cf(OtherGridF),
fun(fun_) {}
virtual double Eval(ElementTransformation &T,
const IntegrationPoint &ip)
{
const double value1 = fun(GridFunctionCoefficient::Eval(T, ip));
const double value2 = fun(OtherGridF_cf.Eval(T, ip));
return value1 - value2;
}
void SetFunction(std::function<double(const double)> fun_) { fun = fun_; }
};
/// @brief Solid isotropic material penalization (SIMP) coefficient
class SIMPInterpolationCoefficient : public Coefficient
{
protected:
GridFunction *rho_filter;
double min_val;
double max_val;
double exponent;
public:
SIMPInterpolationCoefficient(GridFunction *rho_filter_, double min_val_= 1e-6,
double max_val_ = 1.0, double exponent_ = 3)
: rho_filter(rho_filter_), min_val(min_val_), max_val(max_val_),
exponent(exponent_) { }
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip)
{
double val = rho_filter->GetValue(T, ip);
double coeff = min_val + pow(val,exponent)*(max_val-min_val);
return coeff;
}
};
/// @brief Strain energy density coefficient
class StrainEnergyDensityCoefficient : public Coefficient
{
protected:
Coefficient * lambda=nullptr;
Coefficient * mu=nullptr;
GridFunction *u = nullptr; // displacement
GridFunction *rho_filter = nullptr; // filter density
DenseMatrix grad; // auxiliary matrix, used in Eval
double exponent;
double rho_min;
public:
StrainEnergyDensityCoefficient(Coefficient *lambda_, Coefficient *mu_,
GridFunction * u_, GridFunction * rho_filter_, double rho_min_=1e-6,
double exponent_ = 3.0)
: lambda(lambda_), mu(mu_), u(u_), rho_filter(rho_filter_),
exponent(exponent_), rho_min(rho_min_)
{
MFEM_ASSERT(rho_min_ >= 0.0, "rho_min must be >= 0");
MFEM_ASSERT(rho_min_ < 1.0, "rho_min must be > 1");
MFEM_ASSERT(u, "displacement field is not set");
MFEM_ASSERT(rho_filter, "density field is not set");
}
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip)
{
double L = lambda->Eval(T, ip);
double M = mu->Eval(T, ip);
u->GetVectorGradient(T, grad);
double div_u = grad.Trace();
double density = L*div_u*div_u;
int dim = T.GetSpaceDim();
for (int i=0; i<dim; i++)
{
for (int j=0; j<dim; j++)
{
density += M*grad(i,j)*(grad(i,j)+grad(j,i));
}
}
double val = rho_filter->GetValue(T,ip);
return -exponent * pow(val, exponent-1.0) * (1-rho_min) * density;
}
};
/// @brief Volumetric force for linear elasticity
class VolumeForceCoefficient : public VectorCoefficient
{
private:
double r;
Vector center;
Vector force;
public:
VolumeForceCoefficient(double r_,Vector & center_, Vector & force_) :
VectorCoefficient(center_.Size()), r(r_), center(center_), force(force_) { }
using VectorCoefficient::Eval;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip)
{
Vector xx; xx.SetSize(T.GetDimension());
T.Transform(ip,xx);
for (int i=0; i<xx.Size(); i++)
{
xx[i]=xx[i]-center[i];
}
double cr=xx.Norml2();
V.SetSize(T.GetDimension());
if (cr <= r)
{
V = force;
}
else
{
V = 0.0;
}
}
void Set(double r_,Vector & center_, Vector & force_)
{
r=r_;
center = center_;
force = force_;
}
};
/**
* @brief Class for solving Poisson's equation:
*
* - ∇ ⋅(κ ∇ u) = f in Ω
*
*/
class DiffusionSolver
{
private:
Mesh * mesh = nullptr;
int order = 1;
// diffusion coefficient
Coefficient * diffcf = nullptr;
// mass coefficient
Coefficient * masscf = nullptr;
Coefficient * rhscf = nullptr;
Coefficient * essbdr_cf = nullptr;
Coefficient * neumann_cf = nullptr;
VectorCoefficient * gradient_cf = nullptr;
// FEM solver
int dim;
FiniteElementCollection * fec = nullptr;
FiniteElementSpace * fes = nullptr;
Array<int> ess_bdr;
Array<int> neumann_bdr;
GridFunction * u = nullptr;
LinearForm * b = nullptr;
bool parallel;
#ifdef MFEM_USE_MPI
ParMesh * pmesh = nullptr;
ParFiniteElementSpace * pfes = nullptr;
#endif
public:
DiffusionSolver() { }
DiffusionSolver(Mesh * mesh_, int order_, Coefficient * diffcf_,
Coefficient * cf_);
void SetMesh(Mesh * mesh_)
{
mesh = mesh_;
parallel = false;
#ifdef MFEM_USE_MPI
pmesh = dynamic_cast<ParMesh *>(mesh);
if (pmesh) { parallel = true; }
#endif
}
void SetOrder(int order_) { order = order_ ; }
void SetDiffusionCoefficient(Coefficient * diffcf_) { diffcf = diffcf_; }
void SetMassCoefficient(Coefficient * masscf_) { masscf = masscf_; }
void SetRHSCoefficient(Coefficient * rhscf_) { rhscf = rhscf_; }
void SetEssentialBoundary(const Array<int> & ess_bdr_) { ess_bdr = ess_bdr_;};
void SetNeumannBoundary(const Array<int> & neumann_bdr_) { neumann_bdr = neumann_bdr_;};
void SetNeumannData(Coefficient * neumann_cf_) {neumann_cf = neumann_cf_;}
void SetEssBdrData(Coefficient * essbdr_cf_) {essbdr_cf = essbdr_cf_;}
void SetGradientData(VectorCoefficient * gradient_cf_) {gradient_cf = gradient_cf_;}
void ResetFEM();
void SetupFEM();
void Solve();
GridFunction * GetFEMSolution();
LinearForm * GetLinearForm() {return b;}
#ifdef MFEM_USE_MPI
ParGridFunction * GetParFEMSolution();
ParLinearForm * GetParLinearForm()
{
if (parallel)
{
return dynamic_cast<ParLinearForm *>(b);
}
else
{
MFEM_ABORT("Wrong code path. Call GetLinearForm");
return nullptr;
}
}
#endif
~DiffusionSolver();
};
/**
* @brief Class for solving linear elasticity:
*
* -∇ ⋅ σ(u) = f in Ω + BCs
*
* where
*
* σ(u) = λ ∇⋅u I + μ (∇ u + ∇uᵀ)
*
*/
class LinearElasticitySolver
{
private:
Mesh * mesh = nullptr;
int order = 1;
Coefficient * lambda_cf = nullptr;
Coefficient * mu_cf = nullptr;
VectorCoefficient * essbdr_cf = nullptr;
VectorCoefficient * rhs_cf = nullptr;
// FEM solver
int dim;
FiniteElementCollection * fec = nullptr;
FiniteElementSpace * fes = nullptr;
Array<int> ess_bdr;
Array<int> neumann_bdr;
GridFunction * u = nullptr;
LinearForm * b = nullptr;
bool parallel;
#ifdef MFEM_USE_MPI
ParMesh * pmesh = nullptr;
ParFiniteElementSpace * pfes = nullptr;
#endif
public:
LinearElasticitySolver() { }
LinearElasticitySolver(Mesh * mesh_, int order_,
Coefficient * lambda_cf_, Coefficient * mu_cf_);
void SetMesh(Mesh * mesh_)
{
mesh = mesh_;
parallel = false;
#ifdef MFEM_USE_MPI
pmesh = dynamic_cast<ParMesh *>(mesh);
if (pmesh) { parallel = true; }
#endif
}
void SetOrder(int order_) { order = order_ ; }
void SetLameCoefficients(Coefficient * lambda_cf_, Coefficient * mu_cf_) { lambda_cf = lambda_cf_; mu_cf = mu_cf_; }
void SetRHSCoefficient(VectorCoefficient * rhs_cf_) { rhs_cf = rhs_cf_; }
void SetEssentialBoundary(const Array<int> & ess_bdr_) { ess_bdr = ess_bdr_;};
void SetNeumannBoundary(const Array<int> & neumann_bdr_) { neumann_bdr = neumann_bdr_;};
void SetEssBdrData(VectorCoefficient * essbdr_cf_) {essbdr_cf = essbdr_cf_;}
void ResetFEM();
void SetupFEM();
void Solve();
GridFunction * GetFEMSolution();
LinearForm * GetLinearForm() {return b;}
#ifdef MFEM_USE_MPI
ParGridFunction * GetParFEMSolution();
ParLinearForm * GetParLinearForm()
{
if (parallel)
{
return dynamic_cast<ParLinearForm *>(b);
}
else
{
MFEM_ABORT("Wrong code path. Call GetLinearForm");
return nullptr;
}
}
#endif
~LinearElasticitySolver();
};
// Poisson solver
DiffusionSolver::DiffusionSolver(Mesh * mesh_, int order_,
Coefficient * diffcf_, Coefficient * rhscf_)
: mesh(mesh_), order(order_), diffcf(diffcf_), rhscf(rhscf_)
{
#ifdef MFEM_USE_MPI
pmesh = dynamic_cast<ParMesh *>(mesh);
if (pmesh) { parallel = true; }
#endif
SetupFEM();
}
void DiffusionSolver::SetupFEM()
{
dim = mesh->Dimension();
fec = new H1_FECollection(order, dim);
#ifdef MFEM_USE_MPI
if (parallel)
{
pfes = new ParFiniteElementSpace(pmesh, fec);
u = new ParGridFunction(pfes);
b = new ParLinearForm(pfes);
}
else
{
fes = new FiniteElementSpace(mesh, fec);
u = new GridFunction(fes);
b = new LinearForm(fes);
}
#else
fes = new FiniteElementSpace(mesh, fec);
u = new GridFunction(fes);
b = new LinearForm(fes);
#endif
*u=0.0;
if (!ess_bdr.Size())
{
if (mesh->bdr_attributes.Size())
{
ess_bdr.SetSize(mesh->bdr_attributes.Max());
ess_bdr = 1;
}
}
}
void DiffusionSolver::Solve()
{
OperatorPtr A;
Vector B, X;
Array<int> ess_tdof_list;
#ifdef MFEM_USE_MPI
if (parallel)
{
pfes->GetEssentialTrueDofs(ess_bdr,ess_tdof_list);
}
else
{
fes->GetEssentialTrueDofs(ess_bdr,ess_tdof_list);
}
#else
fes->GetEssentialTrueDofs(ess_bdr,ess_tdof_list);
#endif
*u=0.0;
if (b)
{
delete b;
#ifdef MFEM_USE_MPI
if (parallel)
{
b = new ParLinearForm(pfes);
}
else
{
b = new LinearForm(fes);
}
#else
b = new LinearForm(fes);
#endif
}
if (rhscf)
{
b->AddDomainIntegrator(new DomainLFIntegrator(*rhscf));
}
if (neumann_cf)
{
MFEM_VERIFY(neumann_bdr.Size(), "neumann_bdr attributes not provided");
b->AddBoundaryIntegrator(new BoundaryLFIntegrator(*neumann_cf),neumann_bdr);
}
else if (gradient_cf)
{
MFEM_VERIFY(neumann_bdr.Size(), "neumann_bdr attributes not provided");
b->AddBoundaryIntegrator(new BoundaryNormalLFIntegrator(*gradient_cf),
neumann_bdr);
}
b->Assemble();
BilinearForm * a = nullptr;
#ifdef MFEM_USE_MPI
if (parallel)
{
a = new ParBilinearForm(pfes);
}
else
{
a = new BilinearForm(fes);
}
#else
a = new BilinearForm(fes);
#endif
a->AddDomainIntegrator(new DiffusionIntegrator(*diffcf));
if (masscf)
{
a->AddDomainIntegrator(new MassIntegrator(*masscf));
}
a->Assemble();
if (essbdr_cf)
{
u->ProjectBdrCoefficient(*essbdr_cf,ess_bdr);
}
a->FormLinearSystem(ess_tdof_list, *u, *b, A, X, B);
CGSolver * cg = nullptr;
Solver * M = nullptr;
#ifdef MFEM_USE_MPI
if (parallel)
{
M = new HypreBoomerAMG;
dynamic_cast<HypreBoomerAMG*>(M)->SetPrintLevel(0);
cg = new CGSolver(pmesh->GetComm());
}
else
{
M = new GSSmoother((SparseMatrix&)(*A));
cg = new CGSolver;
}
#else
M = new GSSmoother((SparseMatrix&)(*A));
cg = new CGSolver;
#endif
cg->SetRelTol(1e-12);
cg->SetMaxIter(10000);
cg->SetPrintLevel(0);
cg->SetPreconditioner(*M);
cg->SetOperator(*A);
cg->Mult(B, X);
delete M;
delete cg;
a->RecoverFEMSolution(X, *b, *u);
delete a;
}
GridFunction * DiffusionSolver::GetFEMSolution()
{
return u;
}
#ifdef MFEM_USE_MPI
ParGridFunction * DiffusionSolver::GetParFEMSolution()
{
if (parallel)
{
return dynamic_cast<ParGridFunction*>(u);
}
else
{
MFEM_ABORT("Wrong code path. Call GetFEMSolution");
return nullptr;
}
}
#endif
DiffusionSolver::~DiffusionSolver()
{
delete u; u = nullptr;
delete fes; fes = nullptr;
#ifdef MFEM_USE_MPI
delete pfes; pfes=nullptr;
#endif
delete fec; fec = nullptr;
delete b;
}
// Elasticity solver
LinearElasticitySolver::LinearElasticitySolver(Mesh * mesh_, int order_,
Coefficient * lambda_cf_, Coefficient * mu_cf_)
: mesh(mesh_), order(order_), lambda_cf(lambda_cf_), mu_cf(mu_cf_)
{
#ifdef MFEM_USE_MPI
pmesh = dynamic_cast<ParMesh *>(mesh);
if (pmesh) { parallel = true; }
#endif
SetupFEM();
}
void LinearElasticitySolver::SetupFEM()
{
dim = mesh->Dimension();
fec = new H1_FECollection(order, dim,BasisType::Positive);
#ifdef MFEM_USE_MPI
if (parallel)
{
pfes = new ParFiniteElementSpace(pmesh, fec, dim);
u = new ParGridFunction(pfes);
b = new ParLinearForm(pfes);
}
else
{
fes = new FiniteElementSpace(mesh, fec,dim);
u = new GridFunction(fes);
b = new LinearForm(fes);
}
#else
fes = new FiniteElementSpace(mesh, fec, dim);
u = new GridFunction(fes);
b = new LinearForm(fes);
#endif
*u=0.0;
if (!ess_bdr.Size())
{
if (mesh->bdr_attributes.Size())
{
ess_bdr.SetSize(mesh->bdr_attributes.Max());
ess_bdr = 1;
}
}
}
void LinearElasticitySolver::Solve()
{
GridFunction * x = nullptr;
OperatorPtr A;
Vector B, X;
Array<int> ess_tdof_list;
#ifdef MFEM_USE_MPI
if (parallel)
{
x = new ParGridFunction(pfes);
pfes->GetEssentialTrueDofs(ess_bdr,ess_tdof_list);
}
else
{
x = new GridFunction(fes);
fes->GetEssentialTrueDofs(ess_bdr,ess_tdof_list);
}
#else
x = new GridFunction(fes);
fes->GetEssentialTrueDofs(ess_bdr,ess_tdof_list);
#endif
*u=0.0;
if (b)
{
delete b;
#ifdef MFEM_USE_MPI
if (parallel)
{
b = new ParLinearForm(pfes);
}
else
{
b = new LinearForm(fes);
}
#else
b = new LinearForm(fes);
#endif
}
if (rhs_cf)
{
b->AddDomainIntegrator(new VectorDomainLFIntegrator(*rhs_cf));
}
b->Assemble();
*x = 0.0;
BilinearForm * a = nullptr;
#ifdef MFEM_USE_MPI
if (parallel)
{
a = new ParBilinearForm(pfes);
}
else
{
a = new BilinearForm(fes);
}
#else
a = new BilinearForm(fes);
#endif
a->AddDomainIntegrator(new ElasticityIntegrator(*lambda_cf, *mu_cf));
a->Assemble();
if (essbdr_cf)
{
u->ProjectBdrCoefficient(*essbdr_cf,ess_bdr);
}
a->FormLinearSystem(ess_tdof_list, *x, *b, A, X, B);
CGSolver * cg = nullptr;
Solver * M = nullptr;
#ifdef MFEM_USE_MPI
if (parallel)
{
M = new HypreBoomerAMG;
dynamic_cast<HypreBoomerAMG*>(M)->SetPrintLevel(0);
cg = new CGSolver(pmesh->GetComm());
}
else
{
M = new GSSmoother((SparseMatrix&)(*A));
cg = new CGSolver;
}
#else
M = new GSSmoother((SparseMatrix&)(*A));
cg = new CGSolver;
#endif
cg->SetRelTol(1e-10);
cg->SetMaxIter(10000);
cg->SetPrintLevel(0);
cg->SetPreconditioner(*M);
cg->SetOperator(*A);
cg->Mult(B, X);
delete M;
delete cg;
a->RecoverFEMSolution(X, *b, *x);
*u+=*x;
delete a;
delete x;
}
GridFunction * LinearElasticitySolver::GetFEMSolution()
{
return u;
}
#ifdef MFEM_USE_MPI
ParGridFunction * LinearElasticitySolver::GetParFEMSolution()
{
if (parallel)
{
return dynamic_cast<ParGridFunction*>(u);
}
else
{
MFEM_ABORT("Wrong code path. Call GetFEMSolution");
return nullptr;
}
}
#endif
LinearElasticitySolver::~LinearElasticitySolver()
{
delete u; u = nullptr;
delete fes; fes = nullptr;
#ifdef MFEM_USE_MPI
delete pfes; pfes=nullptr;
#endif
delete fec; fec = nullptr;
delete b;
}
} // namespace mfem
-497
View File
@@ -1,497 +0,0 @@
// MFEM Example 37 - Parallel Version
//
// Compile with: make ex37p
//
// Sample runs:
// mpirun -np 4 ex37p -alpha 10 -pv
// mpirun -np 4 ex37p -lambda 0.1 -mu 0.1
// mpirun -np 4 ex37p -o 2 -alpha 5.0 -mi 50 -vf 0.4 -ntol 1e-5
// mpirun -np 4 ex37p -r 6 -o 2 -alpha 10.0 -epsilon 0.02 -mi 50 -ntol 1e-5
//
// Description: This example code demonstrates the use of MFEM to solve a
// density-filtered [3] topology optimization problem. The
// objective is to minimize the compliance
//
// minimize ∫_Ω f⋅u dx over u ∈ [H¹(Ω)]² and ρ ∈ L¹(Ω)
//
// subject to
//
// -Div(r(ρ̃)Cε(u)) = f in Ω + BCs
// -ϵ²Δρ̃ + ρ̃ = ρ in Ω + Neumann BCs
// 0 ≤ ρ ≤ 1 in Ω
// ∫_Ω ρ dx = θ vol(Ω)
//
// Here, r(ρ̃) = ρ₀ + ρ̃³ (1-ρ₀) is the solid isotropic material
// penalization (SIMP) law, C is the elasticity tensor for an
// isotropic linearly elastic material, ϵ > 0 is the design
// length scale, and 0 < θ < 1 is the volume fraction.
//
// The problem is discretized and gradients are computing using
// finite elements [1]. The design is optimized using an entropic
// mirror descent algorithm introduced by Keith and Surowiec [2]
// that is tailored to the bound constraint 0 ≤ ρ ≤ 1.
//
// This example highlights the ability of MFEM to deliver high-
// order solutions to inverse design problems and showcases how
// to set up and solve PDE-constrained optimization problems
// using the so-called reduced space approach.
//
// [1] Andreassen, E., Clausen, A., Schevenels, M., Lazarov, B. S., & Sigmund, O.
// (2011). Efficient topology optimization in MATLAB using 88 lines of
// code. Structural and Multidisciplinary Optimization, 43(1), 1-16.
// [2] Keith, B. and Surowiec, T. (2023) Proximal Galerkin: A structure-
// preserving finite element method for pointwise bound constraints.
// arXiv:2307.12444 [math.NA]
// [3] Lazarov, B. S., & Sigmund, O. (2011). Filters in topology optimization
// based on Helmholtztype differential equations. International Journal
// for Numerical Methods in Engineering, 86(6), 765-781.
#include "mfem.hpp"
#include <iostream>
#include <fstream>
#include "ex37.hpp"
using namespace std;
using namespace mfem;
/**
* @brief Bregman projection of ρ = sigmoid(ψ) onto the subspace
* ∫_Ω ρ dx = θ vol(Ω) as follows:
*
* 1. Compute the root of the R → R function
* f(c) = ∫_Ω sigmoid(ψ + c) dx - θ vol(Ω)
* 2. Set ψ ← ψ + c.
*
* @param psi a GridFunction to be updated
* @param target_volume θ vol(Ω)
* @param tol Newton iteration tolerance
* @param max_its Newton maximum iteration number
* @return double Final volume, ∫_Ω sigmoid(ψ)
*/
double proj(ParGridFunction &psi, double target_volume, double tol=1e-12,
int max_its=10)
{
MappedGridFunctionCoefficient sigmoid_psi(&psi, sigmoid);
MappedGridFunctionCoefficient der_sigmoid_psi(&psi, der_sigmoid);
ParLinearForm int_sigmoid_psi(psi.ParFESpace());
int_sigmoid_psi.AddDomainIntegrator(new DomainLFIntegrator(sigmoid_psi));
ParLinearForm int_der_sigmoid_psi(psi.ParFESpace());
int_der_sigmoid_psi.AddDomainIntegrator(new DomainLFIntegrator(
der_sigmoid_psi));
bool done = false;
for (int k=0; k<max_its; k++) // Newton iteration
{
int_sigmoid_psi.Assemble(); // Recompute f(c) with updated ψ
double f = int_sigmoid_psi.Sum();
MPI_Allreduce(MPI_IN_PLACE, &f, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
f -= target_volume;
int_der_sigmoid_psi.Assemble(); // Recompute df(c) with updated ψ
double df = int_der_sigmoid_psi.Sum();
MPI_Allreduce(MPI_IN_PLACE, &df, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
const double dc = -f/df;
psi += dc;
if (abs(dc) < tol) { done = true; break; }
}
if (!done)
{
mfem_warning("Projection reached maximum iteration without converging. "
"Result may not be accurate.");
}
int_sigmoid_psi.Assemble();
double material_volume = int_sigmoid_psi.Sum();
MPI_Allreduce(MPI_IN_PLACE, &material_volume, 1, MPI_DOUBLE, MPI_SUM,
MPI_COMM_WORLD);
return material_volume;
}
/**
* ---------------------------------------------------------------
* ALGORITHM PREAMBLE
* ---------------------------------------------------------------
*
* The Lagrangian for this problem is
*
* L(u,ρ,ρ̃,w,w̃) = (f,u) - (r(ρ̃) C ε(u),ε(w)) + (f,w)
* - (ϵ² ∇ρ̃,∇w̃) - (ρ̃,w̃) + (ρ,w̃)
*
* where
*
* r(ρ̃) = ρ₀ + ρ̃³ (1 - ρ₀) (SIMP rule)
*
* ε(u) = (∇u + ∇uᵀ)/2 (symmetric gradient)
*
* C e = λtr(e)I + 2μe (isotropic material)
*
* NOTE: The Lame parameters can be computed from Young's modulus E
* and Poisson's ratio ν as follows:
*
* λ = E ν/((1+ν)(1-2ν)), μ = E/(2(1+ν))
*
* ---------------------------------------------------------------
*
* Discretization choices:
*
* u ∈ V ⊂ (H¹)ᵈ (order p)
* ψ ∈ L² (order p - 1), ρ = sigmoid(ψ)
* ρ̃ ∈ H¹ (order p)
* w ∈ V (order p)
* w̃ ∈ H¹ (order p)
*
* ---------------------------------------------------------------
* ALGORITHM
* ---------------------------------------------------------------
*
* Update ρ with projected mirror descent via the following algorithm.
*
* 1. Initialize ψ = inv_sigmoid(vol_fraction) so that ∫ sigmoid(ψ) = θ vol(Ω)
*
* While not converged:
*
* 2. Solve filter equation ∂_w̃ L = 0; i.e.,
*
* (ϵ² ∇ ρ̃, ∇ v ) + (ρ̃,v) = (ρ,v) ∀ v ∈ H¹.
*
* 3. Solve primal problem ∂_w L = 0; i.e.,
*
* (λ r(ρ̃) ∇⋅u, ∇⋅v) + (2 μ r(ρ̃) ε(u), ε(v)) = (f,v) ∀ v ∈ V.
*
* NB. The dual problem ∂_u L = 0 is the negative of the primal problem due to symmetry.
*
* 4. Solve for filtered gradient ∂_ρ̃ L = 0; i.e.,
*
* (ϵ² ∇ w̃ , ∇ v ) + (w̃ ,v) = (-r'(ρ̃) ( λ |∇⋅u|² + 2 μ |ε(u)|²),v) ∀ v ∈ H¹.
*
* 5. Project the gradient onto the discrete latent space; i.e., solve
*
* (G,v) = (w̃,v) ∀ v ∈ L².
*
* 6. Bregman proximal gradient update; i.e.,
*
* ψ ← ψ - αG + c,
*
* where α > 0 is a step size parameter and c ∈ R is a constant ensuring
*
* ∫_Ω sigmoid(ψ - αG + c) dx = θ vol(Ω).
*
* end
*/
int main(int argc, char *argv[])
{
// 0. Initialize MPI and HYPRE.
Mpi::Init();
int num_procs = Mpi::WorldSize();
int myid = Mpi::WorldRank();
Hypre::Init();
// 1. Parse command-line options.
int ref_levels = 5;
int order = 2;
double alpha = 1.0;
double epsilon = 0.01;
double vol_fraction = 0.5;
int max_it = 1e3;
double itol = 1e-1;
double ntol = 1e-4;
double rho_min = 1e-6;
double lambda = 1.0;
double mu = 1.0;
bool glvis_visualization = true;
bool paraview_output = false;
OptionsParser args(argc, argv);
args.AddOption(&ref_levels, "-r", "--refine",
"Number of times to refine the mesh uniformly.");
args.AddOption(&order, "-o", "--order",
"Order (degree) of the finite elements.");
args.AddOption(&alpha, "-alpha", "--alpha-step-length",
"Step length for gradient descent.");
args.AddOption(&epsilon, "-epsilon", "--epsilon-thickness",
"Length scale for ρ.");
args.AddOption(&max_it, "-mi", "--max-it",
"Maximum number of gradient descent iterations.");
args.AddOption(&ntol, "-ntol", "--rel-tol",
"Normalized exit tolerance.");
args.AddOption(&itol, "-itol", "--abs-tol",
"Increment exit tolerance.");
args.AddOption(&vol_fraction, "-vf", "--volume-fraction",
"Volume fraction for the material density.");
args.AddOption(&lambda, "-lambda", "--lambda",
"Lamé constant λ.");
args.AddOption(&mu, "-mu", "--mu",
"Lamé constant μ.");
args.AddOption(&rho_min, "-rmin", "--psi-min",
"Minimum of density coefficient.");
args.AddOption(&glvis_visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.AddOption(&paraview_output, "-pv", "--paraview", "-no-pv",
"--no-paraview",
"Enable or disable ParaView output.");
args.Parse();
if (!args.Good())
{
if (myid == 0)
{
args.PrintUsage(cout);
}
MPI_Finalize();
return 1;
}
if (myid == 0)
{
mfem::out << num_procs << " number of process created.\n";
args.PrintOptions(cout);
}
Mesh mesh = Mesh::MakeCartesian2D(3, 1, mfem::Element::Type::QUADRILATERAL,
true, 3.0, 1.0);
int dim = mesh.Dimension();
// 2. Set BCs.
for (int i = 0; i<mesh.GetNBE(); i++)
{
Element * be = mesh.GetBdrElement(i);
Array<int> vertices;
be->GetVertices(vertices);
double * coords1 = mesh.GetVertex(vertices[0]);
double * coords2 = mesh.GetVertex(vertices[1]);
Vector center(2);
center(0) = 0.5*(coords1[0] + coords2[0]);
center(1) = 0.5*(coords1[1] + coords2[1]);
if (abs(center(0) - 0.0) < 1e-10)
{
// the left edge
be->SetAttribute(1);
}
else
{
// all other boundaries
be->SetAttribute(2);
}
}
mesh.SetAttributes();
// 3. Refine the mesh.
for (int lev = 0; lev < ref_levels; lev++)
{
mesh.UniformRefinement();
}
ParMesh pmesh(MPI_COMM_WORLD, mesh);
mesh.Clear();
// 4. Define the necessary finite element spaces on the mesh.
H1_FECollection state_fec(order, dim); // space for u
H1_FECollection filter_fec(order, dim); // space for ρ̃
L2_FECollection control_fec(order-1, dim,
BasisType::GaussLobatto); // space for ψ
ParFiniteElementSpace state_fes(&pmesh, &state_fec,dim);
ParFiniteElementSpace filter_fes(&pmesh, &filter_fec);
ParFiniteElementSpace control_fes(&pmesh, &control_fec);
HYPRE_BigInt state_size = state_fes.GlobalTrueVSize();
HYPRE_BigInt control_size = control_fes.GlobalTrueVSize();
HYPRE_BigInt filter_size = filter_fes.GlobalTrueVSize();
if (myid==0)
{
cout << "Number of state unknowns: " << state_size << endl;
cout << "Number of filter unknowns: " << filter_size << endl;
cout << "Number of control unknowns: " << control_size << endl;
}
// 5. Set the initial guess for ρ.
ParGridFunction u(&state_fes);
ParGridFunction psi(&control_fes);
ParGridFunction psi_old(&control_fes);
ParGridFunction rho_filter(&filter_fes);
u = 0.0;
rho_filter = vol_fraction;
psi = inv_sigmoid(vol_fraction);
psi_old = inv_sigmoid(vol_fraction);
// ρ = sigmoid(ψ)
MappedGridFunctionCoefficient rho(&psi, sigmoid);
// Interpolation of ρ = sigmoid(ψ) in control fes (for ParaView output)
ParGridFunction rho_gf(&control_fes);
// ρ - ρ_old = sigmoid(ψ) - sigmoid(ψ_old)
DiffMappedGridFunctionCoefficient succ_diff_rho(&psi, &psi_old, sigmoid);
// 6. Set-up the physics solver.
int maxat = pmesh.bdr_attributes.Max();
Array<int> ess_bdr(maxat);
ess_bdr = 0;
ess_bdr[0] = 1;
ConstantCoefficient one(1.0);
ConstantCoefficient lambda_cf(lambda);
ConstantCoefficient mu_cf(mu);
LinearElasticitySolver * ElasticitySolver = new LinearElasticitySolver();
ElasticitySolver->SetMesh(&pmesh);
ElasticitySolver->SetOrder(state_fec.GetOrder());
ElasticitySolver->SetupFEM();
Vector center(2); center(0) = 2.9; center(1) = 0.5;
Vector force(2); force(0) = 0.0; force(1) = -1.0;
double r = 0.05;
VolumeForceCoefficient vforce_cf(r,center,force);
ElasticitySolver->SetRHSCoefficient(&vforce_cf);
ElasticitySolver->SetEssentialBoundary(ess_bdr);
// 7. Set-up the filter solver.
ConstantCoefficient eps2_cf(epsilon*epsilon);
DiffusionSolver * FilterSolver = new DiffusionSolver();
FilterSolver->SetMesh(&pmesh);
FilterSolver->SetOrder(filter_fec.GetOrder());
FilterSolver->SetDiffusionCoefficient(&eps2_cf);
FilterSolver->SetMassCoefficient(&one);
Array<int> ess_bdr_filter;
if (pmesh.bdr_attributes.Size())
{
ess_bdr_filter.SetSize(pmesh.bdr_attributes.Max());
ess_bdr_filter = 0;
}
FilterSolver->SetEssentialBoundary(ess_bdr_filter);
FilterSolver->SetupFEM();
ParBilinearForm mass(&control_fes);
mass.AddDomainIntegrator(new InverseIntegrator(new MassIntegrator(one)));
mass.Assemble();
HypreParMatrix M;
Array<int> empty;
mass.FormSystemMatrix(empty,M);
// 8. Define the Lagrange multiplier and gradient functions.
ParGridFunction grad(&control_fes);
ParGridFunction w_filter(&filter_fes);
// 9. Define some tools for later.
ConstantCoefficient zero(0.0);
ParGridFunction onegf(&control_fes);
onegf = 1.0;
ParGridFunction zerogf(&control_fes);
zerogf = 0.0;
ParLinearForm vol_form(&control_fes);
vol_form.AddDomainIntegrator(new DomainLFIntegrator(one));
vol_form.Assemble();
double domain_volume = vol_form(onegf);
const double target_volume = domain_volume * vol_fraction;
// 10. Connect to GLVis. Prepare for VisIt output.
char vishost[] = "localhost";
int visport = 19916;
socketstream sout_r;
if (glvis_visualization)
{
sout_r.open(vishost, visport);
sout_r.precision(8);
}
mfem::ParaViewDataCollection paraview_dc("ex37p", &pmesh);
if (paraview_output)
{
rho_gf.ProjectCoefficient(rho);
paraview_dc.SetPrefixPath("ParaView");
paraview_dc.SetLevelsOfDetail(order);
paraview_dc.SetDataFormat(VTKFormat::BINARY);
paraview_dc.SetHighOrderOutput(true);
paraview_dc.SetCycle(0);
paraview_dc.SetTime(0.0);
paraview_dc.RegisterField("displacement",&u);
paraview_dc.RegisterField("density",&rho_gf);
paraview_dc.RegisterField("filtered_density",&rho_filter);
paraview_dc.Save();
}
// 11. Iterate:
for (int k = 1; k <= max_it; k++)
{
if (k > 1) { alpha *= ((double) k) / ((double) k-1); }
if (myid == 0)
{
cout << "\nStep = " << k << endl;
}
// Step 1 - Filter solve
// Solve (ϵ^2 ∇ ρ̃, ∇ v ) + (ρ̃,v) = (ρ,v)
FilterSolver->SetRHSCoefficient(&rho);
FilterSolver->Solve();
rho_filter = *FilterSolver->GetFEMSolution();
// Step 2 - State solve
// Solve (λ r(ρ̃) ∇⋅u, ∇⋅v) + (2 μ r(ρ̃) ε(u), ε(v)) = (f,v)
SIMPInterpolationCoefficient SIMP_cf(&rho_filter,rho_min, 1.0);
ProductCoefficient lambda_SIMP_cf(lambda_cf,SIMP_cf);
ProductCoefficient mu_SIMP_cf(mu_cf,SIMP_cf);
ElasticitySolver->SetLameCoefficients(&lambda_SIMP_cf,&mu_SIMP_cf);
ElasticitySolver->Solve();
u = *ElasticitySolver->GetFEMSolution();
// Step 3 - Adjoint filter solve
// Solve (ϵ² ∇ w̃, ∇ v) + (w̃ ,v) = (-r'(ρ̃) ( λ |∇⋅u|² + 2 μ |ε(u)|²),v)
StrainEnergyDensityCoefficient rhs_cf(&lambda_cf,&mu_cf,&u, &rho_filter,
rho_min);
FilterSolver->SetRHSCoefficient(&rhs_cf);
FilterSolver->Solve();
w_filter = *FilterSolver->GetFEMSolution();
// Step 4 - Compute gradient
// Solve G = M⁻¹w̃
GridFunctionCoefficient w_cf(&w_filter);
ParLinearForm w_rhs(&control_fes);
w_rhs.AddDomainIntegrator(new DomainLFIntegrator(w_cf));
w_rhs.Assemble();
M.Mult(w_rhs,grad);
// Step 5 - Update design variable ψ ← proj(ψ - αG)
psi.Add(-alpha, grad);
const double material_volume = proj(psi, target_volume);
// Compute ||ρ - ρ_old|| in control fes.
double norm_increment = zerogf.ComputeL1Error(succ_diff_rho);
double norm_reduced_gradient = norm_increment/alpha;
psi_old = psi;
double compliance = (*(ElasticitySolver->GetLinearForm()))(u);
MPI_Allreduce(MPI_IN_PLACE,&compliance,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD);
if (myid == 0)
{
mfem::out << "norm of the reduced gradient = " << norm_reduced_gradient << endl;
mfem::out << "norm of the increment = " << norm_increment << endl;
mfem::out << "compliance = " << compliance << endl;
mfem::out << "volume fraction = " << material_volume / domain_volume << endl;
}
if (glvis_visualization)
{
ParGridFunction r_gf(&filter_fes);
r_gf.ProjectCoefficient(SIMP_cf);
sout_r << "parallel " << num_procs << " " << myid << "\n";
sout_r << "solution\n" << pmesh << r_gf
<< "window_title 'Design density r(ρ̃)'" << flush;
}
if (paraview_output)
{
rho_gf.ProjectCoefficient(rho);
paraview_dc.SetCycle(k);
paraview_dc.SetTime((double)k);
paraview_dc.Save();
}
if (norm_reduced_gradient < ntol && norm_increment < itol)
{
break;
}
}
delete ElasticitySolver;
delete FilterSolver;
return 0;
}
-10
View File
@@ -5,7 +5,6 @@
// Sample runs: mpirun -np 4 ex3p -m ../data/star.mesh
// mpirun -np 4 ex3p -m ../data/square-disc.mesh -o 2
// mpirun -np 4 ex3p -m ../data/beam-tet.mesh
// mpirun -np 4 ex3p -m ../data/beam-tet.mesh -nc -o 2
// mpirun -np 4 ex3p -m ../data/beam-hex.mesh
// mpirun -np 4 ex3p -m ../data/beam-hex.mesh -o 2 -pa
// mpirun -np 4 ex3p -m ../data/escher.mesh
@@ -71,7 +70,6 @@ int main(int argc, char *argv[])
int order = 1;
bool static_cond = false;
bool pa = false;
bool nc = false;
const char *device_config = "cpu";
bool visualization = true;
#ifdef MFEM_USE_AMGX
@@ -89,9 +87,6 @@ int main(int argc, char *argv[])
"--no-static-condensation", "Enable static condensation.");
args.AddOption(&pa, "-pa", "--partial-assembly", "-no-pa",
"--no-partial-assembly", "Enable Partial Assembly.");
args.AddOption(&nc, "-nc", "--non-conforming", "-c",
"--conforming",
"Mark the mesh as nonconforming before partitioning.");
args.AddOption(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
@@ -129,11 +124,6 @@ int main(int argc, char *argv[])
Mesh *mesh = new Mesh(mesh_file, 1, 1);
dim = mesh->Dimension();
int sdim = mesh->SpaceDimension();
if (nc)
{
// Can set to false to use conformal refinement for simplices.
mesh->EnsureNCMesh(true);
}
// 5. Refine the serial mesh on all processors to increase the resolution. In
// this example we do 'ref_levels' of uniform refinement. We choose
+1 -2
View File
@@ -450,8 +450,7 @@ int main(int argc, char *argv[])
// Implementation of class FE_Evolution
FE_Evolution::FE_Evolution(BilinearForm &M_, BilinearForm &K_, const Vector &b_)
: TimeDependentOperator(M_.FESpace()->GetTrueVSize()),
M(M_), K(K_), b(b_), z(height)
: TimeDependentOperator(M_.Height()), M(M_), K(K_), b(b_), z(M_.Height())
{
Array<int> ess_tdof_list;
if (M.GetAssemblyLevel() == AssemblyLevel::LEGACY)
+2 -2
View File
@@ -659,9 +659,9 @@ int main(int argc, char *argv[])
// Implementation of class FE_Evolution
FE_Evolution::FE_Evolution(ParBilinearForm &M_, ParBilinearForm &K_,
const Vector &b_, PrecType prec_type)
: TimeDependentOperator(M_.ParFESpace()->GetTrueVSize()), b(b_),
: TimeDependentOperator(M_.Height()), b(b_),
M_solver(M_.ParFESpace()->GetComm()),
z(height)
z(M_.Height())
{
if (M_.GetAssemblyLevel()==AssemblyLevel::LEGACY)
{
+2 -9
View File
@@ -23,11 +23,10 @@ MFEM_LIB_FILE = mfem_is_not_built
SEQ_EXAMPLES = ex0 ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 ex10 ex14 ex15 ex16 \
ex17 ex18 ex19 ex20 ex21 ex22 ex23 ex24 ex25 ex26 ex27 ex28 ex29 ex30 \
ex31 ex33 ex34 ex36 ex37
ex31 ex33 ex34 ex36
PAR_EXAMPLES = ex0p ex1p ex2p ex3p ex4p ex5p ex6p ex7p ex8p ex9p ex10p ex11p \
ex12p ex13p ex14p ex15p ex16p ex17p ex18p ex19p ex20p ex21p ex22p ex24p \
ex25p ex26p ex27p ex28p ex29p ex30p ex31p ex32p ex33p ex34p ex35p ex36p \
ex37p
ex25p ex26p ex27p ex28p ex29p ex30p ex31p ex32p ex33p ex34p ex35p ex36p
SEQ_DEVICE_EXAMPLES = ex1 ex3 ex4 ex5 ex6 ex9 ex22 ex24 ex25 ex26 ex34
PAR_DEVICE_EXAMPLES = ex1p ex2p ex3p ex4p ex5p ex6p ex7p ex9p ex13p ex22p \
ex24p ex25p ex26p ex34p ex35p
@@ -93,12 +92,10 @@ $(SUBDIRS_TPRINT):
# Additional dependencies
ex18: $(SRC)ex18.hpp
ex33: $(SRC)ex33.hpp
ex37: $(SRC)ex37.hpp
ifeq ($(MFEM_USE_MPI),YES)
ex18p: $(SRC)ex18.hpp
ex33p: $(SRC)ex33.hpp
ex37p: $(SRC)ex37.hpp
endif
MFEM_TESTS = EXAMPLES
@@ -142,10 +139,6 @@ ex27-test-seq: ex27
@$(call mfem-test,$<,, Serial example,-dg)
ex27p-test-par: ex27p
@$(call mfem-test,$<, $(RUN_MPI), Parallel example,-dg)
ex37-test-seq: ex37
@$(call mfem-test,$<,, Serial example,-mi 3)
ex37p-test-par: ex37p
@$(call mfem-test,$<, $(RUN_MPI), Parallel example,-mi 3)
# Testing: optional tests
ifeq ($(MFEM_USE_STRUMPACK),YES)
ex11p-test-strumpack: ex11p
+10 -40
View File
@@ -24,13 +24,13 @@ if (MFEM_USE_MPI)
ex10p.cpp
)
list(APPEND PETSC_RC_FILES
rc_ex1p rc_ex1p_device rc_ex1p_deviceamg
rc_ex2p rc_ex2p_bddc rc_ex2p_asm
rc_ex1p
rc_ex2p
rc_ex3p rc_ex3p_bddc
rc_ex4p rc_ex4p_bddc
rc_ex5p_bddc rc_ex5p_fieldsplit
rc_ex9p_expl rc_ex9p_expl_device rc_ex9p_impl
rc_ex10p rc_ex10p_mf rc_ex10p_mfop rc_ex10p_jfnk
rc_ex9p_expl rc_ex9p_impl
rc_ex10p
)
endif()
@@ -39,7 +39,7 @@ if (MFEM_USE_SLEPC)
ex11p.cpp
)
list(APPEND PETSC_RC_FILES
rc_ex11p_lobpcg rc_ex11p_lobpcg_device rc_ex11p_gd
rc_ex11p_lobpcg rc_ex11p_gd
)
endif()
@@ -74,13 +74,7 @@ add_mfem_examples(PETSC_EXAMPLES_SRCS ${PFX} copy_petsc_rc_files test_petsc)
# Command line options for the tests.
set(EX1_ARGS_W -m ../../data/amr-quad.mesh --usepetsc)
set(EX1_ARGS_P -m ../../data/amr-quad.mesh --usepetsc --petscopts rc_ex1p)
set(EX1_ARGS_CUDA -m ../../data/star.mesh --usepetsc --partial-assembly --device cuda --petscopts rc_ex1p_device)
set(EX1_ARGS_CUDAAMG -m ../../data/star.mesh --usepetsc --device cuda --petscopts rc_ex1p_deviceamg)
set(EX1_ARGS_HIP -m ../../data/star.mesh --usepetsc --partial-assembly --device hip --petscopts rc_ex1p_device)
set(EX1_ARGS_HIPAMG -m ../../data/star.mesh --usepetsc --device hip --petscopts rc_ex1p_deviceamg)
set(EX2_ARGS -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex2p)
set(EX2_ARGS_BDDC -m ../../data/beam-tri.mesh --usepetsc --nonoverlapping --petscopts rc_ex2p_bddc)
set(EX2_ARGS_ASM -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex2p_asm)
set(EX3_ARGS -m ../../data/klein-bottle.mesh -o 2 -f 0.1 --usepetsc --petscopts rc_ex3p_bddc --nonoverlapping)
set(EX4_ARGS -m ../../data/klein-bottle.mesh -o 2 --usepetsc --petscopts rc_ex4p_bddc --nonoverlapping)
set(EX4_HYB_ARGS -m ../../data/klein-bottle.mesh -o 2 --usepetsc --petscopts rc_ex4p_bddc --nonoverlapping --hybridization)
@@ -91,46 +85,22 @@ set(EX6_ARGS -m ../../data/amr-quad.mesh --usepetsc)
set(EX6_NONOVL_ARGS -m ../../data/amr-quad.mesh --usepetsc --nonoverlapping)
set(EX9_E_ARGS -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_expl -dt 0.1)
set(EX9_ES_ARGS -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_expl --no-step)
set(EX9_ES_ARGS_CUDA -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_expl_device --no-step --partial-assembly --device cuda)
set(EX9_ES_ARGS_HIP -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_expl_device --no-step --partial-assembly --device hip)
set(EX9_IS_ARGS -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_impl --implicit -tf 0.5)
set(EX10_ARGS -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex10p -tf 30 -s 3 -rs 2 -dt 3)
set(EX10_MF_ARGS -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex10p_mf -tf 6 -s 3 -rs 0 -dt 3)
set(EX10_MFOP_ARGS -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex10p_mfop -tf 6 -s 3 -rs 0 -dt 3)
set(EX10_JFNK_ARGS -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex10p_jfnk --jfnk -tf 6 -s 3 -rs 0 -dt 3)
if (MFEM_USE_SLEPC)
set(EX11_ARGS_SINV -m ../../data/star.mesh --useslepc)
set(EX11_ARGS_LOBPCG -m ../../data/star.mesh --useslepc --slepcopts rc_ex11p_lobpcg)
set(EX11_ARGS_LOBPCG_CUDA -m ../../data/star.mesh --useslepc --slepcopts rc_ex11p_lobpcg_device --device cuda)
set(EX11_ARGS_LOBPCG_HIP -m ../../data/star.mesh --useslepc --slepcopts rc_ex11p_lobpcg_device --device hip)
set(EX11_ARGS_GD -m ../../data/star.mesh --useslepc --slepcopts rc_ex11p_gd)
endif()
# Add the tests: one test per command-line-variable.
if (MFEM_ENABLE_TESTING)
set(TEST_OPTIONS_VARS
EX1_ARGS_W EX1_ARGS_P EX2_ARGS EX2_ARGS_BDDC EX2_ARGS_ASM EX3_ARGS
EX4_ARGS EX4_HYB_ARGS EX5_BDDC_LB_ARGS EX5_BDDC_GB_ARGS EX5_FSPL_ARGS
EX6_ARGS EX6_NONOVL_ARGS EX9_E_ARGS EX9_ES_ARGS EX9_IS_ARGS EX10_ARGS
EX10_MF_ARGS EX10_MFOP_ARGS EX10_JFNK_ARGS)
EX1_ARGS_W EX1_ARGS_P EX2_ARGS EX3_ARGS EX4_ARGS EX4_HYB_ARGS
EX5_BDDC_LB_ARGS EX5_BDDC_GB_ARGS EX5_FSPL_ARGS EX6_ARGS EX6_NONOVL_ARGS
EX9_E_ARGS EX9_ES_ARGS EX9_IS_ARGS EX10_ARGS)
if (MFEM_USE_SLEPC)
list(APPEND TEST_OPTIONS_VARS
EX11_ARGS_SINV EX11_ARGS_LOBPCG EX11_ARGS_GD)
endif()
# CUDA/HIP tests
if (MFEM_USE_CUDA)
list(APPEND TEST_OPTIONS_VARS
EX1_ARGS_CUDA EX1_ARGS_CUDAAMG EX9_ES_ARGS_CUDA)
if (MFEM_USE_SLEPC)
list(APPEND TEST_OPTIONS_VARS EX11_ARGS_LOBPCG_CUDA)
endif()
elseif (MFEM_USE_HIP)
list(APPEND TEST_OPTIONS_VARS
EX1_ARGS_HIP EX1_ARGS_HIPAMG EX9_ES_ARGS_HIP)
if (MFEM_USE_SLEPC)
# SLEPc does not support BVSVEC with HIP
# list(APPEND TEST_OPTIONS_VARS EX11_ARGS_LOBPCG_HIP)
endif()
list(APPEND TEST_OPTIONS_VARS EX11_ARGS_SINV EX11_ARGS_LOBPCG EX11_ARGS_GD)
endif()
foreach(TEST_OPTIONS_VAR ${TEST_OPTIONS_VARS})
@@ -145,7 +115,7 @@ if (MFEM_ENABLE_TESTING)
# All PETSC tests are parallel.
if (MFEM_USE_MPI)
add_test(NAME ${TEST_NAME_FULL}_np=${MFEM_MPI_NP}
add_test(NAME ${TEST_NAME_FULL}_np=4
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MFEM_MPI_NP}
${MPIEXEC_PREFLAGS}
$<TARGET_FILE:${TEST_NAME}> ${TEST_OPTIONS}
+1 -1
View File
@@ -7,7 +7,7 @@
// mpirun -np 4 ex1p -m ../../data/amr-quad.mesh --petscopts rc_ex1p
//
// Device sample runs:
// mpirun -np 4 ex1p -pa -d cuda --petscopts rc_ex1p_device
// mpirun -np 4 ex1p -pa -d cuda --petscopts rc_ex1p_cuda
//
// Description: This example code demonstrates the use of MFEM to define a
// simple finite element discretization of the Laplace problem
+1 -1
View File
@@ -17,7 +17,7 @@
// finite elements (velocity u) and piecewise discontinuous
// polynomials (pressure p).
//
// The example demonstrates the use of the BlockOperator class, as
// The example demonstrates the use of the BlockMatrix class, as
// well as the collective saving of several grid functions in a
// VisIt (visit.llnl.gov) visualization format.
//
+2 -2
View File
@@ -520,10 +520,10 @@ int main(int argc, char *argv[])
// Implementation of class FE_Evolution
FE_Evolution::FE_Evolution(ParBilinearForm &M_, ParBilinearForm &K_,
const Vector &b_,bool M_in_lhs)
: TimeDependentOperator(M_.ParFESpace()->GetTrueVSize(), 0.0,
: TimeDependentOperator(M_.Height(), 0.0,
M_in_lhs ? TimeDependentOperator::IMPLICIT
: TimeDependentOperator::EXPLICIT),
b(b_), comm(M_.ParFESpace()->GetComm()), M_solver(comm), z(height),
b(b_), comm(M_.ParFESpace()->GetComm()), M_solver(comm), z(M_.Height()),
iJacobian(NULL), rJacobian(NULL)
{
MAlev = M_.GetAssemblyLevel();
+9 -29
View File
@@ -66,9 +66,7 @@ include $(MFEM_TEST_MK)
# Testing: Parallel runs
RUN_MPI = $(MFEM_MPIEXEC) $(MFEM_MPIEXEC_NP) $(MFEM_MPI_NP)
TESTNAME = Parallel PETSc example
TESTNAME_CUDA = Parallel CUDA PETSc example
TESTNAME_HIP = Parallel HIP PETSc example
TESTNAME = Parallel PETSc example
%-test-par: %
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME))
@@ -76,10 +74,8 @@ TESTNAME_HIP = Parallel HIP PETSc example
# Testing PETSc execution options.
EX1_ARGS_W := -m ../../data/amr-quad.mesh --usepetsc
EX1_ARGS_P := -m ../../data/amr-quad.mesh --usepetsc --petscopts rc_ex1p
EX1_ARGS_CUDA := -m ../../data/star.mesh --usepetsc --partial-assembly --device cuda --petscopts rc_ex1p_device
EX1_ARGS_CUDAAMG := -m ../../data/star.mesh --usepetsc --device cuda --petscopts rc_ex1p_deviceamg
EX1_ARGS_HIP := -m ../../data/star.mesh --usepetsc --partial-assembly --device hip --petscopts rc_ex1p_device
EX1_ARGS_HIPAMG := -m ../../data/star.mesh --usepetsc --device hip --petscopts rc_ex1p_deviceamg
EX1_ARGS_CUDA := -m ../../data/star.mesh --usepetsc --partial-assembly --device cuda --petscopts rc_ex1p_cuda
EX1_ARGS_CUDAAMG := -m ../../data/star.mesh --usepetsc --device cuda --petscopts rc_ex1p_cudaamg
EX2_ARGS := -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex2p
EX2_ARGS_BDDC := -m ../../data/beam-tri.mesh --usepetsc --nonoverlapping --petscopts rc_ex2p_bddc
EX2_ARGS_ASM := -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex2p_asm
@@ -93,8 +89,7 @@ EX6_ARGS := -m ../../data/amr-quad.mesh --usepetsc
EX6_NONOVL_ARGS := -m ../../data/amr-quad.mesh --usepetsc --nonoverlapping
EX9_E_ARGS := -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_expl -dt 0.1
EX9_ES_ARGS := -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_expl --no-step
EX9_ES_ARGS_CUDA := -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_expl_device --no-step --partial-assembly --device cuda
EX9_ES_ARGS_HIP := -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_expl_device --no-step --partial-assembly --device hip
EX9_ES_ARGS_CUDA := -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_expl_cuda --no-step --partial-assembly --device cuda
EX9_IS_ARGS := -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_impl --implicit -tf 0.5
EX10_ARGS := -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex10p -tf 30 -s 3 -rs 2 -dt 3
EX10_MF_ARGS := -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex10p_mf -tf 6 -s 3 -rs 0 -dt 3
@@ -102,20 +97,15 @@ EX10_MFOP_ARGS := -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_
EX10_JFNK_ARGS := -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex10p_jfnk --jfnk -tf 6 -s 3 -rs 0 -dt 3
EX11_ARGS_SINV := -m ../../data/star.mesh --useslepc
EX11_ARGS_LOBPCG := -m ../../data/star.mesh --useslepc --slepcopts rc_ex11p_lobpcg
EX11_ARGS_LOBPCG_CUDA := -m ../../data/star.mesh --useslepc --slepcopts rc_ex11p_lobpcg_device --device cuda
EX11_ARGS_LOBPCG_HIP := -m ../../data/star.mesh --useslepc --slepcopts rc_ex11p_lobpcg_device --device hip
EX11_ARGS_LOBPCG_CUDA := -m ../../data/star.mesh --useslepc --slepcopts rc_ex11p_lobpcg_cuda --device cuda
EX11_ARGS_GD := -m ../../data/star.mesh --useslepc --slepcopts rc_ex11p_gd
ex1p-test-par: ex1p
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX1_ARGS_W))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX1_ARGS_P))
ifeq ($(MFEM_USE_CUDA),YES)
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME_CUDA),$(EX1_ARGS_CUDA))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME_CUDA),$(EX1_ARGS_CUDAAMG))
endif
ifeq ($(MFEM_USE_HIP),YES)
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME_HIP),$(EX1_ARGS_HIP))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME_HIP),$(EX1_ARGS_HIPAMG))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX1_ARGS_CUDA))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX1_ARGS_CUDAAMG))
endif
ex2p-test-par: ex2p
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX2_ARGS))
@@ -138,10 +128,7 @@ ex9p-test-par: ex9p
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX9_ES_ARGS))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX9_IS_ARGS))
ifeq ($(MFEM_USE_CUDA),YES)
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME_CUDA),$(EX9_ES_ARGS_CUDA))
endif
ifeq ($(MFEM_USE_HIP),YES)
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME_HIP),$(EX9_ES_ARGS_HIP))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX9_ES_ARGS_CUDA))
endif
ex10p-test-par: ex10p
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX10_ARGS))
@@ -153,12 +140,8 @@ ex11p-test-par: ex11p
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX11_ARGS_SINV))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX11_ARGS_LOBPCG))
ifeq ($(MFEM_USE_CUDA),YES)
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME_CUDA),$(EX11_ARGS_LOBPCG_CUDA))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX11_ARGS_LOBPCG_CUDA))
endif
# SLEPc does not support BVSVEC with HIP
#ifeq ($(MFEM_USE_HIP),YES)
# @$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME_HIP),$(EX11_ARGS_LOBPCG_HIP))
#endif
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX11_ARGS_GD))
endif
@@ -173,9 +156,6 @@ clean: clean-build clean-exec
clean-build:
rm -f *.o *~ $(SEQ_EXAMPLES) $(PAR_EXAMPLES)
rm -rf *.dSYM *.TVD.*breakpoints
ifneq ($(SRC),)
rm -f $(RC_FILES)
endif
clean-exec:
@rm -rf mesh.* sol.* sol_p.* sol_u.* Example5*
+1 -2
View File
@@ -476,8 +476,7 @@ int main(int argc, char *argv[])
// Implementation of class FE_Evolution
FE_Evolution::FE_Evolution(BilinearForm &M_, BilinearForm &K_, const Vector &b_)
: TimeDependentOperator(M_.FESpace()->GetTrueVSize()),
M(M_), K(K_), b(b_), z(height)
: TimeDependentOperator(M_.Height()), M(M_), K(K_), b(b_), z(M_.Height())
{
Array<int> ess_tdof_list;
if (M.GetAssemblyLevel() == AssemblyLevel::LEGACY)
+2 -2
View File
@@ -679,10 +679,10 @@ int main(int argc, char *argv[])
// Implementation of class FE_Evolution
FE_Evolution::FE_Evolution(ParBilinearForm &M_, ParBilinearForm &K_,
const Vector &b_, PrecType prec_type)
: TimeDependentOperator(M_.ParFESpace()->GetTrueVSize()),
: TimeDependentOperator(M_.Height()),
b(b_),
M_solver(M_.ParFESpace()->GetComm()),
z(height)
z(M_.Height())
{
if (M_.GetAssemblyLevel()==AssemblyLevel::LEGACY)
{
-2
View File
@@ -88,7 +88,6 @@ set(SRCS
ceed/solvers/algebraic.cpp
ceed/solvers/full-assembly.cpp
ceed/solvers/solvers-atpmg.cpp
kdtree.cpp
linearform.cpp
linearform_ext.cpp
lininteg.cpp
@@ -200,7 +199,6 @@ set(HDRS
ceed/solvers/algebraic.hpp
ceed/solvers/full-assembly.hpp
ceed/solvers/solvers-atpmg.hpp
kdtree.hpp
linearform.hpp
linearform_ext.hpp
lininteg.hpp
+1 -1
View File
@@ -433,7 +433,6 @@ void BilinearForm::Assemble(int skip_zeros)
// Element-wise integration
for (int i = 0; i < fes -> GetNE(); i++)
{
doftrans = fes->GetElementVDofs(i, vdofs);
if (element_matrices)
{
elmat_p = &(*element_matrices)(i);
@@ -469,6 +468,7 @@ void BilinearForm::Assemble(int skip_zeros)
{
elmat_p = &elmat;
}
doftrans = fes->GetElementVDofs(i, vdofs);
if (doftrans)
{
doftrans->TransformDual(elmat);
+1 -7
View File
@@ -254,12 +254,6 @@ public:
/// Access all the integrators added with AddDomainIntegrator().
Array<BilinearFormIntegrator*> *GetDBFI() { return &domain_integs; }
/// @brief Access all boundary markers added with AddDomainIntegrator().
///
/// If no marker was specified when the integrator was added, the
/// corresponding pointer (to Array<int>) will be NULL. */
Array<Array<int>*> *GetDBFI_Marker() { return &domain_integs_marker; }
/// Access all the integrators added with AddBoundaryIntegrator().
Array<BilinearFormIntegrator*> *GetBBFI() { return &boundary_integs; }
/** @brief Access all boundary markers added with AddBoundaryIntegrator().
@@ -458,7 +452,7 @@ public:
practice it is convenient to have it in transposed form for
construction of RAP operators in matrix-free methods. */
virtual const Operator *GetOutputRestrictionTranspose() const
{ return fes->GetRestrictionTransposeOperator(); }
{ return GetOutputProlongation(); }
/// Get the output finite element space restriction matrix
virtual const Operator *GetOutputRestriction() const
{ return GetRestriction(); }
+10 -128
View File
@@ -264,14 +264,6 @@ void PABilinearFormExtension::SetupRestrictionOperators(const L2FaceValues m)
localX.SetSize(elem_restrict->Height(), Device::GetDeviceMemoryType());
localY.SetSize(elem_restrict->Height(), Device::GetDeviceMemoryType());
localY.UseDevice(true); // ensure 'localY = 0.0' is done on device
// Gather the attributes on the host from all the elements
const Mesh &mesh = *trial_fes->GetMesh();
elem_attributes.SetSize(mesh.GetNE());
for (int i = 0; i < mesh.GetNE(); ++i)
{
elem_attributes[i] = mesh.GetAttribute(i);
}
}
// Construct face restriction operators only if the bilinear form has
@@ -297,46 +289,6 @@ void PABilinearFormExtension::SetupRestrictionOperators(const L2FaceValues m)
bdr_face_X.SetSize(bdr_face_restrict_lex->Height(), Device::GetMemoryType());
bdr_face_Y.SetSize(bdr_face_restrict_lex->Height(), Device::GetMemoryType());
bdr_face_Y.UseDevice(true); // ensure 'faceBoundY = 0.0' is done on device
const Mesh &mesh = *trial_fes->GetMesh();
// See LinearFormExtension::Update for explanation of f_to_be logic.
std::unordered_map<int,int> f_to_be;
for (int i = 0; i < mesh.GetNBE(); ++i)
{
const int f = mesh.GetBdrElementEdgeIndex(i);
f_to_be[f] = i;
}
const int nf_bdr = trial_fes->GetNFbyType(FaceType::Boundary);
bdr_attributes.SetSize(nf_bdr);
int f_ind = 0;
int missing_bdr_elems = 0;
for (int f = 0; f < mesh.GetNumFaces(); ++f)
{
if (!mesh.GetFaceInformation(f).IsOfFaceType(FaceType::Boundary))
{
continue;
}
int attribute = 1; // default value
if (f_to_be.find(f) != f_to_be.end())
{
const int be = f_to_be[f];
attribute = mesh.GetBdrAttribute(be);
}
else
{
// If a boundary face does not correspond to the a boundary element,
// we assign it the default attribute of 1. We also generate a
// warning at runtime with the number of such missing elements.
++missing_bdr_elems;
}
bdr_attributes[f_ind] = attribute;
++f_ind;
}
if (missing_bdr_elems)
{
MFEM_WARNING("Missing " << missing_bdr_elems << " boundary elements "
"for boundary faces.");
}
}
}
@@ -506,13 +458,11 @@ void PABilinearFormExtension::Mult(const Vector &x, Vector &y) const
{
if (iSz)
{
Array<Array<int>*> &elem_markers = *a->GetDBFI_Marker();
elem_restrict->Mult(x, localX);
localY = 0.0;
for (int i = 0; i < iSz; ++i)
{
AddMultWithMarkers(*integrators[i], localX, elem_markers[i], elem_attributes,
false, localY);
integrators[i]->AddMultPA(localX, localY);
}
elem_restrict->MultTranspose(localY, y);
}
@@ -545,21 +495,17 @@ void PABilinearFormExtension::Mult(const Vector &x, Vector &y) const
const bool has_bdr_integs = (n_bdr_face_integs > 0 || n_bdr_integs > 0);
if (bdr_face_restrict_lex && has_bdr_integs)
{
Array<Array<int>*> &bdr_markers = *a->GetBBFI_Marker();
Array<Array<int>*> &bdr_face_markers = *a->GetBFBFI_Marker();
bdr_face_restrict_lex->Mult(x, bdr_face_X);
if (bdr_face_X.Size()>0)
{
bdr_face_Y = 0.0;
for (int i = 0; i < n_bdr_integs; ++i)
{
AddMultWithMarkers(*bdr_integs[i], bdr_face_X, bdr_markers[i], bdr_attributes,
false, bdr_face_Y);
bdr_integs[i]->AddMultPA(bdr_face_X, bdr_face_Y);
}
for (int i = 0; i < n_bdr_face_integs; ++i)
{
AddMultWithMarkers(*bdr_face_integs[i], bdr_face_X, bdr_face_markers[i],
bdr_attributes, false, bdr_face_Y);
bdr_face_integs[i]->AddMultPA(bdr_face_X, bdr_face_Y);
}
bdr_face_restrict_lex->AddMultTransposeInPlace(bdr_face_Y, y);
}
@@ -572,13 +518,11 @@ void PABilinearFormExtension::MultTranspose(const Vector &x, Vector &y) const
const int iSz = integrators.Size();
if (elem_restrict)
{
Array<Array<int>*> &elem_markers = *a->GetDBFI_Marker();
elem_restrict->Mult(x, localX);
localY = 0.0;
for (int i = 0; i < iSz; ++i)
{
AddMultWithMarkers(*integrators[i], localX, elem_markers[i], elem_attributes,
true, localY);
integrators[i]->AddMultTransposePA(localX, localY);
}
elem_restrict->MultTranspose(localY, y);
}
@@ -608,85 +552,23 @@ void PABilinearFormExtension::MultTranspose(const Vector &x, Vector &y) const
}
}
Array<BilinearFormIntegrator*> &bdr_integs = *a->GetBBFI();
Array<BilinearFormIntegrator*> &bdr_face_integs = *a->GetBFBFI();
const int n_bdr_integs = bdr_integs.Size();
const int n_bdr_face_integs = bdr_face_integs.Size();
const bool has_bdr_integs = (n_bdr_face_integs > 0 || n_bdr_integs > 0);
if (bdr_face_restrict_lex && has_bdr_integs)
Array<BilinearFormIntegrator*> &bdrFaceIntegrators = *a->GetBFBFI();
const int bFISz = bdrFaceIntegrators.Size();
if (bdr_face_restrict_lex && bFISz>0)
{
Array<Array<int>*> &bdr_markers = *a->GetBBFI_Marker();
Array<Array<int>*> &bdr_face_markers = *a->GetBFBFI_Marker();
bdr_face_restrict_lex->Mult(x, bdr_face_X);
if (bdr_face_X.Size() > 0)
if (bdr_face_X.Size()>0)
{
bdr_face_Y = 0.0;
for (int i = 0; i < n_bdr_integs; ++i)
for (int i = 0; i < bFISz; ++i)
{
AddMultWithMarkers(*bdr_integs[i], bdr_face_X, bdr_markers[i], bdr_attributes,
true, bdr_face_Y);
}
for (int i = 0; i < n_bdr_face_integs; ++i)
{
AddMultWithMarkers(*bdr_face_integs[i], bdr_face_X, bdr_face_markers[i],
bdr_attributes, true, bdr_face_Y);
bdrFaceIntegrators[i]->AddMultTransposePA(bdr_face_X, bdr_face_Y);
}
bdr_face_restrict_lex->AddMultTransposeInPlace(bdr_face_Y, y);
}
}
}
// Compute kernels for PABilinearFormExtension::AddMultWithMarkers.
// Cannot be in member function with non-public visibility.
static void AddWithMarkers_(
const int ne,
const int nd,
const Vector &x,
const Array<int> &markers,
const Array<int> &attributes,
Vector &y)
{
const auto d_x = Reshape(x.Read(), nd, ne);
const auto d_m = Reshape(markers.Read(), markers.Size());
const auto d_attr = Reshape(attributes.Read(), ne);
auto d_y = Reshape(y.ReadWrite(), nd, ne);
mfem::forall(ne, [=] MFEM_HOST_DEVICE (int e)
{
const int attr = d_attr[e];
if (d_m[attr - 1] == 0) { return; }
for (int i = 0; i < nd; ++i)
{
d_y(i, e) += d_x(i, e);
}
});
}
void PABilinearFormExtension::AddMultWithMarkers(
const BilinearFormIntegrator &integ,
const Vector &x,
const Array<int> *markers,
const Array<int> &attributes,
const bool transpose,
Vector &y) const
{
if (markers)
{
tmp_evec.SetSize(y.Size());
tmp_evec = 0.0;
if (transpose) { integ.AddMultTransposePA(x, tmp_evec); }
else { integ.AddMultPA(x, tmp_evec); }
const int ne = attributes.Size();
const int nd = x.Size() / ne;
AddWithMarkers_(ne, nd, tmp_evec, *markers, attributes, y);
}
else
{
if (transpose) { integ.AddMultTransposePA(x, y); }
else { integ.AddMultPA(x, y); }
}
}
// Data and methods for element-assembled bilinear forms
EABilinearFormExtension::EABilinearFormExtension(BilinearForm *form)
: PABilinearFormExtension(form),
-22
View File
@@ -68,9 +68,6 @@ class PABilinearFormExtension : public BilinearFormExtension
{
protected:
const FiniteElementSpace *trial_fes, *test_fes; // Not owned
/// Attributes of all mesh elements.
Array<int> elem_attributes, bdr_attributes;
mutable Vector tmp_evec; // Work array
mutable Vector localX, localY;
mutable Vector int_face_X, int_face_Y;
mutable Vector bdr_face_X, bdr_face_Y;
@@ -94,25 +91,6 @@ public:
protected:
void SetupRestrictionOperators(const L2FaceValues m);
/// @brief Accumulate the action (or transpose) of the integrator on @a x
/// into @a y, taking into account the (possibly null) @a markers array.
///
/// If @a markers is non-null, then only those elements or boundary elements
/// whose attribute is marked in the markers array will be added to @a y.
///
/// @param integ The integrator (domain, boundary, or boundary face).
/// @param x Input E-vector.
/// @param markers Marked attributes (possibly null, meaning all attributes).
/// @param attributes Array of element or boundary element attributes.
/// @param transpose Compute the action or transpose of the integrator .
/// @param y Output E-vector
void AddMultWithMarkers(const BilinearFormIntegrator &integ,
const Vector &x,
const Array<int> *markers,
const Array<int> &attributes,
const bool transpose,
Vector &y) const;
};
/// Data and methods for element-assembled bilinear forms
+4 -4
View File
@@ -2456,7 +2456,7 @@ void VectorFEMassIntegrator::AssembleElementMatrix(
{
int dof = el.GetDof();
int spaceDim = Trans.GetSpaceDim();
int vdim = std::max(spaceDim, el.GetRangeDim());
int vdim = std::max(spaceDim, el.GetVDim());
double w;
@@ -2524,7 +2524,7 @@ void VectorFEMassIntegrator::AssembleElementMatrix2(
{
// assume test_fe is scalar FE and trial_fe is vector FE
int spaceDim = Trans.GetSpaceDim();
int vdim = std::max(spaceDim, trial_fe.GetRangeDim());
int vdim = std::max(spaceDim, trial_fe.GetVDim());
int trial_dof = trial_fe.GetDof();
int test_dof = test_fe.GetDof();
double w;
@@ -2622,8 +2622,8 @@ void VectorFEMassIntegrator::AssembleElementMatrix2(
{
// assume both test_fe and trial_fe are vector FE
int spaceDim = Trans.GetSpaceDim();
int trial_vdim = std::max(spaceDim, trial_fe.GetRangeDim());
int test_vdim = std::max(spaceDim, test_fe.GetRangeDim());
int trial_vdim = std::max(spaceDim, trial_fe.GetVDim());
int test_vdim = std::max(spaceDim, test_fe.GetVDim());
int trial_dof = trial_fe.GetDof();
int test_dof = test_fe.GetDof();
double w;
+23 -12
View File
@@ -20,6 +20,17 @@
namespace mfem
{
// Local maximum size of dofs and quads in 1D
constexpr int HCURL_MAX_D1D = 5;
#ifdef MFEM_USE_HIP
constexpr int HCURL_MAX_Q1D = 5;
#else
constexpr int HCURL_MAX_Q1D = 6;
#endif
constexpr int HDIV_MAX_D1D = 5;
constexpr int HDIV_MAX_Q1D = 6;
/// Abstract base class BilinearFormIntegrator
class BilinearFormIntegrator : public NonlinearFormIntegrator
{
@@ -580,7 +591,7 @@ protected:
inline virtual int GetTestVDim(const FiniteElement & test_fe)
{ return std::max(space_dim, test_fe.GetRangeDim()); }
{ return std::max(space_dim, test_fe.GetVDim()); }
inline virtual void CalcTestShape(const FiniteElement & test_fe,
ElementTransformation &Trans,
@@ -588,7 +599,7 @@ protected:
{ test_fe.CalcVShape(Trans, shape); }
inline virtual int GetTrialVDim(const FiniteElement & trial_fe)
{ return std::max(space_dim, trial_fe.GetRangeDim()); }
{ return std::max(space_dim, trial_fe.GetVDim()); }
inline virtual void CalcTrialShape(const FiniteElement & trial_fe,
ElementTransformation &Trans,
@@ -678,7 +689,7 @@ protected:
inline virtual int GetVDim(const FiniteElement & vector_fe)
{ return std::max(space_dim, vector_fe.GetRangeDim()); }
{ return std::max(space_dim, vector_fe.GetVDim()); }
inline virtual void CalcVShape(const FiniteElement & vector_fe,
ElementTransformation &Trans,
@@ -1105,7 +1116,7 @@ public:
const FiniteElement & trial_fe,
const FiniteElement & test_fe) const
{
return (trial_fe.GetRangeDim() == 3 &&
return (trial_fe.GetVDim() == 3 &&
trial_fe.GetRangeType() == mfem::FiniteElement::VECTOR &&
test_fe.GetRangeType() == mfem::FiniteElement::SCALAR &&
test_fe.GetDerivType() == mfem::FiniteElement::GRAD );
@@ -1288,8 +1299,8 @@ public:
const FiniteElement & trial_fe,
const FiniteElement & test_fe) const
{
return (trial_fe.GetCurlDim() == 3 && trial_fe.GetRangeDim() == 3 &&
test_fe.GetCurlDim() == 3 && test_fe.GetRangeDim() == 3 &&
return (trial_fe.GetCurlDim() == 3 && trial_fe.GetVDim() == 3 &&
test_fe.GetCurlDim() == 3 && test_fe.GetVDim() == 3 &&
trial_fe.GetRangeType() == mfem::FiniteElement::VECTOR &&
trial_fe.GetDerivType() == mfem::FiniteElement::CURL &&
test_fe.GetRangeType() == mfem::FiniteElement::VECTOR &&
@@ -1419,7 +1430,7 @@ public:
const FiniteElement & trial_fe,
const FiniteElement & test_fe) const
{
return (trial_fe.GetRangeDim() == 3 && test_fe.GetCurlDim() == 3 &&
return (trial_fe.GetVDim() == 3 && test_fe.GetCurlDim() == 3 &&
trial_fe.GetRangeType() == mfem::FiniteElement::VECTOR &&
test_fe.GetRangeType() == mfem::FiniteElement::VECTOR &&
test_fe.GetDerivType() == mfem::FiniteElement::CURL );
@@ -1489,7 +1500,7 @@ public:
const FiniteElement & trial_fe,
const FiniteElement & test_fe) const
{
return (test_fe.GetRangeDim() == 3 &&
return (test_fe.GetVDim() == 3 &&
trial_fe.GetRangeType() == mfem::FiniteElement::SCALAR &&
trial_fe.GetDerivType() == mfem::FiniteElement::GRAD &&
test_fe.GetRangeType() == mfem::FiniteElement::VECTOR );
@@ -1529,7 +1540,7 @@ public:
const FiniteElement & trial_fe,
const FiniteElement & test_fe) const
{
return (trial_fe.GetCurlDim() == 3 && test_fe.GetRangeDim() == 3 &&
return (trial_fe.GetCurlDim() == 3 && test_fe.GetVDim() == 3 &&
trial_fe.GetRangeType() == mfem::FiniteElement::VECTOR &&
trial_fe.GetDerivType() == mfem::FiniteElement::CURL &&
test_fe.GetRangeType() == mfem::FiniteElement::VECTOR );
@@ -1900,7 +1911,7 @@ protected:
const FiniteElement & trial_fe,
const FiniteElement & test_fe) const
{
return (trial_fe.GetCurlDim() == 3 && test_fe.GetRangeDim() == 3 &&
return (trial_fe.GetCurlDim() == 3 && test_fe.GetVDim() == 3 &&
trial_fe.GetDerivType() == mfem::FiniteElement::CURL &&
test_fe.GetRangeType() == mfem::FiniteElement::VECTOR );
}
@@ -1959,7 +1970,7 @@ protected:
const FiniteElement & trial_fe,
const FiniteElement & test_fe) const
{
return (trial_fe.GetRangeDim() == 3 && test_fe.GetCurlDim() == 3 &&
return (trial_fe.GetVDim() == 3 && test_fe.GetCurlDim() == 3 &&
trial_fe.GetRangeType() == mfem::FiniteElement::VECTOR &&
test_fe.GetDerivType() == mfem::FiniteElement::CURL );
}
@@ -3440,7 +3451,7 @@ private:
void cross_product(const Vector & x, const DenseMatrix & Y, DenseMatrix & Z)
{
int dim = x.Size();
MFEM_VERIFY(Y.Width() == dim, "Size mismatch");
MFEM_VERIFY(Y.Width() == dim, "Size missmatch");
int dimc = dim == 3 ? dim : 1;
int h = Y.Height();
Z.SetSize(h,dimc);
+74 -18
View File
@@ -220,12 +220,12 @@ double TransformedCoefficient::Eval(ElementTransformation &T,
{
if (Q2)
{
return Transform2(Q1->Eval(T, ip, GetTime()),
Q2->Eval(T, ip, GetTime()));
return (*Transform2)(Q1->Eval(T, ip, GetTime()),
Q2->Eval(T, ip, GetTime()));
}
else
{
return Transform1(Q1->Eval(T, ip, GetTime()));
return (*Transform1)(Q1->Eval(T, ip, GetTime()));
}
}
@@ -1041,6 +1041,73 @@ double DeterminantCoefficient::Eval(ElementTransformation &T,
return ma.Det();
}
VectorComponentCoefficient::VectorComponentCoefficient(VectorCoefficient &A,
int c)
: a(&A), va(A.GetVDim())
{
SetComponent(c);
}
void VectorComponentCoefficient::SetComponent(int c)
{
MFEM_ASSERT(c < a->GetVDim() && c >= 0,
"VectorComponentCoefficient: "
"Index not in range.");
component = c;
}
void VectorComponentCoefficient::SetTime(double t)
{
if (a) { a->SetTime(t); }
this->Coefficient::SetTime(t);
}
double VectorComponentCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip)
{
a->Eval(va, T, ip);
return va[component];
}
MatrixComponentCoefficient::MatrixComponentCoefficient(MatrixCoefficient &A,
int ri, int ci)
: a(&A), ma(A.GetHeight(), A.GetWidth())
{
SetRowIndex(ri);
SetColumnIndex(ci);
}
void MatrixComponentCoefficient::SetRowIndex(int ri)
{
MFEM_ASSERT(ri < a->GetHeight() && ri >= 0,
"MatrixComponentCoefficient: "
"Row index not in range.");
row_idx = ri;
}
void MatrixComponentCoefficient::SetColumnIndex(int ci)
{
MFEM_ASSERT(ci < a->GetWidth() && ci >= 0,
"MatrixComponentCoefficient: "
"Column index not in range.");
col_idx = ci;
}
void MatrixComponentCoefficient::SetTime(double t)
{
if (a) { a->SetTime(t); }
this->Coefficient::SetTime(t);
}
double MatrixComponentCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip)
{
a->Eval(ma, T, ip);
return ma(row_idx,col_idx);
}
VectorSumCoefficient::VectorSumCoefficient(int dim)
: VectorCoefficient(dim),
ACoef(NULL), BCoef(NULL),
@@ -1196,6 +1263,7 @@ void MatrixVectorProductCoefficient::SetTime(double t)
void MatrixVectorProductCoefficient::Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip)
{
V.SetSize(ma.Height());
a->Eval(ma, T, ip);
b->Eval(vb, T, ip);
V.SetSize(vdim);
@@ -1591,21 +1659,14 @@ void VectorQuadratureFunctionCoefficient::Eval(Vector &V,
{
QuadF.HostRead();
const int el_idx = QuadF.GetSpace()->GetEntityIndex(T);
// Handle the case of "interior boundary elements" and FaceQuadratureSpace
// with FaceType::Boundary.
if (el_idx < 0) { V = 0.0; return; }
const int ip_idx = QuadF.GetSpace()->GetPermutedIndex(el_idx, ip.index);
if (index == 0 && vdim == QuadF.GetVDim())
{
QuadF.GetValues(el_idx, ip_idx, V);
QuadF.GetValues(T.ElementNo, ip.index, V);
}
else
{
Vector temp;
QuadF.GetValues(el_idx, ip_idx, temp);
QuadF.GetValues(T.ElementNo, ip.index, temp);
V.SetSize(vdim);
for (int i = 0; i < vdim; i++)
{
@@ -1632,12 +1693,7 @@ double QuadratureFunctionCoefficient::Eval(ElementTransformation &T,
{
QuadF.HostRead();
Vector temp(1);
const int el_idx = QuadF.GetSpace()->GetEntityIndex(T);
// Handle the case of "interior boundary elements" and FaceQuadratureSpace
// with FaceType::Boundary.
if (el_idx < 0) { return 0.0; }
const int ip_idx = QuadF.GetSpace()->GetPermutedIndex(el_idx, ip.index);
QuadF.GetValues(el_idx, ip_idx, temp);
QuadF.GetValues(T.ElementNo, ip.index, temp);
return temp[0];
}
+141 -6
View File
@@ -422,15 +422,15 @@ class TransformedCoefficient : public Coefficient
private:
Coefficient * Q1;
Coefficient * Q2;
std::function<double(double)> Transform1;
std::function<double(double, double)> Transform2;
double (*Transform1)(double);
double (*Transform2)(double,double);
public:
TransformedCoefficient (Coefficient * q, std::function<double(double)> F)
: Q1(q), Transform1(std::move(F)) { Q2 = 0; Transform2 = 0; }
TransformedCoefficient (Coefficient * q,double (*F)(double))
: Q1(q), Transform1(F) { Q2 = 0; Transform2 = 0; }
TransformedCoefficient (Coefficient * q1,Coefficient * q2,
std::function<double(double, double)> F)
: Q1(q1), Q2(q2), Transform2(std::move(F)) { Transform1 = 0; }
double (*F)(double,double))
: Q1(q1), Q2(q2), Transform2(F) { Transform1 = 0; }
/// Set the time for internally stored coefficients
void SetTime(double t);
@@ -1672,6 +1672,62 @@ public:
{ return pow(a->Eval(T, ip), p); }
};
/// Coefficient which returns (k*x) or func(k*x) where k is a vector
class PhaseCoefficient : public Coefficient
{
private:
double(*func_)(double);
VectorCoefficient * k_;
mutable Vector kVec_;
public:
PhaseCoefficient(Vector & k, double(*func)(double) = NULL)
: func_(func), k_(NULL), kVec_(k) {}
PhaseCoefficient(VectorCoefficient & k, double(*func)(double) = NULL)
: func_(func), k_(&k), kVec_(k.GetVDim()) {}
double Eval(ElementTransformation &T,
const IntegrationPoint &ip)
{
double x[3];
Vector transip(x, 3);
T.Transform(ip, transip);
if (k_) { k_->Eval(kVec_, T, ip); }
return (func_) ? (*func_)(kVec_ * transip) : (kVec_ * transip);
}
};
/// Coefficient which returns func(kr*x)*exp(-ki*x) where kr and ki are vectors
class ComplexPhaseCoefficient : public Coefficient
{
private:
double(*func_)(double);
VectorCoefficient * kr_;
VectorCoefficient * ki_;
mutable Vector krVec_;
mutable Vector kiVec_;
public:
ComplexPhaseCoefficient(Vector & kr, Vector & ki, double(&func)(double))
: func_(&func), kr_(NULL), ki_(NULL), krVec_(kr), kiVec_(ki) {}
ComplexPhaseCoefficient(VectorCoefficient & kr, VectorCoefficient & ki,
double(&func)(double))
: func_(&func), kr_(&kr), ki_(&ki),
krVec_(kr.GetVDim()), kiVec_(ki.GetVDim()) {}
double Eval(ElementTransformation &T,
const IntegrationPoint &ip)
{
double x[3];
Vector transip(x, 3);
T.Transform(ip, transip);
if (kr_) { kr_->Eval(krVec_, T, ip); }
if (ki_) { ki_->Eval(kiVec_, T, ip); }
return (*func_)(krVec_ * transip)*exp(-(kiVec_ * transip));
}
};
/// Scalar coefficient defined as the inner product of two vector coefficients
class InnerProductCoefficient : public Coefficient
@@ -1761,6 +1817,85 @@ public:
const IntegrationPoint &ip);
};
/// Scalar coefficient defined as component of a vector coefficient
class VectorComponentCoefficient : public Coefficient
{
private:
VectorCoefficient *a = nullptr;
mutable Vector va;
int component;
public:
/// Construct with a vector coefficient.
VectorComponentCoefficient(VectorCoefficient &A)
: a(&A), va(A.GetVDim()), component(0) {};
VectorComponentCoefficient(VectorCoefficient &A, int c);
/// Set the time for internally stored coefficients
void SetTime(double t) override;
/// Reset the vector coefficient
void SetACoef(VectorCoefficient &A) { a = &A; }
/// Return the vector coefficient
VectorCoefficient * GetACoef() const { return a; }
/// Set the component
void SetComponent(int c);
/// Return the component
int GetComponent() const { return component; }
/// Evaluate the trace coefficient at @a ip.
double Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/// Scalar coefficient defined as component of a matrix coefficient
class MatrixComponentCoefficient : public Coefficient
{
private:
MatrixCoefficient *a = nullptr;
mutable DenseMatrix ma;
int row_idx,col_idx;
public:
MatrixComponentCoefficient(MatrixCoefficient &A)
: a(&A), ma(A.GetHeight(), A.GetWidth()), row_idx(0), col_idx(0) {};
/// Construct with the matrix coefficient.
MatrixComponentCoefficient(MatrixCoefficient &A, int ri, int ci);
/// Set the time for internally stored coefficients
void SetTime(double t) override;
/// Reset the matrix coefficient
void SetACoef(MatrixCoefficient &A) { a = &A; }
/// Return the matrix coefficient
MatrixCoefficient * GetACoef() const { return a; }
/// Reset the index
void SetRowIndex(int ri);
/// Return the index
int GetRowIndex() const { return row_idx; }
/// Reset the index
void SetColumnIndex(int ci);
/// Return the index
int GetColumnIndex() const { return col_idx; }
/// Evaluate the trace coefficient at @a ip.
double Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
};
/// Vector coefficient defined as the linear combination of two vectors
class VectorSumCoefficient : public VectorCoefficient
{
+186
View File
@@ -1415,6 +1415,192 @@ ParSesquilinearForm::Update(FiniteElementSpace *nfes)
if ( pblfi ) { pblfi->Update(nfes); }
}
bool ParMixedSesquilinearForm::RealInteg()
{
int nint = pblfr->GetTFBFI()->Size() + pblfr->GetDBFI()->Size() +
pblfr->GetBBFI()->Size() + pblfr->GetBTFBFI()->Size();
return (nint != 0);
}
bool ParMixedSesquilinearForm::ImagInteg()
{
int nint = pblfi->GetTFBFI()->Size() + pblfi->GetDBFI()->Size() +
pblfi->GetBBFI()->Size() + pblfi->GetBTFBFI()->Size();
return (nint != 0);
}
ParMixedSesquilinearForm::ParMixedSesquilinearForm(ParFiniteElementSpace *tr_pf,
ParFiniteElementSpace *te_pf,
ComplexOperator::Convention
convention)
: conv(convention),
pblfr(new ParMixedBilinearForm(tr_pf, te_pf)),
pblfi(new ParMixedBilinearForm(tr_pf, te_pf))
{}
ParMixedSesquilinearForm::ParMixedSesquilinearForm(ParFiniteElementSpace *tr_pf,
ParFiniteElementSpace *te_pf,
ParMixedBilinearForm *pbfr,
ParMixedBilinearForm *pbfi,
ComplexOperator::Convention convention)
: conv(convention),
pblfr(new ParMixedBilinearForm(tr_pf,te_pf,pbfr)),
pblfi(new ParMixedBilinearForm(tr_pf,te_pf,pbfi))
{}
ParMixedSesquilinearForm::~ParMixedSesquilinearForm()
{
delete pblfr;
delete pblfi;
}
void ParMixedSesquilinearForm::Mult(const ParComplexGridFunction & x,
ParComplexLinearForm & y) const
{
pblfr->Mult(x.real(), y.real());
pblfi->AddMult(x.imag(), y.real(), -1.0);
pblfr->Mult(x.imag(), y.imag());
pblfi->AddMult(x.real(), y.imag(), 1.0);
if (conv == ComplexOperator::Convention::BLOCK_SYMMETRIC)
{
y.imag() *= -1.0;
}
}
void ParMixedSesquilinearForm::AddDomainIntegrator(BilinearFormIntegrator
*bfi_real,
BilinearFormIntegrator
*bfi_imag)
{
if (bfi_real) { pblfr->AddDomainIntegrator(bfi_real); }
if (bfi_imag) { pblfi->AddDomainIntegrator(bfi_imag); }
}
void
ParMixedSesquilinearForm::AddBoundaryIntegrator(BilinearFormIntegrator
*bfi_real,
BilinearFormIntegrator *bfi_imag)
{
if (bfi_real) { pblfr->AddBoundaryIntegrator(bfi_real); }
if (bfi_imag) { pblfi->AddBoundaryIntegrator(bfi_imag); }
}
void
ParMixedSesquilinearForm::AddBoundaryIntegrator(BilinearFormIntegrator
*bfi_real,
BilinearFormIntegrator *bfi_imag,
Array<int> & bdr_marker)
{
if (bfi_real) { pblfr->AddBoundaryIntegrator(bfi_real, bdr_marker); }
if (bfi_imag) { pblfi->AddBoundaryIntegrator(bfi_imag, bdr_marker); }
}
void
ParMixedSesquilinearForm::AddTraceFaceIntegrator(BilinearFormIntegrator
*bfi_real,
BilinearFormIntegrator *bfi_imag)
{
if (bfi_real) { pblfr->AddTraceFaceIntegrator(bfi_real); }
if (bfi_imag) { pblfi->AddTraceFaceIntegrator(bfi_imag); }
}
void
ParMixedSesquilinearForm::AddBdrTraceFaceIntegrator(BilinearFormIntegrator
*bfi_real,
BilinearFormIntegrator *bfi_imag)
{
if (bfi_real) { pblfr->AddBdrTraceFaceIntegrator(bfi_real); }
if (bfi_imag) { pblfi->AddBdrTraceFaceIntegrator(bfi_imag); }
}
void
ParMixedSesquilinearForm::AddBdrTraceFaceIntegrator(BilinearFormIntegrator
*bfi_real,
BilinearFormIntegrator *bfi_imag,
Array<int> &bdr_marker)
{
if (bfi_real) { pblfr->AddBdrTraceFaceIntegrator(bfi_real, bdr_marker); }
if (bfi_imag) { pblfi->AddBdrTraceFaceIntegrator(bfi_imag, bdr_marker); }
}
void
ParMixedSesquilinearForm::Assemble(int skip_zeros)
{
pblfr->Assemble(skip_zeros);
pblfi->Assemble(skip_zeros);
}
void
ParMixedSesquilinearForm::Finalize(int skip_zeros)
{
pblfr->Finalize(skip_zeros);
pblfi->Finalize(skip_zeros);
}
ComplexHypreParMatrix *
ParMixedSesquilinearForm::ParallelAssemble()
{
return new ComplexHypreParMatrix(pblfr->ParallelAssemble(),
pblfi->ParallelAssemble(),
true, true, conv);
}
void ParMixedSesquilinearForm::FormRectangularSystemMatrix(
const Array<int> &trial_tdof_list,
const Array<int> &test_tdof_list,
OperatorHandle &A)
{
OperatorHandle A_r, A_i;
if (RealInteg())
{
pblfr->FormRectangularSystemMatrix(trial_tdof_list, test_tdof_list, A_r);
}
if (ImagInteg())
{
pblfi->FormRectangularSystemMatrix(trial_tdof_list, test_tdof_list, A_i);
}
if (!RealInteg() && !ImagInteg())
{
MFEM_ABORT("Both Real and Imaginary part of the MixedSesquilinear form are empty");
}
// A = A_r + i A_i
A.Clear();
if ( A_r.Type() == Operator::Hypre_ParCSR ||
A_i.Type() == Operator::Hypre_ParCSR )
{
ComplexHypreParMatrix * A_hyp =
new ComplexHypreParMatrix(A_r.As<HypreParMatrix>(),
A_i.As<HypreParMatrix>(),
A_r.OwnsOperator(),
A_i.OwnsOperator(),
conv);
A.Reset<ComplexHypreParMatrix>(A_hyp, true);
}
else
{
ComplexOperator * A_op =
new ComplexOperator(A_r.As<Operator>(),
A_i.As<Operator>(),
A_r.OwnsOperator(),
A_i.OwnsOperator(),
conv);
A.Reset<ComplexOperator>(A_op, true);
}
A_r.SetOperatorOwner(false);
A_i.SetOperatorOwner(false);
}
void
ParMixedSesquilinearForm::Update()
{
if ( pblfr ) { pblfr->Update(); }
if ( pblfi ) { pblfi->Update(); }
}
#endif // MFEM_USE_MPI
}
+135
View File
@@ -682,6 +682,141 @@ public:
virtual ~ParSesquilinearForm();
};
/** Class for a parallel mixed sesquilinear form
A sesquilinear form is a generalization of a mixed bilinear form to
complex-valued fields. Sesquilinear forms are linear in the second argument
but the first argument involves a complex conjugate in the sense that:
a(alpha u, beta v) = conj(alpha) beta a(u, v)
The @a convention argument in the class's constructor is documented in the
mfem::ComplexOperator class found in linalg/complex_operator.hpp.
When supplying integrators to the ParSesquilinearForm either the real or
imaginary integrator can be NULL. This indicates that the corresponding
portion of the complex-valued material coefficient is equal to zero.
*/
class ParMixedSesquilinearForm
{
private:
ComplexOperator::Convention conv;
ParMixedBilinearForm *pblfr;
ParMixedBilinearForm *pblfi;
/* These methods check if the real/imag parts of the sesqulinear form are not
empty */
bool RealInteg();
bool ImagInteg();
public:
ParMixedSesquilinearForm(ParFiniteElementSpace *tr_pf,
ParFiniteElementSpace *te_pf,
ComplexOperator::Convention
convention = ComplexOperator::HERMITIAN);
/** @brief Create a ParMixedSesquilinearForm on the ParFiniteElementSpaces
@a tr_pf and @a te_pf, using the same integrators as the
ParMixedBilinearForms @a pbfr and @a pbfi .
The pointer @a pf is not owned by the newly constructed object.
The integrators are copied as pointers and they are not owned by the
newly constructed ParSesquilinearForm. */
ParMixedSesquilinearForm(ParFiniteElementSpace *tr_pf,
ParFiniteElementSpace *te_pf,
ParMixedBilinearForm *pbfr,
ParMixedBilinearForm *pbfi,
ComplexOperator::Convention
convention = ComplexOperator::HERMITIAN);
ComplexOperator::Convention GetConvention() const { return conv; }
void SetConvention(const ComplexOperator::Convention &
convention) { conv = convention; }
/// Set the desired assembly level.
/** Valid choices are:
- AssemblyLevel::LEGACYFULL (default)
- AssemblyLevel::FULL
- AssemblyLevel::PARTIAL
- AssemblyLevel::ELEMENT
- AssemblyLevel::NONE
This method must be called before assembly. */
void SetAssemblyLevel(AssemblyLevel assembly_level)
{
pblfr->SetAssemblyLevel(assembly_level);
pblfi->SetAssemblyLevel(assembly_level);
}
ParMixedBilinearForm & real() { return *pblfr; }
ParMixedBilinearForm & imag() { return *pblfi; }
const ParMixedBilinearForm & real() const { return *pblfr; }
const ParMixedBilinearForm & imag() const { return *pblfi; }
/// Matrix multiplication: \f$ y = M x \f$
void Mult(const ParComplexGridFunction & x,
ParComplexLinearForm & y) const;
/// Adds new Domain Integrator.
void AddDomainIntegrator(BilinearFormIntegrator *bfi_real,
BilinearFormIntegrator *bfi_imag);
/// Adds new Boundary Integrator.
void AddBoundaryIntegrator(BilinearFormIntegrator *bfi_real,
BilinearFormIntegrator *bfi_imag);
/** @brief Adds new boundary Integrator, restricted to specific boundary
attributes.
Assumes ownership of @a bfi.
The array @a bdr_marker is stored internally as a pointer to the given
Array<int> object. */
void AddBoundaryIntegrator(BilinearFormIntegrator *bfi_real,
BilinearFormIntegrator *bfi_imag,
Array<int> &bdr_marker);
/// Adds new Face Integrator. Assumes ownership of @a bfi.
void AddTraceFaceIntegrator(BilinearFormIntegrator *bfi_real,
BilinearFormIntegrator *bfi_imag);
/// Adds new boundary Face Integrator. Assumes ownership of @a bfi.
void AddBdrTraceFaceIntegrator(BilinearFormIntegrator *bfi_real,
BilinearFormIntegrator *bfi_imag);
/** @brief Adds new boundary Face Integrator, restricted to specific boundary
attributes.
Assumes ownership of @a bfi.
The array @a bdr_marker is stored internally as a pointer to the given
Array<int> object. */
void AddBdrTraceFaceIntegrator(BilinearFormIntegrator *bfi_real,
BilinearFormIntegrator *bfi_imag,
Array<int> &bdr_marker);
/// Assemble the local matrix
void Assemble(int skip_zeros = 1);
/// Finalizes the matrix initialization.
void Finalize(int skip_zeros = 1);
/// Returns the matrix assembled on the true dofs, i.e. P_test^t A P_trial.
/** The returned matrix has to be deleted by the caller. */
ComplexHypreParMatrix *ParallelAssemble();
void FormRectangularSystemMatrix(const Array<int> &trial_tdof_list,
const Array<int> &test_tdof_list,
OperatorHandle &A);
virtual void Update();
virtual ~ParMixedSesquilinearForm();
};
#endif // MFEM_USE_MPI
}
+6 -4
View File
@@ -166,19 +166,21 @@ void DGMassInverse::DGMassCGIteration(const Vector &b_, Vector &u_) const
b = b_.Read();
}
static constexpr int NB = Q1D ? Q1D : 1; // block size
constexpr int NB = Q1D ? Q1D : 1; // block size
mfem::forall_2D(NE, NB, NB, [=] MFEM_HOST_DEVICE (int e)
{
constexpr int NB = Q1D ? Q1D : 1; // redefine here for some compilers
// Perform change of basis if needed
if (CHANGE_BASIS)
{
// Transform RHS
DGMassBasis<DIM,D1D>(e, NE, q2d_Bt, b_orig, b2, d1d);
DGMassBasis<DIM,D1D,MAX_D1D>(e, NE, q2d_Bt, b_orig, b2, d1d);
if (IT_MODE)
{
// Transform initial guess
DGMassBasis<DIM,D1D>(e, NE, d2q_B, u, u, d1d);
DGMassBasis<DIM,D1D,MAX_D1D>(e, NE, d2q_B, u, u, d1d);
}
}
@@ -255,7 +257,7 @@ void DGMassInverse::DGMassCGIteration(const Vector &b_, Vector &u_) const
if (CHANGE_BASIS)
{
DGMassBasis<DIM,D1D>(e, NE, q2d_B, u, u, d1d);
DGMassBasis<DIM,D1D,MAX_D1D>(e, NE, q2d_B, u, u, d1d);
}
});
}
+7 -7
View File
@@ -172,7 +172,7 @@ double DGMassDot(const int e,
return s_dot[0];
}
template<int T_D1D = 0>
template<int T_D1D = 0, int MAX_D1D = 0>
MFEM_HOST_DEVICE inline
void DGMassBasis2D(const int e,
const int NE,
@@ -181,7 +181,7 @@ void DGMassBasis2D(const int e,
double *y_,
const int d1d = 0)
{
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
const int D1D = T_D1D ? T_D1D : d1d;
const auto b = Reshape(b_, D1D, D1D);
@@ -213,7 +213,7 @@ void DGMassBasis2D(const int e,
MFEM_SYNC_THREAD;
}
template<int T_D1D = 0>
template<int T_D1D = 0, int MAX_D1D = 0>
MFEM_HOST_DEVICE inline
void DGMassBasis3D(const int e,
const int NE,
@@ -228,7 +228,7 @@ void DGMassBasis3D(const int e,
const auto x = Reshape(x_, D1D, D1D, D1D, NE);
auto y = Reshape(y_, D1D, D1D, D1D, NE);
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
MFEM_SHARED double sB[MD1*MD1];
MFEM_SHARED double sm0[MD1*MD1*MD1];
@@ -260,7 +260,7 @@ void DGMassBasis3D(const int e,
MFEM_SYNC_THREAD;
}
template<int DIM, int T_D1D = 0>
template<int DIM, int T_D1D = 0, int MAX_D1D = 0>
MFEM_HOST_DEVICE inline
void DGMassBasis(const int e,
const int NE,
@@ -271,11 +271,11 @@ void DGMassBasis(const int e,
{
if (DIM == 2)
{
DGMassBasis2D<T_D1D>(e, NE, b_, x_, y_, d1d);
DGMassBasis2D<T_D1D, MAX_D1D>(e, NE, b_, x_, y_, d1d);
}
else if (DIM == 3)
{
DGMassBasis3D<T_D1D>(e, NE, b_, x_, y_, d1d);
DGMassBasis3D<T_D1D, MAX_D1D>(e, NE, b_, x_, y_, d1d);
}
else
{
+1 -1
View File
@@ -125,7 +125,7 @@ public:
DofTransformation objects are provided by the FiniteElementSpace which has
access to the mesh and can therefore provide the face orientations. This is
convenient when working with GridFunction, LinearForm, or BilinearForm
objects or their parallel counterparts.
obejcts or their parallel counterparts.
StatelessDofTransformation objects are provided by FiniteElement or
FiniteElementCollection objects which do not have access to face
-1
View File
@@ -492,7 +492,6 @@ int IsoparametricTransformation::OrderGrad(const FiniteElement *fe) const
void IsoparametricTransformation::Transform (const IntegrationPoint &ip,
Vector &trans)
{
MFEM_ASSERT(FElem != nullptr, "Must provide a valid FiniteElement object!");
shape.SetSize(FElem->GetDof());
trans.SetSize(PointMat.Height());
+60
View File
@@ -498,4 +498,64 @@ void LpErrorEstimator::ComputeEstimates()
current_sequence = sol->FESpace()->GetMesh()->GetSequence();
}
void ComplexLpErrorEstimator::ComputeEstimates()
{
MFEM_VERIFY(real_coef != NULL || real_vcoef != NULL,
"ComplexLpErrorEstimator has no coefficient "
"for the real part! "
"Call SetRealCoef first.");
MFEM_VERIFY(imag_coef != NULL || imag_vcoef != NULL,
"ComplexLpErrorEstimator has no coefficient "
"for the imaginary part! "
"Call SetImagCoef first.");
int ne = 0;
if (sol) { ne = sol->FESpace()->GetMesh()->GetNE(); }
#ifdef MFEM_USE_MPI
if (par_sol) { ne = par_sol->FESpace()->GetMesh()->GetNE(); }
#endif
error_estimates.SetSize(ne);
const Vector & real_errors = real_estimator.GetLocalErrors();
const Vector & imag_errors = imag_estimator.GetLocalErrors();
if (local_norm_p < infinity())
{
for (int i=0; i<ne; i++)
{
const double re = pow(real_errors[i], local_norm_p);
const double ie = pow(imag_errors[i], local_norm_p);
error_estimates[i] = pow(re + ie, 1./local_norm_p);
}
}
else
{
for (int i=0; i<ne; i++)
{
error_estimates[i] = std::max(real_errors[i], imag_errors[i]);
}
}
/*
#ifdef MFEM_USE_MPI
total_error = error_estimates.Sum();
auto pfes = dynamic_cast<ParFiniteElementSpace*>(sol->FESpace());
if (pfes)
{
auto process_local_error = total_error;
MPI_Allreduce(&process_local_error, &total_error, 1, MPI_DOUBLE,
MPI_SUM, pfes->GetComm());
}
#endif // MFEM_USE_MPI
total_error = pow(total_error, 1.0/local_norm_p);
*/
current_sequence = -1;
if (sol) { current_sequence = sol->FESpace()->GetMesh()->GetSequence(); }
#ifdef MFEM_USE_MPI
if (par_sol)
{ current_sequence = par_sol->FESpace()->GetMesh()->GetSequence(); }
#endif
}
} // namespace mfem
+195
View File
@@ -17,6 +17,7 @@
#include "../config/config.hpp"
#include "../linalg/vector.hpp"
#include "bilinearform.hpp"
#include "complex_fem.hpp"
#ifdef MFEM_USE_MPI
#include "pgridfunc.hpp"
#endif
@@ -519,6 +520,200 @@ public:
};
/** @brief The ComplexLpErrorEstimator class compares the solution to a known
coefficient.
This class can be used, for example, to adapt a mesh to a non-trivial
initial condition in a time-dependent simulation. It can also be used to
force refinement in the neighborhood of small features before switching to a
more traditional error estimator.
The ComplexLpErrorEstimator supports either complex-valued scalar or vector\ coefficients and works both in serial and in parallel.
*/
class ComplexLpErrorEstimator : public ErrorEstimator
{
protected:
long current_sequence;
int local_norm_p;
Vector error_estimates;
// double total_error = 0.0;
Coefficient * real_coef;
Coefficient * imag_coef;
VectorCoefficient * real_vcoef;
VectorCoefficient * imag_vcoef;
ComplexGridFunction * sol;
#ifdef MFEM_USE_MPI
ParComplexGridFunction * par_sol;
#endif
LpErrorEstimator real_estimator;
LpErrorEstimator imag_estimator;
/// Check if the mesh of the solution was modified.
bool MeshIsModified()
{
long mesh_sequence = 0;
if (sol) { mesh_sequence = sol->FESpace()->GetMesh()->GetSequence(); }
#ifdef MFEM_USE_MPI
if (par_sol)
{ mesh_sequence = par_sol->FESpace()->GetMesh()->GetSequence(); }
#endif
MFEM_ASSERT(mesh_sequence >= current_sequence, "");
return (mesh_sequence > current_sequence);
}
/// Compute the element error estimates.
void ComputeEstimates();
public:
/** @brief Construct a new ComplexLpErrorEstimator object for a scalar field.
@param p Integer which selects which Lp norm to use.
@param sol The ComplexGridFunction representation of the scalar field.
Note: the coefficient must be set before use with the SetCoef method.
*/
ComplexLpErrorEstimator(int p, ComplexGridFunction &sol)
: current_sequence(-1), local_norm_p(p),
error_estimates(0),
real_coef(NULL), imag_coef(NULL),
real_vcoef(NULL), imag_vcoef(NULL), sol(&sol),
#ifdef MFEM_USE_MPI
par_sol(NULL),
#endif
real_estimator(p, sol.real()), imag_estimator(p, sol.imag()) { }
/** @brief Construct a new ComplexLpErrorEstimator object for a scalar field.
@param p Integer which selects which Lp norm to use.
@param real_coef The scalar Coefficient to compare to the real part of
the solution.
@param imag_coef The scalar Coefficient to compare to the imaginary part
of the solution.
@param sol The ComplexGridFunction representation of the scalar field.
*/
ComplexLpErrorEstimator(int p,
Coefficient &real_coef, Coefficient &imag_coef,
ComplexGridFunction &sol)
: current_sequence(-1), local_norm_p(p),
error_estimates(0),
real_coef(&real_coef), imag_coef(&imag_coef),
real_vcoef(NULL), imag_vcoef(NULL), sol(&sol),
#ifdef MFEM_USE_MPI
par_sol(NULL),
#endif
real_estimator(p, real_coef, sol.real()),
imag_estimator(p, imag_coef, sol.imag()) { }
/** @brief Construct a new ComplexLpErrorEstimator object for a vector field.
@param p Integer which selects which Lp norm to use.
@param real_coef The vector VectorCoefficient to compare to the real
part of the solution.
@param imag_coef The vector VectorCoefficient to compare to the
imaginary part of the solution.
@param sol The ComplexGridFunction representation of the vector field.
*/
ComplexLpErrorEstimator(int p,
VectorCoefficient &real_coef,
VectorCoefficient &imag_coef,
ComplexGridFunction &sol)
: current_sequence(-1), local_norm_p(p),
error_estimates(0),
real_coef(NULL), imag_coef(NULL),
real_vcoef(&real_coef), imag_vcoef(&imag_coef), sol(&sol),
#ifdef MFEM_USE_MPI
par_sol(NULL),
#endif
real_estimator(p, real_coef, sol.real()),
imag_estimator(p, imag_coef, sol.imag()) { }
#ifdef MFEM_USE_MPI
/** @brief Construct a new ComplexLpErrorEstimator object for a scalar field.
@param p Integer which selects which Lp norm to use.
@param sol The ComplexGridFunction representation of the scalar field.
Note: the coefficient must be set before use with the SetCoef method.
*/
ComplexLpErrorEstimator(int p, ParComplexGridFunction &par_sol)
: current_sequence(-1), local_norm_p(p),
error_estimates(0),
real_coef(NULL), imag_coef(NULL),
real_vcoef(NULL), imag_vcoef(NULL),
sol(NULL), par_sol(&par_sol),
real_estimator(p, par_sol.real()), imag_estimator(p, par_sol.imag()) { }
/** @brief Construct a new ComplexLpErrorEstimator object for a scalar field.
@param p Integer which selects which Lp norm to use.
@param real_coef The scalar Coefficient to compare to the real part of
the solution.
@param imag_coef The scalar Coefficient to compare to the imaginary part
of the solution.
@param sol The ComplexGridFunction representation of the scalar field.
*/
ComplexLpErrorEstimator(int p,
Coefficient &real_coef, Coefficient &imag_coef,
ParComplexGridFunction &par_sol)
: current_sequence(-1), local_norm_p(p),
error_estimates(0),
real_coef(&real_coef), imag_coef(&imag_coef),
real_vcoef(NULL), imag_vcoef(NULL),
sol(NULL), par_sol(&par_sol),
real_estimator(p, real_coef, par_sol.real()),
imag_estimator(p, imag_coef, par_sol.imag()) { }
/** @brief Construct a new ComplexLpErrorEstimator object for a vector field.
@param p Integer which selects which Lp norm to use.
@param real_coef The vector VectorCoefficient to compare to the real
part of the solution.
@param imag_coef The vector VectorCoefficient to compare to the
imaginary part of the solution.
@param sol The ComplexGridFunction representation of the vector field.
*/
ComplexLpErrorEstimator(int p,
VectorCoefficient &real_coef,
VectorCoefficient &imag_coef,
ParComplexGridFunction &par_sol)
: current_sequence(-1), local_norm_p(p),
error_estimates(0),
real_coef(NULL), imag_coef(NULL),
real_vcoef(&real_coef), imag_vcoef(&imag_coef),
sol(NULL), par_sol(&par_sol),
real_estimator(p, real_coef, par_sol.real()),
imag_estimator(p, imag_coef, par_sol.imag()) { }
#endif
/** @brief Set the exponent, p, of the Lp norm used for computing the local
element errors. */
void SetLocalErrorNormP(int p)
{
local_norm_p = p;
real_estimator.SetLocalErrorNormP(p);
imag_estimator.SetLocalErrorNormP(p);
}
void SetRealCoef(Coefficient &A)
{ real_coef = &A; real_estimator.SetCoef(A); }
void SetImagCoef(Coefficient &A)
{ imag_coef = &A; imag_estimator.SetCoef(A); }
void SetRealCoef(VectorCoefficient &A)
{ real_vcoef = &A; real_estimator.SetCoef(A); }
void SetImagCoef(VectorCoefficient &A)
{ imag_vcoef = &A; imag_estimator.SetCoef(A); }
/// Reset the error estimator.
virtual void Reset() override
{ current_sequence = -1; real_estimator.Reset(); imag_estimator.Reset(); }
/// Get a Vector with all element errors.
virtual const Vector &GetLocalErrors() override
{
if (MeshIsModified()) { ComputeEstimates(); }
return error_estimates;
}
/// Destructor
virtual ~ComplexLpErrorEstimator() {}
};
/** @brief The KellyErrorEstimator class provides a fast error indication
strategy for smooth scalar parallel problems.
+1 -1
View File
@@ -807,7 +807,7 @@ void NodalFiniteElement::Project(
else
{
DenseMatrix vshape(fe.GetDof(), std::max(Trans.GetSpaceDim(),
fe.GetRangeDim()));
fe.GetVDim()));
I.SetSize(vshape.Width()*dof, fe.GetDof());
for (int k = 0; k < dof; k++)
+6 -7
View File
@@ -307,20 +307,19 @@ public:
FiniteElement(int D, Geometry::Type G, int Do, int O,
int F = FunctionSpace::Pk);
/// Returns the reference space dimension for the finite element.
/// Returns the reference space dimension for the finite element
int GetDim() const { return dim; }
/** @brief Returns the vector dimension for vector-valued finite elements,
which is also the dimension of the interpolation operatrion. */
int GetRangeDim() const { return vdim; }
/// Returns the vector dimension for vector-valued finite elements
int GetVDim() const { return vdim; }
/// Returns the dimension of the curl for vector-valued finite elements.
/// Returns the dimension of the curl for vector-valued finite elements
int GetCurlDim() const { return cdim; }
/// Returns the Geometry::Type of the reference element.
/// Returns the Geometry::Type of the reference element
Geometry::Type GetGeomType() const { return geom_type; }
/// Returns the number of degrees of freedom in the finite element.
/// Returns the number of degrees of freedom in the finite element
int GetDof() const { return dof; }
/** @brief Returns the order of the finite element. In the case of
+2 -2
View File
@@ -1852,7 +1852,7 @@ void ND_R1D_SegmentElement::Project(const FiniteElement &fe,
else
{
double vk[Geometry::MaxDim];
DenseMatrix vshape(fe.GetDof(), fe.GetRangeDim());
DenseMatrix vshape(fe.GetDof(), fe.GetVDim());
double * tk_ptr = const_cast<double*>(tk);
@@ -2293,7 +2293,7 @@ void ND_R2D_FiniteElement::Project(const FiniteElement &fe,
else
{
double vk[Geometry::MaxDim];
DenseMatrix vshape(fe.GetDof(), fe.GetRangeDim());
DenseMatrix vshape(fe.GetDof(), fe.GetVDim());
double * tk_ptr = const_cast<double*>(tk);
+4 -4
View File
@@ -1486,7 +1486,7 @@ void RT_R1D_SegmentElement::Project(const FiniteElement &fe,
else
{
double vk[Geometry::MaxDim];
DenseMatrix vshape(fe.GetDof(), fe.GetRangeDim());
DenseMatrix vshape(fe.GetDof(), fe.GetVDim());
double * nk_ptr = const_cast<double*>(nk);
@@ -1523,7 +1523,7 @@ void RT_R1D_SegmentElement::ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
{
DenseMatrix curl_shape(fe.GetDof(), fe.GetRangeDim());
DenseMatrix curl_shape(fe.GetDof(), fe.GetVDim());
Vector curl_k(fe.GetDof());
double * nk_ptr = const_cast<double*>(nk);
@@ -1849,7 +1849,7 @@ void RT_R2D_FiniteElement::Project(const FiniteElement &fe,
else
{
double vk[Geometry::MaxDim];
DenseMatrix vshape(fe.GetDof(), fe.GetRangeDim());
DenseMatrix vshape(fe.GetDof(), fe.GetVDim());
double * nk_ptr = const_cast<double*>(nk);
@@ -1888,7 +1888,7 @@ void RT_R2D_FiniteElement::ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
{
DenseMatrix curl_shape(fe.GetDof(), fe.GetRangeDim());
DenseMatrix curl_shape(fe.GetDof(), fe.GetVDim());
Vector curl_k(fe.GetDof());
double * nk_ptr = const_cast<double*>(nk);
-10
View File
@@ -87,16 +87,6 @@ int FiniteElementCollection::GetDerivMapType(int dim) const
return FiniteElement::UNKNOWN_MAP_TYPE;
}
int FiniteElementCollection::GetRangeDim(int dim) const
{
const FiniteElement *fe = FiniteElementForDim(dim);
if (fe)
{
return fe->GetRangeDim();
}
return 0;
}
int FiniteElementCollection::HasFaceDofs(Geometry::Type geom, int p) const
{
switch (geom)
+292 -346
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -26,7 +26,6 @@
#include "bilininteg.hpp"
#include "fespace.hpp"
#include "gridfunc.hpp"
#include "kdtree.hpp"
#include "linearform.hpp"
#include "nonlinearform.hpp"
#include "bilinearform.hpp"
+28 -67
View File
@@ -64,7 +64,7 @@ FiniteElementSpace::FiniteElementSpace()
face_dof(NULL),
NURBSext(NULL), own_ext(false),
DoFTrans(0), VDoFTrans(vdim, ordering),
cP_is_set(false),
cP(NULL), cR(NULL), cR_hp(NULL), cP_is_set(false),
Th(Operator::ANY_TYPE),
sequence(0), mesh_sequence(0), orders_changed(false), relaxed_hp(false)
{ }
@@ -123,24 +123,24 @@ void FiniteElementSpace::CopyProlongationAndRestriction(
if (fes.GetConformingProlongation() != NULL)
{
if (perm) { cP.reset(Mult(*perm_mat, *fes.GetConformingProlongation())); }
else { cP.reset(new SparseMatrix(*fes.GetConformingProlongation())); }
if (perm) { cP = Mult(*perm_mat, *fes.GetConformingProlongation()); }
else { cP = new SparseMatrix(*fes.GetConformingProlongation()); }
cP_is_set = true;
}
else if (perm != NULL)
{
cP.reset(perm_mat);
cP = perm_mat;
cP_is_set = true;
perm_mat = NULL;
}
if (fes.GetConformingRestriction() != NULL)
{
if (perm) { cR.reset(Mult(*fes.GetConformingRestriction(), *perm_mat_tr)); }
else { cR.reset(new SparseMatrix(*fes.GetConformingRestriction())); }
if (perm) { cR = Mult(*fes.GetConformingRestriction(), *perm_mat_tr); }
else { cR = new SparseMatrix(*fes.GetConformingRestriction()); }
}
else if (perm != NULL)
{
cR.reset(perm_mat_tr);
cR = perm_mat_tr;
perm_mat_tr = NULL;
}
@@ -960,10 +960,7 @@ void FiniteElementSpace::BuildConformingInterpolation() const
if (FEColl()->GetContType() == FiniteElementCollection::DISCONTINUOUS)
{
cP.reset();
cR.reset();
cR_hp.reset();
R_transpose.reset();
cP = cR = cR_hp = NULL; // will be treated as identities
return;
}
@@ -1117,15 +1114,12 @@ void FiniteElementSpace::BuildConformingInterpolation() const
// if all dofs are true dofs leave cP and cR NULL
if (n_true_dofs == ndofs)
{
cP.reset();
cR.reset();
cR_hp.reset();
R_transpose.reset();
cP = cR = cR_hp = NULL; // will be treated as identities
return;
}
// create the conforming prolongation matrix cP
cP.reset(new SparseMatrix(ndofs, n_true_dofs));
cP = new SparseMatrix(ndofs, n_true_dofs);
// create the conforming restriction matrix cR
int *cR_J;
@@ -1139,19 +1133,12 @@ void FiniteElementSpace::BuildConformingInterpolation() const
cR_A[i] = 1.0;
}
cR_I[n_true_dofs] = n_true_dofs;
cR.reset(new SparseMatrix(cR_I, cR_J, cR_A, n_true_dofs, ndofs));
cR = new SparseMatrix(cR_I, cR_J, cR_A, n_true_dofs, ndofs);
}
// In var. order spaces, create the restriction matrix cR_hp which is similar
// to cR, but has interpolation in the extra master edge/face DOFs.
if (IsVariableOrder())
{
cR_hp.reset(new SparseMatrix(n_true_dofs, ndofs));
}
else
{
cR_hp.reset();
}
cR_hp = IsVariableOrder() ? new SparseMatrix(n_true_dofs, ndofs) : NULL;
Array<bool> finalized(ndofs);
finalized = false;
@@ -1269,28 +1256,21 @@ const SparseMatrix* FiniteElementSpace::GetConformingProlongation() const
{
if (Conforming()) { return NULL; }
if (!cP_is_set) { BuildConformingInterpolation(); }
return cP.get();
return cP;
}
const SparseMatrix* FiniteElementSpace::GetConformingRestriction() const
{
if (Conforming()) { return NULL; }
if (!cP_is_set) { BuildConformingInterpolation(); }
if (cR && !R_transpose) { R_transpose.reset(new TransposeOperator(*cR)); }
return cR.get();
return cR;
}
const SparseMatrix* FiniteElementSpace::GetHpConformingRestriction() const
{
if (Conforming()) { return NULL; }
if (!cP_is_set) { BuildConformingInterpolation(); }
return IsVariableOrder() ? cR_hp.get() : cR.get();
}
const Operator *FiniteElementSpace::GetRestrictionTransposeOperator() const
{
GetRestrictionOperator(); // Ensure that R_transpose is built
return R_transpose.get();
return IsVariableOrder() ? cR_hp : cR;
}
int FiniteElementSpace::GetNConformingDofs() const
@@ -2221,10 +2201,7 @@ void FiniteElementSpace::Constructor(Mesh *mesh_, NURBSExtension *NURBSext_,
own_ext = 1;
}
UpdateNURBS();
cP.reset();
cR.reset();
cR_hp.reset();
R_transpose.reset();
cP = cR = cR_hp = NULL;
cP_is_set = false;
ConstructDoFTrans();
@@ -2386,7 +2363,6 @@ void FiniteElementSpace::Construct()
cR = NULL;
cR_hp = NULL;
cP_is_set = false;
R_transpose = NULL;
// 'Th' is initialized/destroyed before this method is called.
int dim = mesh->Dimension();
@@ -2428,7 +2404,6 @@ void FiniteElementSpace::Construct()
{
// the simple case: all edges are of the same order
nedofs = mesh->GetNEdges() * fec->GetNumDof(Geometry::SEGMENT, order);
var_edge_dofs.Clear(); // ensure any old var_edge_dof table is dumped.
}
}
@@ -2447,7 +2422,6 @@ void FiniteElementSpace::Construct()
// the simple case: all faces are of the same geometry and order
uni_fdof = fec->GetNumDof(mesh->GetFaceGeometry(0), order);
nfdofs = mesh->GetNFaces() * uni_fdof;
var_face_dofs.Clear(); // ensure any old var_face_dof table is dumped.
}
}
@@ -2658,6 +2632,7 @@ int FiniteElementSpace::MakeDofTable(int ent_dim,
int dofs = fec->GetNumDof(geom, order);
list.Append(Connection(i, total_dofs));
total_dofs += dofs;
if (var_ent_order) { var_ent_order->Append(order); }
}
}
@@ -2668,6 +2643,7 @@ int FiniteElementSpace::MakeDofTable(int ent_dim,
// build the table
entity_dofs.MakeFromList(num_ent+1, list);
return total_dofs;
}
@@ -2840,15 +2816,9 @@ void FiniteElementSpace::GetPatchDofs(int patch, Array<int> &dofs) const
const FiniteElement *FiniteElementSpace::GetFE(int i) const
{
if (i < 0 || i >= mesh->GetNE())
{
if (mesh->GetNE() == 0)
{
MFEM_ABORT("Empty MPI partitions are not permitted!");
}
MFEM_ABORT("Invalid element id:" << i << "; minimum allowed:" << 0 <<
", maximum allowed:" << mesh->GetNE()-1);
}
if (i < 0 || !mesh->GetNE()) { return NULL; }
MFEM_VERIFY(i < mesh->GetNE(),
"Invalid element id " << i << ", maximum allowed " << mesh->GetNE()-1);
const FiniteElement *FE =
fec->GetFE(mesh->GetElementGeometry(i), GetElementOrderImpl(i));
@@ -2996,14 +2966,7 @@ int FiniteElementSpace::GetFaceDofs(int face, Array<int> &dofs,
order = !IsVariableOrder() ? fec->GetOrder() :
var_face_orders[var_face_dofs.GetI()[face] + variant];
MFEM_ASSERT(fec->GetNumDof(fgeom, order) == nf, [&]()
{
std::stringstream msg;
msg << "fec->GetNumDof(" << (fgeom == Geometry::SQUARE ? "square" : "triangle")
<< ", " << order << ") = " << fec->GetNumDof(fgeom, order) << " nf " << nf;
msg << " face " << face << " variant " << variant << std::endl;
return msg.str();
}());
MFEM_ASSERT(fec->GetNumDof(fgeom, order) == nf, "");
}
else
{
@@ -3255,10 +3218,9 @@ FiniteElementSpace::~FiniteElementSpace()
void FiniteElementSpace::Destroy()
{
R_transpose.reset();
cR.reset();
cR_hp.reset();
cP.reset();
delete cR;
delete cR_hp;
delete cP;
Th.Clear();
L2E_nat.Clear();
L2E_lex.Clear();
@@ -3271,7 +3233,6 @@ void FiniteElementSpace::Destroy()
{
delete x.second;
}
L2F.clear();
for (int i = 0; i < E2IFQ_array.Size(); i++)
{
delete E2IFQ_array[i];
@@ -3371,14 +3332,14 @@ void FiniteElementSpace::GetTrueTransferOperator(
switch (RP_case)
{
case 1:
T.Reset(new ProductOperator(cR.get(), T.Ptr(), false, owner));
T.Reset(new ProductOperator(cR, T.Ptr(), false, owner));
break;
case 2:
T.Reset(new ProductOperator(T.Ptr(), coarse_P, owner, false));
break;
case 3:
T.Reset(new TripleProductOperator(
cR.get(), T.Ptr(), coarse_P, false, owner, false));
cR, T.Ptr(), coarse_P, false, owner, false));
break;
}
}
@@ -3496,7 +3457,7 @@ void FiniteElementSpace::Update(bool want_transform)
if (cP && cR)
{
Th.SetOperatorOwner(false);
Th.Reset(new TripleProductOperator(cP.get(), cR.get(), Th.Ptr(),
Th.Reset(new TripleProductOperator(cP, cR, Th.Ptr(),
false, false, true));
}
break;
+10 -21
View File
@@ -214,7 +214,7 @@ class FaceQuadratureInterpolator;
@par
Clearly the notion of a @b vdof is relevant in each of the three contexts
mentioned above so extra care must be taken whenever @b vdim != 1 to ensure
that the @b edof, @b ldof, or @b tdof is being interpreted correctly.
that the @b edof, @b ldof, or @b tdof is being interpretted correctly.
*/
class FiniteElementSpace
{
@@ -277,14 +277,12 @@ protected:
/** Matrix representing the prolongation from the global conforming dofs to
a set of intermediate partially conforming dofs, e.g. the dofs associated
with a "cut" space on a non-conforming mesh. */
mutable std::unique_ptr<SparseMatrix> cP;
mutable SparseMatrix *cP; // owned
/// Conforming restriction matrix such that cR.cP=I.
mutable std::unique_ptr<SparseMatrix> cR;
mutable SparseMatrix *cR; // owned
/// A version of the conforming restriction matrix for variable-order spaces.
mutable std::unique_ptr<SparseMatrix> cR_hp;
mutable SparseMatrix *cR_hp; // owned
mutable bool cP_is_set;
/// Operator computing the action of the transpose of the restriction.
mutable std::unique_ptr<Operator> R_transpose;
/// Transformation to apply to GridFunctions after space Update().
OperatorHandle Th;
@@ -594,17 +592,10 @@ public:
{ return GetConformingProlongation(); }
/// Return an operator that performs the transpose of GetRestrictionOperator
/** The returned operator is owned by the FiniteElementSpace.
For a serial conforming space, this returns NULL, indicating the identity
operator.
For a parallel conforming space, this will return a matrix-free
(Device)ConformingProlongationOperator.
For a non-conforming mesh this will return a TransposeOperator wrapping
the restriction matrix. */
const Operator *GetRestrictionTransposeOperator() const;
/** The returned operator is owned by the FiniteElementSpace. In serial this
is the same as GetProlongationMatrix() */
virtual const Operator *GetRestrictionTransposeOperator() const
{ return GetConformingProlongation(); }
/// An abstract operator that performs the same action as GetRestrictionMatrix
/** In some cases this is an optimized matrix-free implementation. The
@@ -907,7 +898,7 @@ public:
/// changed in the forward mappings by passing a value for @a ndofs which
/// differs from that returned by GetNDofs().
///
/// @note These methods, with the exception of VDofToDof(), are designed to
/// @note Thse methods, with the exception of VDofToDof(), are designed to
/// produce the correctly encoded values when dof entries are negative,
/// see @ref ldof for more on negative dof indices.
///
@@ -1124,9 +1115,7 @@ public:
int GetLocalDofForDof(int i) const { return dof_ldof_array[i]; }
/** @brief Returns pointer to the FiniteElement in the FiniteElementCollection
associated with i'th element in the mesh object.
Note: The method has been updated to abort instead of returning NULL for
an empty partition. */
associated with i'th element in the mesh object. */
virtual const FiniteElement *GetFE(int i) const;
/** @brief Returns pointer to the FiniteElement in the FiniteElementCollection
+127 -57
View File
@@ -27,6 +27,7 @@
#include <iostream>
#include <algorithm>
namespace mfem
{
@@ -38,9 +39,8 @@ GridFunction::GridFunction(Mesh *m, std::istream &input)
// Grid functions are stored on the device
UseDevice(true);
owned_fes.reset(new FiniteElementSpace);
fes = owned_fes.get();
fec.reset(fes->Load(m, input));
fes = new FiniteElementSpace;
fec = fes->Load(m, input);
skip_comment_lines(input, '#');
istream::int_type next_char = input.peek();
@@ -82,11 +82,10 @@ GridFunction::GridFunction(Mesh *m, GridFunction *gf_array[], int num_pieces)
int vdim, ordering;
fes = gf_array[0]->FESpace();
fec.reset(FiniteElementCollection::New(fes->FEColl()->Name()));
fec = FiniteElementCollection::New(fes->FEColl()->Name());
vdim = fes->GetVDim();
ordering = fes->GetOrdering();
owned_fes.reset(new FiniteElementSpace(m, fec.get(), vdim, ordering));
fes = owned_fes.get();
fes = new FiniteElementSpace(m, fec, vdim, ordering);
SetSize(fes->GetVSize());
if (m->NURBSext)
@@ -155,9 +154,12 @@ GridFunction::GridFunction(Mesh *m, GridFunction *gf_array[], int num_pieces)
void GridFunction::Destroy()
{
owned_fes.reset();
fec.reset();
fes = nullptr;
if (fec)
{
delete fes;
delete fec;
fec = NULL;
}
}
void GridFunction::Update()
@@ -339,7 +341,7 @@ int GridFunction::VectorDim() const
return fes->GetVDim();
}
return fes->GetVDim()*std::max(fes->GetMesh()->SpaceDimension(),
fe->GetRangeDim());
fe->GetVDim());
}
int GridFunction::CurlDim() const
@@ -719,6 +721,56 @@ void GridFunction::GetVectorValues(int i, const IntegrationRule &ir,
GetVectorValues(*Tr, ir, vals);
}
void be_to_bfe(Geometry::Type geom, int o, const IntegrationPoint &ip,
IntegrationPoint &fip)
{
if (geom == Geometry::TRIANGLE)
{
if (o == 2)
{
fip.x = 1.0 - ip.x - ip.y;
fip.y = ip.x;
}
else if (o == 4)
{
fip.x = ip.y;
fip.y = 1.0 - ip.x - ip.y;
}
else
{
fip.x = ip.x;
fip.y = ip.y;
}
fip.z = ip.z;
}
else
{
if (o == 2)
{
fip.x = ip.y;
fip.y = 1.0 - ip.x;
}
else if (o == 4)
{
fip.x = 1.0 - ip.x;
fip.y = 1.0 - ip.y;
}
else if (o == 6)
{
fip.x = 1.0 - ip.y;
fip.y = ip.x;
}
else
{
fip.x = ip.x;
fip.y = ip.y;
}
fip.z = ip.z;
}
fip.weight = ip.weight;
fip.index = ip.index;
}
double GridFunction::GetValue(ElementTransformation &T,
const IntegrationPoint &ip,
int comp, Vector *tr) const
@@ -783,15 +835,18 @@ double GridFunction::GetValue(ElementTransformation &T,
// boundary so we'll evaluate it in the neighboring element.
FaceElementTransformations * FET =
fes->GetMesh()->GetBdrFaceTransformations(T.ElementNo);
MFEM_ASSERT(FET != nullptr,
"FaceElementTransformation must be valid for a boundary element");
// Boundary elements and boundary faces may have different
// Boundary elements and Boundary Faces may have different
// orientations so adjust the integration point if necessary.
int f, o;
fes->GetMesh()->GetBdrElementFace(T.ElementNo, &f, &o);
IntegrationPoint fip =
Mesh::TransformBdrElementToFace(FET->GetGeometryType(), o, ip);
int o = 0;
if (fes->GetMesh()->Dimension() == 3)
{
int f;
fes->GetMesh()->GetBdrElementFace(T.ElementNo, &f, &o);
}
IntegrationPoint fip;
be_to_bfe(FET->GetGeometryType(), o, ip, fip);
// Compute and set the point in element 1 from fip
FET->SetAllIntPoints(&fip);
@@ -919,15 +974,18 @@ void GridFunction::GetVectorValue(ElementTransformation &T,
// the boundary so we'll evaluate it in the neighboring element.
FaceElementTransformations * FET =
fes->GetMesh()->GetBdrFaceTransformations(T.ElementNo);
MFEM_ASSERT(FET != nullptr,
"FaceElementTransformation must be valid for a boundary element");
// Boundary elements and boundary faces may have different
// Boundary elements and Boundary Faces may have different
// orientations so adjust the integration point if necessary.
int f, o;
fes->GetMesh()->GetBdrElementFace(T.ElementNo, &f, &o);
IntegrationPoint fip =
Mesh::TransformBdrElementToFace(FET->GetGeometryType(), o, ip);
int o = 0;
if (fes->GetMesh()->Dimension() == 3)
{
int f;
fes->GetMesh()->GetBdrElementFace(T.ElementNo, &f, &o);
}
IntegrationPoint fip;
be_to_bfe(FET->GetGeometryType(), o, ip, fip);
// Compute and set the point in element 1 from fip
FET->SetAllIntPoints(&fip);
@@ -940,8 +998,6 @@ void GridFunction::GetVectorValue(ElementTransformation &T,
{
FaceElementTransformations * FET =
dynamic_cast<FaceElementTransformations *>(&T);
MFEM_ASSERT(FET != nullptr,
"FaceElementTransformation must be valid for a boundary element");
// Evaluate in neighboring element for both continuous and
// discontinuous fields (the integration point in T1 should have
@@ -986,7 +1042,7 @@ void GridFunction::GetVectorValue(ElementTransformation &T,
else
{
int spaceDim = fes->GetMesh()->SpaceDimension();
int vdim = std::max(spaceDim, fe->GetRangeDim());
int vdim = std::max(spaceDim, fe->GetVDim());
DenseMatrix vshape(dof, vdim);
fe->CalcVShape(T, vshape);
val.SetSize(vdim);
@@ -1038,7 +1094,7 @@ void GridFunction::GetVectorValues(ElementTransformation &T,
else
{
int spaceDim = fes->GetMesh()->SpaceDimension();
int vdim = std::max(spaceDim, FElem->GetRangeDim());
int vdim = std::max(spaceDim, FElem->GetVDim());
DenseMatrix vshape(dof, vdim);
vals.SetSize(vdim, nip);
@@ -1060,10 +1116,11 @@ int GridFunction::GetFaceVectorValues(
int i, int side, const IntegrationRule &ir,
DenseMatrix &vals, DenseMatrix &tr) const
{
int di;
int n, di;
FaceElementTransformations *Transf;
IntegrationRule eir(ir.GetNPoints()); // ---
n = ir.GetNPoints();
IntegrationRule eir(n); // ---
Transf = fes->GetMesh()->GetFaceElementTransformations(i, 0);
if (side == 2)
{
@@ -1085,14 +1142,12 @@ int GridFunction::GetFaceVectorValues(
if (di == 0)
{
Transf = fes->GetMesh()->GetFaceElementTransformations(i, 5);
MFEM_ASSERT(Transf != nullptr, "FaceElementTransformation cannot be null!");
Transf->Loc1.Transform(ir, eir);
GetVectorValues(*Transf->Elem1, eir, vals, &tr);
}
else
{
Transf = fes->GetMesh()->GetFaceElementTransformations(i, 10);
MFEM_ASSERT(Transf != nullptr, "FaceElementTransformation cannot be null!");
Transf->Loc2.Transform(ir, eir);
GetVectorValues(*Transf->Elem2, eir, vals, &tr);
}
@@ -1450,13 +1505,17 @@ double GridFunction::GetDivergence(ElementTransformation &T) const
FaceElementTransformations * FET =
fes->GetMesh()->GetBdrFaceTransformations(T.ElementNo);
// Boundary elements and boundary faces may have different
// Boundary elements and Boundary Faces may have different
// orientations so adjust the integration point if necessary.
int f, o;
fes->GetMesh()->GetBdrElementFace(T.ElementNo, &f, &o);
IntegrationPoint fip =
Mesh::TransformBdrElementToFace(FET->GetGeometryType(), o,
T.GetIntPoint());
int o = 0;
if (fes->GetMesh()->Dimension() == 3)
{
int f;
fes->GetMesh()->GetBdrElementFace(T.ElementNo, &f, &o);
}
IntegrationPoint fip;
be_to_bfe(FET->GetGeometryType(), o, T.GetIntPoint(), fip);
// Compute and set the point in element 1 from fip
FET->SetAllIntPoints(&fip);
@@ -1543,13 +1602,17 @@ void GridFunction::GetCurl(ElementTransformation &T, Vector &curl) const
FaceElementTransformations * FET =
fes->GetMesh()->GetBdrFaceTransformations(T.ElementNo);
// Boundary elements and boundary faces may have different
// Boundary elements and Boundary Faces may have different
// orientations so adjust the integration point if necessary.
int f, o;
fes->GetMesh()->GetBdrElementFace(T.ElementNo, &f, &o);
IntegrationPoint fip =
Mesh::TransformBdrElementToFace(FET->GetGeometryType(), o,
T.GetIntPoint());
int o = 0;
if (fes->GetMesh()->Dimension() == 3)
{
int f;
fes->GetMesh()->GetBdrElementFace(T.ElementNo, &f, &o);
}
IntegrationPoint fip;
be_to_bfe(FET->GetGeometryType(), o, T.GetIntPoint(), fip);
// Compute and set the point in element 1 from fip
FET->SetAllIntPoints(&fip);
@@ -1608,13 +1671,17 @@ void GridFunction::GetGradient(ElementTransformation &T, Vector &grad) const
FaceElementTransformations * FET =
fes->GetMesh()->GetBdrFaceTransformations(T.ElementNo);
// Boundary elements and boundary faces may have different
// Boundary elements and Boundary Faces may have different
// orientations so adjust the integration point if necessary.
int f, o;
fes->GetMesh()->GetBdrElementFace(T.ElementNo, &f, &o);
IntegrationPoint fip =
Mesh::TransformBdrElementToFace(FET->GetGeometryType(), o,
T.GetIntPoint());
int o = 0;
if (fes->GetMesh()->Dimension() == 3)
{
int f;
fes->GetMesh()->GetBdrElementFace(T.ElementNo, &f, &o);
}
IntegrationPoint fip;
be_to_bfe(FET->GetGeometryType(), o, T.GetIntPoint(), fip);
// Compute and set the point in element 1 from fip
FET->SetAllIntPoints(&fip);
@@ -1690,13 +1757,17 @@ void GridFunction::GetVectorGradient(
FaceElementTransformations * FET =
fes->GetMesh()->GetBdrFaceTransformations(T.ElementNo);
// Boundary elements and boundary faces may have different
// Boundary elements and Boundary Faces may have different
// orientations so adjust the integration point if necessary.
int f, o;
fes->GetMesh()->GetBdrElementFace(T.ElementNo, &f, &o);
IntegrationPoint fip =
Mesh::TransformBdrElementToFace(FET->GetGeometryType(), o,
T.GetIntPoint());
int o = 0;
if (fes->GetMesh()->Dimension() == 3)
{
int f;
fes->GetMesh()->GetBdrElementFace(T.ElementNo, &f, &o);
}
IntegrationPoint fip;
be_to_bfe(FET->GetGeometryType(), o, T.GetIntPoint(), fip);
// Compute and set the point in element 1 from fip
FET->SetAllIntPoints(&fip);
@@ -2667,7 +2738,6 @@ void GridFunction::ProjectBdrCoefficientNormal(
Array<int> dofs;
int dim = vcoeff.GetVDim();
Vector vc(dim), nor(dim), lvec;
for (int i = 0; i < fes->GetNBE(); i++)
{
if (bdr_attr[fes->GetBdrAttribute(i)-1] == 0)
+24 -7
View File
@@ -20,7 +20,6 @@
#include "../general/adios2stream.hpp"
#endif
#include <limits>
#include <memory>
#include <ostream>
#include <string>
@@ -31,13 +30,14 @@ namespace mfem
class GridFunction : public Vector
{
protected:
/// FE space on which the grid function lives.
/// FE space on which the grid function lives. Owned if #fec is not NULL.
FiniteElementSpace *fes;
/** @brief Used when the grid function is read from a file. It can also be
set explicitly, see MakeOwner(). */
std::shared_ptr<FiniteElementCollection> fec;
std::shared_ptr<FiniteElementSpace> owned_fes;
set explicitly, see MakeOwner().
If not NULL, this pointer is owned by the GridFunction. */
FiniteElementCollection *fec;
long fes_sequence; // see FiniteElementSpace::sequence, Mesh::sequence
@@ -74,6 +74,11 @@ public:
GridFunction() { fes = NULL; fec = NULL; fes_sequence = 0; UseDevice(true); }
/// Copy constructor. The internal true-dof vector #t_vec is not copied.
GridFunction(const GridFunction &orig)
: Vector(orig), fes(orig.fes), fec(NULL), fes_sequence(orig.fes_sequence)
{ UseDevice(true); }
/// Construct a GridFunction associated with the FiniteElementSpace @a *f.
GridFunction(FiniteElementSpace *f) : Vector(f->GetVSize())
{ fes = f; fec = NULL; fes_sequence = f->GetSequence(); UseDevice(true); }
@@ -102,12 +107,21 @@ public:
GridFunction(Mesh *m, GridFunction *gf_array[], int num_pieces);
/// Copy assignment. Only the data of the base class Vector is copied.
/** It is assumed that this object and @a rhs use FiniteElementSpace%s that
have the same size.
@note Defining this method overwrites the implicitly defined copy
assignment operator. */
GridFunction &operator=(const GridFunction &rhs)
{ return operator=((const Vector &)rhs); }
/// Make the GridFunction the owner of #fec and #fes.
/** If the new FiniteElementCollection, @a fec_, is NULL, ownership of #fec
and #fes is taken away. */
void MakeOwner(FiniteElementCollection *fec_) { fec.reset(fec_); }
void MakeOwner(FiniteElementCollection *fec_) { fec = fec_; }
FiniteElementCollection *OwnFEC() { return fec.get(); }
FiniteElementCollection *OwnFEC() { return fec; }
int VectorDim() const;
int CurlDim() const;
@@ -740,6 +754,9 @@ public:
/** @brief Write the GridFunction in STL format. Note that the mesh dimension
must be 2 and that quad elements will be broken into two triangles.*/
void SaveSTL(std::ostream &out, int TimesToRefine = 1);
/// Destroys grid function.
virtual ~GridFunction() { Destroy(); }
};
+8 -35
View File
@@ -10,7 +10,6 @@
// CONTRIBUTING.md for details.
#include "gslib.hpp"
#include "geom.hpp"
#ifdef MFEM_USE_GSLIB
@@ -239,8 +238,7 @@ void FindPointsGSLIB::FindPoints(const Vector &point_pos,
}
// Map element number for simplices, and ref_pos from [-1,1] to [0,1] for
// both simplices and quads. Also sets code to 1 for points found on element
// faces/edges.
// both simplices and quads.
MapRefPosAndElemIndices();
}
@@ -683,9 +681,6 @@ void FindPointsGSLIB::MapRefPosAndElemIndices()
int nptorig = points_cnt,
npt = points_cnt;
// tolerance for point to be marked as on element edge/face
double btol = 1e-12;
GridFunction *gf_rst_map_temp = NULL;
int nptsend = 0;
@@ -699,7 +694,7 @@ void FindPointsGSLIB::MapRefPosAndElemIndices()
// Pack data to send via crystal router
struct gslib::array *outpt = new gslib::array;
struct out_pt { double r[3]; uint index, el, proc, code; };
struct out_pt { double r[3]; uint index, el, proc; };
struct out_pt *pt;
array_init(struct out_pt, outpt, nptsend);
outpt->n=nptsend;
@@ -717,12 +712,12 @@ void FindPointsGSLIB::MapRefPosAndElemIndices()
pt->index = index;
pt->proc = gsl_proc[index];
pt->el = gsl_elem[index];
pt->code = gsl_code[index];
++pt;
}
// Transfer data to target MPI ranks
sarray_transfer(struct out_pt, outpt, proc, 1, cr);
// Map received points
npt = outpt->n;
pt = (struct out_pt *)outpt->ptr;
@@ -736,13 +731,7 @@ void FindPointsGSLIB::MapRefPosAndElemIndices()
const Geometry::Type gt = fe->GetGeomType();
pt->el = mesh_elem;
if (gt == Geometry::SQUARE || gt == Geometry::CUBE)
{
// check if it is on element boundary
pt->code = Geometry::CheckPoint(gt, ip, -btol) ? 0 : 1;
++pt;
continue;
}
if (gt == Geometry::SQUARE || gt == Geometry::CUBE) { ++pt; continue; }
else if (gt == Geometry::TRIANGLE)
{
gf_rst_map_temp = gf_rst_map[0];
@@ -769,10 +758,6 @@ void FindPointsGSLIB::MapRefPosAndElemIndices()
{
pt->r[d] = mfem_ref(d);
}
// check if point is on element boundary
ip.Set3(&pt->r[0]);
pt->code = Geometry::CheckPoint(gt, ip, -btol) ? 0 : 1;
++pt;
}
@@ -789,7 +774,6 @@ void FindPointsGSLIB::MapRefPosAndElemIndices()
{
gsl_mfem_ref(d + pt->index*dim) = pt->r[d];
}
gsl_code[pt->index] = pt->code;
++pt;
}
array_free(outpt);
@@ -800,22 +784,12 @@ void FindPointsGSLIB::MapRefPosAndElemIndices()
{
if (gsl_code[index] != 2 && gsl_proc[index] == gsl_comm->id)
{
IntegrationPoint ip;
Vector mfem_ref(gsl_mfem_ref.GetData()+index*dim, dim);
ip.Set2(mfem_ref.GetData());
if (dim == 3) { ip.z = mfem_ref(2); }
const int elem = gsl_elem[index];
const int mesh_elem = split_element_map[elem];
const FiniteElement *fe = mesh->GetNodalFESpace()->GetFE(mesh_elem);
const Geometry::Type gt = fe->GetGeomType();
gsl_mfem_elem[index] = mesh_elem;
if (gt == Geometry::SQUARE || gt == Geometry::CUBE)
{
gsl_code[index] = Geometry::CheckPoint(gt, ip, -btol) ? 0 : 1;
continue;
}
if (gt == Geometry::SQUARE || gt == Geometry::CUBE) { continue; }
else if (gt == Geometry::TRIANGLE)
{
gf_rst_map_temp = gf_rst_map[0];
@@ -834,12 +808,11 @@ void FindPointsGSLIB::MapRefPosAndElemIndices()
}
int local_elem = split_element_index[elem];
gf_rst_map_temp->GetVectorValue(local_elem, ip, mfem_ref);
// Check if the point is on element boundary
IntegrationPoint ip;
Vector mfem_ref(gsl_mfem_ref.GetData()+index*dim, dim);
ip.Set2(mfem_ref.GetData());
if (dim == 3) { ip.z = mfem_ref(2); }
gsl_code[index] = Geometry::CheckPoint(gt, ip, -btol) ? 0 : 1;
gf_rst_map_temp->GetVectorValue(local_elem, ip, mfem_ref);
}
}
}
+11 -11
View File
@@ -28,8 +28,8 @@ static void EAConvectionAssemble1D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto G = Reshape(g.Read(), Q1D, D1D);
auto D = Reshape(padata.Read(), Q1D, NE);
@@ -38,7 +38,7 @@ static void EAConvectionAssemble1D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
double r_Gi[MQ1];
double r_Bj[MQ1];
for (int q = 0; q < Q1D; q++)
@@ -80,8 +80,8 @@ static void EAConvectionAssemble2D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto G = Reshape(g.Read(), Q1D, D1D);
auto D = Reshape(padata.Read(), Q1D, Q1D, 2, NE);
@@ -90,8 +90,8 @@ static void EAConvectionAssemble2D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
double r_B[MQ1][MD1];
double r_G[MQ1][MD1];
for (int d = 0; d < D1D; d++)
@@ -157,8 +157,8 @@ static void EAConvectionAssemble3D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto G = Reshape(g.Read(), Q1D, D1D);
auto D = Reshape(padata.Read(), Q1D, Q1D, Q1D, 3, NE);
@@ -167,8 +167,8 @@ static void EAConvectionAssemble3D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
double r_B[MQ1][MD1];
double r_G[MQ1][MD1];
for (int d = 0; d < D1D; d++)
+32 -32
View File
@@ -203,8 +203,8 @@ void PAConvectionApply2D(const int ne,
const int NE = ne;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto G = Reshape(g.Read(), Q1D, D1D);
auto Bt = Reshape(bt.Read(), D1D, Q1D);
@@ -216,8 +216,8 @@ void PAConvectionApply2D(const int ne,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
// the following variables are evaluated at compile time
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double u[max_D1D][max_D1D];
for (int dy = 0; dy < D1D; ++dy)
@@ -323,8 +323,8 @@ void SmemPAConvectionApply2D(const int ne,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto G = Reshape(g.Read(), Q1D, D1D);
auto Bt = Reshape(bt.Read(), D1D, Q1D);
@@ -338,8 +338,8 @@ void SmemPAConvectionApply2D(const int ne,
const int Q1D = T_Q1D ? T_Q1D : q1d;
// the following variables are evaluated at compile time
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
// constexpr int MDQ = (max_Q1D > max_D1D) ? max_Q1D : max_D1D;
MFEM_SHARED double u[NBZ][max_D1D][max_D1D];
MFEM_FOREACH_THREAD(dy,y,D1D)
@@ -450,8 +450,8 @@ void PAConvectionApply3D(const int ne,
const int NE = ne;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto G = Reshape(g.Read(), Q1D, D1D);
auto Bt = Reshape(bt.Read(), D1D, Q1D);
@@ -463,8 +463,8 @@ void PAConvectionApply3D(const int ne,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
// the following variables are evaluated at compile time
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double u[max_D1D][max_D1D][max_D1D];
for (int dz = 0; dz < D1D; ++dz)
@@ -631,8 +631,8 @@ void SmemPAConvectionApply3D(const int ne,
const int NE = ne;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto G = Reshape(g.Read(), Q1D, D1D);
auto Bt = Reshape(bt.Read(), D1D, Q1D);
@@ -644,8 +644,8 @@ void SmemPAConvectionApply3D(const int ne,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
// the following variables are evaluated at compile time
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int max_DQ = (max_Q1D > max_D1D) ? max_Q1D : max_D1D;
MFEM_SHARED double sm0[max_DQ*max_DQ*max_DQ];
MFEM_SHARED double sm1[max_DQ*max_DQ*max_DQ];
@@ -835,8 +835,8 @@ void PAConvectionApplyT2D(const int ne,
const int NE = ne;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto Bt = Reshape(bt.Read(), D1D, Q1D);
auto Gt = Reshape(gt.Read(), D1D, Q1D);
@@ -848,8 +848,8 @@ void PAConvectionApplyT2D(const int ne,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
// the following variables are evaluated at compile time
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double u[max_D1D][max_D1D];
for (int dy = 0; dy < D1D; ++dy)
@@ -951,8 +951,8 @@ void SmemPAConvectionApplyT2D(const int ne,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto Bt = Reshape(bt.Read(), D1D, Q1D);
auto Gt = Reshape(gt.Read(), D1D, Q1D);
@@ -966,8 +966,8 @@ void SmemPAConvectionApplyT2D(const int ne,
const int Q1D = T_Q1D ? T_Q1D : q1d;
// the following variables are evaluated at compile time
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
MFEM_SHARED double u[NBZ][max_D1D][max_D1D];
MFEM_FOREACH_THREAD(dy,y,D1D)
{
@@ -1073,8 +1073,8 @@ void PAConvectionApplyT3D(const int ne,
const int NE = ne;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto Bt = Reshape(bt.Read(), D1D, Q1D);
auto Gt = Reshape(gt.Read(), D1D, Q1D);
@@ -1086,8 +1086,8 @@ void PAConvectionApplyT3D(const int ne,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
// the following variables are evaluated at compile time
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double u[max_D1D][max_D1D][max_D1D];
for (int dz = 0; dz < D1D; ++dz)
@@ -1249,8 +1249,8 @@ void SmemPAConvectionApplyT3D(const int ne,
const int NE = ne;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto Bt = Reshape(bt.Read(), D1D, Q1D);
auto Gt = Reshape(gt.Read(), D1D, Q1D);
@@ -1262,8 +1262,8 @@ void SmemPAConvectionApplyT3D(const int ne,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
// the following variables are evaluated at compile time
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int max_DQ = (max_Q1D > max_D1D) ? max_Q1D : max_D1D;
MFEM_SHARED double sm0[3*max_DQ*max_DQ*max_DQ];
MFEM_SHARED double sm1[3*max_DQ*max_DQ*max_DQ];
+12 -12
View File
@@ -83,8 +83,8 @@ static void EADGTraceAssemble2DInt(const int NF,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(basis.Read(), Q1D, D1D);
auto D = Reshape(padata.Read(), Q1D, 2, 2, NF);
auto A_int = Reshape(eadata_int.ReadWrite(), D1D, D1D, 2, NF);
@@ -138,8 +138,8 @@ static void EADGTraceAssemble2DBdr(const int NF,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(basis.Read(), Q1D, D1D);
auto D = Reshape(padata.Read(), Q1D, 2, 2, NF);
auto A_bdr = Reshape(eadata_bdr.ReadWrite(), D1D, D1D, NF);
@@ -181,8 +181,8 @@ static void EADGTraceAssemble3DInt(const int NF,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(basis.Read(), Q1D, D1D);
auto D = Reshape(padata.Read(), Q1D, Q1D, 2, 2, NF);
auto A_int = Reshape(eadata_int.ReadWrite(), D1D, D1D, D1D, D1D, 2, NF);
@@ -191,8 +191,8 @@ static void EADGTraceAssemble3DInt(const int NF,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
double r_B[MQ1][MD1];
for (int d = 0; d < D1D; d++)
{
@@ -278,8 +278,8 @@ static void EADGTraceAssemble3DBdr(const int NF,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(basis.Read(), Q1D, D1D);
auto D = Reshape(padata.Read(), Q1D, Q1D, 2, 2, NF);
auto A_bdr = Reshape(eadata_bdr.ReadWrite(), D1D, D1D, D1D, D1D, NF);
@@ -287,8 +287,8 @@ static void EADGTraceAssemble3DBdr(const int NF,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
double r_B[MQ1][MD1];
for (int d = 0; d < D1D; d++)
{
+24 -24
View File
@@ -258,8 +258,8 @@ void PADGTraceApply2D(const int NF,
const int VDIM = 1;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto Bt = Reshape(bt.Read(), D1D, Q1D);
auto op = Reshape(op_.Read(), Q1D, 2, 2, NF);
@@ -272,8 +272,8 @@ void PADGTraceApply2D(const int NF,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
// the following variables are evaluated at compile time
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double u0[max_D1D][VDIM];
double u1[max_D1D][VDIM];
for (int d = 0; d < D1D; d++)
@@ -349,8 +349,8 @@ void PADGTraceApply3D(const int NF,
const int VDIM = 1;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto Bt = Reshape(bt.Read(), D1D, Q1D);
auto op = Reshape(op_.Read(), Q1D, Q1D, 2, 2, NF);
@@ -363,8 +363,8 @@ void PADGTraceApply3D(const int NF,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
// the following variables are evaluated at compile time
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double u0[max_D1D][max_D1D][VDIM];
double u1[max_D1D][max_D1D][VDIM];
for (int d1 = 0; d1 < D1D; d1++)
@@ -494,8 +494,8 @@ void SmemPADGTraceApply3D(const int NF,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto Bt = Reshape(bt.Read(), D1D, Q1D);
auto op = Reshape(op_.Read(), Q1D, Q1D, 2, 2, NF);
@@ -509,8 +509,8 @@ void SmemPADGTraceApply3D(const int NF,
const int Q1D = T_Q1D ? T_Q1D : q1d;
// the following variables are evaluated at compile time
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
MFEM_SHARED double u0[NBZ][max_D1D][max_D1D];
MFEM_SHARED double u1[NBZ][max_D1D][max_D1D];
MFEM_FOREACH_THREAD(d1,x,D1D)
@@ -659,8 +659,8 @@ void PADGTraceApplyTranspose2D(const int NF,
const int VDIM = 1;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto Bt = Reshape(bt.Read(), D1D, Q1D);
auto op = Reshape(op_.Read(), Q1D, 2, 2, NF);
@@ -673,8 +673,8 @@ void PADGTraceApplyTranspose2D(const int NF,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
// the following variables are evaluated at compile time
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double u0[max_D1D][VDIM];
double u1[max_D1D][VDIM];
for (int d = 0; d < D1D; d++)
@@ -755,8 +755,8 @@ void PADGTraceApplyTranspose3D(const int NF,
const int VDIM = 1;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto Bt = Reshape(bt.Read(), D1D, Q1D);
auto op = Reshape(op_.Read(), Q1D, Q1D, 2, 2, NF);
@@ -769,8 +769,8 @@ void PADGTraceApplyTranspose3D(const int NF,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
// the following variables are evaluated at compile time
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double u0[max_D1D][max_D1D][VDIM];
double u1[max_D1D][max_D1D][VDIM];
for (int d1 = 0; d1 < D1D; d1++)
@@ -911,8 +911,8 @@ void SmemPADGTraceApplyTranspose3D(const int NF,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto Bt = Reshape(bt.Read(), D1D, Q1D);
auto op = Reshape(op_.Read(), Q1D, Q1D, 2, 2, NF);
@@ -926,8 +926,8 @@ void SmemPADGTraceApplyTranspose3D(const int NF,
const int Q1D = T_Q1D ? T_Q1D : q1d;
// the following variables are evaluated at compile time
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
MFEM_SHARED double u0[NBZ][max_D1D][max_D1D];
MFEM_SHARED double u1[NBZ][max_D1D][max_D1D];
MFEM_FOREACH_THREAD(d1,x,D1D)
+11 -11
View File
@@ -28,8 +28,8 @@ static void EADiffusionAssemble1D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto G = Reshape(g.Read(), Q1D, D1D);
auto D = Reshape(padata.Read(), Q1D, NE);
auto A = Reshape(eadata.ReadWrite(), D1D, D1D, NE);
@@ -37,7 +37,7 @@ static void EADiffusionAssemble1D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
double r_Gi[MQ1];
double r_Gj[MQ1];
for (int q = 0; q < Q1D; q++)
@@ -79,8 +79,8 @@ static void EADiffusionAssemble2D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto G = Reshape(g.Read(), Q1D, D1D);
auto D = Reshape(padata.Read(), Q1D, Q1D, 3, NE);
@@ -89,8 +89,8 @@ static void EADiffusionAssemble2D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
double r_B[MQ1][MD1];
double r_G[MQ1][MD1];
for (int d = 0; d < D1D; d++)
@@ -156,8 +156,8 @@ static void EADiffusionAssemble3D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto G = Reshape(g.Read(), Q1D, D1D);
auto D = Reshape(padata.Read(), Q1D, Q1D, Q1D, 6, NE);
@@ -166,8 +166,8 @@ static void EADiffusionAssemble3D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
double r_B[MQ1][MD1];
double r_G[MQ1][MD1];
for (int d = 0; d < D1D; d++)
+42 -42
View File
@@ -98,8 +98,8 @@ inline void PADiffusionDiagonal2D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto G = Reshape(g.Read(), Q1D, D1D);
// note the different shape for D, if this is a symmetric matrix we only
@@ -110,8 +110,8 @@ inline void PADiffusionDiagonal2D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
// gradphi \cdot Q \gradphi has four terms
double QD0[MQ1][MD1];
double QD1[MQ1][MD1];
@@ -165,10 +165,10 @@ inline void SmemPADiffusionDiagonal2D(const int NE,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
const int max_q1d = T_Q1D ? T_Q1D : DeviceDofQuadLimits::Get().MAX_Q1D;
const int max_d1d = T_D1D ? T_D1D : DeviceDofQuadLimits::Get().MAX_D1D;
MFEM_VERIFY(D1D <= max_d1d, "");
MFEM_VERIFY(Q1D <= max_q1d, "");
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
MFEM_VERIFY(D1D <= MD1, "");
MFEM_VERIFY(Q1D <= MQ1, "");
auto b = Reshape(b_.Read(), Q1D, D1D);
auto g = Reshape(g_.Read(), Q1D, D1D);
auto D = Reshape(d_.Read(), Q1D*Q1D, symmetric ? 3 : 4, NE);
@@ -179,8 +179,8 @@ inline void SmemPADiffusionDiagonal2D(const int NE,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
MFEM_SHARED double BG[2][MQ1*MD1];
double (*B)[MD1] = (double (*)[MD1]) (BG+0);
double (*G)[MD1] = (double (*)[MD1]) (BG+1);
@@ -260,10 +260,10 @@ inline void PADiffusionDiagonal3D(const int NE,
constexpr int DIM = 3;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
const int max_q1d = T_Q1D ? T_Q1D : DeviceDofQuadLimits::Get().MAX_Q1D;
const int max_d1d = T_D1D ? T_D1D : DeviceDofQuadLimits::Get().MAX_D1D;
MFEM_VERIFY(D1D <= max_d1d, "");
MFEM_VERIFY(Q1D <= max_q1d, "");
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
MFEM_VERIFY(D1D <= MD1, "");
MFEM_VERIFY(Q1D <= MQ1, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto G = Reshape(g.Read(), Q1D, D1D);
auto Q = Reshape(d.Read(), Q1D*Q1D*Q1D, symmetric ? 6 : 9, NE);
@@ -272,8 +272,8 @@ inline void PADiffusionDiagonal3D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
double QQD[MQ1][MQ1][MD1];
double QDD[MQ1][MD1][MD1];
for (int i = 0; i < DIM; ++i)
@@ -361,10 +361,10 @@ inline void SmemPADiffusionDiagonal3D(const int NE,
constexpr int DIM = 3;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
const int max_q1d = T_Q1D ? T_Q1D : DeviceDofQuadLimits::Get().MAX_Q1D;
const int max_d1d = T_D1D ? T_D1D : DeviceDofQuadLimits::Get().MAX_D1D;
MFEM_VERIFY(D1D <= max_d1d, "");
MFEM_VERIFY(Q1D <= max_q1d, "");
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
MFEM_VERIFY(D1D <= MD1, "");
MFEM_VERIFY(Q1D <= MQ1, "");
auto b = Reshape(b_.Read(), Q1D, D1D);
auto g = Reshape(g_.Read(), Q1D, D1D);
auto D = Reshape(d_.Read(), Q1D*Q1D*Q1D, symmetric ? 6 : 9, NE);
@@ -374,8 +374,8 @@ inline void SmemPADiffusionDiagonal3D(const int NE,
const int tidz = MFEM_THREAD_ID(z);
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
MFEM_SHARED double BG[2][MQ1*MD1];
double (*B)[MD1] = (double (*)[MD1]) (BG+0);
double (*G)[MD1] = (double (*)[MD1]) (BG+1);
@@ -521,8 +521,8 @@ inline void PADiffusionApply2D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b_.Read(), Q1D, D1D);
auto G = Reshape(g_.Read(), Q1D, D1D);
auto Bt = Reshape(bt_.Read(), D1D, Q1D);
@@ -535,8 +535,8 @@ inline void PADiffusionApply2D(const int NE,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
// the following variables are evaluated at compile time
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double grad[max_Q1D][max_Q1D][2];
for (int qy = 0; qy < Q1D; ++qy)
@@ -642,10 +642,10 @@ inline void SmemPADiffusionApply2D(const int NE,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
const int max_q1d = T_Q1D ? T_Q1D : DeviceDofQuadLimits::Get().MAX_Q1D;
const int max_d1d = T_D1D ? T_D1D : DeviceDofQuadLimits::Get().MAX_D1D;
MFEM_VERIFY(D1D <= max_d1d, "");
MFEM_VERIFY(Q1D <= max_q1d, "");
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
MFEM_VERIFY(D1D <= MD1, "");
MFEM_VERIFY(Q1D <= MQ1, "");
auto b = Reshape(b_.Read(), Q1D, D1D);
auto g = Reshape(g_.Read(), Q1D, D1D);
auto D = Reshape(d_.Read(), Q1D*Q1D, symmetric ? 3 : 4, NE);
@@ -657,8 +657,8 @@ inline void SmemPADiffusionApply2D(const int NE,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
MFEM_SHARED double sBG[2][MQ1*MD1];
double (*B)[MD1] = (double (*)[MD1]) (sBG+0);
double (*G)[MD1] = (double (*)[MD1]) (sBG+1);
@@ -800,8 +800,8 @@ inline void PADiffusionApply3D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto G = Reshape(g.Read(), Q1D, D1D);
auto Bt = Reshape(bt.Read(), D1D, Q1D);
@@ -813,8 +813,8 @@ inline void PADiffusionApply3D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double grad[max_Q1D][max_Q1D][max_Q1D][3];
for (int qz = 0; qz < Q1D; ++qz)
{
@@ -992,10 +992,10 @@ inline void SmemPADiffusionApply3D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
const int max_q1d = T_Q1D ? T_Q1D : DeviceDofQuadLimits::Get().MAX_Q1D;
const int max_d1d = T_D1D ? T_D1D : DeviceDofQuadLimits::Get().MAX_D1D;
MFEM_VERIFY(D1D <= max_d1d, "");
MFEM_VERIFY(Q1D <= max_q1d, "");
constexpr int M1Q = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int M1D = T_D1D ? T_D1D : MAX_D1D;
MFEM_VERIFY(D1D <= M1D, "");
MFEM_VERIFY(Q1D <= M1Q, "");
auto b = Reshape(b_.Read(), Q1D, D1D);
auto g = Reshape(g_.Read(), Q1D, D1D);
auto d = Reshape(d_.Read(), Q1D, Q1D, Q1D, symmetric ? 6 : 9, NE);
@@ -1005,8 +1005,8 @@ inline void SmemPADiffusionApply3D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MDQ = (MQ1 > MD1) ? MQ1 : MD1;
MFEM_SHARED double sBG[2][MQ1*MD1];
double (*B)[MD1] = (double (*)[MD1]) (sBG+0);
+16 -16
View File
@@ -229,9 +229,9 @@ static void PAGradientApply2D(const int NE,
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(TR_D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(TE_D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(TR_D1D <= MAX_D1D, "");
MFEM_VERIFY(TE_D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, TR_D1D);
auto G = Reshape(g.Read(), Q1D, TR_D1D);
auto Bt = Reshape(bt.Read(), TE_D1D, Q1D);
@@ -245,8 +245,8 @@ static void PAGradientApply2D(const int NE,
const int Q1D = T_Q1D ? T_Q1D : q1d;
const int VDIM = 2;
// the following variables are evaluated at compile time
constexpr int max_TE_D1D = T_TE_D1D ? T_TE_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_TE_D1D = T_TE_D1D ? T_TE_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double grad[max_Q1D][max_Q1D][VDIM];
for (int qy = 0; qy < Q1D; ++qy)
@@ -359,9 +359,9 @@ static void PAGradientApply3D(const int NE,
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(TR_D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(TE_D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(TR_D1D <= MAX_D1D, "");
MFEM_VERIFY(TE_D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, TR_D1D);
auto G = Reshape(g.Read(), Q1D, TR_D1D);
auto Bt = Reshape(bt.Read(), TE_D1D, Q1D);
@@ -375,8 +375,8 @@ static void PAGradientApply3D(const int NE,
const int Q1D = T_Q1D ? T_Q1D : q1d;
const int VDIM = 3;
// the following variables are evaluated at compile time
constexpr int max_TE_D1D = T_TE_D1D ? T_TE_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_TE_D1D = T_TE_D1D ? T_TE_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double grad[max_Q1D][max_Q1D][max_Q1D][VDIM];
for (int qz = 0; qz < Q1D; ++qz)
@@ -555,11 +555,11 @@ static void SmemPAGradientApply3D(const int NE,
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(TR_D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(TE_D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(TR_D1D <= MAX_D1D, "");
MFEM_VERIFY(TE_D1D <= MAX_D1D, "");
MFEM_VERIFY(TR_D1D <= Q1D, "");
MFEM_VERIFY(TE_D1D <= Q1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto b = Reshape(b_.Read(), Q1D, TR_D1D);
auto g = Reshape(g_.Read(), Q1D, TR_D1D);
@@ -575,9 +575,9 @@ static void SmemPAGradientApply3D(const int NE,
const int D1DR = T_TR_D1D ? T_TR_D1D : tr_d1d;
const int D1DE = T_TE_D1D ? T_TE_D1D : te_d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1R = T_TR_D1D ? T_TR_D1D : DofQuadLimits::MAX_D1D;
constexpr int MD1E = T_TE_D1D ? T_TE_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1R = T_TR_D1D ? T_TR_D1D : MAX_D1D;
constexpr int MD1E = T_TE_D1D ? T_TE_D1D : MAX_D1D;
constexpr int MD1 = MD1E > MD1R ? MD1E : MD1R;
constexpr int MDQ = MQ1 > MD1 ? MQ1 : MD1;
MFEM_SHARED double sBG[2][MQ1*MD1];
+29 -35
View File
@@ -26,6 +26,9 @@ void PAHcurlMassAssembleDiagonal2D(const int D1D,
const Vector &pa_data,
Vector &diag)
{
constexpr static int VDIM = 2;
constexpr static int MAX_Q1D = HCURL_MAX_Q1D;
auto Bo = Reshape(bo.Read(), Q1D, D1D-1);
auto Bc = Reshape(bc.Read(), Q1D, D1D);
auto op = Reshape(pa_data.Read(), Q1D, Q1D, symmetric ? 3 : 4, NE);
@@ -33,9 +36,6 @@ void PAHcurlMassAssembleDiagonal2D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int VDIM = 2;
constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
int osc = 0;
for (int c = 0; c < VDIM; ++c) // loop over x, y components
@@ -83,10 +83,11 @@ void PAHcurlMassAssembleDiagonal3D(const int D1D,
const Vector &pa_data,
Vector &diag)
{
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D,
"Error: D1D > MAX_D1D");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().HCURL_MAX_Q1D,
"Error: Q1D > MAX_Q1D");
constexpr static int MAX_D1D = HCURL_MAX_D1D;
constexpr static int MAX_Q1D = HCURL_MAX_Q1D;
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
MFEM_VERIFY(Q1D <= MAX_Q1D, "Error: Q1D > MAX_Q1D");
constexpr static int VDIM = 3;
auto Bo = Reshape(bo.Read(), Q1D, D1D-1);
@@ -96,8 +97,6 @@ void PAHcurlMassAssembleDiagonal3D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
int osc = 0;
for (int c = 0; c < VDIM; ++c) // loop over x, y, z components
@@ -159,6 +158,10 @@ void PAHcurlMassApply2D(const int D1D,
const Vector &x,
Vector &y)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = HCURL_MAX_D1D;
constexpr static int MAX_Q1D = HCURL_MAX_Q1D;
auto Bo = Reshape(bo.Read(), Q1D, D1D-1);
auto Bc = Reshape(bc.Read(), Q1D, D1D);
auto Bot = Reshape(bot.Read(), D1D-1, Q1D);
@@ -169,10 +172,6 @@ void PAHcurlMassApply2D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
double mass[MAX_Q1D][MAX_Q1D][VDIM];
for (int qy = 0; qy < Q1D; ++qy)
@@ -289,10 +288,11 @@ void PAHcurlMassApply3D(const int D1D,
const Vector &x,
Vector &y)
{
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D,
"Error: D1D > MAX_D1D");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().HCURL_MAX_Q1D,
"Error: Q1D > MAX_Q1D");
constexpr static int MAX_D1D = HCURL_MAX_D1D;
constexpr static int MAX_Q1D = HCURL_MAX_Q1D;
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
MFEM_VERIFY(Q1D <= MAX_Q1D, "Error: Q1D > MAX_Q1D");
constexpr static int VDIM = 3;
auto Bo = Reshape(bo.Read(), Q1D, D1D-1);
@@ -305,9 +305,6 @@ void PAHcurlMassApply3D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
double mass[MAX_Q1D][MAX_Q1D][MAX_Q1D][VDIM];
for (int qz = 0; qz < Q1D; ++qz)
@@ -607,6 +604,9 @@ void PACurlCurlAssembleDiagonal2D(const int D1D,
const Vector &pa_data,
Vector &diag)
{
constexpr static int VDIM = 2;
constexpr static int MAX_Q1D = HCURL_MAX_Q1D;
auto Bo = Reshape(bo.Read(), Q1D, D1D-1);
auto Gc = Reshape(gc.Read(), Q1D, D1D);
auto op = Reshape(pa_data.Read(), Q1D, Q1D, NE);
@@ -614,9 +614,6 @@ void PACurlCurlAssembleDiagonal2D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int VDIM = 2;
constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
int osc = 0;
for (int c = 0; c < VDIM; ++c) // loop over x, y components
@@ -664,6 +661,9 @@ void PACurlCurlApply2D(const int D1D,
const Vector &x,
Vector &y)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = HCURL_MAX_D1D;
constexpr static int MAX_Q1D = HCURL_MAX_Q1D;
auto Bo = Reshape(bo.Read(), Q1D, D1D-1);
auto Bot = Reshape(bot.Read(), D1D-1, Q1D);
@@ -675,10 +675,6 @@ void PACurlCurlApply2D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
double curl[MAX_Q1D][MAX_Q1D];
// curl[qy][qx] will be computed as du_y/dx - du_x/dy
@@ -828,6 +824,9 @@ void PAHcurlL2Apply2D(const int D1D,
const Vector &x, // trial = H(curl)
Vector &y) // test = L2 or H1
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = HCURL_MAX_D1D;
constexpr static int MAX_Q1D = HCURL_MAX_Q1D;
const int H1 = (D1Dtest == D1D);
MFEM_VERIFY(y.Size() == NE*D1Dtest*D1Dtest, "Test vector of wrong dimension");
@@ -842,10 +841,6 @@ void PAHcurlL2Apply2D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
double curl[MAX_Q1D][MAX_Q1D];
// curl[qy][qx] will be computed as du_y/dx - du_x/dy
@@ -944,6 +939,9 @@ void PAHcurlL2ApplyTranspose2D(const int D1D,
const Vector &x, // trial = H(curl)
Vector &y) // test = L2 or H1
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = HCURL_MAX_D1D;
constexpr static int MAX_Q1D = HCURL_MAX_Q1D;
const int H1 = (D1Dtest == D1D);
MFEM_VERIFY(x.Size() == NE*D1Dtest*D1Dtest, "Test vector of wrong dimension");
@@ -958,10 +956,6 @@ void PAHcurlL2ApplyTranspose2D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
double mass[MAX_Q1D][MAX_Q1D];
// Zero-order term in L2 or H1 test space
+40 -60
View File
@@ -59,10 +59,8 @@ inline void SmemPAHcurlMassAssembleDiagonal3D(const int d1d,
const Vector &pa_data,
Vector &diag)
{
MFEM_VERIFY(T_D1D || d1d <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D,
"Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= DeviceDofQuadLimits::Get().HCURL_MAX_Q1D,
"Error: q1d > HCURL_MAX_Q1D");
MFEM_VERIFY(T_D1D || d1d <= HCURL_MAX_D1D, "Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= HCURL_MAX_Q1D, "Error: q1d > HCURL_MAX_Q1D");
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -74,8 +72,8 @@ inline void SmemPAHcurlMassAssembleDiagonal3D(const int d1d,
mfem::forall_3D(NE, Q1D, Q1D, Q1D, [=] MFEM_HOST_DEVICE (int e)
{
constexpr int VDIM = 3;
constexpr int MD1D = T_D1D ? T_D1D : DofQuadLimits::HCURL_MAX_D1D;
constexpr int MQ1D = T_Q1D ? T_Q1D : DofQuadLimits::HCURL_MAX_Q1D;
constexpr int MD1D = T_D1D ? T_D1D : HCURL_MAX_D1D;
constexpr int MQ1D = T_Q1D ? T_Q1D : HCURL_MAX_Q1D;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -220,10 +218,8 @@ inline void SmemPAHcurlMassApply3D(const int d1d,
const Vector &x,
Vector &y)
{
MFEM_VERIFY(T_D1D || d1d <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D,
"Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= DeviceDofQuadLimits::Get().HCURL_MAX_Q1D,
"Error: q1d > HCURL_MAX_Q1D");
MFEM_VERIFY(T_D1D || d1d <= HCURL_MAX_D1D, "Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= HCURL_MAX_Q1D, "Error: q1d > HCURL_MAX_Q1D");
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -238,8 +234,8 @@ inline void SmemPAHcurlMassApply3D(const int d1d,
mfem::forall_3D(NE, Q1D, Q1D, Q1D, [=] MFEM_HOST_DEVICE (int e)
{
constexpr int VDIM = 3;
constexpr int MD1D = T_D1D ? T_D1D : DofQuadLimits::HCURL_MAX_D1D;
constexpr int MQ1D = T_Q1D ? T_Q1D : DofQuadLimits::HCURL_MAX_Q1D;
constexpr int MD1D = T_D1D ? T_D1D : HCURL_MAX_D1D;
constexpr int MQ1D = T_Q1D ? T_Q1D : HCURL_MAX_Q1D;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -445,10 +441,8 @@ inline void PACurlCurlAssembleDiagonal3D(const int d1d,
const Vector &pa_data,
Vector &diag)
{
MFEM_VERIFY(T_D1D || d1d <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D,
"Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= DeviceDofQuadLimits::Get().HCURL_MAX_Q1D,
"Error: q1d > HCURL_MAX_Q1D");
MFEM_VERIFY(T_D1D || d1d <= HCURL_MAX_D1D, "Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= HCURL_MAX_Q1D, "Error: q1d > HCURL_MAX_Q1D");
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -482,8 +476,8 @@ inline void PACurlCurlAssembleDiagonal3D(const int d1d,
// which may be non-symmetric depending on a possibly non-symmetric matrix coefficient.
constexpr int VDIM = 3;
constexpr int MD1D = T_D1D ? T_D1D : DofQuadLimits::HCURL_MAX_D1D;
constexpr int MQ1D = T_Q1D ? T_Q1D : DofQuadLimits::HCURL_MAX_Q1D;
constexpr int MD1D = T_D1D ? T_D1D : HCURL_MAX_D1D;
constexpr int MQ1D = T_Q1D ? T_Q1D : HCURL_MAX_Q1D;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -641,10 +635,8 @@ inline void SmemPACurlCurlAssembleDiagonal3D(const int d1d,
const Vector &pa_data,
Vector &diag)
{
MFEM_VERIFY(T_D1D || d1d <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D,
"Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= DeviceDofQuadLimits::Get().HCURL_MAX_Q1D,
"Error: q1d > HCURL_MAX_Q1D");
MFEM_VERIFY(T_D1D || d1d <= HCURL_MAX_D1D, "Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= HCURL_MAX_Q1D, "Error: q1d > HCURL_MAX_Q1D");
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -675,8 +667,8 @@ inline void SmemPACurlCurlAssembleDiagonal3D(const int d1d,
// If c = 2, \hat{\nabla}\times\hat{u} reduces to [(u_2)_{x_1}, -(u_2)_{x_0}, 0]
constexpr int VDIM = 3;
constexpr int MD1D = T_D1D ? T_D1D : DofQuadLimits::HCURL_MAX_D1D;
constexpr int MQ1D = T_Q1D ? T_Q1D : DofQuadLimits::HCURL_MAX_Q1D;
constexpr int MD1D = T_D1D ? T_D1D : HCURL_MAX_D1D;
constexpr int MQ1D = T_Q1D ? T_Q1D : HCURL_MAX_Q1D;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -856,10 +848,8 @@ inline void PACurlCurlApply3D(const int d1d,
const Vector &x,
Vector &y)
{
MFEM_VERIFY(T_D1D || d1d <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D,
"Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= DeviceDofQuadLimits::Get().HCURL_MAX_Q1D,
"Error: q1d > HCURL_MAX_Q1D");
MFEM_VERIFY(T_D1D || d1d <= HCURL_MAX_D1D, "Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= HCURL_MAX_Q1D, "Error: q1d > HCURL_MAX_Q1D");
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -884,8 +874,8 @@ inline void PACurlCurlApply3D(const int d1d,
// If c = 2, \hat{\nabla}\times\hat{u} reduces to [(u_2)_{x_1}, -(u_2)_{x_0}, 0]
constexpr int VDIM = 3;
constexpr int MD1D = T_D1D ? T_D1D : DofQuadLimits::HCURL_MAX_D1D;
constexpr int MQ1D = T_Q1D ? T_Q1D : DofQuadLimits::HCURL_MAX_Q1D;
constexpr int MD1D = T_D1D ? T_D1D : HCURL_MAX_D1D;
constexpr int MQ1D = T_Q1D ? T_Q1D : HCURL_MAX_Q1D;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -1379,10 +1369,8 @@ inline void SmemPACurlCurlApply3D(const int d1d,
const Vector &x,
Vector &y)
{
MFEM_VERIFY(T_D1D || d1d <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D,
"Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= DeviceDofQuadLimits::Get().HCURL_MAX_Q1D,
"Error: q1d > HCURL_MAX_Q1D");
MFEM_VERIFY(T_D1D || d1d <= HCURL_MAX_D1D, "Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= HCURL_MAX_Q1D, "Error: q1d > HCURL_MAX_Q1D");
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -1404,8 +1392,8 @@ inline void SmemPACurlCurlApply3D(const int d1d,
auto device_kernel = [=] MFEM_DEVICE (int e)
{
constexpr int VDIM = 3;
constexpr int MD1D = T_D1D ? T_D1D : DofQuadLimits::HCURL_MAX_D1D;
constexpr int MQ1D = T_Q1D ? T_Q1D : DofQuadLimits::HCURL_MAX_Q1D;
constexpr int MD1D = T_D1D ? T_D1D : HCURL_MAX_D1D;
constexpr int MQ1D = T_Q1D ? T_Q1D : HCURL_MAX_Q1D;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -1750,10 +1738,8 @@ inline void PAHcurlL2Apply3D(const int d1d,
const Vector &x,
Vector &y)
{
MFEM_VERIFY(T_D1D || d1d <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D,
"Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= DeviceDofQuadLimits::Get().HCURL_MAX_Q1D,
"Error: q1d > HCURL_MAX_Q1D");
MFEM_VERIFY(T_D1D || d1d <= HCURL_MAX_D1D, "Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= HCURL_MAX_Q1D, "Error: q1d > HCURL_MAX_Q1D");
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -1778,8 +1764,8 @@ inline void PAHcurlL2Apply3D(const int d1d,
// If c = 2, \hat{\nabla}\times\hat{u} reduces to [(u_2)_{x_1}, -(u_2)_{x_0}, 0]
constexpr int VDIM = 3;
constexpr int MD1D = T_D1D ? T_D1D : DofQuadLimits::HCURL_MAX_D1D;
constexpr int MQ1D = T_Q1D ? T_Q1D : DofQuadLimits::HCURL_MAX_Q1D;
constexpr int MD1D = T_D1D ? T_D1D : HCURL_MAX_D1D;
constexpr int MQ1D = T_Q1D ? T_Q1D : HCURL_MAX_Q1D;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -2121,10 +2107,8 @@ inline void SmemPAHcurlL2Apply3D(const int d1d,
const Vector &x,
Vector &y)
{
MFEM_VERIFY(T_D1D || d1d <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D,
"Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= DeviceDofQuadLimits::Get().HCURL_MAX_Q1D,
"Error: q1d > HCURL_MAX_Q1D");
MFEM_VERIFY(T_D1D || d1d <= HCURL_MAX_D1D, "Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= HCURL_MAX_Q1D, "Error: q1d > HCURL_MAX_Q1D");
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -2139,8 +2123,8 @@ inline void SmemPAHcurlL2Apply3D(const int d1d,
{
constexpr int VDIM = 3;
constexpr int maxCoeffDim = 9;
constexpr int MD1D = T_D1D ? T_D1D : DofQuadLimits::HCURL_MAX_D1D;
constexpr int MQ1D = T_Q1D ? T_Q1D : DofQuadLimits::HCURL_MAX_Q1D;
constexpr int MD1D = T_D1D ? T_D1D : HCURL_MAX_D1D;
constexpr int MQ1D = T_Q1D ? T_Q1D : HCURL_MAX_Q1D;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -2441,10 +2425,8 @@ inline void PAHcurlL2ApplyTranspose3D(const int d1d,
Vector &y)
{
// See PAHcurlL2Apply3D for comments.
MFEM_VERIFY(T_D1D || d1d <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D,
"Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= DeviceDofQuadLimits::Get().HCURL_MAX_Q1D,
"Error: q1d > HCURL_MAX_Q1D");
MFEM_VERIFY(T_D1D || d1d <= HCURL_MAX_D1D, "Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= HCURL_MAX_Q1D, "Error: q1d > HCURL_MAX_Q1D");
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -2460,8 +2442,8 @@ inline void PAHcurlL2ApplyTranspose3D(const int d1d,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr int VDIM = 3;
constexpr int MD1D = T_D1D ? T_D1D : DofQuadLimits::HCURL_MAX_D1D;
constexpr int MQ1D = T_Q1D ? T_Q1D : DofQuadLimits::HCURL_MAX_Q1D;
constexpr int MD1D = T_D1D ? T_D1D : HCURL_MAX_D1D;
constexpr int MQ1D = T_Q1D ? T_Q1D : HCURL_MAX_Q1D;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -2809,10 +2791,8 @@ inline void SmemPAHcurlL2ApplyTranspose3D(const int d1d,
const Vector &x,
Vector &y)
{
MFEM_VERIFY(T_D1D || d1d <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D,
"Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= DeviceDofQuadLimits::Get().HCURL_MAX_Q1D,
"Error: q1d > HCURL_MAX_Q1D");
MFEM_VERIFY(T_D1D || d1d <= HCURL_MAX_D1D, "Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= HCURL_MAX_Q1D, "Error: q1d > HCURL_MAX_Q1D");
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -2827,8 +2807,8 @@ inline void SmemPAHcurlL2ApplyTranspose3D(const int d1d,
{
constexpr int VDIM = 3;
constexpr int maxCoeffDim = 9;
constexpr int MD1D = T_D1D ? T_D1D : DofQuadLimits::HCURL_MAX_D1D;
constexpr int MQ1D = T_Q1D ? T_Q1D : DofQuadLimits::HCURL_MAX_Q1D;
constexpr int MD1D = T_D1D ? T_D1D : HCURL_MAX_D1D;
constexpr int MQ1D = T_Q1D ? T_Q1D : HCURL_MAX_Q1D;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
+13 -15
View File
@@ -224,10 +224,11 @@ void PAHcurlHdivMassApply2D(const int D1D,
const Vector &x_,
Vector &y_)
{
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D,
"Error: D1D > MAX_D1D");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().HCURL_MAX_Q1D,
"Error: Q1D > MAX_Q1D");
constexpr static int MAX_D1D = HCURL_MAX_D1D;
constexpr static int MAX_Q1D = HCURL_MAX_Q1D;
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
MFEM_VERIFY(Q1D <= MAX_Q1D, "Error: Q1D > MAX_Q1D");
constexpr static int VDIM = 2;
auto Bo = Reshape(Bo_.Read(), Q1D, D1D-1);
@@ -243,8 +244,6 @@ void PAHcurlHdivMassApply2D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
double mass[MAX_Q1D][MAX_Q1D][VDIM];
for (int qy = 0; qy < Q1D; ++qy)
@@ -324,7 +323,7 @@ void PAHcurlHdivMassApply2D(const int D1D,
for (int qy = 0; qy < Q1D; ++qy)
{
double massX[DofQuadLimits::HDIV_MAX_D1D];
double massX[HDIV_MAX_D1D];
for (int dx = 0; dx < D1Dx; ++dx)
{
massX[dx] = 0.0;
@@ -371,10 +370,11 @@ void PAHcurlHdivMassApply3D(const int D1D,
const Vector &x_,
Vector &y_)
{
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D,
"Error: D1D > MAX_D1D");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().HCURL_MAX_Q1D,
"Error: Q1D > MAX_Q1D");
constexpr static int MAX_D1D = HCURL_MAX_D1D;
constexpr static int MAX_Q1D = HCURL_MAX_Q1D;
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
MFEM_VERIFY(Q1D <= MAX_Q1D, "Error: Q1D > MAX_Q1D");
constexpr static int VDIM = 3;
auto Bo = Reshape(Bo_.Read(), Q1D, D1D-1);
@@ -395,8 +395,6 @@ void PAHcurlHdivMassApply3D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
double mass[MAX_Q1D][MAX_Q1D][MAX_Q1D][VDIM];
for (int qz = 0; qz < Q1D; ++qz)
@@ -509,7 +507,7 @@ void PAHcurlHdivMassApply3D(const int D1D,
for (int qz = 0; qz < Q1D; ++qz)
{
double massXY[DofQuadLimits::HDIV_MAX_D1D][DofQuadLimits::HDIV_MAX_D1D];
double massXY[HDIV_MAX_D1D][HDIV_MAX_D1D];
osc = 0;
for (int c = 0; c < VDIM; ++c) // loop over x, y, z test components
@@ -530,7 +528,7 @@ void PAHcurlHdivMassApply3D(const int D1D,
}
for (int qy = 0; qy < Q1D; ++qy)
{
double massX[DofQuadLimits::HDIV_MAX_D1D];
double massX[HDIV_MAX_D1D];
for (int dx = 0; dx < D1Dx; ++dx)
{
massX[dx] = 0.0;
+12 -16
View File
@@ -92,12 +92,10 @@ inline void PAHcurlHdivApply3D(const int d1d,
const Vector &x,
Vector &y)
{
MFEM_VERIFY(T_D1D || d1d <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D,
"Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_D1D_TEST || d1dtest <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D,
"Error: d1dtest > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= DeviceDofQuadLimits::Get().HCURL_MAX_Q1D,
"Error: q1d > HCURL_MAX_Q1D");
MFEM_VERIFY(T_D1D || d1d <= HCURL_MAX_D1D, "Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_D1D_TEST ||
d1dtest <= HCURL_MAX_D1D, "Error: d1dtest > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= HCURL_MAX_Q1D, "Error: q1d > HCURL_MAX_Q1D");
const int D1D = T_D1D ? T_D1D : d1d;
const int D1Dtest = T_D1D_TEST ? T_D1D_TEST : d1dtest;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -122,8 +120,8 @@ inline void PAHcurlHdivApply3D(const int d1d,
constexpr int VDIM = 3;
constexpr int MD1D = T_D1D ? T_D1D :
DofQuadLimits::HCURL_MAX_D1D; // Assuming HDIV_MAX_D1D <= HCURL_MAX_D1D
constexpr int MQ1D = T_Q1D ? T_Q1D : DofQuadLimits::HCURL_MAX_Q1D;
HCURL_MAX_D1D; // Assuming HDIV_MAX_D1D <= HCURL_MAX_D1D
constexpr int MQ1D = T_Q1D ? T_Q1D : HCURL_MAX_Q1D;
const int D1D = T_D1D ? T_D1D : d1d;
const int D1Dtest = T_D1D_TEST ? T_D1D_TEST : d1dtest;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -461,12 +459,10 @@ inline void PAHcurlHdivApplyTranspose3D(const int d1d,
const Vector &x,
Vector &y)
{
MFEM_VERIFY(T_D1D || d1d <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D,
"Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_D1D_TEST || d1dtest <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D,
"Error: d1dtest > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= DeviceDofQuadLimits::Get().HCURL_MAX_Q1D,
"Error: q1d > HCURL_MAX_Q1D");
MFEM_VERIFY(T_D1D || d1d <= HCURL_MAX_D1D, "Error: d1d > HCURL_MAX_D1D");
MFEM_VERIFY(T_D1D_TEST ||
d1dtest <= HCURL_MAX_D1D, "Error: d1dtest > HCURL_MAX_D1D");
MFEM_VERIFY(T_Q1D || q1d <= HCURL_MAX_Q1D, "Error: q1d > HCURL_MAX_Q1D");
const int D1D = T_D1D ? T_D1D : d1d;
const int D1Dtest = T_D1D_TEST ? T_D1D_TEST : d1dtest;
const int Q1D = T_Q1D ? T_Q1D : q1d;
@@ -491,8 +487,8 @@ inline void PAHcurlHdivApplyTranspose3D(const int d1d,
constexpr int VDIM = 3;
constexpr int MD1D = T_D1D ? T_D1D :
DofQuadLimits::HCURL_MAX_D1D; // Assuming HDIV_MAX_D1D <= HCURL_MAX_D1D
constexpr int MQ1D = T_Q1D ? T_Q1D : DofQuadLimits::HCURL_MAX_Q1D;
HCURL_MAX_D1D; // Assuming HDIV_MAX_D1D <= HCURL_MAX_D1D
constexpr int MQ1D = T_Q1D ? T_Q1D : HCURL_MAX_Q1D;
const int D1D = T_D1D ? T_D1D : d1d;
const int D1Dtest = T_D1D_TEST ? T_D1D_TEST : d1dtest;
const int Q1D = T_Q1D ? T_Q1D : q1d;
+65 -80
View File
@@ -176,6 +176,9 @@ void PAHdivMassAssembleDiagonal2D(const int D1D,
const Vector &op_,
Vector &diag_)
{
constexpr static int VDIM = 2;
constexpr static int MAX_Q1D = HDIV_MAX_Q1D;
auto Bo = Reshape(Bo_.Read(), Q1D, D1D-1);
auto Bc = Reshape(Bc_.Read(), Q1D, D1D);
auto op = Reshape(op_.Read(), Q1D, Q1D, symmetric ? 3 : 4, NE);
@@ -183,9 +186,6 @@ void PAHdivMassAssembleDiagonal2D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int VDIM = 2;
constexpr static int MAX_Q1D = DofQuadLimits::HDIV_MAX_Q1D;
int osc = 0;
for (int c = 0; c < VDIM; ++c) // loop over x, y components
@@ -232,10 +232,8 @@ void PAHdivMassAssembleDiagonal3D(const int D1D,
const Vector &op_,
Vector &diag_)
{
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().HDIV_MAX_D1D,
"Error: D1D > HDIV_MAX_D1D");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().HDIV_MAX_Q1D,
"Error: Q1D > HDIV_MAX_Q1D");
MFEM_VERIFY(D1D <= HDIV_MAX_D1D, "Error: D1D > HDIV_MAX_D1D");
MFEM_VERIFY(Q1D <= HDIV_MAX_Q1D, "Error: Q1D > HDIV_MAX_Q1D");
constexpr static int VDIM = 3;
auto Bo = Reshape(Bo_.Read(), Q1D, D1D-1);
@@ -256,7 +254,7 @@ void PAHdivMassAssembleDiagonal3D(const int D1D,
const int opc = (c == 0) ? 0 : ((c == 1) ? (symmetric ? 3 : 4) :
(symmetric ? 5 : 8));
double mass[DofQuadLimits::HDIV_MAX_Q1D];
double mass[HDIV_MAX_Q1D];
for (int dz = 0; dz < D1Dz; ++dz)
{
@@ -349,6 +347,10 @@ void PAHdivMassApply2D(const int D1D,
const Vector &x_,
Vector &y_)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = HDIV_MAX_D1D;
constexpr static int MAX_Q1D = HDIV_MAX_Q1D;
auto Bo = Reshape(Bo_.Read(), Q1D, D1D-1);
auto Bc = Reshape(Bc_.Read(), Q1D, D1D);
auto Bot = Reshape(Bot_.Read(), D1D-1, Q1D);
@@ -359,10 +361,6 @@ void PAHdivMassApply2D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = DofQuadLimits::HDIV_MAX_D1D;
constexpr static int MAX_Q1D = DofQuadLimits::HDIV_MAX_Q1D;
double mass[MAX_Q1D][MAX_Q1D][VDIM];
for (int qy = 0; qy < Q1D; ++qy)
@@ -480,10 +478,8 @@ void PAHdivMassApply3D(const int D1D,
const Vector &x_,
Vector &y_)
{
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().HDIV_MAX_D1D,
"Error: D1D > HDIV_MAX_D1D");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().HDIV_MAX_Q1D,
"Error: Q1D > HDIV_MAX_Q1D");
MFEM_VERIFY(D1D <= HDIV_MAX_D1D, "Error: D1D > HDIV_MAX_D1D");
MFEM_VERIFY(Q1D <= HDIV_MAX_Q1D, "Error: Q1D > HDIV_MAX_Q1D");
constexpr static int VDIM = 3;
auto Bo = Reshape(Bo_.Read(), Q1D, D1D-1);
@@ -496,7 +492,7 @@ void PAHdivMassApply3D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
double mass[DofQuadLimits::HDIV_MAX_Q1D][DofQuadLimits::HDIV_MAX_Q1D][DofQuadLimits::HDIV_MAX_Q1D][VDIM];
double mass[HDIV_MAX_Q1D][HDIV_MAX_Q1D][HDIV_MAX_Q1D][VDIM];
for (int qz = 0; qz < Q1D; ++qz)
{
@@ -522,7 +518,7 @@ void PAHdivMassApply3D(const int D1D,
for (int dz = 0; dz < D1Dz; ++dz)
{
double massXY[DofQuadLimits::HDIV_MAX_Q1D][DofQuadLimits::HDIV_MAX_Q1D];
double massXY[HDIV_MAX_Q1D][HDIV_MAX_Q1D];
for (int qy = 0; qy < Q1D; ++qy)
{
for (int qx = 0; qx < Q1D; ++qx)
@@ -533,7 +529,7 @@ void PAHdivMassApply3D(const int D1D,
for (int dy = 0; dy < D1Dy; ++dy)
{
double massX[DofQuadLimits::HDIV_MAX_Q1D];
double massX[HDIV_MAX_Q1D];
for (int qx = 0; qx < Q1D; ++qx)
{
massX[qx] = 0.0;
@@ -604,7 +600,7 @@ void PAHdivMassApply3D(const int D1D,
for (int qz = 0; qz < Q1D; ++qz)
{
double massXY[DofQuadLimits::HDIV_MAX_D1D][DofQuadLimits::HDIV_MAX_D1D];
double massXY[HDIV_MAX_D1D][HDIV_MAX_D1D];
osc = 0;
@@ -623,7 +619,7 @@ void PAHdivMassApply3D(const int D1D,
}
for (int qy = 0; qy < Q1D; ++qy)
{
double massX[DofQuadLimits::HDIV_MAX_D1D];
double massX[HDIV_MAX_D1D];
for (int dx = 0; dx < D1Dx; ++dx)
{
massX[dx] = 0;
@@ -734,6 +730,9 @@ void PADivDivAssembleDiagonal2D(const int D1D,
const Vector &op_,
Vector &diag_)
{
constexpr static int VDIM = 2;
constexpr static int MAX_Q1D = HDIV_MAX_Q1D;
auto Bo = Reshape(Bo_.Read(), Q1D, D1D-1);
auto Gc = Reshape(Gc_.Read(), Q1D, D1D);
auto op = Reshape(op_.Read(), Q1D, Q1D, NE);
@@ -741,9 +740,6 @@ void PADivDivAssembleDiagonal2D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int VDIM = 2;
constexpr static int MAX_Q1D = DofQuadLimits::HDIV_MAX_Q1D;
int osc = 0;
for (int c = 0; c < VDIM; ++c) // loop over x, y components
@@ -790,10 +786,8 @@ void PADivDivAssembleDiagonal3D(const int D1D,
const Vector &op_,
Vector &diag_)
{
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().HDIV_MAX_D1D,
"Error: D1D > HDIV_MAX_D1D");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().HDIV_MAX_Q1D,
"Error: Q1D > HDIV_MAX_Q1D");
MFEM_VERIFY(D1D <= HDIV_MAX_D1D, "Error: D1D > HDIV_MAX_D1D");
MFEM_VERIFY(Q1D <= HDIV_MAX_Q1D, "Error: Q1D > HDIV_MAX_Q1D");
constexpr static int VDIM = 3;
auto Bo = Reshape(Bo_.Read(), Q1D, D1D-1);
@@ -815,7 +809,7 @@ void PADivDivAssembleDiagonal3D(const int D1D,
{
for (int dy = 0; dy < D1Dy; ++dy)
{
double a[DofQuadLimits::HDIV_MAX_Q1D];
double a[HDIV_MAX_Q1D];
for (int qx = 0; qx < Q1D; ++qx)
{
@@ -861,6 +855,10 @@ void PADivDivApply2D(const int D1D,
const Vector &x_,
Vector &y_)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = HDIV_MAX_D1D;
constexpr static int MAX_Q1D = HDIV_MAX_Q1D;
auto Bo = Reshape(Bo_.Read(), Q1D, D1D-1);
auto Bot = Reshape(Bot_.Read(), D1D-1, Q1D);
auto Gc = Reshape(Gc_.Read(), Q1D, D1D);
@@ -871,10 +869,6 @@ void PADivDivApply2D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = DofQuadLimits::HDIV_MAX_D1D;
constexpr static int MAX_Q1D = DofQuadLimits::HDIV_MAX_Q1D;
double div[MAX_Q1D][MAX_Q1D];
// div[qy][qx] will be computed as du_x/dx + du_y/dy
@@ -980,10 +974,8 @@ void PADivDivApply3D(const int D1D,
const Vector &x_,
Vector &y_)
{
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().HDIV_MAX_D1D,
"Error: D1D > HDIV_MAX_D1D");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().HDIV_MAX_Q1D,
"Error: Q1D > HDIV_MAX_Q1D");
MFEM_VERIFY(D1D <= HDIV_MAX_D1D, "Error: D1D > HDIV_MAX_D1D");
MFEM_VERIFY(Q1D <= HDIV_MAX_Q1D, "Error: Q1D > HDIV_MAX_Q1D");
constexpr static int VDIM = 3;
auto Bo = Reshape(Bo_.Read(), Q1D, D1D-1);
@@ -996,7 +988,7 @@ void PADivDivApply3D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
double div[DofQuadLimits::HDIV_MAX_Q1D][DofQuadLimits::HDIV_MAX_Q1D][DofQuadLimits::HDIV_MAX_Q1D];
double div[HDIV_MAX_Q1D][HDIV_MAX_Q1D][HDIV_MAX_Q1D];
for (int qz = 0; qz < Q1D; ++qz)
{
@@ -1019,7 +1011,7 @@ void PADivDivApply3D(const int D1D,
for (int dz = 0; dz < D1Dz; ++dz)
{
double aXY[DofQuadLimits::HDIV_MAX_Q1D][DofQuadLimits::HDIV_MAX_Q1D];
double aXY[HDIV_MAX_Q1D][HDIV_MAX_Q1D];
for (int qy = 0; qy < Q1D; ++qy)
{
for (int qx = 0; qx < Q1D; ++qx)
@@ -1030,7 +1022,7 @@ void PADivDivApply3D(const int D1D,
for (int dy = 0; dy < D1Dy; ++dy)
{
double aX[DofQuadLimits::HDIV_MAX_Q1D];
double aX[HDIV_MAX_Q1D];
for (int qx = 0; qx < Q1D; ++qx)
{
aX[qx] = 0.0;
@@ -1086,7 +1078,7 @@ void PADivDivApply3D(const int D1D,
for (int qz = 0; qz < Q1D; ++qz)
{
double aXY[DofQuadLimits::HDIV_MAX_D1D][DofQuadLimits::HDIV_MAX_D1D];
double aXY[HDIV_MAX_D1D][HDIV_MAX_D1D];
osc = 0;
@@ -1105,7 +1097,7 @@ void PADivDivApply3D(const int D1D,
}
for (int qy = 0; qy < Q1D; ++qy)
{
double aX[DofQuadLimits::HDIV_MAX_D1D];
double aX[HDIV_MAX_D1D];
for (int dx = 0; dx < D1Dx; ++dx)
{
aX[dx] = 0;
@@ -1215,8 +1207,8 @@ void PAHdivL2AssembleDiagonal_ADAt_2D(const int D1D,
// Compute row (rx,ry), assuming all contributions are from
// a single element.
double row[2*DofQuadLimits::HDIV_MAX_D1D*(DofQuadLimits::HDIV_MAX_D1D-1)];
double div[DofQuadLimits::HDIV_MAX_Q1D][DofQuadLimits::HDIV_MAX_Q1D];
double row[2*HDIV_MAX_D1D*(HDIV_MAX_D1D-1)];
double div[HDIV_MAX_Q1D][HDIV_MAX_Q1D];
for (int i=0; i<2*D1D*(D1D - 1); ++i)
{
@@ -1239,7 +1231,7 @@ void PAHdivL2AssembleDiagonal_ADAt_2D(const int D1D,
const int D1Dy = (c == 1) ? D1D : D1D - 1;
const int D1Dx = (c == 0) ? D1D : D1D - 1;
double aX[DofQuadLimits::HDIV_MAX_D1D];
double aX[HDIV_MAX_D1D];
for (int dx = 0; dx < D1Dx; ++dx)
{
aX[dx] = 0;
@@ -1289,10 +1281,8 @@ void PAHdivL2AssembleDiagonal_ADAt_3D(const int D1D,
const Vector &D_,
Vector &diag_)
{
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().HDIV_MAX_D1D,
"Error: D1D > HDIV_MAX_D1D");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().HDIV_MAX_Q1D,
"Error: Q1D > HDIV_MAX_Q1D");
MFEM_VERIFY(D1D <= HDIV_MAX_D1D, "Error: D1D > HDIV_MAX_D1D");
MFEM_VERIFY(Q1D <= HDIV_MAX_Q1D, "Error: Q1D > HDIV_MAX_Q1D");
constexpr static int VDIM = 3;
auto L2Bo = Reshape(L2Bo_.Read(), Q1D, L2D1D);
@@ -1313,9 +1303,8 @@ void PAHdivL2AssembleDiagonal_ADAt_3D(const int D1D,
// Compute row (rx,ry,rz), assuming all contributions are from
// a single element.
double row[3*DofQuadLimits::HDIV_MAX_D1D*(DofQuadLimits::HDIV_MAX_D1D-1)*
(DofQuadLimits::HDIV_MAX_D1D-1)];
double div[DofQuadLimits::HDIV_MAX_Q1D][DofQuadLimits::HDIV_MAX_Q1D][DofQuadLimits::HDIV_MAX_Q1D];
double row[3*HDIV_MAX_D1D*(HDIV_MAX_D1D-1)*(HDIV_MAX_D1D-1)];
double div[HDIV_MAX_Q1D][HDIV_MAX_Q1D][HDIV_MAX_Q1D];
for (int i=0; i<3*D1D*(D1D - 1)*(D1D - 1); ++i)
{
@@ -1336,7 +1325,7 @@ void PAHdivL2AssembleDiagonal_ADAt_3D(const int D1D,
for (int qz = 0; qz < Q1D; ++qz)
{
double aXY[DofQuadLimits::HDIV_MAX_D1D][DofQuadLimits::HDIV_MAX_D1D];
double aXY[HDIV_MAX_D1D][HDIV_MAX_D1D];
int osc = 0;
for (int c = 0; c < VDIM; ++c) // loop over x, y, z components
@@ -1354,7 +1343,7 @@ void PAHdivL2AssembleDiagonal_ADAt_3D(const int D1D,
}
for (int qy = 0; qy < Q1D; ++qy)
{
double aX[DofQuadLimits::HDIV_MAX_D1D];
double aX[HDIV_MAX_D1D];
for (int dx = 0; dx < D1Dx; ++dx)
{
aX[dx] = 0;
@@ -1419,6 +1408,10 @@ void PAHdivL2Apply2D(const int D1D,
const Vector &x_,
Vector &y_)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = HDIV_MAX_D1D;
constexpr static int MAX_Q1D = HDIV_MAX_Q1D;
auto Bo = Reshape(Bo_.Read(), Q1D, D1D-1);
auto Gc = Reshape(Gc_.Read(), Q1D, D1D);
auto L2Bot = Reshape(L2Bot_.Read(), L2D1D, Q1D);
@@ -1428,10 +1421,6 @@ void PAHdivL2Apply2D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = DofQuadLimits::HDIV_MAX_D1D;
constexpr static int MAX_Q1D = DofQuadLimits::HDIV_MAX_Q1D;
double div[MAX_Q1D][MAX_Q1D];
for (int qy = 0; qy < Q1D; ++qy)
@@ -1525,6 +1514,10 @@ void PAHdivL2ApplyTranspose2D(const int D1D,
const Vector &x_,
Vector &y_)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = HDIV_MAX_D1D;
constexpr static int MAX_Q1D = HDIV_MAX_Q1D;
auto L2Bo = Reshape(L2Bo_.Read(), Q1D, L2D1D);
auto Gct = Reshape(Gct_.Read(), D1D, Q1D);
auto Bot = Reshape(Bot_.Read(), D1D-1, Q1D);
@@ -1534,10 +1527,6 @@ void PAHdivL2ApplyTranspose2D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = DofQuadLimits::HDIV_MAX_D1D;
constexpr static int MAX_Q1D = DofQuadLimits::HDIV_MAX_Q1D;
double div[MAX_Q1D][MAX_Q1D];
for (int qy = 0; qy < Q1D; ++qy)
@@ -1633,10 +1622,8 @@ void PAHdivL2Apply3D(const int D1D,
const Vector &x_,
Vector &y_)
{
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().HDIV_MAX_D1D,
"Error: D1D > HDIV_MAX_D1D");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().HDIV_MAX_Q1D,
"Error: Q1D > HDIV_MAX_Q1D");
MFEM_VERIFY(D1D <= HDIV_MAX_D1D, "Error: D1D > HDIV_MAX_D1D");
MFEM_VERIFY(Q1D <= HDIV_MAX_Q1D, "Error: Q1D > HDIV_MAX_Q1D");
constexpr static int VDIM = 3;
auto Bo = Reshape(Bo_.Read(), Q1D, D1D-1);
@@ -1648,7 +1635,7 @@ void PAHdivL2Apply3D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
double div[DofQuadLimits::HDIV_MAX_Q1D][DofQuadLimits::HDIV_MAX_Q1D][DofQuadLimits::HDIV_MAX_Q1D];
double div[HDIV_MAX_Q1D][HDIV_MAX_Q1D][HDIV_MAX_Q1D];
for (int qz = 0; qz < Q1D; ++qz)
{
@@ -1671,7 +1658,7 @@ void PAHdivL2Apply3D(const int D1D,
for (int dz = 0; dz < D1Dz; ++dz)
{
double aXY[DofQuadLimits::HDIV_MAX_Q1D][DofQuadLimits::HDIV_MAX_Q1D];
double aXY[HDIV_MAX_Q1D][HDIV_MAX_Q1D];
for (int qy = 0; qy < Q1D; ++qy)
{
for (int qx = 0; qx < Q1D; ++qx)
@@ -1682,7 +1669,7 @@ void PAHdivL2Apply3D(const int D1D,
for (int dy = 0; dy < D1Dy; ++dy)
{
double aX[DofQuadLimits::HDIV_MAX_Q1D];
double aX[HDIV_MAX_Q1D];
for (int qx = 0; qx < Q1D; ++qx)
{
aX[qx] = 0.0;
@@ -1737,7 +1724,7 @@ void PAHdivL2Apply3D(const int D1D,
for (int qz = 0; qz < Q1D; ++qz)
{
double aXY[DofQuadLimits::HDIV_MAX_D1D][DofQuadLimits::HDIV_MAX_D1D];
double aXY[HDIV_MAX_D1D][HDIV_MAX_D1D];
for (int dy = 0; dy < L2D1D; ++dy)
{
@@ -1748,7 +1735,7 @@ void PAHdivL2Apply3D(const int D1D,
}
for (int qy = 0; qy < Q1D; ++qy)
{
double aX[DofQuadLimits::HDIV_MAX_D1D];
double aX[HDIV_MAX_D1D];
for (int dx = 0; dx < L2D1D; ++dx)
{
aX[dx] = 0;
@@ -1796,10 +1783,8 @@ void PAHdivL2ApplyTranspose3D(const int D1D,
const Vector &x_,
Vector &y_)
{
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().HDIV_MAX_D1D,
"Error: D1D > HDIV_MAX_D1D");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().HDIV_MAX_Q1D,
"Error: Q1D > HDIV_MAX_Q1D");
MFEM_VERIFY(D1D <= HDIV_MAX_D1D, "Error: D1D > HDIV_MAX_D1D");
MFEM_VERIFY(Q1D <= HDIV_MAX_Q1D, "Error: Q1D > HDIV_MAX_Q1D");
constexpr static int VDIM = 3;
auto L2Bo = Reshape(L2Bo_.Read(), Q1D, L2D1D);
@@ -1811,7 +1796,7 @@ void PAHdivL2ApplyTranspose3D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
double div[DofQuadLimits::HDIV_MAX_Q1D][DofQuadLimits::HDIV_MAX_Q1D][DofQuadLimits::HDIV_MAX_Q1D];
double div[HDIV_MAX_Q1D][HDIV_MAX_Q1D][HDIV_MAX_Q1D];
for (int qz = 0; qz < Q1D; ++qz)
{
@@ -1826,7 +1811,7 @@ void PAHdivL2ApplyTranspose3D(const int D1D,
for (int dz = 0; dz < L2D1D; ++dz)
{
double aXY[DofQuadLimits::HDIV_MAX_Q1D][DofQuadLimits::HDIV_MAX_Q1D];
double aXY[HDIV_MAX_Q1D][HDIV_MAX_Q1D];
for (int qy = 0; qy < Q1D; ++qy)
{
for (int qx = 0; qx < Q1D; ++qx)
@@ -1837,7 +1822,7 @@ void PAHdivL2ApplyTranspose3D(const int D1D,
for (int dy = 0; dy < L2D1D; ++dy)
{
double aX[DofQuadLimits::HDIV_MAX_Q1D];
double aX[HDIV_MAX_Q1D];
for (int qx = 0; qx < Q1D; ++qx)
{
aX[qx] = 0.0;
@@ -1889,7 +1874,7 @@ void PAHdivL2ApplyTranspose3D(const int D1D,
for (int qz = 0; qz < Q1D; ++qz)
{
double aXY[DofQuadLimits::HDIV_MAX_D1D][DofQuadLimits::HDIV_MAX_D1D];
double aXY[HDIV_MAX_D1D][HDIV_MAX_D1D];
int osc = 0;
for (int c = 0; c < VDIM; ++c) // loop over x, y, z components
@@ -1907,7 +1892,7 @@ void PAHdivL2ApplyTranspose3D(const int D1D,
}
for (int qy = 0; qy < Q1D; ++qy)
{
double aX[DofQuadLimits::HDIV_MAX_D1D];
double aX[HDIV_MAX_D1D];
for (int dx = 0; dx < D1Dx; ++dx)
{
aX[dx] = 0;
+4 -4
View File
@@ -140,8 +140,8 @@ inline void SmemPAHdivMassApply2D(const int NE,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::HDIV_MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::HDIV_MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : HDIV_MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : HDIV_MAX_D1D;
constexpr int MDQ = (MQ1 > MD1) ? MQ1 : MD1;
MFEM_SHARED double smo[MQ1*(MD1-1)];
@@ -310,8 +310,8 @@ inline void SmemPAHdivMassApply3D(const int NE,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::HDIV_MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::HDIV_MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : HDIV_MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : HDIV_MAX_D1D;
constexpr int MDQ = (MQ1 > MD1) ? MQ1 : MD1;
MFEM_SHARED double smo[MQ1*(MD1-1)];
+29 -42
View File
@@ -34,12 +34,11 @@ static void PAHcurlApplyGradient2D(const int c_dofs1D,
auto x = Reshape(x_.Read(), c_dofs1D, c_dofs1D, NE);
auto y = Reshape(y_.ReadWrite(), 2 * c_dofs1D * o_dofs1D, NE);
MFEM_VERIFY(c_dofs1D <= DeviceDofQuadLimits::Get().MAX_D1D &&
o_dofs1D <= c_dofs1D, "");
constexpr static int MAX_D1D = HCURL_MAX_D1D;
MFEM_VERIFY(c_dofs1D <= MAX_D1D && o_dofs1D <= c_dofs1D, "");
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
double w[MAX_D1D][MAX_D1D];
// horizontal part
@@ -111,12 +110,11 @@ static void PAHcurlApplyGradient2DBId(const int c_dofs1D,
auto x = Reshape(x_.Read(), c_dofs1D, c_dofs1D, NE);
auto y = Reshape(y_.ReadWrite(), 2 * c_dofs1D * o_dofs1D, NE);
MFEM_VERIFY(c_dofs1D <= DeviceDofQuadLimits::Get().MAX_D1D &&
o_dofs1D <= c_dofs1D, "");
constexpr static int MAX_D1D = HCURL_MAX_D1D;
MFEM_VERIFY(c_dofs1D <= MAX_D1D && o_dofs1D <= c_dofs1D, "");
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
double w[MAX_D1D][MAX_D1D];
// horizontal part
@@ -180,12 +178,11 @@ static void PAHcurlApplyGradientTranspose2D(
auto x = Reshape(x_.Read(), 2 * c_dofs1D * o_dofs1D, NE);
auto y = Reshape(y_.ReadWrite(), c_dofs1D, c_dofs1D, NE);
MFEM_VERIFY(c_dofs1D <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D &&
o_dofs1D <= c_dofs1D, "");
constexpr static int MAX_D1D = HCURL_MAX_D1D;
MFEM_VERIFY(c_dofs1D <= MAX_D1D && o_dofs1D <= c_dofs1D, "");
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
double w[MAX_D1D][MAX_D1D];
// horizontal part (open x, closed y)
@@ -256,12 +253,11 @@ static void PAHcurlApplyGradientTranspose2DBId(
auto x = Reshape(x_.Read(), 2 * c_dofs1D * o_dofs1D, NE);
auto y = Reshape(y_.ReadWrite(), c_dofs1D, c_dofs1D, NE);
MFEM_VERIFY(c_dofs1D <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D &&
o_dofs1D <= c_dofs1D, "");
constexpr static int MAX_D1D = HCURL_MAX_D1D;
MFEM_VERIFY(c_dofs1D <= MAX_D1D && o_dofs1D <= c_dofs1D, "");
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
double w[MAX_D1D][MAX_D1D];
// horizontal part (open x, closed y)
@@ -328,12 +324,11 @@ static void PAHcurlApplyGradient3D(const int c_dofs1D,
auto x = Reshape(x_.Read(), c_dofs1D, c_dofs1D, c_dofs1D, NE);
auto y = Reshape(y_.ReadWrite(), (3 * c_dofs1D * c_dofs1D * o_dofs1D), NE);
MFEM_VERIFY(c_dofs1D <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D &&
o_dofs1D <= c_dofs1D, "");
constexpr static int MAX_D1D = HCURL_MAX_D1D;
MFEM_VERIFY(c_dofs1D <= MAX_D1D && o_dofs1D <= c_dofs1D, "");
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
double w1[MAX_D1D][MAX_D1D][MAX_D1D];
double w2[MAX_D1D][MAX_D1D][MAX_D1D];
@@ -516,13 +511,11 @@ static void PAHcurlApplyGradient3DBId(const int c_dofs1D,
auto x = Reshape(x_.Read(), c_dofs1D, c_dofs1D, c_dofs1D, NE);
auto y = Reshape(y_.ReadWrite(), (3 * c_dofs1D * c_dofs1D * o_dofs1D), NE);
MFEM_VERIFY(c_dofs1D <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D &&
o_dofs1D <= c_dofs1D, "");
constexpr static int MAX_D1D = HCURL_MAX_D1D;
MFEM_VERIFY(c_dofs1D <= MAX_D1D && o_dofs1D <= c_dofs1D, "");
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
double w1[MAX_D1D][MAX_D1D][MAX_D1D];
double w2[MAX_D1D][MAX_D1D][MAX_D1D];
@@ -685,12 +678,11 @@ static void PAHcurlApplyGradientTranspose3D(
auto x = Reshape(x_.Read(), (3 * c_dofs1D * c_dofs1D * o_dofs1D), NE);
auto y = Reshape(y_.ReadWrite(), c_dofs1D, c_dofs1D, c_dofs1D, NE);
MFEM_VERIFY(c_dofs1D <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D &&
o_dofs1D <= c_dofs1D, "");
constexpr static int MAX_D1D = HCURL_MAX_D1D;
MFEM_VERIFY(c_dofs1D <= MAX_D1D && o_dofs1D <= c_dofs1D, "");
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
double w1[MAX_D1D][MAX_D1D][MAX_D1D];
double w2[MAX_D1D][MAX_D1D][MAX_D1D];
// ---
@@ -871,13 +863,11 @@ static void PAHcurlApplyGradientTranspose3DBId(
auto x = Reshape(x_.Read(), (3 * c_dofs1D * c_dofs1D * o_dofs1D), NE);
auto y = Reshape(y_.ReadWrite(), c_dofs1D, c_dofs1D, c_dofs1D, NE);
MFEM_VERIFY(c_dofs1D <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D &&
o_dofs1D <= c_dofs1D, "");
constexpr static int MAX_D1D = HCURL_MAX_D1D;
MFEM_VERIFY(c_dofs1D <= MAX_D1D && o_dofs1D <= c_dofs1D, "");
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
double w1[MAX_D1D][MAX_D1D][MAX_D1D];
double w2[MAX_D1D][MAX_D1D][MAX_D1D];
// ---
@@ -1162,13 +1152,12 @@ static void PAHcurlVecH1IdentityApply2D(const int c_dofs1D,
auto vk = Reshape(pa_data.Read(), 2, (2 * c_dofs1D * o_dofs1D), NE);
MFEM_VERIFY(c_dofs1D <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D &&
o_dofs1D <= c_dofs1D, "");
constexpr static int MAX_D1D = HCURL_MAX_D1D;
MFEM_VERIFY(c_dofs1D <= MAX_D1D && o_dofs1D <= c_dofs1D, "");
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
double w[2][MAX_D1D][MAX_D1D];
// dofs that point parallel to x-axis (open in x, closed in y)
@@ -1262,13 +1251,13 @@ static void PAHcurlVecH1IdentityApplyTranspose2D(const int c_dofs1D,
auto vk = Reshape(pa_data.Read(), 2, (2 * c_dofs1D * o_dofs1D), NE);
MFEM_VERIFY(c_dofs1D <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D &&
o_dofs1D <= c_dofs1D, "");
constexpr static int MAX_D1D = HCURL_MAX_D1D;
//constexpr static int MAX_Q1D = HCURL_MAX_Q1D;
MFEM_VERIFY(c_dofs1D <= MAX_D1D && o_dofs1D <= c_dofs1D, "");
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
double w[2][MAX_D1D][MAX_D1D];
// dofs that point parallel to x-axis (open in x, closed in y)
@@ -1371,13 +1360,12 @@ static void PAHcurlVecH1IdentityApply3D(const int c_dofs1D,
auto vk = Reshape(pa_data.Read(), 3, (3 * c_dofs1D * c_dofs1D * o_dofs1D),
NE);
MFEM_VERIFY(c_dofs1D <= DeviceDofQuadLimits::Get().MAX_D1D &&
o_dofs1D <= c_dofs1D, "");
constexpr static int MAX_D1D = HCURL_MAX_D1D;
MFEM_VERIFY(c_dofs1D <= MAX_D1D && o_dofs1D <= c_dofs1D, "");
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
double w1[3][MAX_D1D][MAX_D1D][MAX_D1D];
double w2[3][MAX_D1D][MAX_D1D][MAX_D1D];
@@ -1586,13 +1574,12 @@ static void PAHcurlVecH1IdentityApplyTranspose3D(const int c_dofs1D,
auto vk = Reshape(pa_data.Read(), 3, (3 * c_dofs1D * c_dofs1D * o_dofs1D),
NE);
MFEM_VERIFY(c_dofs1D <= DeviceDofQuadLimits::Get().MAX_D1D &&
o_dofs1D <= c_dofs1D, "");
constexpr static int MAX_D1D = HCURL_MAX_D1D;
MFEM_VERIFY(c_dofs1D <= MAX_D1D && o_dofs1D <= c_dofs1D, "");
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
double w1[3][MAX_D1D][MAX_D1D][MAX_D1D];
double w2[3][MAX_D1D][MAX_D1D][MAX_D1D];
+11 -11
View File
@@ -27,8 +27,8 @@ static void EAMassAssemble1D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(basis.Read(), Q1D, D1D);
auto D = Reshape(padata.Read(), Q1D, NE);
auto M = Reshape(eadata.ReadWrite(), D1D, D1D, NE);
@@ -36,7 +36,7 @@ static void EAMassAssemble1D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
double r_Bi[MQ1];
double r_Bj[MQ1];
for (int q = 0; q < Q1D; q++)
@@ -77,8 +77,8 @@ static void EAMassAssemble2D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(basis.Read(), Q1D, D1D);
auto D = Reshape(padata.Read(), Q1D, Q1D, NE);
auto M = Reshape(eadata.ReadWrite(), D1D, D1D, D1D, D1D, NE);
@@ -86,8 +86,8 @@ static void EAMassAssemble2D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
double r_B[MQ1][MD1];
for (int d = 0; d < D1D; d++)
{
@@ -149,8 +149,8 @@ static void EAMassAssemble3D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(basis.Read(), Q1D, D1D);
auto D = Reshape(padata.Read(), Q1D, Q1D, Q1D, NE);
auto M = Reshape(eadata.ReadWrite(), D1D, D1D, D1D, D1D, D1D, D1D, NE);
@@ -158,8 +158,8 @@ static void EAMassAssemble3D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int DQ = T_D1D * T_Q1D;
// For quadratic and lower it's better to use registers but for higher-order you start to
+7 -3
View File
@@ -25,6 +25,8 @@ static void PAMassAssembleDiagonal1D(const int NE,
const int D1D,
const int Q1D)
{
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto D = Reshape(d.Read(), Q1D, NE);
auto Y = Reshape(y.ReadWrite(), D1D, NE);
@@ -32,6 +34,7 @@ static void PAMassAssembleDiagonal1D(const int NE,
{
for (int dx = 0; dx < D1D; ++dx)
{
Y(dx, e) = 0.0;
for (int qx = 0; qx < Q1D; ++qx)
{
Y(dx, e) += B(qx, dx) * B(qx, dx) * D(qx, e);
@@ -195,7 +198,8 @@ void PAMassApply1D_Element(const int e,
auto X = ConstDeviceMatrix(x_, D1D, NE);
auto Y = DeviceMatrix(y_, D1D, NE);
double XQ[DofQuadLimits::MAX_Q1D];
constexpr int max_Q1D = MAX_Q1D;
double XQ[max_Q1D];
for (int qx = 0; qx < Q1D; ++qx)
{
XQ[qx] = 0.0;
@@ -228,8 +232,8 @@ static void PAMassApply1D(const int NE,
const int d1d = 0,
const int q1d = 0)
{
MFEM_VERIFY(d1d <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(q1d <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(d1d <= MAX_D1D, "");
MFEM_VERIFY(q1d <= MAX_Q1D, "");
const auto B = b_.Read();
const auto Bt = bt_.Read();
+40 -40
View File
@@ -42,8 +42,8 @@ inline void PAMassAssembleDiagonal2D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto D = Reshape(d.Read(), Q1D, Q1D, NE);
auto Y = Reshape(y.ReadWrite(), D1D, D1D, NE);
@@ -51,8 +51,8 @@ inline void PAMassAssembleDiagonal2D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
double QD[MQ1][MD1];
for (int qx = 0; qx < Q1D; ++qx)
{
@@ -90,10 +90,10 @@ inline void SmemPAMassAssembleDiagonal2D(const int NE,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
const int max_q1d = T_Q1D ? T_Q1D : DeviceDofQuadLimits::Get().MAX_Q1D;
const int max_d1d = T_D1D ? T_D1D : DeviceDofQuadLimits::Get().MAX_D1D;
MFEM_VERIFY(D1D <= max_d1d, "");
MFEM_VERIFY(Q1D <= max_q1d, "");
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
MFEM_VERIFY(D1D <= MD1, "");
MFEM_VERIFY(Q1D <= MQ1, "");
auto b = Reshape(b_.Read(), Q1D, D1D);
auto D = Reshape(d_.Read(), Q1D, Q1D, NE);
auto Y = Reshape(y_.ReadWrite(), D1D, D1D, NE);
@@ -103,8 +103,8 @@ inline void SmemPAMassAssembleDiagonal2D(const int NE,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
MFEM_SHARED double B[MQ1][MD1];
MFEM_SHARED double QDZ[NBZ][MQ1][MD1];
double (*QD)[MD1] = (double (*)[MD1])(QDZ + tidz);
@@ -156,8 +156,8 @@ inline void PAMassAssembleDiagonal3D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto D = Reshape(d.Read(), Q1D, Q1D, Q1D, NE);
auto Y = Reshape(y.ReadWrite(), D1D, D1D, D1D, NE);
@@ -165,8 +165,8 @@ inline void PAMassAssembleDiagonal3D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
double QQD[MQ1][MQ1][MD1];
double QDD[MQ1][MD1][MD1];
for (int qx = 0; qx < Q1D; ++qx)
@@ -226,10 +226,10 @@ inline void SmemPAMassAssembleDiagonal3D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
const int max_q1d = T_Q1D ? T_Q1D : DeviceDofQuadLimits::Get().MAX_Q1D;
const int max_d1d = T_D1D ? T_D1D : DeviceDofQuadLimits::Get().MAX_D1D;
MFEM_VERIFY(D1D <= max_d1d, "");
MFEM_VERIFY(Q1D <= max_q1d, "");
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
MFEM_VERIFY(D1D <= MD1, "");
MFEM_VERIFY(Q1D <= MQ1, "");
auto b = Reshape(b_.Read(), Q1D, D1D);
auto D = Reshape(d_.Read(), Q1D, Q1D, Q1D, NE);
auto Y = Reshape(y_.ReadWrite(), D1D, D1D, D1D, NE);
@@ -238,8 +238,8 @@ inline void SmemPAMassAssembleDiagonal3D(const int NE,
const int tidz = MFEM_THREAD_ID(z);
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
MFEM_SHARED double B[MQ1][MD1];
MFEM_SHARED double QQD[MQ1][MQ1][MD1];
MFEM_SHARED double QDD[MQ1][MD1][MD1];
@@ -365,8 +365,8 @@ void PAMassApply2D_Element(const int e,
}
}
constexpr int max_D1D = DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = MAX_D1D;
constexpr int max_Q1D = MAX_Q1D;
double sol_xy[max_Q1D][max_Q1D];
for (int qy = 0; qy < Q1D; ++qy)
{
@@ -447,8 +447,8 @@ void SmemPAMassApply2D_Element(const int e,
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MDQ = (MQ1 > MD1) ? MQ1 : MD1;
auto b = ConstDeviceMatrix(b_, Q1D, D1D);
@@ -592,8 +592,8 @@ void PAMassApply3D_Element(const int e,
}
}
constexpr int max_D1D = DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = MAX_D1D;
constexpr int max_Q1D = MAX_Q1D;
double sol_xyz[max_Q1D][max_Q1D][max_Q1D];
for (int qz = 0; qz < Q1D; ++qz)
{
@@ -722,8 +722,8 @@ void SmemPAMassApply3D_Element(const int e,
{
constexpr int D1D = T_D1D ? T_D1D : d1d;
constexpr int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MDQ = (MQ1 > MD1) ? MQ1 : MD1;
auto b = ConstDeviceMatrix(b_, Q1D, D1D);
@@ -948,8 +948,8 @@ inline void PAMassApply2D(const int NE,
const int d1d = 0,
const int q1d = 0)
{
MFEM_VERIFY(T_D1D ? T_D1D : d1d <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(T_Q1D ? T_Q1D : q1d <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(T_D1D ? T_D1D : d1d <= MAX_D1D, "");
MFEM_VERIFY(T_Q1D ? T_Q1D : q1d <= MAX_Q1D, "");
const auto B = b_.Read();
const auto Bt = bt_.Read();
@@ -978,10 +978,10 @@ inline void SmemPAMassApply2D(const int NE,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int NBZ = T_NBZ ? T_NBZ : 1;
const int max_q1d = T_Q1D ? T_Q1D : DeviceDofQuadLimits::Get().MAX_Q1D;
const int max_d1d = T_D1D ? T_D1D : DeviceDofQuadLimits::Get().MAX_D1D;
MFEM_VERIFY(D1D <= max_d1d, "");
MFEM_VERIFY(Q1D <= max_q1d, "");
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
MFEM_VERIFY(D1D <= MD1, "");
MFEM_VERIFY(Q1D <= MQ1, "");
const auto b = b_.Read();
const auto D = d_.Read();
const auto x = x_.Read();
@@ -1004,8 +1004,8 @@ inline void PAMassApply3D(const int NE,
const int d1d = 0,
const int q1d = 0)
{
MFEM_VERIFY(T_D1D ? T_D1D : d1d <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(T_Q1D ? T_Q1D : q1d <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(T_D1D ? T_D1D : d1d <= MAX_D1D, "");
MFEM_VERIFY(T_Q1D ? T_Q1D : q1d <= MAX_Q1D, "");
const auto B = b_.Read();
const auto Bt = bt_.Read();
@@ -1033,10 +1033,10 @@ inline void SmemPAMassApply3D(const int NE,
MFEM_CONTRACT_VAR(bt_);
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
const int max_q1d = T_Q1D ? T_Q1D : DeviceDofQuadLimits::Get().MAX_Q1D;
const int max_d1d = T_D1D ? T_D1D : DeviceDofQuadLimits::Get().MAX_D1D;
MFEM_VERIFY(D1D <= max_d1d, "");
MFEM_VERIFY(Q1D <= max_q1d, "");
constexpr int M1Q = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int M1D = T_D1D ? T_D1D : MAX_D1D;
MFEM_VERIFY(D1D <= M1D, "");
MFEM_VERIFY(Q1D <= M1Q, "");
auto b = b_.Read();
auto d = d_.Read();
auto x = x_.Read();
+1 -1
View File
@@ -128,7 +128,7 @@ void MassIntegrator::AssemblePABoundary(const FiniteElementSpace &fes)
int map_type = el.GetMapType();
dim = el.GetDim(); // Dimension of the boundary element, *not* the mesh
ne = fes.GetMesh()->GetNFbyType(FaceType::Boundary);
ne = fes.GetMesh()->GetNBE();
nq = ir->GetNPoints();
face_geom = mesh->GetFaceGeometricFactors(*ir, GeometricFactors::DETERMINANTS,
FaceType::Boundary, mt);
+18 -22
View File
@@ -31,6 +31,10 @@ static void PAHcurlH1Apply2D(const int D1D,
const Vector &x,
Vector &y)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = HCURL_MAX_D1D;
constexpr static int MAX_Q1D = HCURL_MAX_Q1D;
auto Bc = Reshape(bc.Read(), Q1D, D1D);
auto Gc = Reshape(gc.Read(), Q1D, D1D);
auto Bot = Reshape(bot.Read(), D1D-1, Q1D);
@@ -41,10 +45,6 @@ static void PAHcurlH1Apply2D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
double mass[MAX_Q1D][MAX_Q1D][VDIM];
for (int qy = 0; qy < Q1D; ++qy)
@@ -155,6 +155,10 @@ static void PAHcurlH1ApplyTranspose2D(const int D1D,
const Vector &x,
Vector &y)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = HCURL_MAX_D1D;
constexpr static int MAX_Q1D = HCURL_MAX_Q1D;
auto Bc = Reshape(bc.Read(), Q1D, D1D);
auto Bo = Reshape(bo.Read(), Q1D, D1D-1);
auto Bt = Reshape(bct.Read(), D1D, Q1D);
@@ -165,10 +169,6 @@ static void PAHcurlH1ApplyTranspose2D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int VDIM = 2;
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
double mass[MAX_Q1D][MAX_Q1D][VDIM];
for (int qy = 0; qy < Q1D; ++qy)
@@ -280,10 +280,11 @@ static void PAHcurlH1Apply3D(const int D1D,
const Vector &x,
Vector &y)
{
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D,
"Error: D1D > MAX_D1D");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().HCURL_MAX_Q1D,
"Error: Q1D > MAX_Q1D");
constexpr static int MAX_D1D = HCURL_MAX_D1D;
constexpr static int MAX_Q1D = HCURL_MAX_Q1D;
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
MFEM_VERIFY(Q1D <= MAX_Q1D, "Error: Q1D > MAX_Q1D");
constexpr static int VDIM = 3;
@@ -297,9 +298,6 @@ static void PAHcurlH1Apply3D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
double mass[MAX_Q1D][MAX_Q1D][MAX_Q1D][VDIM];
for (int qz = 0; qz < Q1D; ++qz)
@@ -472,10 +470,11 @@ static void PAHcurlH1ApplyTranspose3D(const int D1D,
const Vector &x,
Vector &y)
{
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().HCURL_MAX_D1D,
"Error: D1D > MAX_D1D");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().HCURL_MAX_Q1D,
"Error: Q1D > MAX_Q1D");
constexpr static int MAX_D1D = HCURL_MAX_D1D;
constexpr static int MAX_Q1D = HCURL_MAX_Q1D;
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
MFEM_VERIFY(Q1D <= MAX_Q1D, "Error: Q1D > MAX_Q1D");
constexpr static int VDIM = 3;
@@ -489,9 +488,6 @@ static void PAHcurlH1ApplyTranspose3D(const int D1D,
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
{
constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
double mass[MAX_Q1D][MAX_Q1D][MAX_Q1D][VDIM];
for (int qz = 0; qz < Q1D; ++qz)
+18 -18
View File
@@ -233,8 +233,8 @@ static void PAVectorDiffusionDiagonal2D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto G = Reshape(g.Read(), Q1D, D1D);
// note the different shape for D, this is a (symmetric) matrix so we only
@@ -245,8 +245,8 @@ static void PAVectorDiffusionDiagonal2D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
// gradphi \cdot Q \gradphi has four terms
double QD0[MQ1][MD1];
double QD1[MQ1][MD1];
@@ -301,10 +301,10 @@ static void PAVectorDiffusionDiagonal3D(const int NE,
constexpr int DIM = 3;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
const int max_q1d = T_Q1D ? T_Q1D : DeviceDofQuadLimits::Get().MAX_Q1D;
const int max_d1d = T_D1D ? T_D1D : DeviceDofQuadLimits::Get().MAX_D1D;
MFEM_VERIFY(D1D <= max_d1d, "");
MFEM_VERIFY(Q1D <= max_q1d, "");
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
MFEM_VERIFY(D1D <= MD1, "");
MFEM_VERIFY(Q1D <= MQ1, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto G = Reshape(g.Read(), Q1D, D1D);
auto Q = Reshape(d.Read(), Q1D*Q1D*Q1D, 6, NE);
@@ -313,8 +313,8 @@ static void PAVectorDiffusionDiagonal3D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
double QQD[MQ1][MQ1][MD1];
double QDD[MQ1][MD1][MD1];
for (int i = 0; i < DIM; ++i)
@@ -442,8 +442,8 @@ void PAVectorDiffusionApply2D(const int NE,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
const int VDIM = T_VDIM ? T_VDIM : vdim;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto G = Reshape(g.Read(), Q1D, D1D);
auto Bt = Reshape(bt.Read(), D1D, Q1D);
@@ -456,8 +456,8 @@ void PAVectorDiffusionApply2D(const int NE,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
const int VDIM = T_VDIM ? T_VDIM : vdim;
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double grad[max_Q1D][max_Q1D][2];
for (int c = 0; c < VDIM; c++)
@@ -563,8 +563,8 @@ void PAVectorDiffusionApply3D(const int NE,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int VDIM = 3;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto G = Reshape(g.Read(), Q1D, D1D);
auto Bt = Reshape(bt.Read(), D1D, Q1D);
@@ -576,8 +576,8 @@ void PAVectorDiffusionApply3D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
for (int c = 0; c < VDIM; ++ c)
{
double grad[max_Q1D][max_Q1D][max_Q1D][3];
+26 -26
View File
@@ -170,9 +170,9 @@ static void PADivergenceApply2D(const int NE,
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(TR_D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(TE_D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(TR_D1D <= MAX_D1D, "");
MFEM_VERIFY(TE_D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, TR_D1D);
auto G = Reshape(g.Read(), Q1D, TR_D1D);
auto Bt = Reshape(bt.Read(), TE_D1D, Q1D);
@@ -186,8 +186,8 @@ static void PADivergenceApply2D(const int NE,
const int Q1D = T_Q1D ? T_Q1D : q1d;
const int VDIM = 2;
// the following variables are evaluated at compile time
constexpr int max_TE_D1D = T_TE_D1D ? T_TE_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_TE_D1D = T_TE_D1D ? T_TE_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double grad[max_Q1D][max_Q1D][VDIM];
double div[max_Q1D][max_Q1D];
@@ -308,9 +308,9 @@ static void PADivergenceApplyTranspose2D(const int NE,
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(TR_D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(TE_D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(TR_D1D <= MAX_D1D, "");
MFEM_VERIFY(TE_D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto Bt = Reshape(bt.Read(), TR_D1D, Q1D);
auto Gt = Reshape(gt.Read(), TR_D1D, Q1D);
auto B = Reshape(b.Read(), Q1D, TE_D1D);
@@ -324,8 +324,8 @@ static void PADivergenceApplyTranspose2D(const int NE,
const int Q1D = T_Q1D ? T_Q1D : q1d;
const int VDIM = 2;
// the following variables are evaluated at compile time
constexpr int max_TR_D1D = T_TR_D1D ? T_TR_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_TR_D1D = T_TR_D1D ? T_TR_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double quadTest[max_Q1D][max_Q1D];
double grad[max_Q1D][max_Q1D][VDIM];
@@ -424,9 +424,9 @@ static void PADivergenceApply3D(const int NE,
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(TR_D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(TE_D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(TR_D1D <= MAX_D1D, "");
MFEM_VERIFY(TE_D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, TR_D1D);
auto G = Reshape(g.Read(), Q1D, TR_D1D);
auto Bt = Reshape(bt.Read(), TE_D1D, Q1D);
@@ -440,8 +440,8 @@ static void PADivergenceApply3D(const int NE,
const int Q1D = T_Q1D ? T_Q1D : q1d;
const int VDIM = 3;
// the following variables are evaluated at compile time
constexpr int max_TE_D1D = T_TE_D1D ? T_TE_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_TE_D1D = T_TE_D1D ? T_TE_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double grad[max_Q1D][max_Q1D][max_Q1D][VDIM];
double div[max_Q1D][max_Q1D][max_Q1D];
@@ -607,9 +607,9 @@ static void PADivergenceApplyTranspose3D(const int NE,
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(TR_D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(TE_D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(TR_D1D <= MAX_D1D, "");
MFEM_VERIFY(TE_D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto Bt = Reshape(bt.Read(), TR_D1D, Q1D);
auto Gt = Reshape(gt.Read(), TR_D1D, Q1D);
auto B = Reshape(b.Read(), Q1D, TE_D1D);
@@ -623,8 +623,8 @@ static void PADivergenceApplyTranspose3D(const int NE,
const int Q1D = T_Q1D ? T_Q1D : q1d;
const int VDIM = 3;
// the following variables are evaluated at compile time
constexpr int max_TR_D1D = T_TR_D1D ? T_TR_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_TR_D1D = T_TR_D1D ? T_TR_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double quadTest[max_Q1D][max_Q1D][max_Q1D];
double grad[max_Q1D][max_Q1D][max_Q1D][VDIM];
@@ -786,9 +786,9 @@ static void SmemPADivergenceApply3D(const int NE,
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(TR_D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(TE_D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(TR_D1D <= MAX_D1D, "");
MFEM_VERIFY(TE_D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto b = Reshape(b_.Read(), Q1D, TR_D1D);
auto g = Reshape(g_.Read(), Q1D, TR_D1D);
@@ -804,9 +804,9 @@ static void SmemPADivergenceApply3D(const int NE,
const int D1DR = T_TR_D1D ? T_TR_D1D : tr_d1d;
const int D1DE = T_TE_D1D ? T_TE_D1D : te_d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int MD1R = T_TR_D1D ? T_TR_D1D : DofQuadLimits::MAX_D1D;
constexpr int MD1E = T_TE_D1D ? T_TE_D1D : DofQuadLimits::MAX_D1D;
constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int MD1R = T_TR_D1D ? T_TR_D1D : MAX_D1D;
constexpr int MD1E = T_TE_D1D ? T_TE_D1D : MAX_D1D;
constexpr int MD1 = MD1E > MD1R ? MD1E : MD1R;
constexpr int MDQ = MQ1 > MD1 ? MQ1 : MD1;
MFEM_SHARED double sBG[2][MQ1*MD1];
+16 -16
View File
@@ -118,8 +118,8 @@ static void PAVectorMassAssembleDiagonal2D(const int NE,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int VDIM = 2;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(B_.Read(), Q1D, D1D);
auto op = Reshape(op_.Read(), Q1D, Q1D, NE);
auto y = Reshape(diag_.ReadWrite(), D1D, D1D, VDIM, NE);
@@ -127,8 +127,8 @@ static void PAVectorMassAssembleDiagonal2D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double temp[max_Q1D][max_D1D];
for (int qx = 0; qx < Q1D; ++qx)
@@ -170,8 +170,8 @@ static void PAVectorMassAssembleDiagonal3D(const int NE,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int VDIM = 3;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(B_.Read(), Q1D, D1D);
auto op = Reshape(op_.Read(), Q1D, Q1D, Q1D, NE);
auto y = Reshape(diag_.ReadWrite(), D1D, D1D, D1D, VDIM, NE);
@@ -180,8 +180,8 @@ static void PAVectorMassAssembleDiagonal3D(const int NE,
const int D1D = T_D1D ? T_D1D : d1d; // nvcc workaround
const int Q1D = T_Q1D ? T_Q1D : q1d;
// the following variables are evaluated at compile time
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double temp[max_Q1D][max_Q1D][max_D1D];
for (int qx = 0; qx < Q1D; ++qx)
@@ -281,8 +281,8 @@ static void PAVectorMassApply2D(const int NE,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int VDIM = 2;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(B_.Read(), Q1D, D1D);
auto Bt = Reshape(Bt_.Read(), D1D, Q1D);
auto op = Reshape(op_.Read(), Q1D, Q1D, NE);
@@ -293,8 +293,8 @@ static void PAVectorMassApply2D(const int NE,
const int D1D = T_D1D ? T_D1D : d1d; // nvcc workaround
const int Q1D = T_Q1D ? T_Q1D : q1d;
// the following variables are evaluated at compile time
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double sol_xy[max_Q1D][max_Q1D];
for (int c = 0; c < VDIM; ++c)
{
@@ -377,8 +377,8 @@ static void PAVectorMassApply3D(const int NE,
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int VDIM = 3;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(B_.Read(), Q1D, D1D);
auto Bt = Reshape(Bt_.Read(), D1D, Q1D);
auto op = Reshape(op_.Read(), Q1D, Q1D, Q1D, NE);
@@ -388,8 +388,8 @@ static void PAVectorMassApply3D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double sol_xyz[max_Q1D][max_Q1D][max_Q1D];
for (int c = 0; c < VDIM; ++ c)
{
+3 -3
View File
@@ -38,7 +38,7 @@ static void BLFEvalAssemble2D(const int vdim, const int nbe, const int d,
{
if (M(e) == 0) { return; } // ignore
constexpr int Q = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int Q = T_Q1D ? T_Q1D : MAX_Q1D;
double QQ[Q];
for (int c = 0; c < vdim; ++c)
@@ -92,8 +92,8 @@ static void BLFEvalAssemble3D(const int vdim, const int nbe, const int d,
{
if (M(e) == 0) { return; } // ignore
constexpr int Q = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int Q = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int D = T_D1D ? T_D1D : MAX_D1D;
MFEM_SHARED double sBt[Q*D];
MFEM_SHARED double sQQ[Q*Q];
+3 -3
View File
@@ -33,7 +33,7 @@ void BFLFEvalAssemble2D(const int nbe, const int d, const int q,
{
if (M(e) == 0) { return; } // ignore (in a lambda return acts as continue)
constexpr int Q = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int Q = T_Q1D ? T_Q1D : MAX_Q1D;
double QQ[Q];
for (int qx = 0; qx < q; ++qx)
@@ -67,8 +67,8 @@ void BFLFEvalAssemble3D(const int nbe, const int d, const int q,
{
if (M(e) == 0) { return; } // ignore
constexpr int Q = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int Q = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int D = T_D1D ? T_D1D : MAX_D1D;
MFEM_SHARED double sBt[Q*D];
MFEM_SHARED double sQQ[Q*Q];
+4 -4
View File
@@ -36,8 +36,8 @@ static void DLFEvalAssemble2D(const int vdim, const int ne, const int d,
{
if (M(e) == 0) { return; } // ignore
constexpr int Q = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int Q = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int D = T_D1D ? T_D1D : MAX_D1D;
MFEM_SHARED double sBt[Q*D];
MFEM_SHARED double sQQ[Q*Q];
@@ -107,8 +107,8 @@ static void DLFEvalAssemble3D(const int vdim, const int ne, const int d,
{
if (M(e) == 0) { return; } // ignore
constexpr int Q = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int Q = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int D = T_D1D ? T_D1D : MAX_D1D;
constexpr int MQD = (Q >= D) ? Q : D;
double u[D];
+4 -4
View File
@@ -36,8 +36,8 @@ void DLFGradAssemble2D(const int vdim, const int ne, const int d, const int q,
{
if (M(e) == 0) { return; } // ignore
constexpr int Q = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int Q = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int D = T_D1D ? T_D1D : MAX_D1D;
MFEM_SHARED double sBGt[2][Q*D];
MFEM_SHARED double sQQ[2][Q*Q];
@@ -130,8 +130,8 @@ void DLFGradAssemble3D(const int vdim, const int ne, const int d, const int q,
{
if (M(e) == 0) { return; } // ignore
constexpr int Q = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int Q = T_Q1D ? T_Q1D : MAX_Q1D;
constexpr int D = T_D1D ? T_D1D : MAX_D1D;
constexpr int MQD = (Q >= D) ? Q : D;
MFEM_SHARED double sBGt[2][Q*D];
+8 -12
View File
@@ -22,10 +22,8 @@ static void HdivDLFAssemble2D(
const double *bc, const double *j, const double *weights,
const Vector &coeff, double *y)
{
MFEM_VERIFY(T_D1D || d <= DeviceDofQuadLimits::Get().HDIV_MAX_D1D,
"Problem size too large.");
MFEM_VERIFY(T_Q1D || q <= DeviceDofQuadLimits::Get().HDIV_MAX_Q1D,
"Problem size too large.");
MFEM_VERIFY(T_D1D || d <= HDIV_MAX_D1D, "Problem size too large.");
MFEM_VERIFY(T_Q1D || q <= HDIV_MAX_Q1D, "Problem size too large.");
static constexpr int vdim = 2;
const auto F = coeff.Read();
@@ -42,8 +40,8 @@ static void HdivDLFAssemble2D(
{
if (M(e) == 0) { return; } // ignore
constexpr int Q = T_Q1D ? T_Q1D : DofQuadLimits::HDIV_MAX_Q1D;
constexpr int D = T_D1D ? T_D1D : DofQuadLimits::HDIV_MAX_D1D;
constexpr int Q = T_Q1D ? T_Q1D : HDIV_MAX_Q1D;
constexpr int D = T_D1D ? T_D1D : HDIV_MAX_D1D;
MFEM_SHARED double sBot[Q*D];
MFEM_SHARED double sBct[Q*D];
@@ -123,10 +121,8 @@ static void HdivDLFAssemble3D(
const double *bc, const double *j, const double *weights,
const Vector &coeff, double *y)
{
MFEM_VERIFY(T_D1D || d <= DeviceDofQuadLimits::Get().HDIV_MAX_D1D,
"Problem size too large.");
MFEM_VERIFY(T_Q1D || q <= DeviceDofQuadLimits::Get().HDIV_MAX_Q1D,
"Problem size too large.");
MFEM_VERIFY(T_D1D || d <= HDIV_MAX_D1D, "Problem size too large.");
MFEM_VERIFY(T_Q1D || q <= HDIV_MAX_Q1D, "Problem size too large.");
static constexpr int vdim = 3;
const auto F = coeff.Read();
@@ -143,8 +139,8 @@ static void HdivDLFAssemble3D(
{
if (M(e) == 0) { return; } // ignore
constexpr int Q = T_Q1D ? T_Q1D : DofQuadLimits::HDIV_MAX_Q1D;
constexpr int D = T_D1D ? T_D1D : DofQuadLimits::HDIV_MAX_D1D;
constexpr int Q = T_Q1D ? T_Q1D : HDIV_MAX_Q1D;
constexpr int D = T_D1D ? T_D1D : HDIV_MAX_D1D;
MFEM_SHARED double sBot[Q*D];
MFEM_SHARED double sBct[Q*D];
+8 -8
View File
@@ -136,8 +136,8 @@ static void PAConvectionNLApply2D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto G = Reshape(g.Read(), Q1D, D1D);
auto Bt = Reshape(bt.Read(), D1D, Q1D);
@@ -148,8 +148,8 @@ static void PAConvectionNLApply2D(const int NE,
{
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double data[max_Q1D][max_Q1D][2];
double grad0[max_Q1D][max_Q1D][2];
@@ -273,8 +273,8 @@ static void PAConvectionNLApply3D(const int NE,
constexpr int VDIM = 3;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
MFEM_VERIFY(D1D <= DeviceDofQuadLimits::Get().MAX_D1D, "");
MFEM_VERIFY(Q1D <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
MFEM_VERIFY(D1D <= MAX_D1D, "");
MFEM_VERIFY(Q1D <= MAX_Q1D, "");
auto B = Reshape(b.Read(), Q1D, D1D);
auto G = Reshape(g.Read(), Q1D, D1D);
@@ -288,8 +288,8 @@ static void PAConvectionNLApply3D(const int NE,
constexpr int VDIM = 3;
const int D1D = T_D1D ? T_D1D : d1d;
const int Q1D = T_Q1D ? T_Q1D : q1d;
constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
constexpr int max_D1D = T_D1D ? T_D1D : MAX_D1D;
constexpr int max_Q1D = T_Q1D ? T_Q1D : MAX_Q1D;
double data[max_Q1D][max_Q1D][max_Q1D][VDIM];
double grad0[max_Q1D][max_Q1D][max_Q1D][VDIM];

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