Compare commits
771
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17e11faf07 | ||
|
|
2a482c0c9e | ||
|
|
540c21c9e5 | ||
|
|
11030265e2 | ||
|
|
0a00d9f69b | ||
|
|
87298ef8e4 | ||
|
|
635026fc5f | ||
|
|
2a85a72d19 | ||
|
|
8ed11a5c9a | ||
|
|
0739640110 | ||
|
|
96ac1d9444 | ||
|
|
1e29890736 | ||
|
|
6c22a3a1ef | ||
|
|
d6ae740c12 | ||
|
|
8dc00bd3d0 | ||
|
|
c9d87590fc | ||
|
|
04368ef95a | ||
|
|
cfebb493c0 | ||
|
|
af6cc43ad8 | ||
|
|
3303e58921 | ||
|
|
192c4eeeea | ||
|
|
30bf4cae58 | ||
|
|
542a72402c | ||
|
|
344c72ad98 | ||
|
|
fb1a587206 | ||
|
|
bd11106166 | ||
|
|
b2c53715e9 | ||
|
|
957ca0d500 | ||
|
|
20d8f980a5 | ||
|
|
aeeddcb11e | ||
|
|
596b76cee2 | ||
|
|
f8f04c9328 | ||
|
|
8555207d7b | ||
|
|
df87b22266 | ||
|
|
f57aa5a808 | ||
|
|
ed256ff9a3 | ||
|
|
dd127b07b5 | ||
|
|
608ec13913 | ||
|
|
b69059e79b | ||
|
|
d6a4f0ae6c | ||
|
|
0a9a48a9fc | ||
|
|
e0935aa66f | ||
|
|
f56ef541cd | ||
|
|
c5e02ba0cc | ||
|
|
3d43371e9d | ||
|
|
9c13b53522 | ||
|
|
83bd5a2f6c | ||
|
|
47de3415cf | ||
|
|
a80d35b387 | ||
|
|
b21b24b4cf | ||
|
|
d13d2f0f7a | ||
|
|
5574298f29 | ||
|
|
8c09d9109c | ||
|
|
9cbb59b742 | ||
|
|
e5bbc170d3 | ||
|
|
47ddbc4f67 | ||
|
|
4044514851 | ||
|
|
7a9ccc5dad | ||
|
|
60fc13dcaf | ||
|
|
20cb653eb3 | ||
|
|
da8b01bcf1 | ||
|
|
e4cfbc56d7 | ||
|
|
e50e54e090 | ||
|
|
db7072a5c4 | ||
|
|
411ee5b1cf | ||
|
|
fcc353b30c | ||
|
|
b33a8d24ab | ||
|
|
f1f98dd735 | ||
|
|
cc9885695b | ||
|
|
d3a66a5887 | ||
|
|
e77d74aeef | ||
|
|
723e8e656e | ||
|
|
ac2a21516c | ||
|
|
8ba104788f | ||
|
|
a454a5407c | ||
|
|
689b46e3d6 | ||
|
|
fb1d72e453 | ||
|
|
af1bc97a77 | ||
|
|
4fac872989 | ||
|
|
76e7693235 | ||
|
|
39fd1c5dee | ||
|
|
85ccdf210a | ||
|
|
fc802cbd6d | ||
|
|
61a49b8ca0 | ||
|
|
0713dd34f0 | ||
|
|
7d448fec3d | ||
|
|
88c0b0321c | ||
|
|
d303e35976 | ||
|
|
c34fc00644 | ||
|
|
e71352e90e | ||
|
|
1d4f49acfb | ||
|
|
ababf1aab3 | ||
|
|
0971513c89 | ||
|
|
cef0828362 | ||
|
|
46cde14697 | ||
|
|
dd5963bd21 | ||
|
|
e992d41a38 | ||
|
|
5f373e8c2a | ||
|
|
2fad6d25b9 | ||
|
|
898367b198 | ||
|
|
0fdb8a2709 | ||
|
|
0303669e9a | ||
|
|
37d19f99de | ||
|
|
104da453ed | ||
|
|
c82ce947d6 | ||
|
|
c8644c4b13 | ||
|
|
fa10d89676 | ||
|
|
7534d86172 | ||
|
|
e680558010 | ||
|
|
0c12c9298b | ||
|
|
dc13eac9e6 | ||
|
|
993f478c54 | ||
|
|
cdf9cfe1b6 | ||
|
|
4e30030ab7 | ||
|
|
22878ee681 | ||
|
|
aba85bf679 | ||
|
|
3a59281601 | ||
|
|
2360809938 | ||
|
|
69b26cb722 | ||
|
|
f734b1bd92 | ||
|
|
14c31edb4b | ||
|
|
bbc9af2619 | ||
|
|
16fc316ee6 | ||
|
|
fd195a0e8a | ||
|
|
45f5d4bd72 | ||
|
|
2a1cce4663 | ||
|
|
80399de548 | ||
|
|
473bd4177e | ||
|
|
3c886d0c76 | ||
|
|
4877bf12d1 | ||
|
|
70941f93f0 | ||
|
|
f49ffcb99b | ||
|
|
a076bd04cb | ||
|
|
095893d224 | ||
|
|
184c3cbbb8 | ||
|
|
29730813cb | ||
|
|
b023416c47 | ||
|
|
cbbfaede8c | ||
|
|
bb8a5b88da | ||
|
|
057a5a43b0 | ||
|
|
867a26ae4b | ||
|
|
acc8ba9df3 | ||
|
|
73ee69da91 | ||
|
|
bfb3eb786b | ||
|
|
bc729465d6 | ||
|
|
c690c25058 | ||
|
|
4f629c150d | ||
|
|
7b35f3cfde | ||
|
|
9d78e8cc23 | ||
|
|
1c252d79d8 | ||
|
|
fe8562e6e3 | ||
|
|
ce5b362077 | ||
|
|
fd6e0e1659 | ||
|
|
73f84b48f8 | ||
|
|
661e2d3d2b | ||
|
|
1c71292d7c | ||
|
|
0e7dc57fe5 | ||
|
|
337ab968e1 | ||
|
|
0952809e5e | ||
|
|
88f731cf32 | ||
|
|
f89885905c | ||
|
|
b9a1f8689e | ||
|
|
b479f97b54 | ||
|
|
3bf5c6adad | ||
|
|
def84fdd86 | ||
|
|
565c2b800d | ||
|
|
5202ab09c5 | ||
|
|
5fc313d2f2 | ||
|
|
299a8d6c14 | ||
|
|
5683932a61 | ||
|
|
2432eefc23 | ||
|
|
8030334a97 | ||
|
|
e13989a293 | ||
|
|
7f47e0b7ac | ||
|
|
e3ec06fbb8 | ||
|
|
2dd9c9ca65 | ||
|
|
ab503a3fd0 | ||
|
|
46fdcd696f | ||
|
|
9f42d495ca | ||
|
|
0c91dba1bd | ||
|
|
fce85e66a9 | ||
|
|
6d5381cdd2 | ||
|
|
6be7547229 | ||
|
|
63da26c00f | ||
|
|
713f86c134 | ||
|
|
708c477714 | ||
|
|
96382fe2a6 | ||
|
|
5a38a2e712 | ||
|
|
5af524009e | ||
|
|
2137ce1f4f | ||
|
|
c32d62f83c | ||
|
|
8aa00234d8 | ||
|
|
5d6ca8b560 | ||
|
|
cc22712539 | ||
|
|
6fbe2c2280 | ||
|
|
fbc4083001 | ||
|
|
65b3cb157a | ||
|
|
ffa4f84108 | ||
|
|
988439f60a | ||
|
|
09d03b715e | ||
|
|
5398491cd4 | ||
|
|
0ff7174de2 | ||
|
|
0108a83a43 | ||
|
|
151828f435 | ||
|
|
4d1564ff64 | ||
|
|
ac906c8827 | ||
|
|
1710d10dbe | ||
|
|
5292971b7e | ||
|
|
9997d1b718 | ||
|
|
967e0f5bac | ||
|
|
194debfcc0 | ||
|
|
eae459cb15 | ||
|
|
580578aa04 | ||
|
|
82ad111db5 | ||
|
|
f575e45593 | ||
|
|
e5c31240d0 | ||
|
|
70f2f6677f | ||
|
|
31202eb904 | ||
|
|
bf79ef7f90 | ||
|
|
d81bab442d | ||
|
|
9343ffad7b | ||
|
|
e2a8206d35 | ||
|
|
62049a7990 | ||
|
|
d44ff2d39e | ||
|
|
f5219a2484 | ||
|
|
6d2dec6361 | ||
|
|
ce18700b07 | ||
|
|
36d28c6e3e | ||
|
|
098be49296 | ||
|
|
b5b4b5da7d | ||
|
|
24e2d0f959 | ||
|
|
3d80323862 | ||
|
|
ffce41001e | ||
|
|
5724e4f274 | ||
|
|
e189b0b0f0 | ||
|
|
11badb5d2f | ||
|
|
39e3854585 | ||
|
|
c271ac1eda | ||
|
|
ed8ce36e96 | ||
|
|
66c71dd4f2 | ||
|
|
635c487665 | ||
|
|
90c995f0e6 | ||
|
|
9d3ce2c394 | ||
|
|
6fd27950ed | ||
|
|
185b2bba58 | ||
|
|
93e6be67d3 | ||
|
|
7a4ab004c2 | ||
|
|
467cc941f3 | ||
|
|
5a5d9cfe77 | ||
|
|
998b531fe5 | ||
|
|
c33327f234 | ||
|
|
e60145110d | ||
|
|
5f04684f17 | ||
|
|
7f1eb85c45 | ||
|
|
878f94f998 | ||
|
|
a3065a05dc | ||
|
|
ede448d783 | ||
|
|
2e0df87cd6 | ||
|
|
5ec854e9e4 | ||
|
|
842c68b0b5 | ||
|
|
0b75377438 | ||
|
|
c3806304d4 | ||
|
|
74e538404e | ||
|
|
a092f9cad0 | ||
|
|
17eb65d619 | ||
|
|
a042d2db0d | ||
|
|
01819638f7 | ||
|
|
acb5f5acf7 | ||
|
|
75567ae1ef | ||
|
|
5425dbeb5b | ||
|
|
c18e27aeac | ||
|
|
3d84777b69 | ||
|
|
fe918fcdd4 | ||
|
|
c240df5fbe | ||
|
|
950198a3f2 | ||
|
|
d808463114 | ||
|
|
5447bcf8a9 | ||
|
|
ef6d80189f | ||
|
|
7ace2dedf1 | ||
|
|
cb6d48f499 | ||
|
|
36dea0cf38 | ||
|
|
f135f662e7 | ||
|
|
9ca87d3ecf | ||
|
|
10b9503528 | ||
|
|
0572181086 | ||
|
|
8c58872ec8 | ||
|
|
df5b718f16 | ||
|
|
01dfecd67e | ||
|
|
94ca7d26e8 | ||
|
|
46e35d0bce | ||
|
|
d582c31370 | ||
|
|
f387244e57 | ||
|
|
8876a84dd4 | ||
|
|
8153d11274 | ||
|
|
827ed64113 | ||
|
|
ef9f02ba53 | ||
|
|
e9a0b0620a | ||
|
|
4d9d444248 | ||
|
|
6e2badecca | ||
|
|
99b45fcb02 | ||
|
|
003dc46a84 | ||
|
|
7fac0fbd07 | ||
|
|
9bae3b25ab | ||
|
|
c28fd71214 | ||
|
|
ce0d89397b | ||
|
|
c2cc36e559 | ||
|
|
305124eaaf | ||
|
|
e30950f349 | ||
|
|
254ade218b | ||
|
|
9a327eeca6 | ||
|
|
086f6c9847 | ||
|
|
480e90b41b | ||
|
|
bc6ba0252a | ||
|
|
262fa6173d | ||
|
|
e4b8584a16 | ||
|
|
7912d6915d | ||
|
|
293d9009ae | ||
|
|
51bde67bb1 | ||
|
|
9caa48d5c8 | ||
|
|
f4d286b4b7 | ||
|
|
45e2636921 | ||
|
|
57876fbfb0 | ||
|
|
c3eb769a2a | ||
|
|
9286d89b0e | ||
|
|
2b9f428909 | ||
|
|
b230e5f594 | ||
|
|
3e8d7f21a2 | ||
|
|
47b519047a | ||
|
|
35225e045e | ||
|
|
22c1087503 | ||
|
|
a74663d634 | ||
|
|
469096892f | ||
|
|
cd5d2f7c04 | ||
|
|
7fc2ce350d | ||
|
|
4314dc64db | ||
|
|
cbae29ad06 | ||
|
|
4c1d842c72 | ||
|
|
4aa0ed52af | ||
|
|
fca4c314d4 | ||
|
|
8712d02570 | ||
|
|
e5fec6279b | ||
|
|
e90e96f9a5 | ||
|
|
459def6d79 | ||
|
|
cc00ef7d90 | ||
|
|
7b84f6ddc6 | ||
|
|
2c0346bc36 | ||
|
|
56186d8770 | ||
|
|
1645b854a4 | ||
|
|
69fd2f9051 | ||
|
|
a5d230f199 | ||
|
|
ba4b627e68 | ||
|
|
62c535d0ee | ||
|
|
17829d1c38 | ||
|
|
dd198ce3f9 | ||
|
|
b9f36468ba | ||
|
|
76bcd044d0 | ||
|
|
84ce403ffb | ||
|
|
df09aea4da | ||
|
|
d2840464ba | ||
|
|
0dff351b2e | ||
|
|
55a914321d | ||
|
|
1410aef639 | ||
|
|
e1ac8ca08c | ||
|
|
28916b23a4 | ||
|
|
7476c00f2b | ||
|
|
7a0137c496 | ||
|
|
4267b2af05 | ||
|
|
e37daad5eb | ||
|
|
22653aaf6e | ||
|
|
a461f25b4a | ||
|
|
20b4b72071 | ||
|
|
ddf80492c5 | ||
|
|
db8b4c9f20 | ||
|
|
d4137f9c7a | ||
|
|
c6a3ccba0b | ||
|
|
755206a2d3 | ||
|
|
43dd9549f4 | ||
|
|
20b52574c6 | ||
|
|
e33344f539 | ||
|
|
712ae82026 | ||
|
|
606439cfb8 | ||
|
|
147cbc014a | ||
|
|
aa07a1b175 | ||
|
|
53171de727 | ||
|
|
53dd97e0d8 | ||
|
|
0c413570c4 | ||
|
|
d6bfc6370e | ||
|
|
f8d18cd4be | ||
|
|
994d83dd80 | ||
|
|
f218efae09 | ||
|
|
43bb865c26 | ||
|
|
dd9b723cfd | ||
|
|
87362ca1ca | ||
|
|
a6afefc6a5 | ||
|
|
e1dc4680d3 | ||
|
|
44985dacc0 | ||
|
|
9c77f6b407 | ||
|
|
8df0341e11 | ||
|
|
af24eaea27 | ||
|
|
f8c6512cf9 | ||
|
|
4385e6d568 | ||
|
|
171346b20f | ||
|
|
6f7320c240 | ||
|
|
1c17415be3 | ||
|
|
eaed96dae0 | ||
|
|
e6ce6e7532 | ||
|
|
7338e797bb | ||
|
|
31d931a99c | ||
|
|
3ae930c93b | ||
|
|
36f882257e | ||
|
|
1508ae0886 | ||
|
|
8adb7461b0 | ||
|
|
716e370d35 | ||
|
|
37c0768fe3 | ||
|
|
d395caad9b | ||
|
|
3e5e18797c | ||
|
|
aab273b303 | ||
|
|
e4d1a861c9 | ||
|
|
217b77d5f0 | ||
|
|
bb67d6cb98 | ||
|
|
cb6b94d9d9 | ||
|
|
7f118b0793 | ||
|
|
a6f0a23998 | ||
|
|
9eb4e5f947 | ||
|
|
badd444b9f | ||
|
|
a3ce8974f6 | ||
|
|
f33a4ced53 | ||
|
|
6a48f8e165 | ||
|
|
78fff76695 | ||
|
|
947310138e | ||
|
|
1d939a207a | ||
|
|
3a5d89a6fb | ||
|
|
c0cc3eb976 | ||
|
|
696cbd05e8 | ||
|
|
6c8a4188a1 | ||
|
|
829b123641 | ||
|
|
bd52201add | ||
|
|
812ecce84a | ||
|
|
172c38b675 | ||
|
|
875b5f3f52 | ||
|
|
be1f36a523 | ||
|
|
d4c7dd3490 | ||
|
|
e55fb21538 | ||
|
|
a966b0502f | ||
|
|
1bac61ad1c | ||
|
|
c7451115d8 | ||
|
|
72ae003a00 | ||
|
|
d67098b8f8 | ||
|
|
0e6dbaf050 | ||
|
|
32afc8565c | ||
|
|
48ace60875 | ||
|
|
9e75f9e19d | ||
|
|
9b6ee6fcad | ||
|
|
1a1639b87e | ||
|
|
3735aa504b | ||
|
|
367dda6794 | ||
|
|
e4a85f79cd | ||
|
|
22ec7e7ada | ||
|
|
678101938b | ||
|
|
9a3aa18c62 | ||
|
|
5a3ba1424a | ||
|
|
3bb8419a96 | ||
|
|
ce29282f63 | ||
|
|
9575299ae3 | ||
|
|
995ceca6c2 | ||
|
|
012aa50cd3 | ||
|
|
d0193919c4 | ||
|
|
422ca290b5 | ||
|
|
59e1d7bf27 | ||
|
|
09dd9656c8 | ||
|
|
e9afca2cd6 | ||
|
|
6abd0e6002 | ||
|
|
656e3062b4 | ||
|
|
5f083cea48 | ||
|
|
80e29c8950 | ||
|
|
7264091c6f | ||
|
|
33c0df349d | ||
|
|
d3015edb40 | ||
|
|
927c7f82be | ||
|
|
008dda250b | ||
|
|
9c9c519175 | ||
|
|
8300809562 | ||
|
|
cce7296ffe | ||
|
|
a445ad00da | ||
|
|
4db7e1a107 | ||
|
|
c51a1c4aa9 | ||
|
|
d489908e50 | ||
|
|
c4eda188d5 | ||
|
|
677eb4c876 | ||
|
|
69a4aa70b9 | ||
|
|
f07c2f460d | ||
|
|
09c557bdd7 | ||
|
|
e487da01c5 | ||
|
|
a6b00aacbf | ||
|
|
504ae95915 | ||
|
|
b6b6843ad2 | ||
|
|
5d28b67295 | ||
|
|
b19800f1a7 | ||
|
|
011f7b0350 | ||
|
|
41eb57cee3 | ||
|
|
c4b389a4c6 | ||
|
|
6e6eeccf61 | ||
|
|
a82ec2a298 | ||
|
|
ac956e53da | ||
|
|
7332f65373 | ||
|
|
5229753c6f | ||
|
|
5cefe337dd | ||
|
|
292051c8e3 | ||
|
|
68ccd510c2 | ||
|
|
3204614d51 | ||
|
|
bd95160e67 | ||
|
|
bbf6f013af | ||
|
|
a30390c306 | ||
|
|
8e5de72407 | ||
|
|
5691f60988 | ||
|
|
9f9ccdcc55 | ||
|
|
0b10bcbba5 | ||
|
|
a4731e0031 | ||
|
|
e94d3b1628 | ||
|
|
ecdf4717a9 | ||
|
|
c181e720c9 | ||
|
|
fe8cac7082 | ||
|
|
b02f1e492f | ||
|
|
ad1bbd318a | ||
|
|
136eddd3ab | ||
|
|
e6725d8f5c | ||
|
|
484a27c13d | ||
|
|
7b67a8bf15 | ||
|
|
916c13a2ef | ||
|
|
5b4deb99b0 | ||
|
|
6e5a42c921 | ||
|
|
8478f268ac | ||
|
|
66a1379947 | ||
|
|
546ba6c11e | ||
|
|
67ba63c2f4 | ||
|
|
01b25a54c9 | ||
|
|
51dd386f0e | ||
|
|
f0d24c1ffd | ||
|
|
6174655771 | ||
|
|
d91656c768 | ||
|
|
89d95adb09 | ||
|
|
639ae13d24 | ||
|
|
1df6c37ded | ||
|
|
08406c8410 | ||
|
|
1be4bc267f | ||
|
|
4e61084655 | ||
|
|
05e8ef16b8 | ||
|
|
df59f3856a | ||
|
|
4d5a99f3de | ||
|
|
5c6917697a | ||
|
|
459d4a4940 | ||
|
|
76a71f69bc | ||
|
|
51279cb47f | ||
|
|
f9845fe3fc | ||
|
|
802d249684 | ||
|
|
6f86a4241b | ||
|
|
08ef67eafa | ||
|
|
5103b31c6a | ||
|
|
ce810be429 | ||
|
|
287e4835f0 | ||
|
|
261af4c74d | ||
|
|
3d3e0f991d | ||
|
|
d37bbb7d93 | ||
|
|
8f0b439eb8 | ||
|
|
5f4fc3acb8 | ||
|
|
6b744436fb | ||
|
|
bdfd326e8c | ||
|
|
7676d7fff6 | ||
|
|
1fdd927821 | ||
|
|
2374ae0588 | ||
|
|
deec36125c | ||
|
|
abbf08a0f8 | ||
|
|
2473af39c3 | ||
|
|
d3a2aa17b8 | ||
|
|
7b5f9a4157 | ||
|
|
178ae5ea9d | ||
|
|
b9e4187a71 | ||
|
|
053b114172 | ||
|
|
c8dcee1065 | ||
|
|
99c2967920 | ||
|
|
3c561a774d | ||
|
|
6679963094 | ||
|
|
eda46fef52 | ||
|
|
0efb8c8c2d | ||
|
|
ad90bb1acf | ||
|
|
7e5fed72cf | ||
|
|
e96dc7e4aa | ||
|
|
3a113dcdd6 | ||
|
|
6a6d7eb83c | ||
|
|
6d81cb7748 | ||
|
|
ca92a847f2 | ||
|
|
c8d4285c94 | ||
|
|
323db614e1 | ||
|
|
9a2c0ce611 | ||
|
|
2b024ff6b3 | ||
|
|
38e37437bd | ||
|
|
5e0c5469ec | ||
|
|
a095387aa2 | ||
|
|
c084361b5c | ||
|
|
8a0e295691 | ||
|
|
2dc419f1ae | ||
|
|
450d6cea6d | ||
|
|
3386418737 | ||
|
|
2f09777b17 | ||
|
|
75df4ad3e6 | ||
|
|
4048d46443 | ||
|
|
12842aa9e1 | ||
|
|
381cf25cbd | ||
|
|
556b577818 | ||
|
|
a5ca1b6a32 | ||
|
|
1b7f20af7f | ||
|
|
a65f6064ba | ||
|
|
993d5cb831 | ||
|
|
3388132bc3 | ||
|
|
1dedc55a42 | ||
|
|
fd6ac545fa | ||
|
|
736f0aca8a | ||
|
|
cdc9127ed6 | ||
|
|
cdbca8beb2 | ||
|
|
bffd75c0da | ||
|
|
1b5ae7461b | ||
|
|
b07ff3f5db | ||
|
|
b86fdfb46c | ||
|
|
50905e0dcb | ||
|
|
458447caf0 | ||
|
|
a6138169fa | ||
|
|
d65033932e | ||
|
|
d49629b916 | ||
|
|
a642f36524 | ||
|
|
9702811d72 | ||
|
|
955fe9f9df | ||
|
|
97e4f45be3 | ||
|
|
60242d41bd | ||
|
|
1fb47dab6b | ||
|
|
cd671cae3e | ||
|
|
c2154f95fe | ||
|
|
bbd4edce83 | ||
|
|
1742616cac | ||
|
|
2c64bbab79 | ||
|
|
785fa7adc2 | ||
|
|
0248c58591 | ||
|
|
160e783638 | ||
|
|
ddd2500a9c | ||
|
|
2b5dee2b95 | ||
|
|
26393f230f | ||
|
|
8e9948d729 | ||
|
|
9bbbd8c324 | ||
|
|
a19e7cb38e | ||
|
|
3a2912bc0b | ||
|
|
5cfd284cb8 | ||
|
|
eeae538115 | ||
|
|
8a98c0332f | ||
|
|
84d44db3a7 | ||
|
|
c97af2f3dc | ||
|
|
c4ca3bfc5f | ||
|
|
b03cf507be | ||
|
|
066dc9b078 | ||
|
|
70854254e7 | ||
|
|
646df28ac8 | ||
|
|
73d4f987e4 | ||
|
|
c59d519c89 | ||
|
|
1ec2cba9e8 | ||
|
|
26cc1f8387 | ||
|
|
85fe35bec2 | ||
|
|
b57fa2b127 | ||
|
|
596909138a | ||
|
|
c11a76f2c1 | ||
|
|
51d32ad293 | ||
|
|
a433e9e0b4 | ||
|
|
abac61f5b5 | ||
|
|
a121a9d186 | ||
|
|
58ecbf6150 | ||
|
|
bad5ae41d1 | ||
|
|
e773e07373 | ||
|
|
c3ded3c003 | ||
|
|
e706802ed5 | ||
|
|
9e97ad8bb3 | ||
|
|
76e04c4606 | ||
|
|
83ccf77d2f | ||
|
|
a0d53975d8 | ||
|
|
1252c0fbb9 | ||
|
|
04acf613ae | ||
|
|
c8bddb8035 | ||
|
|
467e83da31 | ||
|
|
8b29ef1335 | ||
|
|
1076700714 | ||
|
|
978f1155c5 | ||
|
|
3096d9d9cb | ||
|
|
ffea75abb2 | ||
|
|
a44a8b8789 | ||
|
|
05106096c3 | ||
|
|
ba7fd7a9a9 | ||
|
|
9b0e4e0085 | ||
|
|
3cb64f7f7e | ||
|
|
6642857437 | ||
|
|
91f00d643a | ||
|
|
ce8b62cfe7 | ||
|
|
4064bda60d | ||
|
|
4a21554986 | ||
|
|
165968dc26 | ||
|
|
9eb70f7be0 | ||
|
|
8797a9cb00 | ||
|
|
8366a5a6d6 | ||
|
|
63a9d5749b | ||
|
|
0e6aa41245 | ||
|
|
bbcb054814 | ||
|
|
2e5a86db7a | ||
|
|
057b15cefb | ||
|
|
7c06741f36 | ||
|
|
3a0c42aea5 | ||
|
|
75d5555a5f | ||
|
|
10c1ac9a66 | ||
|
|
692e15c088 | ||
|
|
6be9665bfb | ||
|
|
9be617d754 | ||
|
|
ec4f37fe25 | ||
|
|
6bb4ae9d50 | ||
|
|
c7a3f188c0 | ||
|
|
8e44509585 | ||
|
|
787954715b | ||
|
|
9f03260dd2 | ||
|
|
5c3a3f7fdf | ||
|
|
6693b22c83 | ||
|
|
49c7f60a57 | ||
|
|
ace4608f10 | ||
|
|
3899dfcc64 | ||
|
|
2dc98e9153 | ||
|
|
90f8a2409f | ||
|
|
92dc0db889 | ||
|
|
d8fc48e608 | ||
|
|
611802f990 | ||
|
|
606df86b0a | ||
|
|
2f7d38e6f6 | ||
|
|
b90d665ced | ||
|
|
50dd77ffd4 | ||
|
|
5e5b79783c | ||
|
|
c815114661 | ||
|
|
93f6a53201 | ||
|
|
a3ee0cfe79 | ||
|
|
95b0178514 | ||
|
|
afacf3db45 | ||
|
|
4a80321420 | ||
|
|
9295c69249 | ||
|
|
893f04967c | ||
|
|
fa410a6e02 | ||
|
|
aed2687743 | ||
|
|
978c0d10bc | ||
|
|
25b540e804 | ||
|
|
9aa58cd5c2 | ||
|
|
691be01bcc | ||
|
|
402ed45ee4 | ||
|
|
07dfcd83b9 | ||
|
|
9845dfda2c | ||
|
|
da5ee77e61 | ||
|
|
e1d2966e42 | ||
|
|
17428ce198 | ||
|
|
e87e790215 | ||
|
|
f907191e58 | ||
|
|
62a00562de | ||
|
|
3316d89c63 | ||
|
|
6bf590c3ee | ||
|
|
78bf9951e3 | ||
|
|
532060a646 | ||
|
|
59f76ced6a | ||
|
|
0c2766ee76 | ||
|
|
a90df38643 | ||
|
|
407741b8e3 | ||
|
|
3859678772 | ||
|
|
a6d4e17911 | ||
|
|
bde7846b5a | ||
|
|
01283767a6 |
@@ -0,0 +1,31 @@
|
||||
# Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
|
||||
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
|
||||
# LICENSE and NOTICE for details. LLNL-CODE-806117.
|
||||
#
|
||||
# This file is part of the MFEM library. For more information and source code
|
||||
# availability visit https://mfem.org.
|
||||
#
|
||||
# MFEM is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the BSD-3 license. We welcome feedback and contributions, see file
|
||||
# CONTRIBUTING.md for details.
|
||||
|
||||
name: "Trigger PyMFEM CI"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
trigger-pymfem:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Send POST request to trigger PyMFEM CI
|
||||
run: |
|
||||
curl -L \
|
||||
-X POST \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "Authorization: Bearer ${{ secrets.PYMFEM_CI_TOKEN }}" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
https://api.github.com/repos/mfem/pymfem/actions/workflows/build-and-test-dispatch.yml/dispatches \
|
||||
-d '{"ref":"master", "inputs":{"test_options":"fast"}}'
|
||||
+14
@@ -15,6 +15,9 @@
|
||||
CMakeCache.txt
|
||||
CMakeFiles/
|
||||
|
||||
# Clangd server cache
|
||||
*.cache*
|
||||
|
||||
# Backup files
|
||||
*~
|
||||
|
||||
@@ -272,16 +275,27 @@ miniapps/navier/*_output
|
||||
|
||||
miniapps/nurbs/nurbs_ex1
|
||||
miniapps/nurbs/nurbs_ex1p
|
||||
miniapps/nurbs/nurbs_ex3
|
||||
miniapps/nurbs/nurbs_ex5
|
||||
miniapps/nurbs/nurbs_ex11p
|
||||
miniapps/nurbs/nurbs_ex24
|
||||
miniapps/nurbs/nurbs_solenoidal
|
||||
miniapps/nurbs/nurbs_printfunc
|
||||
miniapps/nurbs/nurbs_patch_ex1
|
||||
miniapps/nurbs/nurbs_curveint
|
||||
miniapps/nurbs/refined.mesh
|
||||
miniapps/nurbs/mesh.*
|
||||
miniapps/nurbs/sol_?.gf
|
||||
miniapps/nurbs/sol.*
|
||||
miniapps/nurbs/mode_*
|
||||
miniapps/nurbs/Example1*
|
||||
miniapps/nurbs/Example3*
|
||||
miniapps/nurbs/Example5*
|
||||
miniapps/nurbs/Solenoidal*
|
||||
miniapps/nurbs/ParaView
|
||||
miniapps/nurbs/sin-fit.mesh
|
||||
miniapps/nurbs/ex5.mesh
|
||||
miniapps/nurbs/exsol.mesh
|
||||
miniapps/nurbs/CurveInt
|
||||
miniapps/nurbs/nurbs_naca_cmesh
|
||||
miniapps/nurbs/naca-cmesh.mesh
|
||||
|
||||
+5
-5
@@ -22,7 +22,7 @@ include:
|
||||
# the "needs" keyword and express the DAG of jobs for more efficiency.
|
||||
# - We use setup and setup_baseline phases to download content outside of mfem
|
||||
# directory.
|
||||
# - Allocate/Release is where quartz resource are allocated/released once for all.
|
||||
# - Allocate/Release is where ruby resource are allocated/released once for all.
|
||||
# - Build and Test is where we build and MFEM for multiple toolchains.
|
||||
# - Baseline_checks gathers baseline-type test suites execution
|
||||
# - Baseline_publish, only available on master, allows to update baseline
|
||||
@@ -53,7 +53,7 @@ variables:
|
||||
AUTOTEST_COMMIT: "YES"
|
||||
|
||||
# Trigger subpipelines:
|
||||
quartz-build-and-test:
|
||||
ruby-build-and-test:
|
||||
stage: sub-pipelines
|
||||
variables:
|
||||
# Explicitly pass down values that we want to be able to set when triggering
|
||||
@@ -61,10 +61,10 @@ quartz-build-and-test:
|
||||
AUTOTEST: "${AUTOTEST}"
|
||||
AUTOTEST_COMMIT: "${AUTOTEST_COMMIT}"
|
||||
trigger:
|
||||
include: .gitlab/quartz-build-and-test.yml
|
||||
include: .gitlab/ruby-build-and-test.yml
|
||||
strategy: depend
|
||||
|
||||
quartz-baseline:
|
||||
ruby-baseline:
|
||||
stage: sub-pipelines
|
||||
variables:
|
||||
# Explicitly pass down values that we want to be able to set when triggering
|
||||
@@ -73,7 +73,7 @@ quartz-baseline:
|
||||
AUTOTEST: "${AUTOTEST}"
|
||||
AUTOTEST_COMMIT: "${AUTOTEST_COMMIT}"
|
||||
trigger:
|
||||
include: .gitlab/quartz-baseline.yml
|
||||
include: .gitlab/ruby-baseline.yml
|
||||
strategy: depend
|
||||
|
||||
lassen-build-and-test:
|
||||
|
||||
+3
-3
@@ -24,7 +24,7 @@ and `test type`.
|
||||
|
||||
Machines typically include:
|
||||
|
||||
* Quartz: Intel bi-socket x86
|
||||
* Ruby: 2nd Gen Intel Xeon (Cascade Lake)
|
||||
* Lassen: Power9 + Nvidia GPU
|
||||
* Corona: AMD GPU
|
||||
|
||||
@@ -76,13 +76,13 @@ with a spack spec of MFEM, within the limits permitted by the MFEM spack
|
||||
package.
|
||||
|
||||
In any build-and-test sub-pipeline a job basically consists in defining the
|
||||
spack spec to use. Adding a job on quartz for example resumes to:
|
||||
spack spec to use. Adding a job on ruby for example resumes to:
|
||||
|
||||
```yaml
|
||||
<job_name>:
|
||||
variables:
|
||||
SPEC: "<spack_spec>"
|
||||
extends: .build_and_test_on_quartz
|
||||
extends: .build_and_test_on_ruby
|
||||
```
|
||||
|
||||
The remaining and non trivial work is to make sure this spec is working. To
|
||||
|
||||
@@ -24,7 +24,7 @@ variables:
|
||||
# TODO: add a clean-up mechanism
|
||||
BUILD_ROOT: ${USER_CI_TOP_DIR}/${CI_PROJECT_NAME}-${MACHINE_NAME}-pipeline-${CI_PIPELINE_ID}
|
||||
|
||||
# On LLNL's quartz, there is only one allocation shared among jobs in order to
|
||||
# On LLNL's ruby, there is only one allocation shared among jobs in order to
|
||||
# save time and resource. This allocation has to be uniquely named so that we
|
||||
# are sure to retrieve it.
|
||||
ALLOC_NAME: ${CI_PROJECT_NAME}_ci_${CI_PIPELINE_ID}
|
||||
|
||||
@@ -9,17 +9,17 @@
|
||||
# terms of the BSD-3 license. We welcome feedback and contributions, see file
|
||||
# CONTRIBUTING.md for details.
|
||||
|
||||
# GitLab pipelines configurations for the Quartz machine at LLNL
|
||||
# GitLab pipelines configurations for the Ruby machine at LLNL
|
||||
variables:
|
||||
MACHINE_NAME: quartz
|
||||
MACHINE_NAME: ruby
|
||||
|
||||
.on_quartz:
|
||||
.on_ruby:
|
||||
tags:
|
||||
- shell
|
||||
- quartz
|
||||
- ruby
|
||||
rules:
|
||||
# Don't run quartz jobs if...
|
||||
- if: '$CI_COMMIT_BRANCH =~ /_qnone/ || $ON_QUARTZ == "OFF"'
|
||||
# Don't run ruby jobs if...
|
||||
- if: '$CI_COMMIT_BRANCH =~ /_qnone/ || $ON_RUBY == "OFF"'
|
||||
when: never
|
||||
# Don't run autotest update if...
|
||||
- if: '$CI_JOB_NAME =~ /report/ && $AUTOTEST != "YES"'
|
||||
@@ -40,13 +40,13 @@ variables:
|
||||
- when: on_success
|
||||
|
||||
# Spack helped builds
|
||||
# Generic quartz build job, extending build script
|
||||
.build_and_test_on_quartz:
|
||||
extends: [.on_quartz]
|
||||
# Generic ruby build job, extending build script
|
||||
.build_and_test_on_ruby:
|
||||
extends: [.on_ruby]
|
||||
stage: build_and_test
|
||||
script:
|
||||
# THREADS is used by 'tests/gitlab/build_and_test', run below
|
||||
- export THREADS=12
|
||||
- export THREADS=16
|
||||
- echo ${ALLOC_NAME}
|
||||
- export JOBID=$(squeue -h --name=${ALLOC_NAME} --format=%A)
|
||||
- echo ${JOBID}
|
||||
@@ -18,7 +18,7 @@
|
||||
setup_baseline:
|
||||
tags:
|
||||
- shell
|
||||
- quartz
|
||||
- ruby
|
||||
stage: setup
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
setup:
|
||||
tags:
|
||||
- shell
|
||||
- quartz
|
||||
- ruby
|
||||
stage: setup
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
|
||||
@@ -19,8 +19,8 @@ stages:
|
||||
- cleanup
|
||||
- baseline_publish
|
||||
|
||||
baselinecheck_mfem_intel_quartz:
|
||||
extends: [.on_quartz]
|
||||
baselinecheck_mfem_intel_ruby:
|
||||
extends: [.on_ruby]
|
||||
stage: baseline_check
|
||||
variables:
|
||||
# TPLS_DIR is used in .gitlab/scripts/baseline to provide the tpls location
|
||||
@@ -32,7 +32,7 @@ baselinecheck_mfem_intel_quartz:
|
||||
- echo ${BUILD_ROOT}
|
||||
- echo ${TPLS_DIR}
|
||||
# Used by the tests in MFEM/tests:
|
||||
- export MFEM_TEST_NP=32
|
||||
- export MFEM_TEST_NP=48
|
||||
# The next script uses the following environment variables:
|
||||
# * BASELINE_TEST, SYS_TYPE, CI_PROJECT_DIR, ARTIFACTS_DIR,
|
||||
# * BUILD_ROOT, TPLS_DIR, MACHINE_NAME
|
||||
@@ -44,18 +44,16 @@ baselinecheck_mfem_intel_quartz:
|
||||
allow_failure: true
|
||||
|
||||
cleanup:
|
||||
extends: .on_quartz
|
||||
extends: .on_ruby
|
||||
stage: cleanup
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
script:
|
||||
- echo "BUILD_ROOT=${BUILD_ROOT}"
|
||||
- rm -rf "${BUILD_ROOT}" || true
|
||||
- echo "CI_PROJECT_DIR=${CI_PROJECT_DIR}"
|
||||
- make -C "${CI_PROJECT_DIR}" distclean
|
||||
|
||||
report_baseline:
|
||||
extends: [.on_quartz]
|
||||
extends: [.on_ruby]
|
||||
stage: baseline_report
|
||||
script:
|
||||
- echo ${MACHINE_NAME}
|
||||
@@ -115,8 +113,8 @@ report_baseline:
|
||||
exit $err
|
||||
) 9> autotest.lock
|
||||
|
||||
baselinepublish_mfem_quartz:
|
||||
extends: [.on_quartz]
|
||||
baselinepublish_mfem_ruby:
|
||||
extends: [.on_ruby]
|
||||
stage: baseline_publish
|
||||
rules:
|
||||
# - if: '$CI_COMMIT_BRANCH == "master" || $REBASELINE == "YES"'
|
||||
@@ -131,5 +129,5 @@ baselinepublish_mfem_quartz:
|
||||
|
||||
include:
|
||||
- local: .gitlab/configs/common.yml
|
||||
- local: .gitlab/configs/quartz-config.yml
|
||||
- local: .gitlab/configs/ruby-config.yml
|
||||
- local: .gitlab/configs/setup-baseline.yml
|
||||
@@ -19,54 +19,54 @@ stages:
|
||||
allocate_resource:
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
extends: .on_quartz
|
||||
extends: .on_ruby
|
||||
stage: allocate_resource
|
||||
script:
|
||||
- echo ${ALLOC_NAME}
|
||||
- salloc --exclusive --nodes=1 --reservation=ci --time=60 --no-shell --job-name=${ALLOC_NAME}
|
||||
timeout: 6h
|
||||
|
||||
# GitLab jobs for the Quartz machine at LLNL
|
||||
# GitLab jobs for the Ruby machine at LLNL
|
||||
debug_ser_gcc_10:
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 +debug~mpi"
|
||||
extends: .build_and_test_on_quartz
|
||||
extends: .build_and_test_on_ruby
|
||||
|
||||
debug_par_gcc_10:
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 +debug+mpi"
|
||||
extends: .build_and_test_on_quartz
|
||||
extends: .build_and_test_on_ruby
|
||||
|
||||
opt_ser_gcc_10:
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 ~mpi"
|
||||
extends: .build_and_test_on_quartz
|
||||
extends: .build_and_test_on_ruby
|
||||
|
||||
opt_par_gcc_10:
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1"
|
||||
extends: .build_and_test_on_quartz
|
||||
extends: .build_and_test_on_ruby
|
||||
|
||||
opt_par_gcc_10_sundials:
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 +sundials"
|
||||
extends: .build_and_test_on_quartz
|
||||
extends: .build_and_test_on_ruby
|
||||
|
||||
opt_par_gcc_10_petsc:
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 +petsc ^petsc+mumps~superlu-dist"
|
||||
extends: .build_and_test_on_quartz
|
||||
extends: .build_and_test_on_ruby
|
||||
|
||||
opt_par_gcc_10_pumi:
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 +pumi"
|
||||
extends: .build_and_test_on_quartz
|
||||
extends: .build_and_test_on_ruby
|
||||
|
||||
# Release
|
||||
release_resource:
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
extends: .on_quartz
|
||||
extends: .on_ruby
|
||||
stage: release_resource_and_report
|
||||
script:
|
||||
- echo ${ALLOC_NAME}
|
||||
@@ -78,17 +78,17 @@ release_resource:
|
||||
report_job_success:
|
||||
stage: release_resource_and_report
|
||||
extends:
|
||||
- .on_quartz
|
||||
- .on_ruby
|
||||
- .report_job_success
|
||||
|
||||
report_job_failure:
|
||||
stage: release_resource_and_report
|
||||
extends:
|
||||
- .on_quartz
|
||||
- .on_ruby
|
||||
- .report_job_failure
|
||||
|
||||
include:
|
||||
- local: .gitlab/configs/common.yml
|
||||
- local: .gitlab/configs/quartz-config.yml
|
||||
- local: .gitlab/configs/ruby-config.yml
|
||||
- local: .gitlab/configs/setup-build-and-test.yml
|
||||
- local: .gitlab/configs/report-build-and-test.yml
|
||||
@@ -14,7 +14,7 @@
|
||||
# locals
|
||||
glob_err=${BASELINE_TEST}.err
|
||||
base=${BASELINE_TEST}-${SYS_TYPE}
|
||||
if [[ "${MACHINE_NAME}" == "quartz" ]]; then
|
||||
if [[ "${MACHINE_NAME}" == "ruby" ]]; then
|
||||
base="${BASELINE_TEST}-${MACHINE_NAME}"
|
||||
fi
|
||||
base_diff=${base}.diff
|
||||
@@ -31,8 +31,8 @@ cd tests
|
||||
mkdir _${BASELINE_TEST} && cd _${BASELINE_TEST}
|
||||
|
||||
# run
|
||||
if [[ "${MACHINE_NAME}" == "quartz" || "${MACHINE_NAME}" == "ruby" ]]; then
|
||||
salloc --nodes=1 --reservation=ci ../runtest ../../mfem "${BASELINE_TEST} ${TPLS_DIR}"
|
||||
if [[ "${MACHINE_NAME}" == "ruby" ]]; then
|
||||
salloc --nodes=1 --exclusive --reservation=ci ../runtest ../../mfem "${BASELINE_TEST} ${TPLS_DIR}"
|
||||
elif [[ ${MACHINE_NAME} == "corona" ]]; then
|
||||
salloc --nodes=1 -t 60 -p pbatch ../runtest ../../mfem "${BASELINE_TEST} ${TPLS_DIR}"
|
||||
elif [[ ${MACHINE_NAME} == "lassen" ]]; then
|
||||
@@ -41,11 +41,11 @@ else
|
||||
echo "Unknown machine: MACHINE_NAME=$MACHINE_NAME"
|
||||
exit 1
|
||||
fi
|
||||
status="$?"
|
||||
|
||||
# post
|
||||
mkdir ${artifacts_path}
|
||||
|
||||
status=0
|
||||
if [[ -f ${BASELINE_TEST}.out ]]; then
|
||||
cp ${BASELINE_TEST}.out ${artifacts_path}
|
||||
fi
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
# terms of the BSD-3 license. We welcome feedback and contributions, see file
|
||||
# CONTRIBUTING.md for details.
|
||||
|
||||
# There will be collision between corona and quartz baselines.
|
||||
# There will be collision between corona and ruby baselines.
|
||||
# Once the corresponding files have been generated, we can switch to machine
|
||||
# specific ref.
|
||||
ARTIFACT_PATH=${CI_PROJECT_DIR}/${ARTIFACTS_DIR}/baseline-${SYS_TYPE}
|
||||
@@ -21,7 +21,7 @@ PATCH_FILE=${ARTIFACT_PATH}.patch
|
||||
FULL_FILE=${ARTIFACT_PATH}.out
|
||||
DIFF_FILE=${ARTIFACT_PATH}.diff
|
||||
|
||||
# There will be collision between corona and quartz baselines.
|
||||
# There will be collision between corona and ruby baselines.
|
||||
# Once the corresponding files have been generated, we can switch to machine
|
||||
# specific ref.
|
||||
SAVED_NAME=baseline-${SYS_TYPE}.saved
|
||||
|
||||
@@ -11,9 +11,63 @@
|
||||
Version 4.7.1 (development)
|
||||
===========================
|
||||
|
||||
Discretization improvements
|
||||
---------------------------
|
||||
- Added NURBS-based H(div) and H(curl) elements in 2D and 3D. Only on single
|
||||
patch meshes. Only implemented for serial computations.
|
||||
|
||||
- Added support for boundary constraints to the hybridization class.
|
||||
|
||||
Meshing improvements
|
||||
--------------------
|
||||
- The ExodusII reader now handles pyramid and wedge element types. Mixed meshes
|
||||
are also supported.
|
||||
|
||||
New and updated examples and miniapps
|
||||
-------------------------------------
|
||||
- Added miniapps to demonstrate the H(div) and H(curl) NURBS elements.
|
||||
|
||||
- Added an MFEM example for the eikonal equation. This new solver is based on
|
||||
the proximal Galerkin method introduced by Keith and Surowiec.
|
||||
|
||||
- Added a command line option to all miniapps (`-p` or `--send-port`) for
|
||||
specifying the GLVis server socket port (19916 by default).
|
||||
|
||||
GPU computing
|
||||
-------------
|
||||
- Added support for GPU-accelerated batched linear algebra (using cuBLAS,
|
||||
hipBLAS, MAGMA, or native MFEM functionality) through the BatchedLinAlg class.
|
||||
|
||||
- A new GPU kernel dispatch mechanism was introduced. Users can instantiate
|
||||
specialized kernels for specific combinations of (for example) polynomial
|
||||
degree and number of quadrature points using
|
||||
`DiffusionIntegrator::AddSpecialization` and
|
||||
`MassIntegrator::AddSpecialization` (this functionality may be added to more
|
||||
integrators in the future).
|
||||
|
||||
- Calls to slower fallback kernels can be reported to `mfem::err` by setting
|
||||
the environment variable `MFEM_REPORT_KERNELS` to any value other than `NO`
|
||||
or by explicitly calling `KernelReporter::Enable`. Users can then add
|
||||
specializations for these kernels to achieve higher performance.
|
||||
|
||||
Miscellaneous
|
||||
-------------
|
||||
- Refactored the `ARKStepSolver` class (ARKODE interface) to use
|
||||
`TimeDependentOperator::Mult` only when the associated ODE operator is
|
||||
expressed in explicit form (i.e., `TimeDependentOperator::isExplicit()`),
|
||||
otherwise `TimeDependentOperator::ExplicitMult` is used. A check has been
|
||||
added to `ARKStepSolver` to verify that the associated ODE operator is not in
|
||||
explicit form when a mass matrix solver is enabled via a call to either the
|
||||
`UseMFEMMassLinearSolver` or `UseSundialsMassLinearSolver` methods. This is
|
||||
because enabling a mass matrix solver assumes that F(u,k,t) = M k in the
|
||||
associated ODE operator.
|
||||
|
||||
- Added support for custom interpolation procedure in FindPointsGSLIB.
|
||||
|
||||
API changes
|
||||
-----------
|
||||
- API change: in class GridFunction, 'fec' was renamed to 'fec_owned'.
|
||||
|
||||
|
||||
Version 4.7, released on May 7, 2024
|
||||
====================================
|
||||
@@ -38,6 +92,9 @@ Meshing improvements
|
||||
|
||||
- Added support for internal boundary elements in nonconforming meshes.
|
||||
|
||||
- Added ExodusII output capability. The writer can handle first-order (Pyramid5,
|
||||
Wedge6, Hex8, Tet4) and second-order FE types (Pyramid14, Wedge18, Hex27, Tet10).
|
||||
|
||||
- The ReadCubit Genesis mesh importer has been rewritten to improve readability.
|
||||
|
||||
Discretization improvements
|
||||
|
||||
+12
-4
@@ -146,7 +146,9 @@ if (MFEM_USE_CUDA)
|
||||
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} ${CUDA_FLAGS}")
|
||||
find_package(CUDAToolkit REQUIRED)
|
||||
set(CUSPARSE_FOUND TRUE)
|
||||
set(CUBLAS_FOUND TRUE)
|
||||
get_target_property(CUSPARSE_LIBRARIES CUDA::cusparse LOCATION)
|
||||
get_target_property(CUBLAS_LIBRARIES CUDA::cublas LOCATION)
|
||||
endif()
|
||||
|
||||
if (XSDK_ENABLE_C)
|
||||
@@ -231,6 +233,7 @@ if (MFEM_USE_HIP)
|
||||
list(INSERT CMAKE_PREFIX_PATH 0 ${ROCM_PATH})
|
||||
endif()
|
||||
find_package(HIP REQUIRED)
|
||||
find_package(HIPBLAS REQUIRED)
|
||||
find_package(HIPSPARSE REQUIRED)
|
||||
endif()
|
||||
|
||||
@@ -396,6 +399,10 @@ if (MFEM_USE_AMGX)
|
||||
find_package(AMGX REQUIRED)
|
||||
endif()
|
||||
|
||||
if (MFEM_USE_MAGMA)
|
||||
find_package(MAGMA REQUIRED)
|
||||
endif()
|
||||
|
||||
if (MFEM_USE_CONDUIT)
|
||||
find_package(Conduit REQUIRED conduit relay blueprint)
|
||||
endif()
|
||||
@@ -557,8 +564,9 @@ find_package(Threads REQUIRED)
|
||||
set(MFEM_TPLS OPENMP HYPRE LAPACK BLAS SuperLUDist STRUMPACK METIS SuiteSparse
|
||||
SUNDIALS PETSC SLEPC MUMPS AXOM FMS CONDUIT Ginkgo GNUTLS GSLIB
|
||||
NETCDF MPFR PUMI HIOP POSIXCLOCKS MFEMBacktrace ZLIB OCCA CEED RAJA UMPIRE
|
||||
ADIOS2 CUSPARSE MKL_CPARDISO MKL_PARDISO AMGX CALIPER CODIPACK
|
||||
BENCHMARK PARELAG TRIBOL MPI_CXX HIP HIPSPARSE MOONOLITH BLITZ ALGOIM ENZYME)
|
||||
ADIOS2 MKL_CPARDISO MKL_PARDISO AMGX MAGMA CUSPARSE CUBLAS CALIPER CODIPACK
|
||||
BENCHMARK PARELAG TRIBOL MPI_CXX HIP HIPBLAS HIPSPARSE MOONOLITH BLITZ
|
||||
ALGOIM ENZYME)
|
||||
|
||||
# Add all *_FOUND libraries in the variable TPL_LIBRARIES.
|
||||
set(TPL_LIBRARIES "")
|
||||
@@ -673,7 +681,7 @@ if (NOT ("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}"))
|
||||
#include \"${PROJECT_SOURCE_DIR}/${Header}\"
|
||||
")
|
||||
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${PROJECT_BINARY_DIR}/${Header}.tmp"
|
||||
"${PROJECT_BINARY_DIR}/${Header}"
|
||||
)
|
||||
@@ -687,7 +695,7 @@ if (NOT ("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}"))
|
||||
#include \"mfem/${Header}\"
|
||||
")
|
||||
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${PROJECT_BINARY_DIR}/InstallHeaders/${Header}.tmp"
|
||||
"${PROJECT_BINARY_DIR}/InstallHeaders/${Header}"
|
||||
)
|
||||
|
||||
@@ -273,7 +273,13 @@ Installation options:
|
||||
PREFIX - Specify the installation directory. The library (libmfem.a) will be
|
||||
installed in $(PREFIX)/lib, the headers in $(PREFIX)/include, and
|
||||
the configuration makefile (config.mk) in $(PREFIX)/share/mfem.
|
||||
INSTALL - Specify the install program, e.g /usr/bin/install
|
||||
INSTALL - Specify the install program, default = /usr/bin/install
|
||||
INSTALL_DEF_PERM - Specify the default install permissions. This affects
|
||||
headers and configuration makefiles, default = 644
|
||||
INSTALL_BIN_PERM - Specify the install permissions for binaries. This only
|
||||
affects the shared version of the library, default = 755
|
||||
INSTALL_DIR_PERM - Specify the install permissions for directories and,
|
||||
on macOS/BSD, for symlinks as well, default = 755
|
||||
|
||||
MFEM library features/options (GNU make)
|
||||
----------------------------------------
|
||||
@@ -388,6 +394,11 @@ MFEM_USE_AMGX = YES/NO
|
||||
Allows the user to use SparseMatrices and HypreParMatrices to solve linear
|
||||
systems with the routines from the AmgX library.
|
||||
|
||||
MFEM_USE_MAGMA = YES/NO
|
||||
Enable MFEM functionality based on the MAGMA high-performance linear algebra
|
||||
library. The MAGMA library provides a BLAS/LAPACK interface, with
|
||||
implementations that have been optimized for Nvidia and AMD GPUs.
|
||||
|
||||
MFEM_USE_GNUTLS = YES/NO
|
||||
Enable secure socket support in class socketstream, using the auxiliary
|
||||
GnuTLS_* classes, based on the GnuTLS library. This option may be useful in
|
||||
@@ -699,6 +710,11 @@ The specific libraries and their options are:
|
||||
Options: AMGX_OPT, AMGX_LIB.
|
||||
Versions: AmgX >= 2.1, older versions may work too.
|
||||
|
||||
- MAGMA (optional), used with MFEM_USE_MAGMA = YES.
|
||||
URL: https://icl.utk.edu/magma/
|
||||
Options: MAGMA_OPT, MAGMA_LIB
|
||||
Versions: MAGMA >= 2.8.0
|
||||
|
||||
- GnuTLS (optional), used when MFEM_USE_GNUTLS = YES. On most Linux systems,
|
||||
GnuTLS is available as a development package, e.g. gnutls-devel. On Mac OS X,
|
||||
one can get the library through the Homebrew package manager (http://brew.sh).
|
||||
|
||||
@@ -37,6 +37,7 @@ set(MFEM_USE_MUMPS @MFEM_USE_MUMPS@)
|
||||
set(MFEM_USE_STRUMPACK @MFEM_USE_STRUMPACK@)
|
||||
set(MFEM_USE_GINKGO @MFEM_USE_GINKGO@)
|
||||
set(MFEM_USE_AMGX @MFEM_USE_AMGX@)
|
||||
set(MFEM_USE_MAGMA @MFEM_USE_MAGMA@)
|
||||
set(MFEM_USE_HIOP @MFEM_USE_HIOP@)
|
||||
set(MFEM_USE_GNUTLS @MFEM_USE_GNUTLS@)
|
||||
set(MFEM_USE_GSLIB @MFEM_USE_GSLIB@)
|
||||
|
||||
@@ -114,6 +114,9 @@
|
||||
// Enable MFEM functionality based on the AmgX library.
|
||||
#cmakedefine MFEM_USE_AMGX
|
||||
|
||||
// Enable MFEM functionality based on the MAGMA library.
|
||||
#cmakedefine MFEM_USE_MAGMA
|
||||
|
||||
// Enable secure socket streams based on the GNUTLS library.
|
||||
#cmakedefine MFEM_USE_GNUTLS
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
# Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
|
||||
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
|
||||
# LICENSE and NOTICE for details. LLNL-CODE-806117.
|
||||
#
|
||||
# This file is part of the MFEM library. For more information and source code
|
||||
# availability visit https://mfem.org.
|
||||
#
|
||||
# MFEM is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the BSD-3 license. We welcome feedback and contributions, see file
|
||||
# CONTRIBUTING.md for details.
|
||||
|
||||
# Defines the following variables:
|
||||
# - MAGMA_FOUND
|
||||
# - MAGMA_LIBRARIES
|
||||
# - MAGMA_INCLUDE_DIRS
|
||||
|
||||
include(MfemCmakeUtilities)
|
||||
mfem_find_package(MAGMA MAGMA MAGMA_DIR "include" "magma.h" "lib" "magma"
|
||||
"Paths to headers required by MAGMA." "Libraries required by MAGMA.")
|
||||
|
||||
if (MAGMA_FOUND AND MFEM_USE_CUDA)
|
||||
get_target_property(CUSPARSE_LIBRARIES CUDA::cusparse LOCATION)
|
||||
get_target_property(CUBLAS_LIBRARIES CUDA::cublas LOCATION)
|
||||
list(APPEND MAGMA_LIBRARIES ${CUSPARSE_LIBRARIES} ${CUBLAS_LIBRARIES})
|
||||
set(MAGMA_LIBRARIES ${MAGMA_LIBRARIES} CACHE STRING
|
||||
"MAGMA libraries + dependencies." FORCE)
|
||||
message(STATUS "Updated MAGMA_LIBRARIES: ${MAGMA_LIBRARIES}")
|
||||
endif()
|
||||
|
||||
if (MAGMA_FOUND AND MFEM_USE_HIP)
|
||||
find_package(HIPBLAS REQUIRED)
|
||||
find_package(HIPSPARSE REQUIRED)
|
||||
list(APPEND MAGMA_LIBRARIES ${HIPBLAS_LIBRARIES} ${HIPSPARSE_LIBRARIES})
|
||||
set(MAGMA_LIBRARIES ${MAGMA_LIBRARIES} CACHE STRING
|
||||
"MAGMA libraries + dependencies." FORCE)
|
||||
message(STATUS "Updated MAGMA_LIBRARIES: ${MAGMA_LIBRARIES}")
|
||||
endif()
|
||||
@@ -846,14 +846,14 @@ function(mfem_export_mk_files)
|
||||
MFEM_USE_ZLIB MFEM_USE_LIBUNWIND MFEM_USE_LAPACK MFEM_THREAD_SAFE
|
||||
MFEM_USE_LEGACY_OPENMP MFEM_USE_OPENMP MFEM_USE_MEMALLOC MFEM_USE_SUNDIALS
|
||||
MFEM_USE_SUITESPARSE MFEM_USE_SUPERLU MFEM_USE_SUPERLU5 MFEM_USE_MUMPS
|
||||
MFEM_USE_STRUMPACK MFEM_USE_GINKGO MFEM_USE_AMGX MFEM_USE_GNUTLS
|
||||
MFEM_USE_NETCDF MFEM_USE_PETSC MFEM_USE_SLEPC MFEM_USE_MPFR MFEM_USE_SIDRE
|
||||
MFEM_USE_FMS MFEM_USE_CONDUIT MFEM_USE_PUMI MFEM_USE_HIOP MFEM_USE_GSLIB
|
||||
MFEM_USE_CUDA MFEM_USE_HIP MFEM_USE_RAJA MFEM_USE_OCCA MFEM_USE_CEED
|
||||
MFEM_USE_CALIPER MFEM_USE_UMPIRE MFEM_USE_SIMD MFEM_USE_ADIOS2
|
||||
MFEM_USE_MKL_CPARDISO MFEM_USE_MKL_PARDISO MFEM_USE_ADFORWARD
|
||||
MFEM_USE_CODIPACK MFEM_USE_BENCHMARK MFEM_USE_PARELAG MFEM_USE_TRIBOL
|
||||
MFEM_USE_MOONOLITH MFEM_USE_ALGOIM MFEM_USE_ENZYME)
|
||||
MFEM_USE_STRUMPACK MFEM_USE_GINKGO MFEM_USE_AMGX MFEM_USE_MAGMA
|
||||
MFEM_USE_GNUTLS MFEM_USE_NETCDF MFEM_USE_PETSC MFEM_USE_SLEPC
|
||||
MFEM_USE_MPFR MFEM_USE_SIDRE MFEM_USE_FMS MFEM_USE_CONDUIT MFEM_USE_PUMI
|
||||
MFEM_USE_HIOP MFEM_USE_GSLIB MFEM_USE_CUDA MFEM_USE_HIP MFEM_USE_RAJA
|
||||
MFEM_USE_OCCA MFEM_USE_CEED MFEM_USE_CALIPER MFEM_USE_UMPIRE MFEM_USE_SIMD
|
||||
MFEM_USE_ADIOS2 MFEM_USE_MKL_CPARDISO MFEM_USE_MKL_PARDISO
|
||||
MFEM_USE_ADFORWARD MFEM_USE_CODIPACK MFEM_USE_BENCHMARK MFEM_USE_PARELAG
|
||||
MFEM_USE_TRIBOL MFEM_USE_MOONOLITH MFEM_USE_ALGOIM MFEM_USE_ENZYME)
|
||||
foreach(var ${CONFIG_MK_BOOL_VARS})
|
||||
if (${var})
|
||||
set(${var} YES)
|
||||
|
||||
@@ -114,6 +114,9 @@
|
||||
// Enable MFEM functionality based on the AmgX library.
|
||||
// #define MFEM_USE_AMGX
|
||||
|
||||
// Enable MFEM functionality based on the MAGMA library.
|
||||
// #define MFEM_USE_MAGMA
|
||||
|
||||
// Enable secure socket streams based on the GNUTLS library.
|
||||
// #define MFEM_USE_GNUTLS
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ MFEM_USE_MUMPS = @MFEM_USE_MUMPS@
|
||||
MFEM_USE_STRUMPACK = @MFEM_USE_STRUMPACK@
|
||||
MFEM_USE_GINKGO = @MFEM_USE_GINKGO@
|
||||
MFEM_USE_AMGX = @MFEM_USE_AMGX@
|
||||
MFEM_USE_MAGMA = @MFEM_USE_MAGMA@
|
||||
MFEM_USE_GNUTLS = @MFEM_USE_GNUTLS@
|
||||
MFEM_USE_NETCDF = @MFEM_USE_NETCDF@
|
||||
MFEM_USE_PETSC = @MFEM_USE_PETSC@
|
||||
|
||||
@@ -40,6 +40,7 @@ option(MFEM_USE_MUMPS "Enable MUMPS usage" OFF)
|
||||
option(MFEM_USE_STRUMPACK "Enable STRUMPACK usage" OFF)
|
||||
option(MFEM_USE_GINKGO "Enable Ginkgo usage" OFF)
|
||||
option(MFEM_USE_AMGX "Enable AmgX usage" OFF)
|
||||
option(MFEM_USE_MAGMA "Enable MAGMA usage" OFF)
|
||||
option(MFEM_USE_GNUTLS "Enable GNUTLS usage" OFF)
|
||||
option(MFEM_USE_GSLIB "Enable GSLIB usage" OFF)
|
||||
option(MFEM_USE_NETCDF "Enable NETCDF usage" OFF)
|
||||
@@ -183,6 +184,10 @@ set(Ginkgo_DIR "${MFEM_DIR}/../ginkgo" CACHE PATH "Path to the Ginkgo library.")
|
||||
|
||||
set(AMGX_DIR "${MFEM_DIR}/../amgx" CACHE PATH "Path to AmgX")
|
||||
|
||||
set(MAGMA_DIR "${MFEM_DIR}/../magma" CACHE PATH "Path to MAGMA")
|
||||
set(MAGMA_REQUIRED_PACKAGES "BLAS" "LAPACK" CACHE STRING
|
||||
"Additional packages required by MAGMA.")
|
||||
|
||||
set(GNUTLS_DIR "" CACHE PATH "Path to the GnuTLS library.")
|
||||
|
||||
set(GSLIB_DIR "" CACHE PATH "Path to the GSLIB library.")
|
||||
@@ -259,7 +264,7 @@ set(PARELAG_LIBRARIES "${PARELAG_DIR}/build/src/libParELAG.a" CACHE STRING
|
||||
"The ParELAG library.")
|
||||
|
||||
set(TRIBOL_DIR "${MFEM_DIR}/../tribol" CACHE PATH "Path to Tribol")
|
||||
set(Tribol_REQUIRED_PACKAGES "Axom/core/mint/slam/slic" CACHE STRING
|
||||
set(Tribol_REQUIRED_PACKAGES "Axom/core/mint/slam/slic" CACHE STRING
|
||||
"Additional packages required by Tribol")
|
||||
|
||||
set(BLAS_INCLUDE_DIRS "" CACHE STRING "Path to BLAS headers.")
|
||||
|
||||
+12
-2
@@ -95,6 +95,10 @@ else
|
||||
# Silence unused command line argument warnings when generating dependencies
|
||||
# with mpicxx and clang
|
||||
DEP_FLAGS := -Wno-unused-command-line-argument $(DEP_FLAGS)
|
||||
# Silence "ignoring duplicate libraries" warnings on new (Xcode 15) linker
|
||||
ifneq (,$(findstring PROJECT:dyld,$(shell ld -v 2>&1)))
|
||||
LDFLAGS_INTERNAL = -Xlinker -no_warn_duplicate_libraries
|
||||
endif
|
||||
endif
|
||||
|
||||
# Set CXXFLAGS to overwrite the default selection of DEBUG_FLAGS/OPTIM_FLAGS
|
||||
@@ -139,6 +143,7 @@ MFEM_USE_MUMPS = NO
|
||||
MFEM_USE_STRUMPACK = NO
|
||||
MFEM_USE_GINKGO = NO
|
||||
MFEM_USE_AMGX = NO
|
||||
MFEM_USE_MAGMA = NO
|
||||
MFEM_USE_GNUTLS = NO
|
||||
MFEM_USE_NETCDF = NO
|
||||
MFEM_USE_PETSC = NO
|
||||
@@ -390,6 +395,11 @@ AMGX_DIR = @MFEM_DIR@/../amgx
|
||||
AMGX_OPT = -I$(AMGX_DIR)/include
|
||||
AMGX_LIB = -L$(AMGX_DIR)/lib -lamgx -lcusparse -lcusolver -lcublas -lnvToolsExt
|
||||
|
||||
# MAGMA library configuration
|
||||
MAGMA_DIR = @MFEM_DIR@/../magma
|
||||
MAGMA_OPT = -I$(MAGMA_DIR)/include
|
||||
MAGMA_LIB = -L$(MAGMA_DIR)/lib -l:libmagma.a -lcublas -lcusparse $(LAPACK_LIB)
|
||||
|
||||
# GnuTLS library configuration
|
||||
GNUTLS_OPT =
|
||||
GNUTLS_LIB = -lgnutls
|
||||
@@ -497,11 +507,11 @@ GSLIB_LIB = -L$(GSLIB_DIR)/lib -lgs
|
||||
|
||||
# CUDA library configuration
|
||||
CUDA_OPT =
|
||||
CUDA_LIB = -lcusparse
|
||||
CUDA_LIB = -lcusparse -lcublas
|
||||
|
||||
# HIP library configuration
|
||||
HIP_OPT =
|
||||
HIP_LIB = -L$(HIP_DIR)/lib $(XLINKER)-rpath,$(HIP_DIR)/lib -lhipsparse
|
||||
HIP_LIB = -L$(HIP_DIR)/lib $(XLINKER)-rpath,$(HIP_DIR)/lib -lhipsparse -lhipblas
|
||||
|
||||
# OCCA library configuration
|
||||
OCCA_DIR = @MFEM_DIR@/../occa
|
||||
|
||||
+83
-13
@@ -32,7 +32,7 @@ groups_serial=(
|
||||
'"examples"
|
||||
"Examples:"
|
||||
"examples"
|
||||
"ex{,1,2,3}[0-9].cpp"'
|
||||
"ex{,[1-9]}[0-9].cpp"'
|
||||
# "ex1.cpp"'
|
||||
'"sundials"
|
||||
"SUNDIALS examples:"
|
||||
@@ -58,6 +58,10 @@ groups_serial=(
|
||||
"HiOp examples:"
|
||||
"examples/hiop"
|
||||
"ex9.cpp"'
|
||||
'"moonolith"
|
||||
"Moonolith examples:"
|
||||
"examples/moonolith"
|
||||
"ex1.cpp"'
|
||||
'"pumi"
|
||||
"PUMI examples:"
|
||||
"examples/pumi"
|
||||
@@ -66,25 +70,38 @@ groups_serial=(
|
||||
'"meshing"
|
||||
"Meshing miniapps:"
|
||||
"miniapps/meshing"
|
||||
"mobius-strip.cpp klein-bottle.cpp extruder.cpp toroid.cpp
|
||||
"mobius-strip.cpp klein-bottle.cpp extruder.cpp toroid.cpp mesh-quality.cpp
|
||||
polar-nc.cpp reflector.cpp shaper.cpp trimmer.cpp twist.cpp
|
||||
mesh-optimizer.cpp minimal-surface.cpp"'
|
||||
'"adjoint"
|
||||
"Adjoint miniapps:"
|
||||
"miniapps/adjoint"
|
||||
"cvsRoberts_ASAi_dns.cpp"'
|
||||
'"autodiff"
|
||||
"Autodiff miniapps:"
|
||||
"miniapps/autodiff"
|
||||
"seq_example.cpp seq_test.cpp"' # 'seq_test.cpp' has no sample runs
|
||||
'"dpg"
|
||||
"DPG miniapps:"
|
||||
"miniapps/dpg"
|
||||
"{acoustics,convection-diffusion,diffusion,maxwell}.cpp"'
|
||||
'"gslib"
|
||||
"GSLIB miniapps:"
|
||||
"miniapps/gslib"
|
||||
"field-diff.cpp field-interp.cpp findpts.cpp schwarz_ex1.cpp "'
|
||||
# todo: miniapps/mtop
|
||||
'"nurbs"
|
||||
"NURBS miniapps:"
|
||||
"miniapps/nurbs"
|
||||
"nurbs_ex1.cpp"'
|
||||
# todo: add other nurbs miniapps
|
||||
# todo: miniapps/solvers (serial)
|
||||
'"tools"
|
||||
"Tools miniapps:"
|
||||
"miniapps/tools"
|
||||
"convert-dc.cpp display-basis.cpp get-values.cpp load-dc.cpp
|
||||
lor-transfer.cpp"'
|
||||
# todo: add other tools miniapps
|
||||
'"toys"
|
||||
"Toys miniapps:"
|
||||
"miniapps/toys"
|
||||
@@ -100,7 +117,7 @@ groups_parallel=(
|
||||
'"examples"
|
||||
"Examples:"
|
||||
"examples"
|
||||
"ex{,1,2,3}[0-9]p.cpp"'
|
||||
"ex{,[1-9]}[0-9]p.cpp"'
|
||||
# "ex1p.cpp"'
|
||||
'"sundials"
|
||||
"SUNDIALS examples:"
|
||||
@@ -126,6 +143,10 @@ groups_parallel=(
|
||||
"HiOp examples:"
|
||||
"examples/hiop"
|
||||
"ex9p.cpp"'
|
||||
'"moonolith"
|
||||
"Moonolith examples:"
|
||||
"examples/moonolith"
|
||||
"ex{1,2}p.cpp"'
|
||||
'"pumi"
|
||||
"PUMI examples:"
|
||||
"examples/pumi"
|
||||
@@ -138,24 +159,41 @@ groups_parallel=(
|
||||
'"meshing"
|
||||
"Meshing miniapps:"
|
||||
"miniapps/meshing"
|
||||
"pmesh-optimizer.cpp pmesh-fitting.cpp pminimal-surface.cpp"'
|
||||
"pmesh-optimizer.cpp pmesh-fitting.cpp pminimal-surface.cpp
|
||||
fit-node-position.cpp"'
|
||||
'"electromagnetics"
|
||||
"Electromagnetics miniapps:"
|
||||
"miniapps/electromagnetics"
|
||||
"joule.cpp"'
|
||||
# "{volta,tesla,joule}.cpp"' # todo: multiline sample runs
|
||||
# "{joule,maxwell,tesla,volta}.cpp"' # todo: multiline sample runs
|
||||
'"adjoint"
|
||||
"Adjoint miniapps:"
|
||||
"miniapps/adjoint"
|
||||
"adjoint_advection_diffusion.cpp"'
|
||||
'"autodiff"
|
||||
"Autodiff miniapps:"
|
||||
"miniapps/autodiff"
|
||||
"par_example.cpp"'
|
||||
'"dpg"
|
||||
"DPG miniapps:"
|
||||
"miniapps/dpg"
|
||||
"p{acoustics,convection-diffusion,diffusion,maxwell}.cpp"'
|
||||
'"gslib"
|
||||
"GSLIB miniapps:"
|
||||
"miniapps/gslib"
|
||||
"pfindpts.cpp schwarz_ex1p.cpp"'
|
||||
'"hdiv-linear-solver"
|
||||
"H(div) linear solver miniapps:"
|
||||
"miniapps/hdiv-linear-solver"
|
||||
"grad_div.cpp darcy.cpp"'
|
||||
# 'miniapps/hooke/hooke.cpp' has no sample runs
|
||||
# todo: miniapps/mtop
|
||||
# todo: miniapps/multidomain
|
||||
'"navier"
|
||||
"Navier miniapps:"
|
||||
"miniapps/navier"
|
||||
"navier_cht.cpp"'
|
||||
# todo: add other navier miniapps
|
||||
'"nurbs"
|
||||
"NURBS miniapps:"
|
||||
"miniapps/nurbs"
|
||||
@@ -164,14 +202,18 @@ groups_parallel=(
|
||||
"Shifted miniapps:"
|
||||
"miniapps/shifted"
|
||||
"distance.cpp"'
|
||||
# todo: add other shifted miniapps
|
||||
'"solvers"
|
||||
"Solvers miniapps:"
|
||||
"miniapps/solvers"
|
||||
"block-solvers.cpp"'
|
||||
# todo: add other solvers miniapps
|
||||
# todo: miniapps/spde
|
||||
'"tools"
|
||||
"Tools miniapps:"
|
||||
"miniapps/tools"
|
||||
"convert-cd.cpp get-values.cpp load-dc.cpp"'
|
||||
"convert-dc.cpp get-values.cpp load-dc.cpp"'
|
||||
# todo: add other tools miniapps
|
||||
'"convergence"
|
||||
"Convergence tests:"
|
||||
"tests/convergence"
|
||||
@@ -186,7 +228,7 @@ groups_all=(
|
||||
'"examples"
|
||||
"Examples:"
|
||||
"examples"
|
||||
"ex\"{,1,2,3}[0-9]\"{,p}.cpp"'
|
||||
"ex\"{,[1-9]}[0-9]\"{,p}.cpp"'
|
||||
'"sundials"
|
||||
"SUNDIALS examples:"
|
||||
"examples/sundials"
|
||||
@@ -215,10 +257,14 @@ groups_all=(
|
||||
"HiOp examples:"
|
||||
"examples/hiop"
|
||||
"ex9.cpp ex9p.cpp"'
|
||||
'"moonolith"
|
||||
"Moonolith examples:"
|
||||
"examples/moonolith"
|
||||
"ex1.cpp ex{1,2}p.cpp"'
|
||||
'"pumi"
|
||||
"PUMI examples:"
|
||||
"examples/pumi"
|
||||
"ex1.cpp ex1p.cpp ex2.cpp ex6p.cpp"'
|
||||
"ex1.cpp ex2.cpp ex1p.cpp ex6p.cpp"'
|
||||
'"superlu"
|
||||
"Superlu examples:"
|
||||
"examples/superlu"
|
||||
@@ -226,43 +272,67 @@ groups_all=(
|
||||
'"meshing"
|
||||
"Meshing miniapps:"
|
||||
"miniapps/meshing"
|
||||
"mobius-strip.cpp klein-bottle.cpp extruder.cpp toroid.cpp
|
||||
{,p}mesh-optimizer.cpp pmesh-fitting.cpp {,p}minimal-surface.cpp"'
|
||||
"mobius-strip.cpp klein-bottle.cpp extruder.cpp toroid.cpp mesh-quality.cpp
|
||||
polar-nc.cpp reflector.cpp shaper.cpp trimmer.cpp twist.cpp
|
||||
{,p}mesh-optimizer.cpp pmesh-fitting.cpp {,p}minimal-surface.cpp
|
||||
fit-node-position.cpp"'
|
||||
'"electromagnetics"
|
||||
"Electromagnetics miniapps:"
|
||||
"miniapps/electromagnetics"
|
||||
"joule.cpp"'
|
||||
# "{volta,tesla,joule}.cpp"' # todo: multiline sample runs
|
||||
# "{joule,maxwell,tesla,volta}.cpp"' # todo: multiline sample runs
|
||||
'"adjoint"
|
||||
"Adjoint miniapps:"
|
||||
"miniapps/adjoint"
|
||||
"adjoint_advection_diffusion.cpp cvsRoberts_ASAi_dns.cpp"'
|
||||
"cvsRoberts_ASAi_dns.cpp adjoint_advection_diffusion.cpp"'
|
||||
'"autodiff"
|
||||
"Autodiff miniapps:"
|
||||
"miniapps/autodiff"
|
||||
"seq_example.cpp seq_test.cpp par_example.cpp"'
|
||||
# 'seq_test.cpp' has no sample runs
|
||||
'"dpg"
|
||||
"DPG miniapps:"
|
||||
"miniapps/dpg"
|
||||
"{,p}{acoustics,convection-diffusion,diffusion,maxwell}.cpp"'
|
||||
'"gslib"
|
||||
"GSLIB miniapps:"
|
||||
"miniapps/gslib"
|
||||
"field-diff.cpp field-interp.cpp findpts.cpp schwarz_ex1.cpp pfindpts.cpp
|
||||
schwarz_ex1p.cpp"'
|
||||
'"hdiv-linear-solver"
|
||||
"H(div) linear solver miniapps:"
|
||||
"miniapps/hdiv-linear-solver"
|
||||
"grad_div.cpp darcy.cpp"'
|
||||
# 'miniapps/hooke/hooke.cpp' has no sample runs
|
||||
# todo: miniapps/mtop
|
||||
# todo: miniapps/multidomain
|
||||
'"navier"
|
||||
"Navier miniapps:"
|
||||
"miniapps/navier"
|
||||
"navier_cht.cpp"'
|
||||
# todo: add other navier miniapps
|
||||
'"nurbs"
|
||||
"NURBS miniapps:"
|
||||
"miniapps/nurbs"
|
||||
"nurbs_ex1.cpp nurbs_ex1p.cpp nurbs_ex11p.cpp"'
|
||||
# todo: add other nurbs miniapps
|
||||
'"shifted"
|
||||
"Shifted miniapps:"
|
||||
"miniapps/shifted"
|
||||
"distance.cpp"'
|
||||
# todo: add other shifted miniapps
|
||||
'"solvers"
|
||||
"Solvers miniapps:"
|
||||
"miniapps/solvers"
|
||||
"block-solvers.cpp"'
|
||||
# todo: add other solvers miniapps
|
||||
# todo: miniapps/spde
|
||||
'"tools"
|
||||
"Tools miniapps:"
|
||||
"miniapps/tools"
|
||||
"convert-dc.cpp display-basis.cpp get-values.cpp load-dc.cpp
|
||||
lor-transfer.cpp"'
|
||||
# todo: add other tools miniapps
|
||||
'"toys"
|
||||
"Toys miniapps:"
|
||||
"miniapps/toys"
|
||||
@@ -386,7 +456,7 @@ function help_message()
|
||||
mfem_config [${mfem_config}]
|
||||
Set MFEM configuration options
|
||||
make [${make}], mpiexec [${mpiexec}], mpiexec_np [${mpiexec_np}]
|
||||
Their values can also set using the respective uppercase environment
|
||||
Their values can also be set using the respective uppercase environment
|
||||
variable
|
||||
mfem_build_dir [${mfem_build_dir}]
|
||||
Same as '-d': set this variable to something different from <mfem_dir>
|
||||
|
||||
@@ -18,9 +18,9 @@ elements
|
||||
boundary
|
||||
4
|
||||
1 1 0 1
|
||||
1 1 2 3
|
||||
1 1 3 0
|
||||
1 1 1 2
|
||||
2 1 2 3
|
||||
3 1 3 0
|
||||
4 1 1 2
|
||||
|
||||
edges
|
||||
4
|
||||
|
||||
@@ -938,6 +938,7 @@ INPUT = @MFEM_SOURCE_DIR@/doc/CodeDocumentation.dox \
|
||||
@MFEM_SOURCE_DIR@/config \
|
||||
@MFEM_SOURCE_DIR@/general \
|
||||
@MFEM_SOURCE_DIR@/linalg \
|
||||
@MFEM_SOURCE_DIR@/linalg/batched \
|
||||
@MFEM_SOURCE_DIR@/linalg/simd \
|
||||
@MFEM_SOURCE_DIR@/mesh \
|
||||
@MFEM_SOURCE_DIR@/mesh/submesh \
|
||||
@@ -1049,7 +1050,8 @@ RECURSIVE = NO
|
||||
EXCLUDE = @MFEM_SOURCE_DIR@/config/_config.hpp \
|
||||
@MFEM_SOURCE_DIR@/config/get_hypre_version.cpp \
|
||||
@MFEM_SOURCE_DIR@/general/tinyxml2.h \
|
||||
@MFEM_SOURCE_DIR@/general/tinyxml2.cpp
|
||||
@MFEM_SOURCE_DIR@/general/tinyxml2.cpp \
|
||||
@MFEM_SOURCE_DIR@/linalg/lapack.hpp
|
||||
|
||||
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
|
||||
# directories that are symbolic links (a Unix file system feature) are excluded
|
||||
|
||||
@@ -182,6 +182,21 @@ namespace mfem {
|
||||
* <a class="el" href="examples_2superlu_2ex1p_8cpp_source.html">1p</a>,
|
||||
* demonstrating the use of MFEM's \link superlu.hpp SuperLU integration\endlink.
|
||||
*
|
||||
* <H4>NURBS Examples</H4>
|
||||
* - Variants of Examples
|
||||
* <a class="el" href="nurbs__ex1_8cpp_source.html">1</a>,
|
||||
* <a class="el" href="nurbs__ex1p_8cpp_source.html">1p</a>,
|
||||
* <a class="el" href="nurbs__ex3_8cpp_source.html">3</a>,
|
||||
* <a class="el" href="nurbs__ex5_8cpp_source.html">5</a>,
|
||||
* <a class="el" href="nurbs__ex11p_8cpp_source.html">11p</a>, and
|
||||
* <a class="el" href="nurbs__ex24_8cpp_source.html">24</a>,
|
||||
* demonstrating howto perform NURBS-based Isogeometric Analysis.
|
||||
* - Variant of Example <a class="el" href="nurbs__patch__ex1_8cpp_source.html">1</a>: demonstrates the use of patch integration
|
||||
* - <a class="el" href="nurbs__solenoidal_8cpp_source.html">NURBS Divergence-free</a>: solve a solenoidal vector projection with NURBS-based H(div) elements
|
||||
* - <a class="el" href="nurbs__curveint_8cpp_source.html">NURBS Interpolation</a>: NURBS interpolation of given geometry
|
||||
* - <a class="el" href="nurbs__naca__cmesh_8cpp_source.html">NURBS NACA Mesher</a>: generate NURBS based mesh around a NACA foil
|
||||
* - <a class="el" href="nurbs__printfunc_8cpp_source.html">NURBS Printer</a>: print the NURBS-basis
|
||||
*
|
||||
* <H3>Miniapps</H3>
|
||||
* - <a class="el" href="volta_8cpp_source.html">Volta</a>: simple electrostatics simulation code
|
||||
* - <a class="el" href="tesla_8cpp_source.html">Tesla</a>: simple magnetostatics simulation code
|
||||
|
||||
@@ -12,11 +12,10 @@
|
||||
# Use the MFEM build directory
|
||||
MFEM_DIR ?= ../..
|
||||
MFEM_BUILD_DIR ?= ../..
|
||||
MFEM_INSTALL_DIR ?= ../../mfem
|
||||
SRC = $(if $(MFEM_DIR:../..=),$(MFEM_DIR)/examples/amgx/,)
|
||||
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
|
||||
# Use the MFEM install directory
|
||||
# MFEM_INSTALL_DIR = ../../mfem
|
||||
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
|
||||
CONFIG_MK = $(or $(wildcard $(MFEM_BUILD_DIR)/config/config.mk),\
|
||||
$(wildcard $(MFEM_INSTALL_DIR)/share/mfem/config.mk))
|
||||
|
||||
MFEM_LIB_FILE = mfem_is_not_built
|
||||
-include $(CONFIG_MK)
|
||||
|
||||
@@ -12,11 +12,10 @@
|
||||
# Use the MFEM build directory
|
||||
MFEM_DIR ?= ../..
|
||||
MFEM_BUILD_DIR ?= ../..
|
||||
MFEM_INSTALL_DIR ?= ../../mfem
|
||||
SRC = $(if $(MFEM_DIR:../..=),$(MFEM_DIR)/examples/caliper,)
|
||||
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
|
||||
# Use the MFEM install directory
|
||||
# MFEM_INSTALL_DIR = ../../mfem
|
||||
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
|
||||
CONFIG_MK = $(or $(wildcard $(MFEM_BUILD_DIR)/config/config.mk),\
|
||||
$(wildcard $(MFEM_INSTALL_DIR)/share/mfem/config.mk))
|
||||
|
||||
MFEM_LIB_FILE = mfem_is_not_built
|
||||
-include $(CONFIG_MK)
|
||||
|
||||
+8
-8
@@ -87,16 +87,16 @@ public:
|
||||
real_t visc, real_t mu, real_t K);
|
||||
|
||||
/// Compute the right-hand side of the ODE system.
|
||||
virtual void Mult(const Vector &vx, Vector &dvx_dt) const;
|
||||
void Mult(const Vector &vx, Vector &dvx_dt) const override;
|
||||
/** Solve the Backward-Euler equation: k = f(x + dt*k, t), for the unknown k.
|
||||
This is the only requirement for high-order SDIRK implicit integration.*/
|
||||
virtual void ImplicitSolve(const real_t dt, const Vector &x, Vector &k);
|
||||
void ImplicitSolve(const real_t dt, const Vector &x, Vector &k) override;
|
||||
|
||||
real_t ElasticEnergy(const Vector &x) const;
|
||||
real_t KineticEnergy(const Vector &v) const;
|
||||
void GetElasticEnergyDensity(const GridFunction &x, GridFunction &w) const;
|
||||
|
||||
virtual ~HyperelasticOperator();
|
||||
~HyperelasticOperator() override;
|
||||
};
|
||||
|
||||
/** Nonlinear operator of the form:
|
||||
@@ -120,12 +120,12 @@ public:
|
||||
void SetParameters(real_t dt_, const Vector *v_, const Vector *x_);
|
||||
|
||||
/// Compute y = H(x + dt (v + dt k)) + M k + S (v + dt k).
|
||||
virtual void Mult(const Vector &k, Vector &y) const;
|
||||
void Mult(const Vector &k, Vector &y) const override;
|
||||
|
||||
/// Compute J = M + dt S + dt^2 grad_H(x + dt (v + dt k)).
|
||||
virtual Operator &GetGradient(const Vector &k) const;
|
||||
Operator &GetGradient(const Vector &k) const override;
|
||||
|
||||
virtual ~ReducedSystemOperator();
|
||||
~ReducedSystemOperator() override;
|
||||
};
|
||||
|
||||
|
||||
@@ -141,8 +141,8 @@ private:
|
||||
public:
|
||||
ElasticEnergyCoefficient(HyperelasticModel &m, const GridFunction &x_)
|
||||
: model(m), x(x_) { }
|
||||
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
|
||||
virtual ~ElasticEnergyCoefficient() { }
|
||||
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
|
||||
~ElasticEnergyCoefficient() override { }
|
||||
};
|
||||
|
||||
void InitialDeformation(const Vector &x, Vector &y);
|
||||
|
||||
+8
-8
@@ -89,17 +89,17 @@ public:
|
||||
real_t visc, real_t mu, real_t K);
|
||||
|
||||
/// Compute the right-hand side of the ODE system.
|
||||
virtual void Mult(const Vector &vx, Vector &dvx_dt) const;
|
||||
void Mult(const Vector &vx, Vector &dvx_dt) const override;
|
||||
/** Solve the Backward-Euler equation: k = f(x + dt*k, t), for the unknown k.
|
||||
This is the only requirement for high-order SDIRK implicit integration.*/
|
||||
virtual void ImplicitSolve(const real_t dt, const Vector &x, Vector &k);
|
||||
void ImplicitSolve(const real_t dt, const Vector &x, Vector &k) override;
|
||||
|
||||
real_t ElasticEnergy(const ParGridFunction &x) const;
|
||||
real_t KineticEnergy(const ParGridFunction &v) const;
|
||||
void GetElasticEnergyDensity(const ParGridFunction &x,
|
||||
ParGridFunction &w) const;
|
||||
|
||||
virtual ~HyperelasticOperator();
|
||||
~HyperelasticOperator() override;
|
||||
};
|
||||
|
||||
/** Nonlinear operator of the form:
|
||||
@@ -125,12 +125,12 @@ public:
|
||||
void SetParameters(real_t dt_, const Vector *v_, const Vector *x_);
|
||||
|
||||
/// Compute y = H(x + dt (v + dt k)) + M k + S (v + dt k).
|
||||
virtual void Mult(const Vector &k, Vector &y) const;
|
||||
void Mult(const Vector &k, Vector &y) const override;
|
||||
|
||||
/// Compute J = M + dt S + dt^2 grad_H(x + dt (v + dt k)).
|
||||
virtual Operator &GetGradient(const Vector &k) const;
|
||||
Operator &GetGradient(const Vector &k) const override;
|
||||
|
||||
virtual ~ReducedSystemOperator();
|
||||
~ReducedSystemOperator() override;
|
||||
};
|
||||
|
||||
|
||||
@@ -146,8 +146,8 @@ private:
|
||||
public:
|
||||
ElasticEnergyCoefficient(HyperelasticModel &m, const ParGridFunction &x_)
|
||||
: model(m), x(x_) { }
|
||||
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
|
||||
virtual ~ElasticEnergyCoefficient() { }
|
||||
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
|
||||
~ElasticEnergyCoefficient() override { }
|
||||
};
|
||||
|
||||
void InitialDeformation(const Vector &x, Vector &y);
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ public:
|
||||
pmesh(pmesh_),
|
||||
pgf(pgf_) {}
|
||||
|
||||
void MonitorSolution(int i, real_t norm, const Vector &x, bool final)
|
||||
void MonitorSolution(int i, real_t norm, const Vector &x, bool final) override
|
||||
{
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
|
||||
+3
-3
@@ -76,15 +76,15 @@ public:
|
||||
ConductionOperator(FiniteElementSpace &f, real_t alpha, real_t kappa,
|
||||
const Vector &u);
|
||||
|
||||
virtual void Mult(const Vector &u, Vector &du_dt) const;
|
||||
void Mult(const Vector &u, Vector &du_dt) const override;
|
||||
/** Solve the Backward-Euler equation: k = f(u + dt*k, t), for the unknown k.
|
||||
This is the only requirement for high-order SDIRK implicit integration.*/
|
||||
virtual void ImplicitSolve(const real_t dt, const Vector &u, Vector &k);
|
||||
void ImplicitSolve(const real_t dt, const Vector &u, Vector &k) override;
|
||||
|
||||
/// Update the diffusion BilinearForm K using the given true-dof vector `u`.
|
||||
void SetParameters(const Vector &u);
|
||||
|
||||
virtual ~ConductionOperator();
|
||||
~ConductionOperator() override;
|
||||
};
|
||||
|
||||
real_t InitialTemperature(const Vector &x);
|
||||
|
||||
+3
-3
@@ -78,15 +78,15 @@ public:
|
||||
ConductionOperator(ParFiniteElementSpace &f, real_t alpha, real_t kappa,
|
||||
const Vector &u);
|
||||
|
||||
virtual void Mult(const Vector &u, Vector &du_dt) const;
|
||||
void Mult(const Vector &u, Vector &du_dt) const override;
|
||||
/** Solve the Backward-Euler equation: k = f(u + dt*k, t), for the unknown k.
|
||||
This is the only requirement for high-order SDIRK implicit integration.*/
|
||||
virtual void ImplicitSolve(const real_t dt, const Vector &u, Vector &k);
|
||||
void ImplicitSolve(const real_t dt, const Vector &u, Vector &k) override;
|
||||
|
||||
/// Update the diffusion BilinearForm K using the given true-dof vector `u`.
|
||||
void SetParameters(const Vector &u);
|
||||
|
||||
virtual ~ConductionOperator();
|
||||
~ConductionOperator() override;
|
||||
};
|
||||
|
||||
real_t InitialTemperature(const Vector &x);
|
||||
|
||||
+2
-2
@@ -69,7 +69,7 @@ public:
|
||||
void SetDisplacement(GridFunction &u_) { u = &u_; }
|
||||
void SetComponent(int i, int j) { si = i; sj = j; }
|
||||
|
||||
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
// Simple GLVis visualization manager.
|
||||
@@ -89,7 +89,7 @@ public:
|
||||
void NewWindow();
|
||||
void CloseConnection();
|
||||
void PositionWindow();
|
||||
virtual ~VisMan();
|
||||
~VisMan() override;
|
||||
};
|
||||
|
||||
// Manipulators for the GLVis visualization manager.
|
||||
|
||||
+2
-2
@@ -69,7 +69,7 @@ public:
|
||||
void SetDisplacement(GridFunction &u_) { u = &u_; }
|
||||
void SetComponent(int i, int j) { si = i; sj = j; }
|
||||
|
||||
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
// Simple GLVis visualization manager.
|
||||
@@ -89,7 +89,7 @@ public:
|
||||
void NewWindow();
|
||||
void CloseConnection();
|
||||
void PositionWindow();
|
||||
virtual ~VisMan();
|
||||
~VisMan() override;
|
||||
};
|
||||
|
||||
// Manipulators for the GLVis visualization manager.
|
||||
|
||||
+7
-7
@@ -48,7 +48,7 @@ public:
|
||||
print_level = print_lvl;
|
||||
}
|
||||
|
||||
virtual void MonitorResidual(int it, real_t norm, const Vector &r, bool final);
|
||||
void MonitorResidual(int it, real_t norm, const Vector &r, bool final) override;
|
||||
|
||||
private:
|
||||
const std::string prefix;
|
||||
@@ -116,10 +116,10 @@ public:
|
||||
JacobianPreconditioner(Array<FiniteElementSpace *> &fes,
|
||||
SparseMatrix &mass, Array<int> &offsets);
|
||||
|
||||
virtual void Mult(const Vector &k, Vector &y) const;
|
||||
virtual void SetOperator(const Operator &op);
|
||||
void Mult(const Vector &k, Vector &y) const override;
|
||||
void SetOperator(const Operator &op) override;
|
||||
|
||||
virtual ~JacobianPreconditioner();
|
||||
~JacobianPreconditioner() override;
|
||||
};
|
||||
|
||||
// After spatial discretization, the rubber model can be written as:
|
||||
@@ -161,13 +161,13 @@ public:
|
||||
int iter, Coefficient &mu);
|
||||
|
||||
// Required to use the native newton solver
|
||||
virtual Operator &GetGradient(const Vector &xp) const;
|
||||
virtual void Mult(const Vector &k, Vector &y) const;
|
||||
Operator &GetGradient(const Vector &xp) const override;
|
||||
void Mult(const Vector &k, Vector &y) const override;
|
||||
|
||||
// Driver for the newton solver
|
||||
void Solve(Vector &xp) const;
|
||||
|
||||
virtual ~RubberOperator();
|
||||
~RubberOperator() override;
|
||||
};
|
||||
|
||||
// Visualization driver
|
||||
|
||||
+7
-7
@@ -62,7 +62,7 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void MonitorResidual(int it, real_t norm, const Vector &r, bool final);
|
||||
void MonitorResidual(int it, real_t norm, const Vector &r, bool final) override;
|
||||
|
||||
private:
|
||||
const std::string prefix;
|
||||
@@ -130,10 +130,10 @@ public:
|
||||
JacobianPreconditioner(Array<ParFiniteElementSpace *> &fes,
|
||||
Operator &mass, Array<int> &offsets);
|
||||
|
||||
virtual void Mult(const Vector &k, Vector &y) const;
|
||||
virtual void SetOperator(const Operator &op);
|
||||
void Mult(const Vector &k, Vector &y) const override;
|
||||
void SetOperator(const Operator &op) override;
|
||||
|
||||
virtual ~JacobianPreconditioner();
|
||||
~JacobianPreconditioner() override;
|
||||
};
|
||||
|
||||
// After spatial discretization, the rubber model can be written as:
|
||||
@@ -175,13 +175,13 @@ public:
|
||||
int iter, Coefficient &mu);
|
||||
|
||||
// Required to use the native newton solver
|
||||
virtual Operator &GetGradient(const Vector &xp) const;
|
||||
virtual void Mult(const Vector &k, Vector &y) const;
|
||||
Operator &GetGradient(const Vector &xp) const override;
|
||||
void Mult(const Vector &k, Vector &y) const override;
|
||||
|
||||
// Driver for the newton solver
|
||||
void Solve(Vector &xp) const;
|
||||
|
||||
virtual ~RubberOperator();
|
||||
~RubberOperator() override;
|
||||
};
|
||||
|
||||
// Visualization driver
|
||||
|
||||
+2
-2
@@ -79,14 +79,14 @@ class GradT : public Operator
|
||||
{
|
||||
public:
|
||||
GradT() : Operator(1) {}
|
||||
void Mult(const Vector &x, Vector &y) const { y.Set(1.0/m_, x); }
|
||||
void Mult(const Vector &x, Vector &y) const override { y.Set(1.0/m_, x); }
|
||||
};
|
||||
|
||||
class NegGradV : public TimeDependentOperator
|
||||
{
|
||||
public:
|
||||
NegGradV() : TimeDependentOperator(1) {}
|
||||
void Mult(const Vector &x, Vector &y) const;
|
||||
void Mult(const Vector &x, Vector &y) const override;
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
||||
+2
-2
@@ -84,14 +84,14 @@ class GradT : public Operator
|
||||
{
|
||||
public:
|
||||
GradT() : Operator(1) {}
|
||||
void Mult(const Vector &x, Vector &y) const { y.Set(1.0/m_, x); }
|
||||
void Mult(const Vector &x, Vector &y) const override { y.Set(1.0/m_, x); }
|
||||
};
|
||||
|
||||
class NegGradV : public TimeDependentOperator
|
||||
{
|
||||
public:
|
||||
NegGradV() : TimeDependentOperator(1) {}
|
||||
void Mult(const Vector &x, Vector &y) const;
|
||||
void Mult(const Vector &x, Vector &y) const override;
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
||||
+21
-25
@@ -44,7 +44,7 @@ protected:
|
||||
BilinearForm *M;
|
||||
BilinearForm *K;
|
||||
|
||||
SparseMatrix Mmat, Kmat, Kmat0;
|
||||
SparseMatrix Mmat, Kmat;
|
||||
SparseMatrix *T; // T = M + dt K
|
||||
real_t current_dt;
|
||||
|
||||
@@ -61,20 +61,20 @@ public:
|
||||
WaveOperator(FiniteElementSpace &f, Array<int> &ess_bdr, real_t speed);
|
||||
|
||||
using SecondOrderTimeDependentOperator::Mult;
|
||||
virtual void Mult(const Vector &u, const Vector &du_dt,
|
||||
Vector &d2udt2) const;
|
||||
void Mult(const Vector &u, const Vector &du_dt,
|
||||
Vector &d2udt2) const override;
|
||||
|
||||
/** Solve the Backward-Euler equation:
|
||||
d2udt2 = f(u + fac0*d2udt2,dudt + fac1*d2udt2, t),
|
||||
for the unknown d2udt2. */
|
||||
using SecondOrderTimeDependentOperator::ImplicitSolve;
|
||||
virtual void ImplicitSolve(const real_t fac0, const real_t fac1,
|
||||
const Vector &u, const Vector &dudt, Vector &d2udt2);
|
||||
void ImplicitSolve(const real_t fac0, const real_t fac1,
|
||||
const Vector &u, const Vector &dudt, Vector &d2udt2) override;
|
||||
|
||||
///
|
||||
void SetParameters(const Vector &u);
|
||||
|
||||
virtual ~WaveOperator();
|
||||
~WaveOperator() override;
|
||||
};
|
||||
|
||||
|
||||
@@ -83,25 +83,24 @@ WaveOperator::WaveOperator(FiniteElementSpace &f,
|
||||
: SecondOrderTimeDependentOperator(f.GetTrueVSize(), (real_t) 0.0),
|
||||
fespace(f), M(NULL), K(NULL), T(NULL), current_dt(0.0), z(height)
|
||||
{
|
||||
const real_t rel_tol = 1e-8;
|
||||
|
||||
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
|
||||
|
||||
// Assemble Laplace matrix
|
||||
c2 = new ConstantCoefficient(speed*speed);
|
||||
|
||||
K = new BilinearForm(&fespace);
|
||||
K->AddDomainIntegrator(new DiffusionIntegrator(*c2));
|
||||
K->Assemble();
|
||||
|
||||
Array<int> dummy;
|
||||
K->FormSystemMatrix(dummy, Kmat0);
|
||||
K->FormSystemMatrix(ess_tdof_list, Kmat);
|
||||
|
||||
// Assemble Mass matrix
|
||||
M = new BilinearForm(&fespace);
|
||||
M->AddDomainIntegrator(new MassIntegrator());
|
||||
M->Assemble();
|
||||
|
||||
// Apply Bcs
|
||||
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
|
||||
K->FormSystemMatrix(ess_tdof_list, Kmat);
|
||||
M->FormSystemMatrix(ess_tdof_list, Mmat);
|
||||
|
||||
// Configure preconditioner
|
||||
const real_t rel_tol = 1e-8;
|
||||
M_solver.iterative_mode = false;
|
||||
M_solver.SetRelTol(rel_tol);
|
||||
M_solver.SetAbsTol(0.0);
|
||||
@@ -110,14 +109,13 @@ WaveOperator::WaveOperator(FiniteElementSpace &f,
|
||||
M_solver.SetPreconditioner(M_prec);
|
||||
M_solver.SetOperator(Mmat);
|
||||
|
||||
// Configure solver
|
||||
T_solver.iterative_mode = false;
|
||||
T_solver.SetRelTol(rel_tol);
|
||||
T_solver.SetAbsTol(0.0);
|
||||
T_solver.SetMaxIter(100);
|
||||
T_solver.SetPrintLevel(0);
|
||||
T_solver.SetPreconditioner(T_prec);
|
||||
|
||||
T = NULL;
|
||||
}
|
||||
|
||||
void WaveOperator::Mult(const Vector &u, const Vector &du_dt,
|
||||
@@ -126,9 +124,11 @@ void WaveOperator::Mult(const Vector &u, const Vector &du_dt,
|
||||
// Compute:
|
||||
// d2udt2 = M^{-1}*-K(u)
|
||||
// for d2udt2
|
||||
Kmat.Mult(u, z);
|
||||
K->FullMult(u, z);
|
||||
z.Neg(); // z = -z
|
||||
z.SetSubVector(ess_tdof_list, 0.0);
|
||||
M_solver.Mult(z, d2udt2);
|
||||
d2udt2.SetSubVector(ess_tdof_list, 0.0);
|
||||
}
|
||||
|
||||
void WaveOperator::ImplicitSolve(const real_t fac0, const real_t fac1,
|
||||
@@ -142,14 +142,11 @@ void WaveOperator::ImplicitSolve(const real_t fac0, const real_t fac1,
|
||||
T = Add(1.0, Mmat, fac0, Kmat);
|
||||
T_solver.SetOperator(*T);
|
||||
}
|
||||
Kmat0.Mult(u, z);
|
||||
K->FullMult(u, z);
|
||||
z.Neg();
|
||||
|
||||
for (int i = 0; i < ess_tdof_list.Size(); i++)
|
||||
{
|
||||
z[ess_tdof_list[i]] = 0.0;
|
||||
}
|
||||
z.SetSubVector(ess_tdof_list, 0.0);
|
||||
T_solver.Mult(z, d2udt2);
|
||||
d2udt2.SetSubVector(ess_tdof_list, 0.0);
|
||||
}
|
||||
|
||||
void WaveOperator::SetParameters(const Vector &u)
|
||||
@@ -314,7 +311,6 @@ int main(int argc, char *argv[])
|
||||
ess_bdr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
WaveOperator oper(fespace, ess_bdr, speed);
|
||||
|
||||
u_gf.SetFromTrueDofs(u);
|
||||
|
||||
+2
-2
@@ -103,8 +103,8 @@ public:
|
||||
|
||||
using VectorCoefficient::Eval;
|
||||
|
||||
virtual void Eval(Vector &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip)
|
||||
void Eval(Vector &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override
|
||||
{
|
||||
real_t x[3];
|
||||
Vector transip(x, 3);
|
||||
|
||||
+2
-2
@@ -102,8 +102,8 @@ public:
|
||||
|
||||
using VectorCoefficient::Eval;
|
||||
|
||||
virtual void Eval(Vector &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip)
|
||||
void Eval(Vector &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override
|
||||
{
|
||||
real_t x[3];
|
||||
Vector transip(x, 3);
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~DiffusionMultigrid()
|
||||
~DiffusionMultigrid() override
|
||||
{
|
||||
delete amg;
|
||||
}
|
||||
|
||||
+3
-3
@@ -53,7 +53,7 @@ public:
|
||||
real_t min_val_=-36)
|
||||
: u(&u_), obstacle(&obst_), min_val(min_val_) { }
|
||||
|
||||
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
class ExponentialGridFunctionCoefficient : public Coefficient
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
real_t min_val_=0.0, real_t max_val_=1e6)
|
||||
: u(&u_), obstacle(&obst_), min_val(min_val_), max_val(max_val_) { }
|
||||
|
||||
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@@ -258,7 +258,7 @@ int main(int argc, char *argv[])
|
||||
MixedBilinearForm a10(&H1fes,&L2fes);
|
||||
a10.AddDomainIntegrator(new MixedScalarMassIntegrator());
|
||||
a10.Assemble();
|
||||
a10.EliminateTrialDofs(ess_bdr, x.GetBlock(0), rhs.GetBlock(1));
|
||||
a10.EliminateTrialEssentialBC(ess_bdr, x.GetBlock(0), rhs.GetBlock(1));
|
||||
a10.Finalize();
|
||||
SparseMatrix &A10 = a10.SpMat();
|
||||
|
||||
|
||||
+2
-2
@@ -53,7 +53,7 @@ public:
|
||||
real_t min_val_=-36)
|
||||
: u(&u_), obstacle(&obst_), min_val(min_val_) { }
|
||||
|
||||
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
class ExponentialGridFunctionCoefficient : public Coefficient
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
real_t min_val_=0.0, real_t max_val_=1e6)
|
||||
: u(&u_), obstacle(&obst_), min_val(min_val_), max_val(max_val_) { }
|
||||
|
||||
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
||||
+8
-8
@@ -52,8 +52,8 @@ public:
|
||||
fun(fun_) {}
|
||||
|
||||
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip)
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override
|
||||
{
|
||||
return fun(GridFunctionCoefficient::Eval(T, ip));
|
||||
}
|
||||
@@ -83,8 +83,8 @@ public:
|
||||
OtherGridF_cf(OtherGridF),
|
||||
fun(fun_) {}
|
||||
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip)
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override
|
||||
{
|
||||
const real_t value1 = fun(GridFunctionCoefficient::Eval(T, ip));
|
||||
const real_t value2 = fun(OtherGridF_cf.Eval(T, ip));
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
: rho_filter(rho_filter_), min_val(min_val_), max_val(max_val_),
|
||||
exponent(exponent_) { }
|
||||
|
||||
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip)
|
||||
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override
|
||||
{
|
||||
real_t val = rho_filter->GetValue(T, ip);
|
||||
real_t coeff = min_val + pow(val,exponent)*(max_val-min_val);
|
||||
@@ -142,7 +142,7 @@ public:
|
||||
MFEM_ASSERT(rho_filter, "density field is not set");
|
||||
}
|
||||
|
||||
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip)
|
||||
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override
|
||||
{
|
||||
real_t L = lambda->Eval(T, ip);
|
||||
real_t M = mu->Eval(T, ip);
|
||||
@@ -176,8 +176,8 @@ public:
|
||||
|
||||
using VectorCoefficient::Eval;
|
||||
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip)
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override
|
||||
{
|
||||
Vector xx; xx.SetSize(T.GetDimension());
|
||||
T.Transform(ip,xx);
|
||||
|
||||
+6
-6
@@ -408,9 +408,9 @@ public:
|
||||
@param [in] Tr transformation of finite element
|
||||
@param [out] elvect vector containing the
|
||||
*/
|
||||
virtual void AssembleRHSElementVect(const FiniteElement &el,
|
||||
ElementTransformation &Tr,
|
||||
Vector &elvect) override
|
||||
void AssembleRHSElementVect(const FiniteElement &el,
|
||||
ElementTransformation &Tr,
|
||||
Vector &elvect) override
|
||||
{
|
||||
int dof = el.GetDof();
|
||||
shape.SetSize(dof);
|
||||
@@ -476,9 +476,9 @@ public:
|
||||
@param [in] Tr transformation of finite element
|
||||
@param [out] elvect vector containing the
|
||||
*/
|
||||
virtual void AssembleRHSElementVect(const FiniteElement &el,
|
||||
ElementTransformation &Tr,
|
||||
Vector &elvect) override
|
||||
void AssembleRHSElementVect(const FiniteElement &el,
|
||||
ElementTransformation &Tr,
|
||||
Vector &elvect) override
|
||||
{
|
||||
int dof = el.GetDof();
|
||||
shape.SetSize(dof);
|
||||
|
||||
+6
-4
@@ -67,8 +67,10 @@ public:
|
||||
ZCoefficient(int vdim, GridFunction &psi_, real_t alpha_ = 1.0)
|
||||
: VectorCoefficient(vdim), psi(&psi_), alpha(alpha_) { }
|
||||
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
using VectorCoefficient::Eval;
|
||||
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
void SetAlpha(real_t alpha_) { alpha = alpha_; }
|
||||
};
|
||||
|
||||
@@ -82,8 +84,8 @@ public:
|
||||
DZCoefficient(int height, GridFunction &psi_, real_t alpha_ = 1.0)
|
||||
: MatrixCoefficient(height), psi(&psi_), alpha(alpha_) { }
|
||||
|
||||
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(DenseMatrix &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
void SetAlpha(real_t alpha_) { alpha = alpha_; }
|
||||
};
|
||||
|
||||
|
||||
+6
-4
@@ -67,8 +67,10 @@ public:
|
||||
ZCoefficient(int vdim, ParGridFunction &psi_, real_t alpha_ = 1.0)
|
||||
: VectorCoefficient(vdim), psi(&psi_), alpha(alpha_) { }
|
||||
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
using VectorCoefficient::Eval;
|
||||
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
void SetAlpha(real_t alpha_) { alpha = alpha_; }
|
||||
};
|
||||
|
||||
@@ -82,8 +84,8 @@ public:
|
||||
DZCoefficient(int height, ParGridFunction &psi_, real_t alpha_ = 1.0)
|
||||
: MatrixCoefficient(height), psi(&psi_), alpha(alpha_) { }
|
||||
|
||||
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(DenseMatrix &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
void SetAlpha(real_t alpha_) { alpha = alpha_; }
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -157,7 +157,7 @@ int main(int argc, char *argv[])
|
||||
MixedBilinearForm *B0 = new MixedBilinearForm(x0_space,test_space);
|
||||
B0->AddDomainIntegrator(new DiffusionIntegrator(one));
|
||||
B0->Assemble();
|
||||
B0->EliminateTrialDofs(ess_bdr, x.GetBlock(x0_var), F);
|
||||
B0->EliminateTrialEssentialBC(ess_bdr, x.GetBlock(x0_var), F);
|
||||
B0->Finalize();
|
||||
|
||||
MixedBilinearForm *Bhat = new MixedBilinearForm(xhat_space,test_space);
|
||||
|
||||
+5
-5
@@ -104,12 +104,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void SetOperator(const Operator &op)
|
||||
void SetOperator(const Operator &op) override
|
||||
{
|
||||
linear_solver.SetOperator(op);
|
||||
}
|
||||
|
||||
virtual void Mult(const Vector &x, Vector &y) const
|
||||
void Mult(const Vector &x, Vector &y) const override
|
||||
{
|
||||
linear_solver.Mult(x, y);
|
||||
}
|
||||
@@ -134,10 +134,10 @@ private:
|
||||
public:
|
||||
FE_Evolution(BilinearForm &M_, BilinearForm &K_, const Vector &b_);
|
||||
|
||||
virtual void Mult(const Vector &x, Vector &y) const;
|
||||
virtual void ImplicitSolve(const real_t dt, const Vector &x, Vector &k);
|
||||
void Mult(const Vector &x, Vector &y) const override;
|
||||
void ImplicitSolve(const real_t dt, const Vector &x, Vector &k) override;
|
||||
|
||||
virtual ~FE_Evolution();
|
||||
~FE_Evolution() override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
+9
-9
@@ -92,7 +92,7 @@ private:
|
||||
public:
|
||||
AIR_prec(int blocksize_) : AIR_solver(NULL), blocksize(blocksize_) { }
|
||||
|
||||
void SetOperator(const Operator &op)
|
||||
void SetOperator(const Operator &op) override
|
||||
{
|
||||
width = op.Width();
|
||||
height = op.Height();
|
||||
@@ -110,7 +110,7 @@ public:
|
||||
AIR_solver->SetMaxLevels(50);
|
||||
}
|
||||
|
||||
virtual void Mult(const Vector &x, Vector &y) const
|
||||
void Mult(const Vector &x, Vector &y) const override
|
||||
{
|
||||
// Scale the rhs by block inverse and solve system
|
||||
HypreParVector z_s;
|
||||
@@ -119,7 +119,7 @@ public:
|
||||
AIR_solver->Mult(z_s, y);
|
||||
}
|
||||
|
||||
~AIR_prec()
|
||||
~AIR_prec() override
|
||||
{
|
||||
delete AIR_solver;
|
||||
}
|
||||
@@ -185,17 +185,17 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void SetOperator(const Operator &op)
|
||||
void SetOperator(const Operator &op) override
|
||||
{
|
||||
linear_solver.SetOperator(op);
|
||||
}
|
||||
|
||||
virtual void Mult(const Vector &x, Vector &y) const
|
||||
void Mult(const Vector &x, Vector &y) const override
|
||||
{
|
||||
linear_solver.Mult(x, y);
|
||||
}
|
||||
|
||||
~DG_Solver()
|
||||
~DG_Solver() override
|
||||
{
|
||||
delete prec;
|
||||
delete A;
|
||||
@@ -223,10 +223,10 @@ public:
|
||||
FE_Evolution(ParBilinearForm &M_, ParBilinearForm &K_, const Vector &b_,
|
||||
PrecType prec_type);
|
||||
|
||||
virtual void Mult(const Vector &x, Vector &y) const;
|
||||
virtual void ImplicitSolve(const real_t dt, const Vector &x, Vector &k);
|
||||
void Mult(const Vector &x, Vector &y) const override;
|
||||
void ImplicitSolve(const real_t dt, const Vector &x, Vector &k) override;
|
||||
|
||||
virtual ~FE_Evolution();
|
||||
~FE_Evolution() override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -12,11 +12,10 @@
|
||||
# Use the MFEM build directory
|
||||
MFEM_DIR ?= ../..
|
||||
MFEM_BUILD_DIR ?= ../..
|
||||
MFEM_INSTALL_DIR ?= ../../mfem
|
||||
SRC = $(if $(MFEM_DIR:../..=),$(MFEM_DIR)/examples/ginkgo/,)
|
||||
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
|
||||
# Use the MFEM install directory
|
||||
# MFEM_INSTALL_DIR = ../../mfem
|
||||
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
|
||||
CONFIG_MK = $(or $(wildcard $(MFEM_BUILD_DIR)/config/config.mk),\
|
||||
$(wildcard $(MFEM_INSTALL_DIR)/share/mfem/config.mk))
|
||||
|
||||
MFEM_LIB_FILE = mfem_is_not_built
|
||||
-include $(CONFIG_MK)
|
||||
|
||||
@@ -96,6 +96,7 @@ public:
|
||||
{
|
||||
Vector w_glob(width);
|
||||
pfes.Dof_TrueDof_Matrix()->MultTranspose(w, w_glob);
|
||||
w_glob.HostReadWrite(); // read+write -> can use w_glob(i) (non-const)
|
||||
for (int i = 0; i < width; i++) { grad(0, i) = w_glob(i); }
|
||||
}
|
||||
|
||||
|
||||
@@ -12,11 +12,10 @@
|
||||
# Use the MFEM build directory
|
||||
MFEM_DIR ?= ../..
|
||||
MFEM_BUILD_DIR ?= ../..
|
||||
MFEM_INSTALL_DIR ?= ../../mfem
|
||||
SRC = $(if $(MFEM_DIR:../..=),$(MFEM_DIR)/examples/hiop/,)
|
||||
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
|
||||
# Use the MFEM install directory
|
||||
# MFEM_INSTALL_DIR = ../../mfem
|
||||
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
|
||||
CONFIG_MK = $(or $(wildcard $(MFEM_BUILD_DIR)/config/config.mk),\
|
||||
$(wildcard $(MFEM_INSTALL_DIR)/share/mfem/config.mk))
|
||||
|
||||
MFEM_LIB_FILE = mfem_is_not_built
|
||||
-include $(CONFIG_MK)
|
||||
|
||||
+3
-4
@@ -12,11 +12,10 @@
|
||||
# Use the MFEM build directory
|
||||
MFEM_DIR ?= ..
|
||||
MFEM_BUILD_DIR ?= ..
|
||||
MFEM_INSTALL_DIR ?= ../mfem
|
||||
SRC = $(if $(MFEM_DIR:..=),$(MFEM_DIR)/examples/,)
|
||||
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
|
||||
# Use the MFEM install directory
|
||||
# MFEM_INSTALL_DIR = ../mfem
|
||||
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
|
||||
CONFIG_MK = $(or $(wildcard $(MFEM_BUILD_DIR)/config/config.mk),\
|
||||
$(wildcard $(MFEM_INSTALL_DIR)/share/mfem/config.mk))
|
||||
|
||||
MFEM_LIB_FILE = mfem_is_not_built
|
||||
-include $(CONFIG_MK)
|
||||
|
||||
@@ -12,11 +12,10 @@
|
||||
# Use the MFEM build directory
|
||||
MFEM_DIR ?= ../..
|
||||
MFEM_BUILD_DIR ?= ../..
|
||||
MFEM_INSTALL_DIR ?= ../../mfem
|
||||
SRC = $(if $(MFEM_DIR:../..=),$(MFEM_DIR)/examples/moonolith/,)
|
||||
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
|
||||
# Use the MFEM install directory
|
||||
# MFEM_INSTALL_DIR = ../../mfem
|
||||
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
|
||||
CONFIG_MK = $(or $(wildcard $(MFEM_BUILD_DIR)/config/config.mk),\
|
||||
$(wildcard $(MFEM_INSTALL_DIR)/share/mfem/config.mk))
|
||||
|
||||
MFEM_LIB_FILE = mfem_is_not_built
|
||||
-include $(CONFIG_MK)
|
||||
|
||||
@@ -206,6 +206,7 @@ int main(int argc, char *argv[])
|
||||
bool use_petsc = true;
|
||||
const char *petscrc_file = "";
|
||||
bool petsc_use_jfnk = false;
|
||||
const char *device_config = "cpu";
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
@@ -243,6 +244,8 @@ int main(int argc, char *argv[])
|
||||
args.AddOption(&petsc_use_jfnk, "-jfnk", "--jfnk", "-no-jfnk",
|
||||
"--no-jfnk",
|
||||
"Use JFNK with user-defined preconditioner factory.");
|
||||
args.AddOption(&device_config, "-d", "--device",
|
||||
"Device configuration string, see Device::Configure().");
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
@@ -257,7 +260,12 @@ int main(int argc, char *argv[])
|
||||
args.PrintOptions(cout);
|
||||
}
|
||||
|
||||
// 2b. We initialize PETSc
|
||||
// 2b. Enable hardware devices such as GPUs, and programming models such as
|
||||
// CUDA, OCCA, RAJA and OpenMP based on command line options.
|
||||
Device device(device_config);
|
||||
if (myid == 0) { device.Print(); }
|
||||
|
||||
// 2c. We initialize PETSc
|
||||
if (use_petsc)
|
||||
{
|
||||
MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL);
|
||||
|
||||
@@ -67,6 +67,7 @@ int main(int argc, char *argv[])
|
||||
bool use_petsc = true;
|
||||
const char *petscrc_file = "";
|
||||
bool use_nonoverlapping = false;
|
||||
const char *device_config = "cpu";
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
@@ -95,6 +96,8 @@ int main(int argc, char *argv[])
|
||||
"-no-nonoverlapping", "--no-nonoverlapping",
|
||||
"Use or not the block diagonal PETSc's matrix format "
|
||||
"for non-overlapping domain decomposition.");
|
||||
args.AddOption(&device_config, "-d", "--device",
|
||||
"Device configuration string, see Device::Configure().");
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
@@ -109,7 +112,12 @@ int main(int argc, char *argv[])
|
||||
args.PrintOptions(cout);
|
||||
}
|
||||
|
||||
// 2b. We initialize PETSc
|
||||
// 2b. Enable hardware devices such as GPUs, and programming models such as
|
||||
// CUDA, OCCA, RAJA and OpenMP based on command line options.
|
||||
Device device(device_config);
|
||||
if (myid == 0) { device.Print(); }
|
||||
|
||||
// 2c. We initialize PETSc
|
||||
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
|
||||
|
||||
// 3. Read the (serial) mesh from the given mesh file on all processors. We
|
||||
|
||||
+11
-2
@@ -61,6 +61,7 @@ int main(int argc, char *argv[])
|
||||
bool use_petsc = true;
|
||||
const char *petscrc_file = "";
|
||||
bool use_nonoverlapping = false;
|
||||
const char *device_config = "cpu";
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
@@ -87,6 +88,8 @@ int main(int argc, char *argv[])
|
||||
"-no-nonoverlapping", "--no-nonoverlapping",
|
||||
"Use or not the block diagonal PETSc's matrix format "
|
||||
"for non-overlapping domain decomposition.");
|
||||
args.AddOption(&device_config, "-d", "--device",
|
||||
"Device configuration string, see Device::Configure().");
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
@@ -100,10 +103,16 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
args.PrintOptions(cout);
|
||||
}
|
||||
// 2b. We initialize PETSc
|
||||
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
|
||||
kappa = freq * M_PI;
|
||||
|
||||
// 2b. Enable hardware devices such as GPUs, and programming models such as
|
||||
// CUDA, OCCA, RAJA and OpenMP based on command line options.
|
||||
Device device(device_config);
|
||||
if (myid == 0) { device.Print(); }
|
||||
|
||||
// 2c. We initialize PETSc
|
||||
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
|
||||
|
||||
// 3. Read the (serial) mesh from the given mesh file on all processors. We
|
||||
// can handle triangular, quadrilateral, tetrahedral, hexahedral, surface
|
||||
// and volume meshes with the same code.
|
||||
|
||||
+11
-2
@@ -58,6 +58,7 @@ int main(int argc, char *argv[])
|
||||
bool use_petsc = true;
|
||||
const char *petscrc_file = "";
|
||||
bool use_nonoverlapping = false;
|
||||
const char *device_config = "cpu";
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
@@ -88,6 +89,8 @@ int main(int argc, char *argv[])
|
||||
"-no-nonoverlapping", "--no-nonoverlapping",
|
||||
"Use or not the block diagonal PETSc's matrix format "
|
||||
"for non-overlapping domain decomposition.");
|
||||
args.AddOption(&device_config, "-d", "--device",
|
||||
"Device configuration string, see Device::Configure().");
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
@@ -101,10 +104,16 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
args.PrintOptions(cout);
|
||||
}
|
||||
// 2b. We initialize PETSc
|
||||
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
|
||||
kappa = freq * M_PI;
|
||||
|
||||
// 2b. Enable hardware devices such as GPUs, and programming models such as
|
||||
// CUDA, OCCA, RAJA and OpenMP based on command line options.
|
||||
Device device(device_config);
|
||||
if (myid == 0) { device.Print(); }
|
||||
|
||||
// 2c. We initialize PETSc
|
||||
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
|
||||
|
||||
// 3. Read the (serial) mesh from the given mesh file on all processors. We
|
||||
// can handle triangular, quadrilateral, tetrahedral, hexahedral, surface
|
||||
// and volume, as well as periodic meshes with the same code.
|
||||
|
||||
+28
-7
@@ -59,6 +59,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
// 2. Parse command-line options.
|
||||
const char *mesh_file = "../../data/star.mesh";
|
||||
int ser_ref_levels = -1;
|
||||
int par_ref_levels = 2;
|
||||
int order = 1;
|
||||
bool par_format = false;
|
||||
bool visualization = 1;
|
||||
@@ -66,15 +68,22 @@ int main(int argc, char *argv[])
|
||||
bool use_nonoverlapping = false;
|
||||
bool local_bdr_spec = false;
|
||||
const char *petscrc_file = "";
|
||||
const char *device_config = "cpu";
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
"Mesh file to use.");
|
||||
args.AddOption(&ser_ref_levels, "-rs", "--refine-serial",
|
||||
"Number of times to refine the mesh uniformly in serial.");
|
||||
args.AddOption(&par_ref_levels, "-rp", "--refine-parallel",
|
||||
"Number of times to refine the mesh uniformly in parallel.");
|
||||
args.AddOption(&order, "-o", "--order",
|
||||
"Finite element order (polynomial degree).");
|
||||
args.AddOption(&par_format, "-pf", "--parallel-format", "-sf",
|
||||
"--serial-format",
|
||||
"Format to use when saving the results for VisIt.");
|
||||
args.AddOption(&device_config, "-d", "--device",
|
||||
"Device configuration string, see Device::Configure().");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
@@ -103,7 +112,13 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
args.PrintOptions(cout);
|
||||
}
|
||||
// 2b. We initialize PETSc
|
||||
|
||||
// 2b. Enable hardware devices such as GPUs, and programming models such as
|
||||
// CUDA, OCCA, RAJA and OpenMP based on command line options.
|
||||
Device device(device_config);
|
||||
if (myid == 0) { device.Print(); }
|
||||
|
||||
// 2c. We initialize PETSc
|
||||
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
|
||||
|
||||
// 3. Read the (serial) mesh from the given mesh file on all processors. We
|
||||
@@ -117,9 +132,11 @@ int main(int argc, char *argv[])
|
||||
// 'ref_levels' to be the largest number that gives a final mesh with no
|
||||
// more than 10,000 elements.
|
||||
{
|
||||
int ref_levels =
|
||||
(int)floor(log(10000./mesh->GetNE())/log(2.)/dim);
|
||||
for (int l = 0; l < ref_levels; l++)
|
||||
if (ser_ref_levels < 0)
|
||||
{
|
||||
ser_ref_levels = (int)floor(log(10000./mesh->GetNE())/log(2.)/dim);
|
||||
}
|
||||
for (int l = 0; l < ser_ref_levels; l++)
|
||||
{
|
||||
mesh->UniformRefinement();
|
||||
}
|
||||
@@ -131,7 +148,6 @@ int main(int argc, char *argv[])
|
||||
ParMesh *pmesh = new ParMesh(MPI_COMM_WORLD, *mesh);
|
||||
delete mesh;
|
||||
{
|
||||
int par_ref_levels = 2;
|
||||
for (int l = 0; l < par_ref_levels; l++)
|
||||
{
|
||||
pmesh->UniformRefinement();
|
||||
@@ -187,21 +203,26 @@ int main(int argc, char *argv[])
|
||||
|
||||
// 9. Define the parallel grid function and parallel linear forms, solution
|
||||
// vector and rhs.
|
||||
BlockVector x(block_offsets), rhs(block_offsets);
|
||||
BlockVector trueX(block_trueOffsets), trueRhs(block_trueOffsets);
|
||||
MemoryType mt = device.GetMemoryType();
|
||||
BlockVector x(block_offsets, mt), rhs(block_offsets, mt);
|
||||
BlockVector trueX(block_trueOffsets, mt), trueRhs(block_trueOffsets, mt);
|
||||
|
||||
ParLinearForm *fform(new ParLinearForm);
|
||||
fform->Update(R_space, rhs.GetBlock(0), 0);
|
||||
fform->AddDomainIntegrator(new VectorFEDomainLFIntegrator(fcoeff));
|
||||
fform->AddBoundaryIntegrator(new VectorFEBoundaryFluxLFIntegrator(fnatcoeff));
|
||||
fform->Assemble();
|
||||
fform->SyncAliasMemory(rhs);
|
||||
fform->ParallelAssemble(trueRhs.GetBlock(0));
|
||||
trueRhs.GetBlock(0).SyncAliasMemory(trueRhs);
|
||||
|
||||
ParLinearForm *gform(new ParLinearForm);
|
||||
gform->Update(W_space, rhs.GetBlock(1), 0);
|
||||
gform->AddDomainIntegrator(new DomainLFIntegrator(gcoeff));
|
||||
gform->Assemble();
|
||||
gform->SyncAliasMemory(rhs);
|
||||
gform->ParallelAssemble(trueRhs.GetBlock(1));
|
||||
trueRhs.GetBlock(1).SyncAliasMemory(trueRhs);
|
||||
|
||||
// 10. Assemble the finite element matrices for the Darcy operator
|
||||
//
|
||||
|
||||
+10
-1
@@ -53,6 +53,7 @@ int main(int argc, char *argv[])
|
||||
bool use_petsc = true;
|
||||
const char *petscrc_file = "";
|
||||
bool use_nonoverlapping = false;
|
||||
const char *device_config = "cpu";
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
@@ -73,6 +74,8 @@ int main(int argc, char *argv[])
|
||||
"-no-nonoverlapping", "--no-nonoverlapping",
|
||||
"Use or not the block diagonal PETSc's matrix format "
|
||||
"for non-overlapping domain decomposition.");
|
||||
args.AddOption(&device_config, "-d", "--device",
|
||||
"Device configuration string, see Device::Configure().");
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
@@ -86,7 +89,13 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
args.PrintOptions(cout);
|
||||
}
|
||||
// 2b. We initialize PETSc
|
||||
|
||||
// 2b. Enable hardware devices such as GPUs, and programming models such as
|
||||
// CUDA, OCCA, RAJA and OpenMP based on command line options.
|
||||
Device device(device_config);
|
||||
if (myid == 0) { device.Print(); }
|
||||
|
||||
// 2c. We initialize PETSc
|
||||
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
|
||||
|
||||
// 3. Read the (serial) mesh from the given mesh file on all processors. We
|
||||
|
||||
@@ -12,11 +12,10 @@
|
||||
# Use the MFEM build directory
|
||||
MFEM_DIR ?= ../..
|
||||
MFEM_BUILD_DIR ?= ../..
|
||||
MFEM_INSTALL_DIR ?= ../../mfem
|
||||
SRC = $(if $(MFEM_DIR:../..=),$(MFEM_DIR)/examples/petsc/,)
|
||||
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
|
||||
# Use the MFEM install directory
|
||||
# MFEM_INSTALL_DIR = ../../mfem
|
||||
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
|
||||
CONFIG_MK = $(or $(wildcard $(MFEM_BUILD_DIR)/config/config.mk),\
|
||||
$(wildcard $(MFEM_INSTALL_DIR)/share/mfem/config.mk))
|
||||
|
||||
MFEM_LIB_FILE = mfem_is_not_built
|
||||
-include $(CONFIG_MK)
|
||||
|
||||
@@ -66,7 +66,6 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
// 1. Initialize MPI (required by PUMI) and HYPRE.
|
||||
Mpi::Init(argc, argv);
|
||||
int num_procs = Mpi::WorldSize();
|
||||
int myid = Mpi::WorldRank();
|
||||
Hypre::Init();
|
||||
|
||||
|
||||
@@ -80,8 +80,6 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
// 1. Initialize MPI (required by PUMI) and HYPRE.
|
||||
Mpi::Init(argc, argv);
|
||||
int num_proc = Mpi::WorldSize();
|
||||
int myId = Mpi::WorldRank();
|
||||
Hypre::Init();
|
||||
|
||||
// 2. Parse command-line options.
|
||||
|
||||
@@ -12,11 +12,10 @@
|
||||
# Use the MFEM build directory
|
||||
MFEM_DIR ?= ../..
|
||||
MFEM_BUILD_DIR ?= ../..
|
||||
MFEM_INSTALL_DIR ?= ../../mfem
|
||||
SRC = $(if $(MFEM_DIR:../..=),$(MFEM_DIR)/examples/pumi/,)
|
||||
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
|
||||
# Use the MFEM install directory
|
||||
# MFEM_INSTALL_DIR = ../../mfem
|
||||
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
|
||||
CONFIG_MK = $(or $(wildcard $(MFEM_BUILD_DIR)/config/config.mk),\
|
||||
$(wildcard $(MFEM_INSTALL_DIR)/share/mfem/config.mk))
|
||||
|
||||
MFEM_LIB_FILE = mfem_is_not_built
|
||||
-include $(CONFIG_MK)
|
||||
|
||||
@@ -31,11 +31,21 @@ include_directories(BEFORE ${PROJECT_BINARY_DIR})
|
||||
add_custom_target(test_sundials
|
||||
${CMAKE_CTEST_COMMAND} -R sundials USES_TERMINAL)
|
||||
|
||||
# Add one executable per cpp file, adding "sundials_" as prefix. Sets
|
||||
# "test_sundials" as a target that depends on the given examples.
|
||||
# Add one executable per cpp file, adding "sundials_" as prefix so the CMake
|
||||
# target is unique from those in the non-SUNDIALS examples. Also sets
|
||||
# "test_sundials" as a target that depends on the given SUNDIALS examples.
|
||||
set(PFX sundials_)
|
||||
add_mfem_examples(SUNDIALS_EXAMPLES_SRCS ${PFX} "" test_sundials)
|
||||
|
||||
# Remove "sundials_" prefix from exectuable name for consistency with GNU build
|
||||
# system.
|
||||
foreach(SRC_FILE ${SUNDIALS_EXAMPLES_SRCS})
|
||||
get_filename_component(SRC_FILENAME ${SRC_FILE} NAME)
|
||||
string(REPLACE ".cpp" "" TARGET_NAME "${PFX}${SRC_FILENAME}")
|
||||
string(REPLACE ${PFX} "" EXE_NAME ${TARGET_NAME})
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME ${EXE_NAME})
|
||||
endforeach()
|
||||
|
||||
# Testing.
|
||||
# The SUNDIALS tests can be run separately using the target "test_sundials"
|
||||
# which builds the examples and runs:
|
||||
@@ -51,7 +61,10 @@ if (MFEM_ENABLE_TESTING)
|
||||
set(EX10_COMMON_OPTS -m ../../data/beam-quad.mesh -o 2 -s 5 -dt 0.15 -tf 6 -vs 10)
|
||||
set(EX10_TEST_OPTS ${EX10_COMMON_OPTS} -r 2)
|
||||
set(EX10P_TEST_OPTS ${EX10_COMMON_OPTS} -rp 1)
|
||||
# Example 16: use the default options
|
||||
# Example 16: test ARKODE with implicit time stepping using mass form
|
||||
set(EX16_COMMON_OPTS -s 15)
|
||||
set(EX16_TEST_OPTS ${EX16_COMMON_OPTS})
|
||||
set(EX16P_TEST_OPTS ${EX16_COMMON_OPTS})
|
||||
|
||||
# Add the tests: one test per source file.
|
||||
foreach(SRC_FILE ${SUNDIALS_EXAMPLES_SRCS})
|
||||
|
||||
+108
-50
@@ -1,15 +1,17 @@
|
||||
// MFEM Example 10
|
||||
// SUNDIALS Modification
|
||||
//
|
||||
// Compile with: make ex10
|
||||
// Compile with:
|
||||
// make ex10 (GNU make)
|
||||
// make sundials_ex10 (CMake)
|
||||
//
|
||||
// Sample runs:
|
||||
// ex10 -m ../../data/beam-quad.mesh -r 2 -o 2 -s 12 -dt 0.15 -vs 10
|
||||
// ex10 -m ../../data/beam-tri.mesh -r 2 -o 2 -s 16 -dt 0.3 -vs 5
|
||||
// ex10 -m ../../data/beam-hex.mesh -r 1 -o 2 -s 12 -dt 0.2 -vs 5
|
||||
// ex10 -m ../../data/beam-tri.mesh -r 2 -o 2 -s 2 -dt 3 -nls kinsol
|
||||
// ex10 -m ../../data/beam-quad.mesh -r 2 -o 2 -s 2 -dt 3 -nls kinsol
|
||||
// ex10 -m ../../data/beam-hex.mesh -r 1 -o 2 -s 2 -dt 3 -nls kinsol
|
||||
// ex10 -m ../../data/beam-tri.mesh -r 2 -o 2 -s 2 -dt 3 -nls 1
|
||||
// ex10 -m ../../data/beam-quad.mesh -r 2 -o 2 -s 2 -dt 3 -nls 2
|
||||
// ex10 -m ../../data/beam-hex.mesh -r 1 -o 2 -s 2 -dt 3 -nls 4
|
||||
// ex10 -m ../../data/beam-quad.mesh -r 2 -o 2 -s 14 -dt 0.15 -vs 10
|
||||
// ex10 -m ../../data/beam-tri.mesh -r 2 -o 2 -s 17 -dt 0.01 -vs 30
|
||||
// ex10 -m ../../data/beam-hex.mesh -r 1 -o 2 -s 14 -dt 0.15 -vs 10
|
||||
@@ -97,16 +99,11 @@ protected:
|
||||
double saved_gamma; // saved gamma value from implicit setup
|
||||
|
||||
public:
|
||||
/// Solver type to use in the ImplicitSolve() method, used by SDIRK methods.
|
||||
enum NonlinearSolverType
|
||||
{
|
||||
NEWTON = 0, ///< Use MFEM's plain NewtonSolver
|
||||
KINSOL = 1 ///< Use SUNDIALS' KINSOL (through MFEM's class KINSolver)
|
||||
};
|
||||
|
||||
HyperelasticOperator(FiniteElementSpace &f, Array<int> &ess_bdr,
|
||||
double visc, double mu, double K,
|
||||
NonlinearSolverType nls_type);
|
||||
int kinsol_nls_type = -1, double kinsol_damping = 0.0,
|
||||
int kinsol_aa_n = 0);
|
||||
|
||||
/// Compute the right-hand side of the ODE system.
|
||||
virtual void Mult(const Vector &vx, Vector &dvx_dt) const;
|
||||
@@ -224,8 +221,10 @@ int main(int argc, char *argv[])
|
||||
double mu = 0.25;
|
||||
double K = 5.0;
|
||||
bool visualization = true;
|
||||
const char *nls = "newton";
|
||||
int nonlinear_solver_type = 0;
|
||||
int vis_steps = 1;
|
||||
double kinsol_damping = 0.0;
|
||||
int kinsol_aa_n = -1;
|
||||
|
||||
// Relative and absolute tolerances for CVODE and ARKODE.
|
||||
const double reltol = 1e-1, abstol = 1e-1;
|
||||
@@ -262,9 +261,18 @@ int main(int argc, char *argv[])
|
||||
"15 - ARKODE implicit, approximate Jacobian,\n\t"
|
||||
"16 - ARKODE implicit, specified Jacobian,\n\t"
|
||||
"17 - ARKODE explicit, 4th order.");
|
||||
args.AddOption(&nls, "-nls", "--nonlinear-solver",
|
||||
"Nonlinear systems solver: "
|
||||
"\"newton\" (plain Newton) or \"kinsol\" (KINSOL).");
|
||||
args.AddOption(&nonlinear_solver_type, "-nls", "--nonlinear-solver",
|
||||
"Nonlinear system solver:\n\t"
|
||||
"0 - MFEM Newton method,\n\t"
|
||||
"1 - KINSOL Newton method,\n\t"
|
||||
"2 - KINSOL Newton method with globalization,\n\t"
|
||||
"3 - KINSOL fixed-point method (with or without AA),\n\t"
|
||||
"4 - KINSOL Picard method (with or without AA).");
|
||||
args.AddOption(&kinsol_damping, "-damp", "--kinsol-damping",
|
||||
"Picard or Fixed-Point damping parameter (only valid with KINSOL): "
|
||||
"0 < d <= 1.0");
|
||||
args.AddOption(&kinsol_aa_n, "-aan", "--anderson-subspace",
|
||||
"Anderson Acceleration subspace size (only valid with KINSOL)");
|
||||
args.AddOption(&t_final, "-tf", "--t-final",
|
||||
"Final time; start time is 0.");
|
||||
args.AddOption(&dt, "-dt", "--time-step",
|
||||
@@ -295,22 +303,32 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
// check for valid nonlinear solver options
|
||||
if (nonlinear_solver_type < 0 || nonlinear_solver_type > 4)
|
||||
{
|
||||
cout << "Unknown nonlinear solver type: " << nonlinear_solver_type << "\n";
|
||||
return 1;
|
||||
}
|
||||
if (kinsol_damping > 0.0 &&
|
||||
!(nonlinear_solver_type == 3 || nonlinear_solver_type == 4))
|
||||
{
|
||||
cout << "Only KINSOL fixed-point and Picard methods can use damping\n";
|
||||
return 1;
|
||||
}
|
||||
if (kinsol_aa_n > 0 &&
|
||||
!(nonlinear_solver_type == 3 || nonlinear_solver_type == 4))
|
||||
{
|
||||
cout << "Only KINSOL fixed-point and Picard methods can use AA\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// 2. Read the mesh from the given mesh file. We can handle triangular,
|
||||
// quadrilateral, tetrahedral and hexahedral meshes with the same code.
|
||||
Mesh *mesh = new Mesh(mesh_file, 1, 1);
|
||||
int dim = mesh->Dimension();
|
||||
|
||||
// 3. Setup the nonlinear solver
|
||||
map<string,HyperelasticOperator::NonlinearSolverType> nls_map;
|
||||
nls_map["newton"] = HyperelasticOperator::NEWTON;
|
||||
nls_map["kinsol"] = HyperelasticOperator::KINSOL;
|
||||
if (nls_map.find(nls) == nls_map.end())
|
||||
{
|
||||
cout << "Unknown type of nonlinear solver: " << nls << endl;
|
||||
return 4;
|
||||
}
|
||||
|
||||
// 4. Refine the mesh to increase the resolution. In this example we do
|
||||
// 3. Refine the mesh to increase the resolution. In this example we do
|
||||
// 'ref_levels' of uniform refinement, where 'ref_levels' is a
|
||||
// command-line parameter.
|
||||
for (int lev = 0; lev < ref_levels; lev++)
|
||||
@@ -318,7 +336,7 @@ int main(int argc, char *argv[])
|
||||
mesh->UniformRefinement();
|
||||
}
|
||||
|
||||
// 5. Define the vector finite element spaces representing the mesh
|
||||
// 4. Define the vector finite element spaces representing the mesh
|
||||
// deformation x, the velocity v, and the initial configuration, x_ref.
|
||||
// Define also the elastic energy density, w, which is in a discontinuous
|
||||
// higher-order space. Since x and v are integrated in time as a system,
|
||||
@@ -346,7 +364,7 @@ int main(int argc, char *argv[])
|
||||
FiniteElementSpace w_fespace(mesh, &w_fec);
|
||||
GridFunction w(&w_fespace);
|
||||
|
||||
// 6. Set the initial conditions for v and x, and the boundary conditions on
|
||||
// 5. Set the initial conditions for v and x, and the boundary conditions on
|
||||
// a beam-like mesh (see description above).
|
||||
VectorFunctionCoefficient velo(dim, InitialVelocity);
|
||||
v.ProjectCoefficient(velo);
|
||||
@@ -359,9 +377,34 @@ int main(int argc, char *argv[])
|
||||
ess_bdr = 0;
|
||||
ess_bdr[0] = 1; // boundary attribute 1 (index 0) is fixed
|
||||
|
||||
// 7. Initialize the hyperelastic operator, the GLVis visualization and print
|
||||
// 6. Initialize the hyperelastic operator, the GLVis visualization and print
|
||||
// the initial energies.
|
||||
HyperelasticOperator oper(fespace, ess_bdr, visc, mu, K, nls_map[nls]);
|
||||
std::unique_ptr<HyperelasticOperator> oper;
|
||||
if (nonlinear_solver_type == 0)
|
||||
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr, visc, mu,
|
||||
K);
|
||||
else
|
||||
{
|
||||
switch (nonlinear_solver_type)
|
||||
{
|
||||
case 1:
|
||||
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
|
||||
visc, mu, K, KIN_NONE);
|
||||
break;
|
||||
case 2:
|
||||
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
|
||||
visc, mu, K, KIN_LINESEARCH);
|
||||
break;
|
||||
case 3:
|
||||
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
|
||||
visc, mu, K, KIN_FP, kinsol_damping, kinsol_aa_n);
|
||||
break;
|
||||
case 4:
|
||||
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
|
||||
visc, mu, K, KIN_PICARD, kinsol_damping, kinsol_aa_n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
socketstream vis_v, vis_w;
|
||||
if (visualization)
|
||||
@@ -375,23 +418,23 @@ int main(int argc, char *argv[])
|
||||
vis_w.open(vishost, visport);
|
||||
if (vis_w)
|
||||
{
|
||||
oper.GetElasticEnergyDensity(x, w);
|
||||
oper->GetElasticEnergyDensity(x, w);
|
||||
vis_w.precision(8);
|
||||
visualize(vis_w, mesh, &x, &w, "Elastic energy density", true);
|
||||
}
|
||||
}
|
||||
|
||||
double ee0 = oper.ElasticEnergy(x.GetTrueVector());
|
||||
double ke0 = oper.KineticEnergy(v.GetTrueVector());
|
||||
double ee0 = oper->ElasticEnergy(x.GetTrueVector());
|
||||
double ke0 = oper->KineticEnergy(v.GetTrueVector());
|
||||
cout << "initial elastic energy (EE) = " << ee0 << endl;
|
||||
cout << "initial kinetic energy (KE) = " << ke0 << endl;
|
||||
cout << "initial total energy (TE) = " << (ee0 + ke0) << endl;
|
||||
|
||||
// 8. Define the ODE solver used for time integration. Several implicit
|
||||
// 7. Define the ODE solver used for time integration. Several implicit
|
||||
// singly diagonal implicit Runge-Kutta (SDIRK) methods, as well as
|
||||
// explicit Runge-Kutta methods are available.
|
||||
double t = 0.0;
|
||||
oper.SetTime(t);
|
||||
oper->SetTime(t);
|
||||
|
||||
ODESolver *ode_solver = NULL;
|
||||
CVODESolver *cvode = NULL;
|
||||
@@ -415,7 +458,7 @@ int main(int argc, char *argv[])
|
||||
case 11:
|
||||
case 12:
|
||||
cvode = new CVODESolver(CV_BDF);
|
||||
cvode->Init(oper);
|
||||
cvode->Init(*oper);
|
||||
cvode->SetSStolerances(reltol, abstol);
|
||||
CVodeSetEpsLin(cvode->GetMem(), cvode_eps_lin);
|
||||
cvode->SetMaxStep(dt);
|
||||
@@ -428,7 +471,7 @@ int main(int argc, char *argv[])
|
||||
case 13:
|
||||
case 14:
|
||||
cvode = new CVODESolver(CV_ADAMS);
|
||||
cvode->Init(oper);
|
||||
cvode->Init(*oper);
|
||||
cvode->SetSStolerances(reltol, abstol);
|
||||
CVodeSetEpsLin(cvode->GetMem(), cvode_eps_lin);
|
||||
cvode->SetMaxStep(dt);
|
||||
@@ -441,7 +484,7 @@ int main(int argc, char *argv[])
|
||||
case 15:
|
||||
case 16:
|
||||
arkode = new ARKStepSolver(ARKStepSolver::IMPLICIT);
|
||||
arkode->Init(oper);
|
||||
arkode->Init(*oper);
|
||||
arkode->SetSStolerances(reltol, abstol);
|
||||
ARKStepSetNonlinConvCoef(arkode->GetMem(), arkode_eps_nonlin);
|
||||
arkode->SetMaxStep(dt);
|
||||
@@ -453,16 +496,16 @@ int main(int argc, char *argv[])
|
||||
// ARKStep Explicit methods
|
||||
case 17:
|
||||
arkode = new ARKStepSolver(ARKStepSolver::EXPLICIT);
|
||||
arkode->Init(oper);
|
||||
arkode->Init(*oper);
|
||||
arkode->SetSStolerances(reltol, abstol);
|
||||
arkode->SetMaxStep(dt);
|
||||
ode_solver = arkode; break;
|
||||
}
|
||||
|
||||
// Initialize MFEM integrators, SUNDIALS integrators are initialized above
|
||||
if (ode_solver_type < 11) { ode_solver->Init(oper); }
|
||||
if (ode_solver_type < 11) { ode_solver->Init(*oper); }
|
||||
|
||||
// 9. Perform time-integration (looping over the time iterations, ti, with a
|
||||
// 8. Perform time-integration (looping over the time iterations, ti, with a
|
||||
// time-step dt).
|
||||
bool last_step = false;
|
||||
for (int ti = 1; !last_step; ti++)
|
||||
@@ -475,8 +518,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (last_step || (ti % vis_steps) == 0)
|
||||
{
|
||||
double ee = oper.ElasticEnergy(x.GetTrueVector());
|
||||
double ke = oper.KineticEnergy(v.GetTrueVector());
|
||||
double ee = oper->ElasticEnergy(x.GetTrueVector());
|
||||
double ke = oper->KineticEnergy(v.GetTrueVector());
|
||||
|
||||
cout << "step " << ti << ", t = " << t << ", EE = " << ee << ", KE = "
|
||||
<< ke << ", ΔTE = " << (ee+ke)-(ee0+ke0) << endl;
|
||||
@@ -490,14 +533,14 @@ int main(int argc, char *argv[])
|
||||
visualize(vis_v, mesh, &x, &v);
|
||||
if (vis_w)
|
||||
{
|
||||
oper.GetElasticEnergyDensity(x, w);
|
||||
oper->GetElasticEnergyDensity(x, w);
|
||||
visualize(vis_w, mesh, &x, &w);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 10. Save the displaced mesh, the velocity and elastic energy.
|
||||
// 9. Save the displaced mesh, the velocity and elastic energy.
|
||||
{
|
||||
v.SetFromTrueVector(); x.SetFromTrueVector();
|
||||
GridFunction *nodes = &x;
|
||||
@@ -512,11 +555,11 @@ int main(int argc, char *argv[])
|
||||
v.Save(velo_ofs);
|
||||
ofstream ee_ofs("elastic_energy.sol");
|
||||
ee_ofs.precision(8);
|
||||
oper.GetElasticEnergyDensity(x, w);
|
||||
oper->GetElasticEnergyDensity(x, w);
|
||||
w.Save(ee_ofs);
|
||||
}
|
||||
|
||||
// 11. Free the used memory.
|
||||
// 10. Free the used memory.
|
||||
delete ode_solver;
|
||||
delete mesh;
|
||||
|
||||
@@ -600,7 +643,9 @@ ReducedSystemOperator::~ReducedSystemOperator()
|
||||
HyperelasticOperator::HyperelasticOperator(FiniteElementSpace &f,
|
||||
Array<int> &ess_bdr, double visc,
|
||||
double mu, double K,
|
||||
NonlinearSolverType nls_type)
|
||||
int kinsol_nls_type,
|
||||
double kinsol_damping,
|
||||
int kinsol_aa_n)
|
||||
: TimeDependentOperator(2*f.GetTrueVSize(), 0.0), fespace(f),
|
||||
M(&fespace), S(&fespace), H(&fespace),
|
||||
viscosity(visc), z(height/2),
|
||||
@@ -651,15 +696,28 @@ HyperelasticOperator::HyperelasticOperator(FiniteElementSpace &f,
|
||||
J_prec = NULL;
|
||||
#endif
|
||||
|
||||
if (nls_type == KINSOL)
|
||||
if (kinsol_nls_type > 0)
|
||||
{
|
||||
KINSolver *kinsolver = new KINSolver(KIN_NONE, true);
|
||||
KINSolver *kinsolver = new KINSolver(kinsol_nls_type, true);
|
||||
if (kinsol_nls_type != KIN_PICARD)
|
||||
{
|
||||
kinsolver->SetJFNK(true);
|
||||
kinsolver->SetLSMaxIter(100);
|
||||
}
|
||||
if (kinsol_aa_n > 0)
|
||||
{
|
||||
kinsolver->EnableAndersonAcc(kinsol_aa_n);
|
||||
}
|
||||
newton_solver = kinsolver;
|
||||
newton_solver->SetOperator(*reduced_oper);
|
||||
newton_solver->SetMaxIter(200);
|
||||
newton_solver->SetRelTol(rel_tol);
|
||||
newton_solver->SetPrintLevel(0);
|
||||
kinsolver->SetMaxSetupCalls(4);
|
||||
if (kinsol_damping > 0.0)
|
||||
{
|
||||
kinsolver->SetDamping(kinsol_damping);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+126
-60
@@ -1,15 +1,17 @@
|
||||
// MFEM Example 10 - Parallel Version
|
||||
// SUNDIALS Modification
|
||||
//
|
||||
// Compile with: make ex10p
|
||||
// Compile with:
|
||||
// make ex10p (GNU make)
|
||||
// make sundials_ex10p (CMake)
|
||||
//
|
||||
// Sample runs:
|
||||
// mpirun -np 4 ex10p -m ../../data/beam-quad.mesh -rp 1 -o 2 -s 12 -dt 0.15 -vs 10
|
||||
// mpirun -np 4 ex10p -m ../../data/beam-tri.mesh -rp 1 -o 2 -s 16 -dt 0.25 -vs 10
|
||||
// mpirun -np 4 ex10p -m ../../data/beam-hex.mesh -rp 0 -o 2 -s 12 -dt 0.15 -vs 10
|
||||
// mpirun -np 4 ex10p -m ../../data/beam-tri.mesh -rp 1 -o 2 -s 2 -dt 3 -nls kinsol
|
||||
// mpirun -np 4 ex10p -m ../../data/beam-quad.mesh -rp 1 -o 2 -s 2 -dt 3 -nls kinsol
|
||||
// mpirun -np 4 ex10p -m ../../data/beam-hex.mesh -rs 1 -o 2 -s 2 -dt 3 -nls kinsol
|
||||
// mpirun -np 4 ex10p -m ../../data/beam-tri.mesh -rp 1 -o 2 -s 2 -dt 3 -nls 1
|
||||
// mpirun -np 4 ex10p -m ../../data/beam-quad.mesh -rp 1 -o 2 -s 2 -dt 3 -nls 2
|
||||
// mpirun -np 4 ex10p -m ../../data/beam-hex.mesh -rs 1 -o 2 -s 2 -dt 3 -nls 4
|
||||
// mpirun -np 4 ex10p -m ../../data/beam-quad.mesh -rp 1 -o 2 -s 14 -dt 0.15 -vs 10
|
||||
// mpirun -np 4 ex10p -m ../../data/beam-tri.mesh -rp 1 -o 2 -s 17 -dt 5e-3 -vs 60
|
||||
// mpirun -np 4 ex10p -m ../../data/beam-hex.mesh -rp 0 -o 2 -s 14 -dt 0.15 -vs 10
|
||||
@@ -99,16 +101,11 @@ protected:
|
||||
double saved_gamma; // saved gamma value from implicit setup
|
||||
|
||||
public:
|
||||
/// Solver type to use in the ImplicitSolve() method, used by SDIRK methods.
|
||||
enum NonlinearSolverType
|
||||
{
|
||||
NEWTON = 0, ///< Use MFEM's plain NewtonSolver
|
||||
KINSOL = 1 ///< Use SUNDIALS' KINSOL (through MFEM's class KINSolver)
|
||||
};
|
||||
|
||||
HyperelasticOperator(ParFiniteElementSpace &f, Array<int> &ess_bdr,
|
||||
double visc, double mu, double K,
|
||||
NonlinearSolverType nls_type);
|
||||
int kinsol_nls_type = -1, double kinsol_damping = 0.0,
|
||||
int kinsol_aa_n = 0);
|
||||
|
||||
/// Compute the right-hand side of the ODE system.
|
||||
virtual void Mult(const Vector &vx, Vector &dvx_dt) const;
|
||||
@@ -233,8 +230,10 @@ int main(int argc, char *argv[])
|
||||
double mu = 0.25;
|
||||
double K = 5.0;
|
||||
bool visualization = true;
|
||||
const char *nls = "newton";
|
||||
int nonlinear_solver_type = 0;
|
||||
int vis_steps = 1;
|
||||
double kinsol_damping = 0.0;
|
||||
int kinsol_aa_n = -1;
|
||||
|
||||
// Relative and absolute tolerances for CVODE and ARKODE.
|
||||
const double reltol = 1e-1, abstol = 1e-1;
|
||||
@@ -273,9 +272,18 @@ int main(int argc, char *argv[])
|
||||
"15 - ARKODE implicit, approximate Jacobian,\n\t"
|
||||
"16 - ARKODE implicit, specified Jacobian,\n\t"
|
||||
"17 - ARKODE explicit, 4th order.");
|
||||
args.AddOption(&nls, "-nls", "--nonlinear-solver",
|
||||
"Nonlinear systems solver: "
|
||||
"\"newton\" (plain Newton) or \"kinsol\" (KINSOL).");
|
||||
args.AddOption(&nonlinear_solver_type, "-nls", "--nonlinear-solver",
|
||||
"Nonlinear system solver:\n\t"
|
||||
"0 - MFEM Newton method,\n\t"
|
||||
"1 - KINSOL Newton method,\n\t"
|
||||
"2 - KINSOL Newton method with globalization,\n\t"
|
||||
"3 - KINSOL fixed-point method (with or without AA),\n\t"
|
||||
"4 - KINSOL Picard method (with or without AA).");
|
||||
args.AddOption(&kinsol_damping, "-damp", "--kinsol-damping",
|
||||
"Picard or Fixed-Point damping parameter (only valid with KINSOL): "
|
||||
"0 < d <= 1.0");
|
||||
args.AddOption(&kinsol_aa_n, "-aan", "--anderson-subspace",
|
||||
"Anderson Acceleration subspace size (only valid with KINSOL)");
|
||||
args.AddOption(&t_final, "-tf", "--t-final",
|
||||
"Final time; start time is 0.");
|
||||
args.AddOption(&dt, "-dt", "--time-step",
|
||||
@@ -315,27 +323,42 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
// check for valid nonlinear solver options
|
||||
if (nonlinear_solver_type < 0 || nonlinear_solver_type > 4)
|
||||
{
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "Unknown nonlinear solver type: " << nonlinear_solver_type
|
||||
<< "\n";
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (kinsol_damping > 0.0 &&
|
||||
!(nonlinear_solver_type == 3 || nonlinear_solver_type == 4))
|
||||
{
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "Only KINSOL fixed-point and Picard methods can use damping\n";
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (kinsol_aa_n > 0 &&
|
||||
!(nonlinear_solver_type == 3 || nonlinear_solver_type == 4))
|
||||
{
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "Only KINSOL fixed-point and Picard methods can use AA\n";
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 3. Read the serial mesh from the given mesh file on all processors. We can
|
||||
// handle triangular, quadrilateral, tetrahedral and hexahedral meshes
|
||||
// with the same code.
|
||||
Mesh *mesh = new Mesh(mesh_file, 1, 1);
|
||||
int dim = mesh->Dimension();
|
||||
|
||||
// 4. Nonlinear solver
|
||||
map<string,HyperelasticOperator::NonlinearSolverType> nls_map;
|
||||
nls_map["newton"] = HyperelasticOperator::NEWTON;
|
||||
nls_map["kinsol"] = HyperelasticOperator::KINSOL;
|
||||
if (nls_map.find(nls) == nls_map.end())
|
||||
{
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "Unknown type of nonlinear solver: " << nls << endl;
|
||||
}
|
||||
delete mesh;
|
||||
return 4;
|
||||
}
|
||||
|
||||
// 5. Refine the mesh in serial to increase the resolution. In this example
|
||||
// 4. Refine the mesh in serial to increase the resolution. In this example
|
||||
// we do 'ser_ref_levels' of uniform refinement, where 'ser_ref_levels' is
|
||||
// a command-line parameter.
|
||||
for (int lev = 0; lev < ser_ref_levels; lev++)
|
||||
@@ -343,7 +366,7 @@ int main(int argc, char *argv[])
|
||||
mesh->UniformRefinement();
|
||||
}
|
||||
|
||||
// 6. Define a parallel mesh by a partitioning of the serial mesh. Refine
|
||||
// 5. Define a parallel mesh by a partitioning of the serial mesh. Refine
|
||||
// this mesh further in parallel to increase the resolution. Once the
|
||||
// parallel mesh is defined, the serial mesh can be deleted.
|
||||
ParMesh *pmesh = new ParMesh(MPI_COMM_WORLD, *mesh);
|
||||
@@ -353,7 +376,7 @@ int main(int argc, char *argv[])
|
||||
pmesh->UniformRefinement();
|
||||
}
|
||||
|
||||
// 7. Define the parallel vector finite element spaces representing the mesh
|
||||
// 6. Define the parallel vector finite element spaces representing the mesh
|
||||
// deformation x_gf, the velocity v_gf, and the initial configuration,
|
||||
// x_ref. Define also the elastic energy density, w_gf, which is in a
|
||||
// discontinuous higher-order space. Since x and v are integrated in time
|
||||
@@ -385,7 +408,7 @@ int main(int argc, char *argv[])
|
||||
ParFiniteElementSpace w_fespace(pmesh, &w_fec);
|
||||
ParGridFunction w_gf(&w_fespace);
|
||||
|
||||
// 8. Set the initial conditions for v_gf, x_gf and vx, and define the
|
||||
// 7. Set the initial conditions for v_gf, x_gf and vx, and define the
|
||||
// boundary conditions on a beam-like mesh (see description above).
|
||||
VectorFunctionCoefficient velo(dim, InitialVelocity);
|
||||
v_gf.ProjectCoefficient(velo);
|
||||
@@ -400,9 +423,38 @@ int main(int argc, char *argv[])
|
||||
ess_bdr = 0;
|
||||
ess_bdr[0] = 1; // boundary attribute 1 (index 0) is fixed
|
||||
|
||||
// 9. Initialize the hyperelastic operator, the GLVis visualization and print
|
||||
// 8. Initialize the hyperelastic operator, the GLVis visualization and print
|
||||
// the initial energies.
|
||||
HyperelasticOperator oper(fespace, ess_bdr, visc, mu, K, nls_map[nls]);
|
||||
std::unique_ptr<HyperelasticOperator> oper;
|
||||
if (nonlinear_solver_type == 0)
|
||||
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr, visc, mu,
|
||||
K);
|
||||
else
|
||||
{
|
||||
switch (nonlinear_solver_type)
|
||||
{
|
||||
case 1:
|
||||
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
|
||||
visc, mu, K, KIN_NONE);
|
||||
break;
|
||||
case 2:
|
||||
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
|
||||
visc, mu, K, KIN_LINESEARCH);
|
||||
break;
|
||||
case 3:
|
||||
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
|
||||
visc, mu, K, KIN_FP, kinsol_damping, kinsol_aa_n);
|
||||
break;
|
||||
case 4:
|
||||
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
|
||||
visc, mu, K, KIN_PICARD, kinsol_damping, kinsol_aa_n);
|
||||
break;
|
||||
default:
|
||||
cout << "Unknown type of nonlinear solver: "
|
||||
<< nonlinear_solver_type << endl;
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
socketstream vis_v, vis_w;
|
||||
if (visualization)
|
||||
@@ -418,14 +470,14 @@ int main(int argc, char *argv[])
|
||||
vis_w.open(vishost, visport);
|
||||
if (vis_w)
|
||||
{
|
||||
oper.GetElasticEnergyDensity(x_gf, w_gf);
|
||||
oper->GetElasticEnergyDensity(x_gf, w_gf);
|
||||
vis_w.precision(8);
|
||||
visualize(vis_w, pmesh, &x_gf, &w_gf, "Elastic energy density", true);
|
||||
}
|
||||
}
|
||||
|
||||
double ee0 = oper.ElasticEnergy(x_gf);
|
||||
double ke0 = oper.KineticEnergy(v_gf);
|
||||
double ee0 = oper->ElasticEnergy(x_gf);
|
||||
double ke0 = oper->KineticEnergy(v_gf);
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "initial elastic energy (EE) = " << ee0 << endl;
|
||||
@@ -433,11 +485,11 @@ int main(int argc, char *argv[])
|
||||
cout << "initial total energy (TE) = " << (ee0 + ke0) << endl;
|
||||
}
|
||||
|
||||
// 10. Define the ODE solver used for time integration. Several implicit
|
||||
// singly diagonal implicit Runge-Kutta (SDIRK) methods, as well as
|
||||
// explicit Runge-Kutta methods are available.
|
||||
// 9. Define the ODE solver used for time integration. Several implicit
|
||||
// singly diagonal implicit Runge-Kutta (SDIRK) methods, as well as
|
||||
// explicit Runge-Kutta methods are available.
|
||||
double t = 0.0;
|
||||
oper.SetTime(t);
|
||||
oper->SetTime(t);
|
||||
|
||||
ODESolver *ode_solver = NULL;
|
||||
CVODESolver *cvode = NULL;
|
||||
@@ -461,7 +513,7 @@ int main(int argc, char *argv[])
|
||||
case 11:
|
||||
case 12:
|
||||
cvode = new CVODESolver(MPI_COMM_WORLD, CV_BDF);
|
||||
cvode->Init(oper);
|
||||
cvode->Init(*oper);
|
||||
cvode->SetSStolerances(reltol, abstol);
|
||||
CVodeSetEpsLin(cvode->GetMem(), cvode_eps_lin);
|
||||
cvode->SetMaxStep(dt);
|
||||
@@ -474,7 +526,7 @@ int main(int argc, char *argv[])
|
||||
case 13:
|
||||
case 14:
|
||||
cvode = new CVODESolver(MPI_COMM_WORLD, CV_ADAMS);
|
||||
cvode->Init(oper);
|
||||
cvode->Init(*oper);
|
||||
cvode->SetSStolerances(reltol, abstol);
|
||||
CVodeSetEpsLin(cvode->GetMem(), cvode_eps_lin);
|
||||
cvode->SetMaxStep(dt);
|
||||
@@ -487,7 +539,7 @@ int main(int argc, char *argv[])
|
||||
case 15:
|
||||
case 16:
|
||||
arkode = new ARKStepSolver(MPI_COMM_WORLD, ARKStepSolver::IMPLICIT);
|
||||
arkode->Init(oper);
|
||||
arkode->Init(*oper);
|
||||
arkode->SetSStolerances(reltol, abstol);
|
||||
ARKStepSetNonlinConvCoef(arkode->GetMem(), arkode_eps_nonlin);
|
||||
arkode->SetMaxStep(dt);
|
||||
@@ -499,16 +551,16 @@ int main(int argc, char *argv[])
|
||||
// ARKStep Explicit methods
|
||||
case 17:
|
||||
arkode = new ARKStepSolver(MPI_COMM_WORLD, ARKStepSolver::EXPLICIT);
|
||||
arkode->Init(oper);
|
||||
arkode->Init(*oper);
|
||||
arkode->SetSStolerances(reltol, abstol);
|
||||
arkode->SetMaxStep(dt);
|
||||
ode_solver = arkode; break;
|
||||
}
|
||||
|
||||
// Initialize MFEM integrators, SUNDIALS integrators are initialized above
|
||||
if (ode_solver_type < 11) { ode_solver->Init(oper); }
|
||||
if (ode_solver_type < 11) { ode_solver->Init(*oper); }
|
||||
|
||||
// 11. Perform time-integration
|
||||
// 10. Perform time-integration
|
||||
// (looping over the time iterations, ti, with a time-step dt).
|
||||
bool last_step = false;
|
||||
for (int ti = 1; !last_step; ti++)
|
||||
@@ -523,8 +575,8 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
v_gf.SetFromTrueVector(); x_gf.SetFromTrueVector();
|
||||
|
||||
double ee = oper.ElasticEnergy(x_gf);
|
||||
double ke = oper.KineticEnergy(v_gf);
|
||||
double ee = oper->ElasticEnergy(x_gf);
|
||||
double ke = oper->KineticEnergy(v_gf);
|
||||
|
||||
if (myid == 0)
|
||||
{
|
||||
@@ -540,14 +592,14 @@ int main(int argc, char *argv[])
|
||||
visualize(vis_v, pmesh, &x_gf, &v_gf);
|
||||
if (vis_w)
|
||||
{
|
||||
oper.GetElasticEnergyDensity(x_gf, w_gf);
|
||||
oper->GetElasticEnergyDensity(x_gf, w_gf);
|
||||
visualize(vis_w, pmesh, &x_gf, &w_gf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 12. Save the displaced mesh, the velocity and elastic energy.
|
||||
// 11. Save the displaced mesh, the velocity and elastic energy.
|
||||
{
|
||||
v_gf.SetFromTrueVector(); x_gf.SetFromTrueVector();
|
||||
GridFunction *nodes = &x_gf;
|
||||
@@ -568,11 +620,11 @@ int main(int argc, char *argv[])
|
||||
v_gf.Save(velo_ofs);
|
||||
ofstream ee_ofs(ee_name.str().c_str());
|
||||
ee_ofs.precision(8);
|
||||
oper.GetElasticEnergyDensity(x_gf, w_gf);
|
||||
oper->GetElasticEnergyDensity(x_gf, w_gf);
|
||||
w_gf.Save(ee_ofs);
|
||||
}
|
||||
|
||||
// 13. Free the used memory.
|
||||
// 12. Free the used memory.
|
||||
delete ode_solver;
|
||||
delete pmesh;
|
||||
|
||||
@@ -662,7 +714,10 @@ ReducedSystemOperator::~ReducedSystemOperator()
|
||||
HyperelasticOperator::HyperelasticOperator(ParFiniteElementSpace &f,
|
||||
Array<int> &ess_bdr, double visc,
|
||||
double mu, double K,
|
||||
NonlinearSolverType nls_type)
|
||||
int kinsol_nls_type,
|
||||
double kinsol_damping,
|
||||
int kinsol_aa_n)
|
||||
|
||||
: TimeDependentOperator(2*f.TrueVSize(), 0.0), fespace(f),
|
||||
M(&fespace), S(&fespace), H(&fespace),
|
||||
viscosity(visc), M_solver(f.GetComm()), z(height/2),
|
||||
@@ -714,17 +769,28 @@ HyperelasticOperator::HyperelasticOperator(ParFiniteElementSpace &f,
|
||||
J_minres->SetPreconditioner(*J_prec);
|
||||
J_solver = J_minres;
|
||||
|
||||
if (nls_type == KINSOL)
|
||||
if (kinsol_nls_type > 0)
|
||||
{
|
||||
KINSolver *kinsolver = new KINSolver(f.GetComm(), KIN_LINESEARCH, true);
|
||||
kinsolver->SetJFNK(true);
|
||||
kinsolver->SetLSMaxIter(100);
|
||||
KINSolver *kinsolver = new KINSolver(f.GetComm(), kinsol_nls_type, true);
|
||||
if (kinsol_nls_type != KIN_PICARD)
|
||||
{
|
||||
kinsolver->SetJFNK(true);
|
||||
kinsolver->SetLSMaxIter(100);
|
||||
}
|
||||
if (kinsol_aa_n > 0)
|
||||
{
|
||||
kinsolver->EnableAndersonAcc(kinsol_aa_n);
|
||||
}
|
||||
newton_solver = kinsolver;
|
||||
newton_solver->SetOperator(*reduced_oper);
|
||||
newton_solver->SetMaxIter(200);
|
||||
newton_solver->SetRelTol(rel_tol);
|
||||
newton_solver->SetPrintLevel(1);
|
||||
newton_solver->SetPrintLevel(0);
|
||||
kinsolver->SetMaxSetupCalls(4);
|
||||
if (kinsol_damping > 0.0)
|
||||
{
|
||||
kinsolver->SetDamping(kinsol_damping);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+256
-163
@@ -1,15 +1,21 @@
|
||||
// MFEM Example 16
|
||||
// SUNDIALS Modification
|
||||
//
|
||||
// Compile with: make ex16
|
||||
// Compile with:
|
||||
// make ex16 (GNU make)
|
||||
// make sundials_ex16 (CMake)
|
||||
//
|
||||
// Sample runs: ex16
|
||||
// ex16 -m ../../data/inline-tri.mesh
|
||||
// ex16 -m ../../data/disc-nurbs.mesh -tf 2
|
||||
// ex16 -s 12 -a 0.0 -k 1.0
|
||||
// ex16 -s 15 -a 0.0 -k 1.0
|
||||
// ex16 -s 8 -a 1.0 -k 0.0 -dt 1e-4 -tf 5e-2 -vs 25
|
||||
// ex16 -s 11 -a 1.0 -k 0.0 -dt 1e-4 -tf 5e-2 -vs 25
|
||||
// ex16 -s 9 -a 0.5 -k 0.5 -o 4 -dt 1e-4 -tf 2e-2 -vs 25
|
||||
// ex16 -s 12 -a 0.5 -k 0.5 -o 4 -dt 1e-4 -tf 2e-2 -vs 25
|
||||
// ex16 -s 10 -dt 1.0e-4 -tf 4.0e-2 -vs 40
|
||||
// ex16 -s 13 -dt 1.0e-4 -tf 4.0e-2 -vs 40
|
||||
// ex16 -m ../../data/fichera-q2.mesh
|
||||
// ex16 -m ../../data/escher.mesh
|
||||
// ex16 -m ../../data/beam-tet.mesh -tf 10 -dt 0.1
|
||||
@@ -37,75 +43,102 @@
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
/** After spatial discretization, the conduction model can be written as:
|
||||
/** After spatial discretization, the conduction model is expressed as
|
||||
*
|
||||
* du/dt = M^{-1}(-Ku)
|
||||
* M du/dt = - K(u) u
|
||||
*
|
||||
* where u is the vector representing the temperature, M is the mass matrix,
|
||||
* and K is the diffusion operator with diffusivity depending on u:
|
||||
* and K(u) is the diffusion operator with diffusivity depending on u:
|
||||
* (\kappa + \alpha u).
|
||||
*
|
||||
* Class ConductionOperator represents the right-hand side of the above ODE.
|
||||
* Class ConductionOperatorOperator represents the above ODE operator in the
|
||||
* general form F(u, k, t) = G(u, t) where
|
||||
*
|
||||
* 1. F(u, du/dt, t) = du/dt (ODE is expressed in EXPLICIT form)
|
||||
* G(u, t) = - inv(M) K(u) u
|
||||
* 2. F(u, du/dt, t) = M du/dt (ODE is expressed in IMPLICIT form)
|
||||
* G(u, t) = - K(u) u
|
||||
*/
|
||||
class ConductionOperator : public TimeDependentOperator
|
||||
{
|
||||
protected:
|
||||
FiniteElementSpace &fespace;
|
||||
Array<int> ess_tdof_list; // this list remains empty for pure Neumann b.c.
|
||||
|
||||
BilinearForm *M;
|
||||
BilinearForm *K;
|
||||
BilinearForm M;
|
||||
SparseMatrix Mmat;
|
||||
|
||||
SparseMatrix Mmat, Kmat;
|
||||
SparseMatrix *T; // T = M + dt K
|
||||
const real_t alpha, kappa;
|
||||
std::unique_ptr<BilinearForm> K;
|
||||
SparseMatrix Kmat;
|
||||
|
||||
std::unique_ptr<SparseMatrix> T; // T = M + gam K(u)
|
||||
|
||||
CGSolver M_solver; // Krylov solver for inverting the mass matrix M
|
||||
DSmoother M_prec; // Preconditioner for the mass matrix M
|
||||
|
||||
CGSolver T_solver; // Implicit solver for T = M + dt K
|
||||
CGSolver T_solver; // Implicit solver for T = M + gam K(u)
|
||||
DSmoother T_prec; // Preconditioner for the implicit solver
|
||||
|
||||
double alpha, kappa;
|
||||
|
||||
mutable Vector z; // auxiliary vector
|
||||
|
||||
public:
|
||||
ConductionOperator(FiniteElementSpace &f, double alpha, double kappa,
|
||||
const Vector &u);
|
||||
|
||||
virtual void Mult(const Vector &u, Vector &du_dt) const;
|
||||
ConductionOperator(FiniteElementSpace &f, const real_t alpha,
|
||||
const real_t kappa, const Vector &u,
|
||||
const Type &ode_expression_type);
|
||||
|
||||
/** Solve the Backward-Euler equation: k = f(u + dt*k, t), for the unknown k.
|
||||
This is the only requirement for high-order SDIRK implicit integration.*/
|
||||
virtual void ImplicitSolve(const double dt, const Vector &u, Vector &k);
|
||||
// Compute K(u_n) for use as an approximation in - K(u) u
|
||||
void SetConductionTensor(const Vector &u);
|
||||
|
||||
/// Custom Jacobian system solver for the SUNDIALS time integrators.
|
||||
/** For the ODE system represented by ConductionOperator
|
||||
/** Compute G(u, t) as defined in the IMPLICIT expression form of the ODE
|
||||
operator, i.e., @a v = - K(u_n) @a u. Note that K(u_n) is an
|
||||
approximation to K(u). */
|
||||
void ExplicitMult(const Vector &u, Vector &v) const override;
|
||||
|
||||
M du/dt = -K(u),
|
||||
/** Solve for k in F(u, k, t) = G(u, t) for either EXPLICIT or IMPLICIT
|
||||
expression forms of the ODE operator, i.e., @a k = - inv(M) K(u_n) @a u.
|
||||
Note that K(u_n) is an approximation to K(u). */
|
||||
void Mult(const Vector &u, Vector &k) const override;
|
||||
|
||||
this class facilitates the solution of linear systems of the form
|
||||
/** Solve for k in F(u + gam*k, k, t) = G(u + gam*k, t) for either EXPLICIT
|
||||
or IMPLICIT expression forms of the ODE operator, i.e.,
|
||||
[ M + @a gam K(u_n) ] @a k = - K(u_n) @a u . Note that K(u_n) is an
|
||||
approximation to K(u). */
|
||||
void ImplicitSolve(const real_t gam, const Vector &u, Vector &k) override;
|
||||
|
||||
(M + γK) y = M b,
|
||||
/** Setup to solve for dk in [dF/dk + gam*dF/du - gam*dG/du] dk = G - F for
|
||||
either EXPLICIT or IMPLICIT expression forms of the ODE operator, i.e.,
|
||||
[M - @a gam Jf(u)] dk = G - F, where Jf(u) is an approximation of the
|
||||
Jacobian of -K(u) u. The approximation chosen here is Jf(u) = -K(u_n). */
|
||||
int SUNImplicitSetup(const Vector &u, const Vector &fu, int jok, int *jcur,
|
||||
real_t gam) override;
|
||||
|
||||
for given b, u (not used), and γ = GetTimeStep(). */
|
||||
/** Solve for @a dk in the system in SUNImplicitSetup to the given tolerance,
|
||||
with the residual @a r providing either
|
||||
1. @a r = G - F = inv(M) f(u) - k (EXPLICIT expression form)
|
||||
1. @a r = G - F = f(u) - M k (IMPLICIT expression form)
|
||||
*/
|
||||
int SUNImplicitSolve(const Vector &r, Vector &dk, real_t tol) override;
|
||||
|
||||
/** Setup the system (M + dt K) x = M b. This method is used by the implicit
|
||||
SUNDIALS solvers. */
|
||||
virtual int SUNImplicitSetup(const Vector &x, const Vector &fx,
|
||||
int jok, int *jcur, double gamma);
|
||||
int SUNMassSetup() override;
|
||||
|
||||
/** Solve the system (M + dt K) x = M b. This method is used by the implicit
|
||||
SUNDIALS solvers. */
|
||||
virtual int SUNImplicitSolve(const Vector &b, Vector &x, double tol);
|
||||
int SUNMassSolve(const Vector &b, Vector &x, real_t tol) override;
|
||||
|
||||
/// Update the diffusion BilinearForm K using the given true-dof vector `u`.
|
||||
void SetParameters(const Vector &u);
|
||||
|
||||
virtual ~ConductionOperator();
|
||||
int SUNMassMult(const Vector &x, Vector &v) override;
|
||||
};
|
||||
|
||||
double InitialTemperature(const Vector &x);
|
||||
real_t InitialTemperature(const Vector &x)
|
||||
{
|
||||
if (x.Norml2() < 0.5)
|
||||
{
|
||||
return 2.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -117,16 +150,16 @@ int main(int argc, char *argv[])
|
||||
int ref_levels = 2;
|
||||
int order = 2;
|
||||
int ode_solver_type = 9; // CVODE implicit BDF
|
||||
double t_final = 0.5;
|
||||
double dt = 1.0e-2;
|
||||
double alpha = 1.0e-2;
|
||||
double kappa = 0.5;
|
||||
real_t t_final = 0.5;
|
||||
real_t dt = 1.0e-2;
|
||||
real_t alpha = 1.0e-2;
|
||||
real_t kappa = 0.5;
|
||||
bool visualization = true;
|
||||
bool visit = false;
|
||||
int vis_steps = 5;
|
||||
|
||||
// Relative and absolute tolerances for CVODE and ARKODE.
|
||||
const double reltol = 1e-4, abstol = 1e-4;
|
||||
const real_t reltol = 1e-4, abstol = 1e-4;
|
||||
|
||||
int precision = 8;
|
||||
cout.precision(precision);
|
||||
@@ -151,7 +184,10 @@ int main(int argc, char *argv[])
|
||||
"9 - CVODE (implicit BDF),\n\t"
|
||||
"10 - ARKODE (default explicit),\n\t"
|
||||
"11 - ARKODE (explicit Fehlberg-6-4-5),\n\t"
|
||||
"12 - ARKODE (default impicit).");
|
||||
"12 - ARKODE (default implicit),\n\t"
|
||||
"13 - ARKODE (default explicit with MFEM mass solve),\n\t"
|
||||
"14 - ARKODE (explicit Fehlberg-6-4-5 with MFEM mass solve),\n\t"
|
||||
"15 - ARKODE (default implicit with MFEM mass solve).");
|
||||
args.AddOption(&t_final, "-tf", "--t-final",
|
||||
"Final time; start time is 0.");
|
||||
args.AddOption(&dt, "-dt", "--time-step",
|
||||
@@ -174,16 +210,13 @@ int main(int argc, char *argv[])
|
||||
args.PrintUsage(cout);
|
||||
return 1;
|
||||
}
|
||||
if (ode_solver_type < 1 || ode_solver_type > 12)
|
||||
{
|
||||
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
|
||||
return 3;
|
||||
}
|
||||
args.PrintOptions(cout);
|
||||
|
||||
bool use_mass_solver = ode_solver_type >= 13;
|
||||
|
||||
// 2. Read the mesh from the given mesh file. We can handle triangular,
|
||||
// quadrilateral, tetrahedral and hexahedral meshes with the same code.
|
||||
Mesh *mesh = new Mesh(mesh_file, 1, 1);
|
||||
std::unique_ptr<Mesh> mesh(new Mesh(mesh_file, 1, 1));
|
||||
int dim = mesh->Dimension();
|
||||
|
||||
// 3. Refine the mesh to increase the resolution. In this example we do
|
||||
@@ -197,7 +230,7 @@ int main(int argc, char *argv[])
|
||||
// 4. Define the vector finite element space representing the current and the
|
||||
// initial temperature, u_ref.
|
||||
H1_FECollection fe_coll(order, dim);
|
||||
FiniteElementSpace fespace(mesh, &fe_coll);
|
||||
FiniteElementSpace fespace(mesh.get(), &fe_coll);
|
||||
|
||||
int fe_size = fespace.GetTrueVSize();
|
||||
cout << "Number of temperature unknowns: " << fe_size << endl;
|
||||
@@ -211,8 +244,17 @@ int main(int argc, char *argv[])
|
||||
Vector u;
|
||||
u_gf.GetTrueDofs(u);
|
||||
|
||||
// 6. Initialize the conduction operator and the visualization.
|
||||
ConductionOperator oper(fespace, alpha, kappa, u);
|
||||
// 6. Initialize the conduction ODE operator and the visualization.
|
||||
ConductionOperator::Type ode_expression_type;
|
||||
if (use_mass_solver)
|
||||
{
|
||||
ode_expression_type = ConductionOperator::Type::IMPLICIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
ode_expression_type = ConductionOperator::Type::EXPLICIT;
|
||||
}
|
||||
ConductionOperator oper(fespace, alpha, kappa, u, ode_expression_type);
|
||||
|
||||
u_gf.SetFromTrueDofs(u);
|
||||
{
|
||||
@@ -224,7 +266,7 @@ int main(int argc, char *argv[])
|
||||
u_gf.Save(osol);
|
||||
}
|
||||
|
||||
VisItDataCollection visit_dc("Example16", mesh);
|
||||
VisItDataCollection visit_dc("Example16", mesh.get());
|
||||
visit_dc.RegisterField("temperature", &u_gf);
|
||||
if (visit)
|
||||
{
|
||||
@@ -258,52 +300,75 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// 7. Define the ODE solver used for time integration.
|
||||
double t = 0.0;
|
||||
ODESolver *ode_solver = NULL;
|
||||
CVODESolver *cvode = NULL;
|
||||
ARKStepSolver *arkode = NULL;
|
||||
real_t t = 0.0;
|
||||
std::unique_ptr<ODESolver> ode_solver;
|
||||
switch (ode_solver_type)
|
||||
{
|
||||
// MFEM explicit methods
|
||||
case 1: ode_solver = new ForwardEulerSolver; break;
|
||||
case 2: ode_solver = new RK2Solver(0.5); break; // midpoint method
|
||||
case 3: ode_solver = new RK3SSPSolver; break;
|
||||
case 4: ode_solver = new RK4Solver; break;
|
||||
case 1: ode_solver = std::make_unique<ForwardEulerSolver>(); break;
|
||||
case 2: ode_solver = std::make_unique<RK2Solver>(0.5); break; // midpoint method
|
||||
case 3: ode_solver = std::make_unique<RK3SSPSolver>(); break;
|
||||
case 4: ode_solver = std::make_unique<RK4Solver>(); break;
|
||||
// MFEM implicit L-stable methods
|
||||
case 5: ode_solver = new BackwardEulerSolver; break;
|
||||
case 6: ode_solver = new SDIRK23Solver(2); break;
|
||||
case 7: ode_solver = new SDIRK33Solver; break;
|
||||
case 5: ode_solver = std::make_unique<BackwardEulerSolver>(); break;
|
||||
case 6: ode_solver = std::make_unique<SDIRK23Solver>(2); break;
|
||||
case 7: ode_solver = std::make_unique<SDIRK33Solver>(); break;
|
||||
// CVODE
|
||||
case 8:
|
||||
cvode = new CVODESolver(CV_ADAMS);
|
||||
cvode->Init(oper);
|
||||
cvode->SetSStolerances(reltol, abstol);
|
||||
cvode->SetMaxStep(dt);
|
||||
ode_solver = cvode; break;
|
||||
case 9:
|
||||
cvode = new CVODESolver(CV_BDF);
|
||||
{
|
||||
int cvode_solver_type;
|
||||
if (ode_solver_type == 8)
|
||||
{
|
||||
cvode_solver_type = CV_ADAMS;
|
||||
}
|
||||
else
|
||||
{
|
||||
cvode_solver_type = CV_BDF;
|
||||
}
|
||||
std::unique_ptr<CVODESolver> cvode(new CVODESolver(cvode_solver_type));
|
||||
cvode->Init(oper);
|
||||
cvode->SetSStolerances(reltol, abstol);
|
||||
cvode->SetMaxStep(dt);
|
||||
ode_solver = cvode; break;
|
||||
ode_solver = std::move(cvode);
|
||||
break;
|
||||
}
|
||||
// ARKODE
|
||||
case 10:
|
||||
case 11:
|
||||
arkode = new ARKStepSolver(ARKStepSolver::EXPLICIT);
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
{
|
||||
ARKStepSolver::Type arkode_solver_type;
|
||||
if (ode_solver_type == 12 || ode_solver_type == 15)
|
||||
{
|
||||
arkode_solver_type = ARKStepSolver::IMPLICIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
arkode_solver_type = ARKStepSolver::EXPLICIT;
|
||||
}
|
||||
std::unique_ptr<ARKStepSolver> arkode(
|
||||
new ARKStepSolver(arkode_solver_type));
|
||||
arkode->Init(oper);
|
||||
arkode->SetSStolerances(reltol, abstol);
|
||||
arkode->SetMaxStep(dt);
|
||||
if (ode_solver_type == 11)
|
||||
if (ode_solver_type == 11 || ode_solver_type == 14)
|
||||
{
|
||||
arkode->SetERKTableNum(ARKODE_FEHLBERG_13_7_8);
|
||||
}
|
||||
ode_solver = arkode; break;
|
||||
case 12:
|
||||
arkode = new ARKStepSolver(ARKStepSolver::IMPLICIT);
|
||||
arkode->Init(oper);
|
||||
arkode->SetSStolerances(reltol, abstol);
|
||||
arkode->SetMaxStep(dt);
|
||||
ode_solver = arkode; break;
|
||||
if (use_mass_solver)
|
||||
{
|
||||
arkode->UseMFEMMassLinearSolver(SUNFALSE);
|
||||
}
|
||||
ode_solver = std::move(arkode);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
|
||||
return 3;
|
||||
}
|
||||
|
||||
// Initialize MFEM integrators, SUNDIALS integrators are initialized above
|
||||
@@ -311,8 +376,14 @@ int main(int argc, char *argv[])
|
||||
|
||||
// Since we want to update the diffusion coefficient after every time step,
|
||||
// we need to use the "one-step" mode of the SUNDIALS solvers.
|
||||
if (cvode) { cvode->SetStepMode(CV_ONE_STEP); }
|
||||
if (arkode) { arkode->SetStepMode(ARK_ONE_STEP); }
|
||||
if (CVODESolver* cvode = dynamic_cast<CVODESolver*>(ode_solver.get()))
|
||||
{
|
||||
cvode->SetStepMode(CV_ONE_STEP);
|
||||
}
|
||||
else if (ARKStepSolver* arkode = dynamic_cast<ARKStepSolver*>(ode_solver.get()))
|
||||
{
|
||||
arkode->SetStepMode(ARK_ONE_STEP);
|
||||
}
|
||||
|
||||
// 8. Perform time-integration (looping over the time iterations, ti, with a
|
||||
// time-step dt).
|
||||
@@ -323,7 +394,7 @@ int main(int argc, char *argv[])
|
||||
bool last_step = false;
|
||||
for (int ti = 1; !last_step; ti++)
|
||||
{
|
||||
double dt_real = min(dt, t_final - t);
|
||||
real_t dt_real = min(dt, t_final - t);
|
||||
|
||||
// Note that since we are using the "one-step" mode of the SUNDIALS
|
||||
// solvers, they will, generally, step over the final time and will not
|
||||
@@ -337,8 +408,14 @@ int main(int argc, char *argv[])
|
||||
if (last_step || (ti % vis_steps) == 0)
|
||||
{
|
||||
cout << "step " << ti << ", t = " << t << endl;
|
||||
if (cvode) { cvode->PrintInfo(); }
|
||||
if (arkode) { arkode->PrintInfo(); }
|
||||
if (CVODESolver* cvode = dynamic_cast<CVODESolver*>(ode_solver.get()))
|
||||
{
|
||||
cvode->PrintInfo();
|
||||
}
|
||||
else if (ARKStepSolver* arkode = dynamic_cast<ARKStepSolver*>(ode_solver.get()))
|
||||
{
|
||||
arkode->PrintInfo();
|
||||
}
|
||||
|
||||
u_gf.SetFromTrueDofs(u);
|
||||
if (visualization)
|
||||
@@ -353,137 +430,153 @@ int main(int argc, char *argv[])
|
||||
visit_dc.Save();
|
||||
}
|
||||
}
|
||||
oper.SetParameters(u);
|
||||
oper.SetConductionTensor(u);
|
||||
}
|
||||
tic_toc.Stop();
|
||||
cout << "Done, " << tic_toc.RealTime() << "s." << endl;
|
||||
|
||||
// 9. Save the final solution. This output can be viewed later using GLVis:
|
||||
// "glvis -m ex16.mesh -g ex16-final.gf".
|
||||
{
|
||||
ofstream osol("ex16-final.gf");
|
||||
osol.precision(precision);
|
||||
u_gf.Save(osol);
|
||||
}
|
||||
|
||||
// 10. Free the used memory.
|
||||
delete ode_solver;
|
||||
delete mesh;
|
||||
u_gf.Save("ex16-final.gf", precision);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ConductionOperator::ConductionOperator(FiniteElementSpace &f, double al,
|
||||
double kap, const Vector &u)
|
||||
: TimeDependentOperator(f.GetTrueVSize(), 0.0), fespace(f), M(NULL), K(NULL),
|
||||
T(NULL), z(height)
|
||||
ConductionOperator::ConductionOperator(FiniteElementSpace &fes,
|
||||
const real_t alpha, const real_t kappa,
|
||||
const Vector &u,
|
||||
const Type &ode_expression_type)
|
||||
: TimeDependentOperator(fes.GetTrueVSize(), 0.0, ode_expression_type),
|
||||
fespace(fes), alpha(alpha), kappa(kappa), M(&fespace), z(height)
|
||||
{
|
||||
const double rel_tol = 1e-8;
|
||||
// specify a relative tolerance for all solves with MFEM integrators
|
||||
const real_t rel_tol = 1e-8;
|
||||
|
||||
M = new BilinearForm(&fespace);
|
||||
M->AddDomainIntegrator(new MassIntegrator());
|
||||
M->Assemble();
|
||||
M->FormSystemMatrix(ess_tdof_list, Mmat);
|
||||
M.AddDomainIntegrator(new MassIntegrator());
|
||||
M.Assemble();
|
||||
M.FormSystemMatrix(ess_tdof_list, Mmat);
|
||||
|
||||
M_solver.iterative_mode = false;
|
||||
M_solver.SetRelTol(rel_tol);
|
||||
M_solver.SetRelTol(rel_tol); // will be overwritten with SUNDIALS integrators
|
||||
M_solver.SetAbsTol(0.0);
|
||||
M_solver.SetMaxIter(50);
|
||||
M_solver.SetPrintLevel(0);
|
||||
M_solver.SetPreconditioner(M_prec);
|
||||
M_solver.SetOperator(Mmat);
|
||||
|
||||
alpha = al;
|
||||
kappa = kap;
|
||||
|
||||
T_solver.iterative_mode = false;
|
||||
T_solver.SetRelTol(rel_tol);
|
||||
T_solver.SetRelTol(rel_tol); // will be overwritten with SUNDIALS integrators
|
||||
T_solver.SetAbsTol(0.0);
|
||||
T_solver.SetMaxIter(100);
|
||||
T_solver.SetPrintLevel(0);
|
||||
T_solver.SetPreconditioner(T_prec);
|
||||
|
||||
SetParameters(u);
|
||||
SetConductionTensor(u);
|
||||
}
|
||||
|
||||
void ConductionOperator::Mult(const Vector &u, Vector &du_dt) const
|
||||
{
|
||||
// Compute:
|
||||
// du_dt = M^{-1}*-K(u)
|
||||
// for du_dt
|
||||
Kmat.Mult(u, z);
|
||||
z.Neg(); // z = -z
|
||||
M_solver.Mult(z, du_dt);
|
||||
}
|
||||
|
||||
void ConductionOperator::ImplicitSolve(const double dt,
|
||||
const Vector &u, Vector &du_dt)
|
||||
{
|
||||
// Solve the equation:
|
||||
// du_dt = M^{-1}*[-K(u + dt*du_dt)]
|
||||
// for du_dt
|
||||
if (T) { delete T; }
|
||||
T = Add(1.0, Mmat, dt, Kmat);
|
||||
T_solver.SetOperator(*T);
|
||||
Kmat.Mult(u, z);
|
||||
z.Neg();
|
||||
T_solver.Mult(z, du_dt);
|
||||
}
|
||||
|
||||
void ConductionOperator::SetParameters(const Vector &u)
|
||||
void ConductionOperator::SetConductionTensor(const Vector &u)
|
||||
{
|
||||
// Compute K(u_n).
|
||||
GridFunction u_alpha_gf(&fespace);
|
||||
u_alpha_gf.SetFromTrueDofs(u);
|
||||
for (int i = 0; i < u_alpha_gf.Size(); i++)
|
||||
{
|
||||
u_alpha_gf(i) = kappa + alpha*u_alpha_gf(i);
|
||||
}
|
||||
|
||||
delete K;
|
||||
K = new BilinearForm(&fespace);
|
||||
|
||||
GridFunctionCoefficient u_coeff(&u_alpha_gf);
|
||||
|
||||
K = std::make_unique<BilinearForm>(&fespace);
|
||||
K->AddDomainIntegrator(new DiffusionIntegrator(u_coeff));
|
||||
K->Assemble();
|
||||
K->FormSystemMatrix(ess_tdof_list, Kmat);
|
||||
}
|
||||
|
||||
int ConductionOperator::SUNImplicitSetup(const Vector &x,
|
||||
const Vector &fx, int jok, int *jcur,
|
||||
double gamma)
|
||||
void ConductionOperator::ExplicitMult(const Vector &u, Vector &v) const
|
||||
{
|
||||
// Setup the ODE Jacobian T = M + gamma K.
|
||||
if (T) { delete T; }
|
||||
T = Add(1.0, Mmat, gamma, Kmat);
|
||||
// Compute - K(u_n) u.
|
||||
Kmat.Mult(u, v);
|
||||
v.Neg();
|
||||
}
|
||||
|
||||
void ConductionOperator::Mult(const Vector &u, Vector &k) const
|
||||
{
|
||||
// Compute - inv(M) K(u_n) u.
|
||||
ExplicitMult(u, z);
|
||||
M_solver.Mult(z, k);
|
||||
}
|
||||
|
||||
void ConductionOperator::ImplicitSolve(const real_t gam, const Vector &u,
|
||||
Vector &k)
|
||||
{
|
||||
// Solve for k in M k = - K(u_n) [u + gam*k].
|
||||
ExplicitMult(u, z);
|
||||
T = std::unique_ptr<SparseMatrix>(Add(1.0, Mmat, gam, Kmat));
|
||||
T_solver.SetOperator(*T);
|
||||
*jcur = 1;
|
||||
return (0);
|
||||
T_solver.Mult(z, k);
|
||||
}
|
||||
|
||||
int ConductionOperator::SUNImplicitSolve(const Vector &b, Vector &x, double tol)
|
||||
int ConductionOperator::SUNImplicitSetup(const Vector &u, const Vector &fu,
|
||||
int jok, int *jcur, real_t gam)
|
||||
{
|
||||
// Solve the system A x = z => (M - gamma K) x = M b.
|
||||
Mmat.Mult(b, z);
|
||||
T_solver.Mult(z, x);
|
||||
return (0);
|
||||
// Compute T = M + gamma K(u_n).
|
||||
T = std::unique_ptr<SparseMatrix>(Add(1.0, Mmat, gam, Kmat));
|
||||
T_solver.SetOperator(*T);
|
||||
*jcur = SUNTRUE; // this should eventually only be set true if K(u) is used
|
||||
return SUNLS_SUCCESS;
|
||||
}
|
||||
|
||||
ConductionOperator::~ConductionOperator()
|
||||
int ConductionOperator::SUNImplicitSolve(const Vector &r, Vector &dk,
|
||||
real_t tol)
|
||||
{
|
||||
delete T;
|
||||
delete M;
|
||||
delete K;
|
||||
}
|
||||
|
||||
double InitialTemperature(const Vector &x)
|
||||
{
|
||||
if (x.Norml2() < 0.5)
|
||||
// Solve the system [M + gamma K(u_n)] dk = - K(u_n) u - M k.
|
||||
// What value r is providing depends on the ODE expression form:
|
||||
// EXPLICIT form: r = -inv(M) K(u_n) u - k
|
||||
// IMPLICIT form: r = -K(u_n) u - M k
|
||||
T_solver.SetRelTol(tol);
|
||||
if (isExplicit())
|
||||
{
|
||||
return 2.0;
|
||||
Mmat.Mult(r, z);
|
||||
T_solver.Mult(z, dk);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1.0;
|
||||
T_solver.Mult(r, dk);
|
||||
}
|
||||
if (T_solver.GetConverged())
|
||||
{
|
||||
return SUNLS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SUNLS_CONV_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int ConductionOperator::SUNMassSetup()
|
||||
{
|
||||
// Do nothing b/c mass solver was setup in constructor.
|
||||
return SUNLS_SUCCESS;
|
||||
}
|
||||
|
||||
int ConductionOperator::SUNMassSolve(const Vector &b, Vector &x, real_t tol)
|
||||
{
|
||||
// Solve the system M x = b.
|
||||
M_solver.SetRelTol(tol);
|
||||
M_solver.Mult(b, x);
|
||||
if (M_solver.GetConverged())
|
||||
{
|
||||
return SUNLS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SUNLS_CONV_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int ConductionOperator::SUNMassMult(const Vector &x, Vector &v)
|
||||
{
|
||||
// Compute M x.
|
||||
Mmat.Mult(x, v);
|
||||
return SUNLS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
+285
-188
@@ -1,16 +1,22 @@
|
||||
// MFEM Example 16 - Parallel Version
|
||||
// SUNDIALS Modification
|
||||
//
|
||||
// Compile with: make ex16p
|
||||
// Compile with:
|
||||
// make ex16p (GNU make)
|
||||
// make sundials_ex16p (CMake)
|
||||
//
|
||||
// Sample runs:
|
||||
// mpirun -np 4 ex16p
|
||||
// mpirun -np 4 ex16p -m ../../data/inline-tri.mesh
|
||||
// mpirun -np 4 ex16p -m ../../data/disc-nurbs.mesh -tf 2
|
||||
// mpirun -np 4 ex16p -s 12 -a 0.0 -k 1.0
|
||||
// mpirun -np 4 ex16p -s 15 -a 0.0 -k 1.0
|
||||
// mpirun -np 4 ex16p -s 8 -a 1.0 -k 0.0 -dt 4e-6 -tf 2e-2 -vs 50
|
||||
// mpirun -np 4 ex16p -s 11 -a 1.0 -k 0.0 -dt 4e-6 -tf 2e-2 -vs 50
|
||||
// mpirun -np 8 ex16p -s 9 -a 0.5 -k 0.5 -o 4 -dt 8e-6 -tf 2e-2 -vs 50
|
||||
// mpirun -np 8 ex16p -s 12 -a 0.5 -k 0.5 -o 4 -dt 8e-6 -tf 2e-2 -vs 50
|
||||
// mpirun -np 4 ex16p -s 10 -dt 2.0e-4 -tf 4.0e-2
|
||||
// mpirun -np 4 ex16p -s 13 -dt 2.0e-4 -tf 4.0e-2
|
||||
// mpirun -np 16 ex16p -m ../../data/fichera-q2.mesh
|
||||
// mpirun -np 16 ex16p -m ../../data/escher-p2.mesh
|
||||
// mpirun -np 8 ex16p -m ../../data/beam-tet.mesh -tf 10 -dt 0.1
|
||||
@@ -38,66 +44,102 @@
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
/** After spatial discretization, the conduction model can be written as:
|
||||
/** After spatial discretization, the conduction model is expressed as
|
||||
*
|
||||
* du/dt = M^{-1}(-Ku)
|
||||
* M du/dt = - K(u) u
|
||||
*
|
||||
* where u is the vector representing the temperature, M is the mass matrix,
|
||||
* and K is the diffusion operator with diffusivity depending on u:
|
||||
* and K(u) is the diffusion operator with diffusivity depending on u:
|
||||
* (\kappa + \alpha u).
|
||||
*
|
||||
* Class ConductionOperator represents the right-hand side of the above ODE.
|
||||
* Class ConductionOperatorOperator represents the above ODE operator in the
|
||||
* general form F(u, k, t) = G(u, t) where either
|
||||
*
|
||||
* 1. F(u, du/dt, t) = du/dt (ODE is expressed in EXPLICIT form)
|
||||
* G(u, t) = - inv(M) K(u) u
|
||||
* 2. F(u, du/dt, t) = M du/dt (ODE is expressed in IMPLICIT form)
|
||||
* G(u, t) = - K(u) u
|
||||
*/
|
||||
class ConductionOperator : public TimeDependentOperator
|
||||
{
|
||||
protected:
|
||||
ParFiniteElementSpace &fespace;
|
||||
Array<int> ess_tdof_list; // this list remains empty for pure Neumann b.c.
|
||||
|
||||
ParBilinearForm *M;
|
||||
ParBilinearForm *K;
|
||||
|
||||
ParBilinearForm M;
|
||||
HypreParMatrix Mmat;
|
||||
|
||||
const real_t alpha, kappa;
|
||||
std::unique_ptr<BilinearForm> K;
|
||||
HypreParMatrix Kmat;
|
||||
HypreParMatrix *T; // T = M + dt K
|
||||
double current_dt;
|
||||
|
||||
CGSolver M_solver; // Krylov solver for inverting the mass matrix M
|
||||
HypreSmoother M_prec; // Preconditioner for the mass matrix M
|
||||
std::unique_ptr<HypreParMatrix> T; // T = M + gam K(u)
|
||||
|
||||
CGSolver T_solver; // Implicit solver for T = M + dt K
|
||||
HypreSmoother T_prec; // Preconditioner for the implicit solver
|
||||
CGSolver M_solver; // Krylov solver for inverting the mass matrix M
|
||||
HypreSmoother M_prec; // Preconditioner for the mass matrix M
|
||||
|
||||
double alpha, kappa;
|
||||
CGSolver T_solver; // Implicit solver for T = M + gam K(u)
|
||||
HypreSmoother T_prec; // Preconditioner for the implicit solver
|
||||
|
||||
mutable Vector z; // auxiliary vector
|
||||
|
||||
public:
|
||||
ConductionOperator(ParFiniteElementSpace &f, double alpha, double kappa,
|
||||
const Vector &u);
|
||||
|
||||
virtual void Mult(const Vector &u, Vector &du_dt) const;
|
||||
ConductionOperator(ParFiniteElementSpace &f, const real_t alpha,
|
||||
const real_t kappa, const Vector &u,
|
||||
const Type &ode_expression_type);
|
||||
|
||||
/** Solve the Backward-Euler equation: k = f(u + dt*k, t), for the unknown k.
|
||||
This is the only requirement for high-order SDIRK implicit integration.*/
|
||||
virtual void ImplicitSolve(const double dt, const Vector &u, Vector &k);
|
||||
// Compute K(u_n) for use as an approximation in - K(u) u
|
||||
void SetConductionTensor(const Vector &u);
|
||||
|
||||
/** Setup the system (M + dt K) x = M b. This method is used by the implicit
|
||||
SUNDIALS solvers. */
|
||||
virtual int SUNImplicitSetup(const Vector &x, const Vector &fx,
|
||||
int jok, int *jcur, double gamma);
|
||||
/** Compute G(u, t) as defined in the IMPLICIT expression form of the ODE
|
||||
operator, i.e., @a v = - K(u_n) @a u. Note that K(u_n) is an
|
||||
approximation to K(u). */
|
||||
void ExplicitMult(const Vector &u, Vector &v) const override;
|
||||
|
||||
/** Solve the system (M + dt K) x = M b. This method is used by the implicit
|
||||
SUNDIALS solvers. */
|
||||
virtual int SUNImplicitSolve(const Vector &b, Vector &x, double tol);
|
||||
/** Solve for k in F(u, k, t) = G(u, t) for either EXPLICIT or IMPLICIT
|
||||
expression forms of the ODE operator, i.e., @a k = - inv(M) K(u_n) @a u.
|
||||
Note that K(u_n) is an approximation to K(u). */
|
||||
void Mult(const Vector &u, Vector &k) const override;
|
||||
|
||||
/// Update the diffusion BilinearForm K using the given true-dof vector `u`.
|
||||
void SetParameters(const Vector &u);
|
||||
/** Solve for k in F(u + gam*k, k, t) = G(u + gam*k, t) for either EXPLICIT
|
||||
or IMPLICIT expression forms of the ODE operator, i.e.,
|
||||
[ M + @a gam K(u_n) ] @a k = - K(u_n) @a u . Note that K(u_n) is an
|
||||
approximation to K(u). */
|
||||
void ImplicitSolve(const real_t gam, const Vector &u, Vector &k) override;
|
||||
|
||||
virtual ~ConductionOperator();
|
||||
/** Setup to solve for dk in [dF/dk + gam*dF/du - gam*dG/du] dk = G - F for
|
||||
either EXPLICIT or IMPLICIT expression forms of the ODE operator, i.e.,
|
||||
[M - @a gam Jf(u)] dk = G - F, where Jf(u) is an approximation of the
|
||||
Jacobian of -K(u) u. The approximation chosen here is Jf(u) = -K(u_n). */
|
||||
int SUNImplicitSetup(const Vector &u, const Vector &fu, int jok, int *jcur,
|
||||
real_t gam) override;
|
||||
|
||||
/** Solve for @a dk in the system in SUNImplicitSetup to the given tolerance,
|
||||
with the residual @a r providing either
|
||||
1. @a r = G - F = inv(M) f(u) - k (EXPLICIT expression form)
|
||||
1. @a r = G - F = f(u) - M k (IMPLICIT expression form)
|
||||
*/
|
||||
int SUNImplicitSolve(const Vector &r, Vector &dk, real_t tol) override;
|
||||
|
||||
int SUNMassSetup() override;
|
||||
|
||||
int SUNMassSolve(const Vector &b, Vector &x, real_t tol) override;
|
||||
|
||||
int SUNMassMult(const Vector &x, Vector &v) override;
|
||||
};
|
||||
|
||||
double InitialTemperature(const Vector &x);
|
||||
real_t InitialTemperature(const Vector &x)
|
||||
{
|
||||
if (x.Norml2() < 0.5)
|
||||
{
|
||||
return 2.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -114,16 +156,16 @@ int main(int argc, char *argv[])
|
||||
int par_ref_levels = 1;
|
||||
int order = 2;
|
||||
int ode_solver_type = 9; // CVODE implicit BDF
|
||||
double t_final = 0.5;
|
||||
double dt = 1.0e-2;
|
||||
double alpha = 1.0e-2;
|
||||
double kappa = 0.5;
|
||||
real_t t_final = 0.5;
|
||||
real_t dt = 1.0e-2;
|
||||
real_t alpha = 1.0e-2;
|
||||
real_t kappa = 0.5;
|
||||
bool visualization = true;
|
||||
bool visit = false;
|
||||
int vis_steps = 5;
|
||||
|
||||
// Relative and absolute tolerances for CVODE and ARKODE.
|
||||
const double reltol = 1e-4, abstol = 1e-4;
|
||||
const real_t reltol = 1e-4, abstol = 1e-4;
|
||||
|
||||
int precision = 8;
|
||||
cout.precision(precision);
|
||||
@@ -150,7 +192,10 @@ int main(int argc, char *argv[])
|
||||
"9 - CVODE (implicit BDF),\n\t"
|
||||
"10 - ARKODE (default explicit),\n\t"
|
||||
"11 - ARKODE (explicit Fehlberg-6-4-5),\n\t"
|
||||
"12 - ARKODE (default impicit).");
|
||||
"12 - ARKODE (default implicit),\n\t"
|
||||
"13 - ARKODE (default explicit with MFEM mass solve),\n\t"
|
||||
"14 - ARKODE (explicit Fehlberg-6-4-5 with MFEM mass solve),\n\t"
|
||||
"15 - ARKODE (default implicit with MFEM mass solve).");
|
||||
args.AddOption(&t_final, "-tf", "--t-final",
|
||||
"Final time; start time is 0.");
|
||||
args.AddOption(&dt, "-dt", "--time-step",
|
||||
@@ -174,40 +219,33 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (myid == 0)
|
||||
if (Mpi::Root())
|
||||
{
|
||||
args.PrintOptions(cout);
|
||||
}
|
||||
|
||||
// check for valid ODE solver option
|
||||
if (ode_solver_type < 1 || ode_solver_type > 12)
|
||||
{
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
bool use_mass_solver = ode_solver_type >= 13;
|
||||
|
||||
// 3. Read the serial mesh from the given mesh file on all processors. We can
|
||||
// 3. Define a parallel mesh by a partitioning of a serial mesh. Read the
|
||||
// serial mesh from the given mesh file on all processors. We can
|
||||
// handle triangular, quadrilateral, tetrahedral and hexahedral meshes
|
||||
// with the same code.
|
||||
Mesh *mesh = new Mesh(mesh_file, 1, 1);
|
||||
int dim = mesh->Dimension();
|
||||
|
||||
// 4. Refine the mesh in serial to increase the resolution. In this example
|
||||
// we do 'ser_ref_levels' of uniform refinement, where 'ser_ref_levels' is
|
||||
// a command-line parameter.
|
||||
for (int lev = 0; lev < ser_ref_levels; lev++)
|
||||
std::unique_ptr<ParMesh> pmesh;
|
||||
{
|
||||
mesh->UniformRefinement();
|
||||
}
|
||||
std::unique_ptr<Mesh> mesh(new Mesh(mesh_file, 1, 1));
|
||||
|
||||
// 5. Define a parallel mesh by a partitioning of the serial mesh. Refine
|
||||
// this mesh further in parallel to increase the resolution. Once the
|
||||
// parallel mesh is defined, the serial mesh can be deleted.
|
||||
ParMesh *pmesh = new ParMesh(MPI_COMM_WORLD, *mesh);
|
||||
delete mesh;
|
||||
// 4. Refine the mesh in serial to increase the resolution. In this example
|
||||
// we do 'ser_ref_levels' of uniform refinement, where 'ser_ref_levels' is
|
||||
// a command-line parameter.
|
||||
for (int lev = 0; lev < ser_ref_levels; lev++)
|
||||
{
|
||||
mesh->UniformRefinement();
|
||||
}
|
||||
|
||||
// 5. Refine this mesh further in parallel to increase the resolution.
|
||||
// Once the parallel mesh is defined, the serial mesh can be deleted.
|
||||
pmesh = std::make_unique<ParMesh>(MPI_COMM_WORLD, *mesh);
|
||||
}
|
||||
for (int lev = 0; lev < par_ref_levels; lev++)
|
||||
{
|
||||
pmesh->UniformRefinement();
|
||||
@@ -215,8 +253,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
// 6. Define the vector finite element space representing the current and the
|
||||
// initial temperature, u_ref.
|
||||
int dim = pmesh->Dimension();
|
||||
H1_FECollection fe_coll(order, dim);
|
||||
ParFiniteElementSpace fespace(pmesh, &fe_coll);
|
||||
ParFiniteElementSpace fespace(pmesh.get(), &fe_coll);
|
||||
|
||||
int fe_size = fespace.GlobalTrueVSize();
|
||||
if (myid == 0)
|
||||
@@ -233,8 +272,17 @@ int main(int argc, char *argv[])
|
||||
Vector u;
|
||||
u_gf.GetTrueDofs(u);
|
||||
|
||||
// 8. Initialize the conduction operator and the VisIt visualization.
|
||||
ConductionOperator oper(fespace, alpha, kappa, u);
|
||||
// 8. Initialize the conduction ODE operator and the visualization.
|
||||
ConductionOperator::Type ode_expression_type;
|
||||
if (use_mass_solver)
|
||||
{
|
||||
ode_expression_type = ConductionOperator::Type::IMPLICIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
ode_expression_type = ConductionOperator::Type::EXPLICIT;
|
||||
}
|
||||
ConductionOperator oper(fespace, alpha, kappa, u, ode_expression_type);
|
||||
|
||||
u_gf.SetFromTrueDofs(u);
|
||||
{
|
||||
@@ -249,7 +297,7 @@ int main(int argc, char *argv[])
|
||||
u_gf.Save(osol);
|
||||
}
|
||||
|
||||
VisItDataCollection visit_dc("Example16-Parallel", pmesh);
|
||||
VisItDataCollection visit_dc("Example16-Parallel", pmesh.get());
|
||||
visit_dc.RegisterField("temperature", &u_gf);
|
||||
if (visit)
|
||||
{
|
||||
@@ -293,52 +341,76 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// 9. Define the ODE solver used for time integration.
|
||||
double t = 0.0;
|
||||
ODESolver *ode_solver = NULL;
|
||||
CVODESolver *cvode = NULL;
|
||||
ARKStepSolver *arkode = NULL;
|
||||
real_t t = 0.0;
|
||||
std::unique_ptr<ODESolver> ode_solver;
|
||||
switch (ode_solver_type)
|
||||
{
|
||||
// MFEM explicit methods
|
||||
case 1: ode_solver = new ForwardEulerSolver; break;
|
||||
case 2: ode_solver = new RK2Solver(0.5); break; // midpoint method
|
||||
case 3: ode_solver = new RK3SSPSolver; break;
|
||||
case 4: ode_solver = new RK4Solver; break;
|
||||
case 1: ode_solver = std::make_unique<ForwardEulerSolver>(); break;
|
||||
case 2: ode_solver = std::make_unique<RK2Solver>(0.5); break; // midpoint method
|
||||
case 3: ode_solver = std::make_unique<RK3SSPSolver>(); break;
|
||||
case 4: ode_solver = std::make_unique<RK4Solver>(); break;
|
||||
// MFEM implicit L-stable methods
|
||||
case 5: ode_solver = new BackwardEulerSolver; break;
|
||||
case 6: ode_solver = new SDIRK23Solver(2); break;
|
||||
case 7: ode_solver = new SDIRK33Solver; break;
|
||||
case 5: ode_solver = std::make_unique<BackwardEulerSolver>(); break;
|
||||
case 6: ode_solver = std::make_unique<SDIRK23Solver>(2); break;
|
||||
case 7: ode_solver = std::make_unique<SDIRK33Solver>(); break;
|
||||
// CVODE
|
||||
case 8:
|
||||
cvode = new CVODESolver(MPI_COMM_WORLD, CV_ADAMS);
|
||||
cvode->Init(oper);
|
||||
cvode->SetSStolerances(reltol, abstol);
|
||||
cvode->SetMaxStep(dt);
|
||||
ode_solver = cvode; break;
|
||||
case 9:
|
||||
cvode = new CVODESolver(MPI_COMM_WORLD, CV_BDF);
|
||||
{
|
||||
int cvode_solver_type;
|
||||
if (ode_solver_type == 8)
|
||||
{
|
||||
cvode_solver_type = CV_ADAMS;
|
||||
}
|
||||
else
|
||||
{
|
||||
cvode_solver_type = CV_BDF;
|
||||
}
|
||||
std::unique_ptr<CVODESolver> cvode(
|
||||
new CVODESolver(MPI_COMM_WORLD, cvode_solver_type));
|
||||
cvode->Init(oper);
|
||||
cvode->SetSStolerances(reltol, abstol);
|
||||
cvode->SetMaxStep(dt);
|
||||
ode_solver = cvode; break;
|
||||
ode_solver = std::move(cvode);
|
||||
break;
|
||||
}
|
||||
// ARKODE
|
||||
case 10:
|
||||
case 11:
|
||||
arkode = new ARKStepSolver(MPI_COMM_WORLD, ARKStepSolver::EXPLICIT);
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
{
|
||||
ARKStepSolver::Type arkode_solver_type;
|
||||
if (ode_solver_type == 12 || ode_solver_type == 15)
|
||||
{
|
||||
arkode_solver_type = ARKStepSolver::IMPLICIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
arkode_solver_type = ARKStepSolver::EXPLICIT;
|
||||
}
|
||||
std::unique_ptr<ARKStepSolver> arkode(
|
||||
new ARKStepSolver(MPI_COMM_WORLD, arkode_solver_type));
|
||||
arkode->Init(oper);
|
||||
arkode->SetSStolerances(reltol, abstol);
|
||||
arkode->SetMaxStep(dt);
|
||||
if (ode_solver_type == 11)
|
||||
if (ode_solver_type == 11 || ode_solver_type == 14)
|
||||
{
|
||||
arkode->SetERKTableNum(ARKODE_FEHLBERG_13_7_8);
|
||||
}
|
||||
ode_solver = arkode; break;
|
||||
case 12:
|
||||
arkode = new ARKStepSolver(MPI_COMM_WORLD, ARKStepSolver::IMPLICIT);
|
||||
arkode->Init(oper);
|
||||
arkode->SetSStolerances(reltol, abstol);
|
||||
arkode->SetMaxStep(dt);
|
||||
ode_solver = arkode; break;
|
||||
if (use_mass_solver)
|
||||
{
|
||||
arkode->UseMFEMMassLinearSolver(SUNFALSE);
|
||||
}
|
||||
ode_solver = std::move(arkode);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
|
||||
return 3;
|
||||
}
|
||||
|
||||
// Initialize MFEM integrators, SUNDIALS integrators are initialized above
|
||||
@@ -346,12 +418,18 @@ int main(int argc, char *argv[])
|
||||
|
||||
// Since we want to update the diffusion coefficient after every time step,
|
||||
// we need to use the "one-step" mode of the SUNDIALS solvers.
|
||||
if (cvode) { cvode->SetStepMode(CV_ONE_STEP); }
|
||||
if (arkode) { arkode->SetStepMode(ARK_ONE_STEP); }
|
||||
if (CVODESolver* cvode = dynamic_cast<CVODESolver*>(ode_solver.get()))
|
||||
{
|
||||
cvode->SetStepMode(CV_ONE_STEP);
|
||||
}
|
||||
else if (ARKStepSolver* arkode = dynamic_cast<ARKStepSolver*>(ode_solver.get()))
|
||||
{
|
||||
arkode->SetStepMode(ARK_ONE_STEP);
|
||||
}
|
||||
|
||||
// 10. Perform time-integration (looping over the time iterations, ti, with a
|
||||
// time-step dt).
|
||||
if (myid == 0)
|
||||
if (Mpi::Root())
|
||||
{
|
||||
cout << "Integrating the ODE ..." << endl;
|
||||
}
|
||||
@@ -361,7 +439,7 @@ int main(int argc, char *argv[])
|
||||
bool last_step = false;
|
||||
for (int ti = 1; !last_step; ti++)
|
||||
{
|
||||
double dt_real = min(dt, t_final - t);
|
||||
real_t dt_real = min(dt, t_final - t);
|
||||
|
||||
// Note that since we are using the "one-step" mode of the SUNDIALS
|
||||
// solvers, they will, generally, step over the final time and will not
|
||||
@@ -377,8 +455,14 @@ int main(int argc, char *argv[])
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "step " << ti << ", t = " << t << endl;
|
||||
if (cvode) { cvode->PrintInfo(); }
|
||||
if (arkode) { arkode->PrintInfo(); }
|
||||
if (CVODESolver* cvode = dynamic_cast<CVODESolver*>(ode_solver.get()))
|
||||
{
|
||||
cvode->PrintInfo();
|
||||
}
|
||||
else if (ARKStepSolver* arkode = dynamic_cast<ARKStepSolver*>(ode_solver.get()))
|
||||
{
|
||||
arkode->PrintInfo();
|
||||
}
|
||||
}
|
||||
|
||||
u_gf.SetFromTrueDofs(u);
|
||||
@@ -395,46 +479,38 @@ int main(int argc, char *argv[])
|
||||
visit_dc.Save();
|
||||
}
|
||||
}
|
||||
oper.SetParameters(u);
|
||||
oper.SetConductionTensor(u);
|
||||
}
|
||||
tic_toc.Stop();
|
||||
if (myid == 0)
|
||||
if (Mpi::Root())
|
||||
{
|
||||
cout << "Done, " << tic_toc.RealTime() << "s." << endl;
|
||||
}
|
||||
|
||||
// 11. Save the final solution in parallel. This output can be viewed later
|
||||
// using GLVis: "glvis -np <np> -m ex16-mesh -g ex16-final".
|
||||
{
|
||||
ostringstream sol_name;
|
||||
sol_name << "ex16-final." << setfill('0') << setw(6) << myid;
|
||||
ofstream osol(sol_name.str().c_str());
|
||||
osol.precision(precision);
|
||||
u_gf.Save(osol);
|
||||
}
|
||||
|
||||
// 12. Free the used memory.
|
||||
delete ode_solver;
|
||||
delete pmesh;
|
||||
u_gf.Save("ex16-final", precision);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ConductionOperator::ConductionOperator(ParFiniteElementSpace &f, double al,
|
||||
double kap, const Vector &u)
|
||||
: TimeDependentOperator(f.GetTrueVSize(), 0.0), fespace(f), M(NULL), K(NULL),
|
||||
T(NULL),
|
||||
M_solver(f.GetComm()), T_solver(f.GetComm()), z(height)
|
||||
ConductionOperator::ConductionOperator(ParFiniteElementSpace &fes,
|
||||
const real_t alpha, const real_t kappa,
|
||||
const Vector &u,
|
||||
const Type &ode_expression_type)
|
||||
: TimeDependentOperator(fes.GetTrueVSize(), 0.0, ode_expression_type),
|
||||
fespace(fes), alpha(alpha), kappa(kappa), M(&fespace),
|
||||
M_solver(fes.GetComm()), T_solver(fes.GetComm()), z(height)
|
||||
{
|
||||
const double rel_tol = 1e-8;
|
||||
// specify a relative tolerance for all solves with MFEM integrators
|
||||
const real_t rel_tol = 1e-8;
|
||||
|
||||
M = new ParBilinearForm(&fespace);
|
||||
M->AddDomainIntegrator(new MassIntegrator());
|
||||
M->Assemble(0); // keep sparsity pattern of M and K the same
|
||||
M->FormSystemMatrix(ess_tdof_list, Mmat);
|
||||
M.AddDomainIntegrator(new MassIntegrator());
|
||||
M.Assemble(0); // keep zeros to keep sparsity pattern of M and K the same
|
||||
M.FormSystemMatrix(ess_tdof_list, Mmat);
|
||||
|
||||
M_solver.iterative_mode = false;
|
||||
M_solver.SetRelTol(rel_tol);
|
||||
M_solver.SetRelTol(rel_tol); // will be overwritten with SUNDIALS integrators
|
||||
M_solver.SetAbsTol(0.0);
|
||||
M_solver.SetMaxIter(100);
|
||||
M_solver.SetPrintLevel(0);
|
||||
@@ -442,97 +518,118 @@ ConductionOperator::ConductionOperator(ParFiniteElementSpace &f, double al,
|
||||
M_solver.SetPreconditioner(M_prec);
|
||||
M_solver.SetOperator(Mmat);
|
||||
|
||||
alpha = al;
|
||||
kappa = kap;
|
||||
|
||||
T_solver.iterative_mode = false;
|
||||
T_solver.SetRelTol(rel_tol);
|
||||
T_solver.SetRelTol(rel_tol); // will be overwritten with SUNDIALS integrators
|
||||
T_solver.SetAbsTol(0.0);
|
||||
T_solver.SetMaxIter(100);
|
||||
T_solver.SetPrintLevel(0);
|
||||
T_solver.SetPreconditioner(T_prec);
|
||||
|
||||
SetParameters(u);
|
||||
SetConductionTensor(u);
|
||||
}
|
||||
|
||||
void ConductionOperator::Mult(const Vector &u, Vector &du_dt) const
|
||||
{
|
||||
// Compute:
|
||||
// du_dt = M^{-1}*-K(u)
|
||||
// for du_dt
|
||||
Kmat.Mult(u, z);
|
||||
z.Neg(); // z = -z
|
||||
M_solver.Mult(z, du_dt);
|
||||
}
|
||||
|
||||
void ConductionOperator::ImplicitSolve(const double dt,
|
||||
const Vector &u, Vector &du_dt)
|
||||
{
|
||||
// Solve the equation:
|
||||
// du_dt = M^{-1}*[-K(u + dt*du_dt)]
|
||||
// for du_dt
|
||||
if (T) { delete T; }
|
||||
T = Add(1.0, Mmat, dt, Kmat);
|
||||
T_solver.SetOperator(*T);
|
||||
Kmat.Mult(u, z);
|
||||
z.Neg();
|
||||
T_solver.Mult(z, du_dt);
|
||||
}
|
||||
|
||||
int ConductionOperator::SUNImplicitSetup(const Vector &x,
|
||||
const Vector &fx, int jok, int *jcur,
|
||||
double gamma)
|
||||
{
|
||||
// Setup the ODE Jacobian T = M + gamma K.
|
||||
if (T) { delete T; }
|
||||
T = Add(1.0, Mmat, gamma, Kmat);
|
||||
T_solver.SetOperator(*T);
|
||||
*jcur = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int ConductionOperator::SUNImplicitSolve(const Vector &b, Vector &x, double tol)
|
||||
{
|
||||
// Solve the system A x = z => (M - gamma K) x = M b.
|
||||
Mmat.Mult(b, z);
|
||||
T_solver.Mult(z, x);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void ConductionOperator::SetParameters(const Vector &u)
|
||||
void ConductionOperator::SetConductionTensor(const Vector &u)
|
||||
{
|
||||
// Compute K(u_n).
|
||||
ParGridFunction u_alpha_gf(&fespace);
|
||||
u_alpha_gf.SetFromTrueDofs(u);
|
||||
for (int i = 0; i < u_alpha_gf.Size(); i++)
|
||||
{
|
||||
u_alpha_gf(i) = kappa + alpha*u_alpha_gf(i);
|
||||
}
|
||||
|
||||
delete K;
|
||||
K = new ParBilinearForm(&fespace);
|
||||
|
||||
GridFunctionCoefficient u_coeff(&u_alpha_gf);
|
||||
|
||||
K = std::make_unique<ParBilinearForm>(&fespace);
|
||||
K->AddDomainIntegrator(new DiffusionIntegrator(u_coeff));
|
||||
K->Assemble(0); // keep sparsity pattern of M and K the same
|
||||
K->Assemble(0); // keep zeros to keep sparsity pattern of M and K the same
|
||||
K->FormSystemMatrix(ess_tdof_list, Kmat);
|
||||
}
|
||||
|
||||
ConductionOperator::~ConductionOperator()
|
||||
void ConductionOperator::ExplicitMult(const Vector &u, Vector &v) const
|
||||
{
|
||||
delete T;
|
||||
delete M;
|
||||
delete K;
|
||||
// Compute - K(u_n) u.
|
||||
Kmat.Mult(u, v);
|
||||
v.Neg();
|
||||
}
|
||||
|
||||
double InitialTemperature(const Vector &x)
|
||||
void ConductionOperator::Mult(const Vector &u, Vector &k) const
|
||||
{
|
||||
if (x.Norml2() < 0.5)
|
||||
// Compute - inv(M) K(u_n) u.
|
||||
ExplicitMult(u, z);
|
||||
M_solver.Mult(z, k);
|
||||
}
|
||||
|
||||
void ConductionOperator::ImplicitSolve(const real_t gam, const Vector &u,
|
||||
Vector &k)
|
||||
{
|
||||
// Solve for k in M k = - K(u_n) [u + gam*k].
|
||||
ExplicitMult(u, z);
|
||||
T = std::unique_ptr<HypreParMatrix>(Add(1.0, Mmat, gam, Kmat));
|
||||
T_solver.SetOperator(*T);
|
||||
T_solver.Mult(z, k);
|
||||
}
|
||||
|
||||
int ConductionOperator::SUNImplicitSetup(const Vector &u, const Vector &fu,
|
||||
int jok, int *jcur, real_t gam)
|
||||
{
|
||||
// Compute T = M + gamma K(u_n).
|
||||
T = std::unique_ptr<HypreParMatrix>(Add(1.0, Mmat, gam, Kmat));
|
||||
T_solver.SetOperator(*T);
|
||||
*jcur = SUNTRUE; // this should eventually only be set true if K(u) is used
|
||||
return SUNLS_SUCCESS;
|
||||
}
|
||||
|
||||
int ConductionOperator::SUNImplicitSolve(const Vector &r, Vector &dk,
|
||||
real_t tol)
|
||||
{
|
||||
// Solve the system [M + gamma K(u_n)] dk = - K(u_n) u - M k.
|
||||
// What value r is providing depends on the ODE expression form:
|
||||
// EXPLICIT form: r = -inv(M) K(u_n) u - k
|
||||
// IMPLICIT form: r = -K(u_n) u - M k
|
||||
T_solver.SetRelTol(tol);
|
||||
if (isExplicit())
|
||||
{
|
||||
return 2.0;
|
||||
Mmat.Mult(r, z);
|
||||
T_solver.Mult(z, dk);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1.0;
|
||||
T_solver.Mult(r, dk);
|
||||
}
|
||||
if (T_solver.GetConverged())
|
||||
{
|
||||
return SUNLS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SUNLS_CONV_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int ConductionOperator::SUNMassSetup()
|
||||
{
|
||||
// Do nothing b/c mass solver was setup in constructor.
|
||||
return SUNLS_SUCCESS;
|
||||
}
|
||||
|
||||
int ConductionOperator::SUNMassSolve(const Vector &b, Vector &x, real_t tol)
|
||||
{
|
||||
// Solve the system M x = b.
|
||||
M_solver.SetRelTol(tol);
|
||||
M_solver.Mult(b, x);
|
||||
if (M_solver.GetConverged())
|
||||
{
|
||||
return SUNLS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SUNLS_CONV_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int ConductionOperator::SUNMassMult(const Vector &x, Vector &v)
|
||||
{
|
||||
// Compute M x.
|
||||
Mmat.Mult(x, v);
|
||||
return SUNLS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
// MFEM Example 9
|
||||
// SUNDIALS Modification
|
||||
//
|
||||
// Compile with: make ex9
|
||||
// Compile with:
|
||||
// make ex9 (GNU make)
|
||||
// make sundials_ex9 (CMake)
|
||||
//
|
||||
// Sample runs:
|
||||
// ex9 -m ../../data/periodic-segment.mesh -p 0 -r 2 -s 7 -dt 0.005
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
// MFEM Example 9 - Parallel Version
|
||||
// SUNDIALS Modification
|
||||
//
|
||||
// Compile with: make ex9p
|
||||
// Compile with:
|
||||
// make ex9p (GNU make)
|
||||
// make sundials_ex9p (CMake)
|
||||
//
|
||||
// Sample runs:
|
||||
// mpirun -np 4 ex9p -m ../../data/periodic-segment.mesh -p 1 -rp 1 -s 7 -dt 0.0025
|
||||
|
||||
@@ -12,11 +12,10 @@
|
||||
# Use the MFEM build directory
|
||||
MFEM_DIR ?= ../..
|
||||
MFEM_BUILD_DIR ?= ../..
|
||||
MFEM_INSTALL_DIR ?= ../../mfem
|
||||
SRC = $(if $(MFEM_DIR:../..=),$(MFEM_DIR)/examples/sundials/,)
|
||||
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
|
||||
# Use the MFEM install directory
|
||||
# MFEM_INSTALL_DIR = ../../mfem
|
||||
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
|
||||
CONFIG_MK = $(or $(wildcard $(MFEM_BUILD_DIR)/config/config.mk),\
|
||||
$(wildcard $(MFEM_INSTALL_DIR)/share/mfem/config.mk))
|
||||
|
||||
MFEM_LIB_FILE = mfem_is_not_built
|
||||
-include $(CONFIG_MK)
|
||||
@@ -100,6 +99,12 @@ ex10-test-seq: ex10
|
||||
@$(call mfem-test,$<,, $(SERIAL_NAME),$(EX10_ARGS))
|
||||
ex10p-test-par: ex10p
|
||||
@$(call mfem-test,$<, $(RUN_MPI), $(PARALLEL_NAME),$(EX10P_ARGS))
|
||||
# Example 16: test ARKODE with implicit time stepping using mass form
|
||||
EX16_COMMON_ARGS := -s 15
|
||||
ex16-test-seq: ex16
|
||||
@$(call mfem-test,$<,, $(SERIAL_NAME),$(EX16_COMMON_ARGS))
|
||||
ex16p-test-par: ex16p
|
||||
@$(call mfem-test,$<, $(RUN_MPI), $(PARALLEL_NAME),$(EX16_COMMON_ARGS))
|
||||
|
||||
# Testing: "test" target and mfem-test* variables are defined in config/test.mk
|
||||
|
||||
|
||||
@@ -12,11 +12,10 @@
|
||||
# Use the MFEM build directory
|
||||
MFEM_DIR ?= ../..
|
||||
MFEM_BUILD_DIR ?= ../..
|
||||
MFEM_INSTALL_DIR ?= ../../mfem
|
||||
SRC = $(if $(MFEM_DIR:../..=),$(MFEM_DIR)/examples/superlu/,)
|
||||
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
|
||||
# Use the MFEM install directory
|
||||
# MFEM_INSTALL_DIR = ../../mfem
|
||||
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
|
||||
CONFIG_MK = $(or $(wildcard $(MFEM_BUILD_DIR)/config/config.mk),\
|
||||
$(wildcard $(MFEM_INSTALL_DIR)/share/mfem/config.mk))
|
||||
|
||||
MFEM_LIB_FILE = mfem_is_not_built
|
||||
-include $(CONFIG_MK)
|
||||
|
||||
+3
-3
@@ -112,8 +112,6 @@ set(SRCS
|
||||
qinterp/eval_by_vdim.cpp
|
||||
qinterp/grad_by_nodes.cpp
|
||||
qinterp/grad_by_vdim.cpp
|
||||
qinterp/grad_phys_by_nodes.cpp
|
||||
qinterp/grad_phys_by_vdim.cpp
|
||||
qspace.cpp
|
||||
quadinterpolator.cpp
|
||||
quadinterpolator_face.cpp
|
||||
@@ -192,6 +190,9 @@ set(HDRS
|
||||
hybridization.hpp
|
||||
intrules.hpp
|
||||
intrules_cut.hpp
|
||||
kernel_dispatch.hpp
|
||||
kernel_reporter.hpp
|
||||
kernels.hpp
|
||||
ceed/interface/basis.hpp
|
||||
ceed/interface/integrator.hpp
|
||||
ceed/interface/interface.hpp
|
||||
@@ -223,7 +224,6 @@ set(HDRS
|
||||
nonlinearform_ext.hpp
|
||||
nonlininteg.hpp
|
||||
qfunction.hpp
|
||||
qinterp/dispatch.hpp
|
||||
qinterp/eval.hpp
|
||||
qinterp/grad.hpp
|
||||
qspace.hpp
|
||||
|
||||
+470
-66
@@ -280,7 +280,7 @@ void BilinearForm::AddBdrFaceIntegrator(BilinearFormIntegrator *bfi,
|
||||
boundary_face_integs_marker.Append(&bdr_marker);
|
||||
}
|
||||
|
||||
void BilinearForm::ComputeElementMatrix(int i, DenseMatrix &elmat)
|
||||
void BilinearForm::ComputeElementMatrix(int i, DenseMatrix &elmat) const
|
||||
{
|
||||
if (element_matrices)
|
||||
{
|
||||
@@ -289,9 +289,10 @@ void BilinearForm::ComputeElementMatrix(int i, DenseMatrix &elmat)
|
||||
return;
|
||||
}
|
||||
|
||||
const FiniteElement &fe = *fes->GetFE(i);
|
||||
|
||||
if (domain_integs.Size())
|
||||
{
|
||||
const FiniteElement &fe = *fes->GetFE(i);
|
||||
ElementTransformation *eltrans = fes->GetElementTransformation(i);
|
||||
domain_integs[0]->AssembleElementMatrix(fe, *eltrans, elmat);
|
||||
for (int k = 1; k < domain_integs.Size(); k++)
|
||||
@@ -302,17 +303,18 @@ void BilinearForm::ComputeElementMatrix(int i, DenseMatrix &elmat)
|
||||
}
|
||||
else
|
||||
{
|
||||
fes->GetElementVDofs(i, vdofs);
|
||||
elmat.SetSize(vdofs.Size());
|
||||
const int ndof = fe.GetDof() * fes->GetVDim();
|
||||
elmat.SetSize(ndof);
|
||||
elmat = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void BilinearForm::ComputeBdrElementMatrix(int i, DenseMatrix &elmat)
|
||||
void BilinearForm::ComputeBdrElementMatrix(int i, DenseMatrix &elmat) const
|
||||
{
|
||||
const FiniteElement &be = *fes->GetBE(i);
|
||||
|
||||
if (boundary_integs.Size())
|
||||
{
|
||||
const FiniteElement &be = *fes->GetBE(i);
|
||||
ElementTransformation *eltrans = fes->GetBdrElementTransformation(i);
|
||||
boundary_integs[0]->AssembleElementMatrix(be, *eltrans, elmat);
|
||||
for (int k = 1; k < boundary_integs.Size(); k++)
|
||||
@@ -323,8 +325,81 @@ void BilinearForm::ComputeBdrElementMatrix(int i, DenseMatrix &elmat)
|
||||
}
|
||||
else
|
||||
{
|
||||
fes->GetBdrElementVDofs(i, vdofs);
|
||||
elmat.SetSize(vdofs.Size());
|
||||
const int ndof = be.GetDof() * fes->GetVDim();
|
||||
elmat.SetSize(ndof);
|
||||
elmat = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void BilinearForm::ComputeFaceMatrix(int i, DenseMatrix &elmat) const
|
||||
{
|
||||
FaceElementTransformations *tr;
|
||||
Mesh *mesh = fes -> GetMesh();
|
||||
tr = mesh -> GetFaceElementTransformations (i);
|
||||
|
||||
const FiniteElement *fe1, *fe2;
|
||||
fe1 = fes->GetFE(tr->Elem1No);
|
||||
if (tr->Elem2No >= 0)
|
||||
{
|
||||
fe2 = fes->GetFE(tr->Elem2No);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The fe2 object is really a dummy and not used on the
|
||||
// boundaries, but we can't dereference a NULL pointer, and we don't
|
||||
// want to actually make a fake element.
|
||||
fe2 = fe1;
|
||||
}
|
||||
|
||||
if (interior_face_integs.Size())
|
||||
{
|
||||
interior_face_integs[0] -> AssembleFaceMatrix (*fe1, *fe2, *tr, elmat);
|
||||
for (int k = 1; k < interior_face_integs.Size(); k++)
|
||||
{
|
||||
interior_face_integs[k] -> AssembleFaceMatrix (*fe1, *fe2, *tr, elemmat);
|
||||
elmat += elemmat;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int ndof = fe1->GetDof() * fes->GetVDim();
|
||||
if (tr->Elem2No >= 0)
|
||||
{
|
||||
ndof += fe2->GetDof() * fes->GetVDim();
|
||||
}
|
||||
|
||||
elmat.SetSize(ndof);
|
||||
elmat = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void BilinearForm::ComputeBdrFaceMatrix(int i, DenseMatrix &elmat) const
|
||||
{
|
||||
FaceElementTransformations *tr;
|
||||
Mesh *mesh = fes -> GetMesh();
|
||||
tr = mesh -> GetBdrFaceTransformations (i);
|
||||
|
||||
const FiniteElement *fe1, *fe2;
|
||||
|
||||
fe1 = fes -> GetFE (tr -> Elem1No);
|
||||
// The fe2 object is really a dummy and not used on the boundaries,
|
||||
// but we can't dereference a NULL pointer, and we don't want to
|
||||
// actually make a fake element.
|
||||
fe2 = fe1;
|
||||
|
||||
if (boundary_face_integs.Size())
|
||||
{
|
||||
boundary_face_integs[0] -> AssembleFaceMatrix (*fe1, *fe2, *tr, elmat);
|
||||
for (int k = 1; k < boundary_face_integs.Size(); k++)
|
||||
{
|
||||
boundary_face_integs[k] -> AssembleFaceMatrix (*fe1, *fe2, *tr, elemmat);
|
||||
elmat += elemmat;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int ndof = fe1->GetDof() * fes->GetVDim();
|
||||
elmat.SetSize(ndof);
|
||||
elmat = 0.0;
|
||||
}
|
||||
}
|
||||
@@ -1356,32 +1431,50 @@ void MixedBilinearForm::GetBlocks(Array2D<SparseMatrix *> &blocks) const
|
||||
mat->GetBlocks(blocks);
|
||||
}
|
||||
|
||||
void MixedBilinearForm::AddDomainIntegrator (BilinearFormIntegrator * bfi)
|
||||
void MixedBilinearForm::AddDomainIntegrator(BilinearFormIntegrator *bfi)
|
||||
{
|
||||
domain_integs.Append (bfi);
|
||||
domain_integs.Append(bfi);
|
||||
domain_integs_marker.Append(NULL); // NULL marker means apply everywhere
|
||||
}
|
||||
|
||||
void MixedBilinearForm::AddDomainIntegrator (BilinearFormIntegrator * bfi,
|
||||
Array<int> &elem_marker)
|
||||
void MixedBilinearForm::AddDomainIntegrator(BilinearFormIntegrator *bfi,
|
||||
Array<int> &elem_marker)
|
||||
{
|
||||
domain_integs.Append (bfi);
|
||||
domain_integs.Append(bfi);
|
||||
domain_integs_marker.Append(&elem_marker);
|
||||
}
|
||||
|
||||
void MixedBilinearForm::AddBoundaryIntegrator (BilinearFormIntegrator * bfi)
|
||||
void MixedBilinearForm::AddBoundaryIntegrator(BilinearFormIntegrator *bfi)
|
||||
{
|
||||
boundary_integs.Append (bfi);
|
||||
boundary_integs.Append(bfi);
|
||||
boundary_integs_marker.Append(NULL); // NULL marker means apply everywhere
|
||||
}
|
||||
|
||||
void MixedBilinearForm::AddBoundaryIntegrator (BilinearFormIntegrator * bfi,
|
||||
Array<int> &bdr_marker)
|
||||
void MixedBilinearForm::AddBoundaryIntegrator(BilinearFormIntegrator *bfi,
|
||||
Array<int> &bdr_marker)
|
||||
{
|
||||
boundary_integs.Append (bfi);
|
||||
boundary_integs.Append(bfi);
|
||||
boundary_integs_marker.Append(&bdr_marker);
|
||||
}
|
||||
|
||||
void MixedBilinearForm::AddInteriorFaceIntegrator(BilinearFormIntegrator *bfi)
|
||||
{
|
||||
interior_face_integs.Append(bfi);
|
||||
}
|
||||
|
||||
void MixedBilinearForm::AddBdrFaceIntegrator(BilinearFormIntegrator *bfi)
|
||||
{
|
||||
boundary_face_integs.Append(bfi);
|
||||
boundary_face_integs_marker.Append(NULL); // NULL marker means apply everywhere
|
||||
}
|
||||
|
||||
void MixedBilinearForm::AddBdrFaceIntegrator(BilinearFormIntegrator *bfi,
|
||||
Array<int> &bdr_marker)
|
||||
{
|
||||
boundary_face_integs.Append(bfi);
|
||||
boundary_face_integs_marker.Append(&bdr_marker);
|
||||
}
|
||||
|
||||
void MixedBilinearForm::AddTraceFaceIntegrator (BilinearFormIntegrator * bfi)
|
||||
{
|
||||
trace_face_integs.Append (bfi);
|
||||
@@ -1514,6 +1607,108 @@ void MixedBilinearForm::Assemble(int skip_zeros)
|
||||
}
|
||||
}
|
||||
|
||||
if (interior_face_integs.Size())
|
||||
{
|
||||
FaceElementTransformations *ftr;
|
||||
Array<int> trial_vdofs2, test_vdofs2;
|
||||
const FiniteElement *trial_fe1, *trial_fe2, *test_fe1, *test_fe2;
|
||||
|
||||
int nfaces = mesh->GetNumFaces();
|
||||
for (int i = 0; i < nfaces; i++)
|
||||
{
|
||||
ftr = mesh->GetInteriorFaceTransformations(i);
|
||||
if (ftr != NULL)
|
||||
{
|
||||
trial_fes->GetElementVDofs(ftr->Elem1No, trial_vdofs);
|
||||
test_fes->GetElementVDofs(ftr->Elem1No, test_vdofs);
|
||||
trial_fe1 = trial_fes->GetFE(ftr->Elem1No);
|
||||
test_fe1 = test_fes->GetFE(ftr->Elem1No);
|
||||
if (ftr->Elem2No >= 0)
|
||||
{
|
||||
trial_fes->GetElementVDofs(ftr->Elem2No, trial_vdofs2);
|
||||
test_fes->GetElementVDofs(ftr->Elem2No, test_vdofs2);
|
||||
trial_vdofs.Append(trial_vdofs2);
|
||||
test_vdofs.Append(test_vdofs2);
|
||||
trial_fe2 = trial_fes->GetFE(ftr->Elem2No);
|
||||
test_fe2 = test_fes->GetFE(ftr->Elem2No);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The test_fe2 object is really a dummy and not used on the
|
||||
// boundaries, but we can't dereference a NULL pointer, and we don't
|
||||
// want to actually make a fake element.
|
||||
trial_fe2 = trial_fe1;
|
||||
test_fe2 = test_fe1;
|
||||
}
|
||||
for (int k = 0; k < interior_face_integs.Size(); k++)
|
||||
{
|
||||
interior_face_integs[k]->AssembleFaceMatrix(*trial_fe1, *test_fe1, *trial_fe2,
|
||||
*test_fe2,
|
||||
*ftr, elemmat);
|
||||
mat->AddSubMatrix(test_vdofs, trial_vdofs, elemmat, skip_zeros);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (boundary_face_integs.Size())
|
||||
{
|
||||
FaceElementTransformations *ftr;
|
||||
Array<int> tr_vdofs2, te_vdofs2;
|
||||
const FiniteElement *trial_fe1, *trial_fe2, *test_fe1, *test_fe2;
|
||||
|
||||
// Which boundary attributes need to be processed?
|
||||
Array<int> bdr_attr_marker(mesh->bdr_attributes.Size() ?
|
||||
mesh->bdr_attributes.Max() : 0);
|
||||
bdr_attr_marker = 0;
|
||||
for (int k = 0; k < boundary_face_integs.Size(); k++)
|
||||
{
|
||||
if (boundary_face_integs_marker[k] == NULL)
|
||||
{
|
||||
bdr_attr_marker = 1;
|
||||
break;
|
||||
}
|
||||
Array<int> &bdr_marker = *boundary_face_integs_marker[k];
|
||||
MFEM_ASSERT(bdr_marker.Size() == bdr_attr_marker.Size(),
|
||||
"invalid boundary marker for boundary face integrator #"
|
||||
<< k << ", counting from zero");
|
||||
for (int i = 0; i < bdr_attr_marker.Size(); i++)
|
||||
{
|
||||
bdr_attr_marker[i] |= bdr_marker[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < trial_fes -> GetNBE(); i++)
|
||||
{
|
||||
const int bdr_attr = mesh->GetBdrAttribute(i);
|
||||
if (bdr_attr_marker[bdr_attr-1] == 0) { continue; }
|
||||
|
||||
ftr = mesh -> GetBdrFaceTransformations (i);
|
||||
if (ftr != NULL)
|
||||
{
|
||||
trial_fes->GetElementVDofs(ftr->Elem1No, trial_vdofs);
|
||||
test_fes->GetElementVDofs(ftr->Elem1No, test_vdofs);
|
||||
trial_fe1 = trial_fes->GetFE(ftr->Elem1No);
|
||||
test_fe1 = test_fes->GetFE(ftr->Elem1No);
|
||||
// The test_fe2 object is really a dummy and not used on the
|
||||
// boundaries, but we can't dereference a NULL pointer, and we don't
|
||||
// want to actually make a fake element.
|
||||
trial_fe2 = trial_fe1;
|
||||
test_fe2 = test_fe1;
|
||||
for (int k = 0; k < boundary_face_integs.Size(); k++)
|
||||
{
|
||||
if (boundary_face_integs_marker[k] &&
|
||||
(*boundary_face_integs_marker[k])[bdr_attr-1] == 0) { continue; }
|
||||
|
||||
boundary_face_integs[k]->AssembleFaceMatrix(*trial_fe1, *test_fe1, *trial_fe2,
|
||||
*test_fe2,
|
||||
*ftr, elemmat);
|
||||
mat->AddSubMatrix(test_vdofs, trial_vdofs, elemmat, skip_zeros);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (trace_face_integs.Size())
|
||||
{
|
||||
FaceElementTransformations *ftr;
|
||||
@@ -1692,12 +1887,13 @@ void MixedBilinearForm::ConformingAssemble()
|
||||
}
|
||||
|
||||
|
||||
void MixedBilinearForm::ComputeElementMatrix(int i, DenseMatrix &elmat)
|
||||
void MixedBilinearForm::ComputeElementMatrix(int i, DenseMatrix &elmat) const
|
||||
{
|
||||
const FiniteElement &trial_fe = *trial_fes->GetFE(i);
|
||||
const FiniteElement &test_fe = *test_fes->GetFE(i);
|
||||
|
||||
if (domain_integs.Size())
|
||||
{
|
||||
const FiniteElement &trial_fe = *trial_fes->GetFE(i);
|
||||
const FiniteElement &test_fe = *test_fes->GetFE(i);
|
||||
ElementTransformation *eltrans = test_fes->GetElementTransformation(i);
|
||||
domain_integs[0]->AssembleElementMatrix2(trial_fe, test_fe, *eltrans,
|
||||
elmat);
|
||||
@@ -1710,19 +1906,21 @@ void MixedBilinearForm::ComputeElementMatrix(int i, DenseMatrix &elmat)
|
||||
}
|
||||
else
|
||||
{
|
||||
trial_fes->GetElementVDofs(i, trial_vdofs);
|
||||
test_fes->GetElementVDofs(i, test_vdofs);
|
||||
elmat.SetSize(test_vdofs.Size(), trial_vdofs.Size());
|
||||
const int tr_dofs = trial_fe.GetDof() * trial_fes->GetVDim();
|
||||
const int te_dofs = test_fe.GetDof() * test_fes->GetVDim();
|
||||
|
||||
elmat.SetSize(te_dofs, tr_dofs);
|
||||
elmat = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void MixedBilinearForm::ComputeBdrElementMatrix(int i, DenseMatrix &elmat)
|
||||
void MixedBilinearForm::ComputeBdrElementMatrix(int i, DenseMatrix &elmat) const
|
||||
{
|
||||
const FiniteElement &trial_be = *trial_fes->GetBE(i);
|
||||
const FiniteElement &test_be = *test_fes->GetBE(i);
|
||||
|
||||
if (boundary_integs.Size())
|
||||
{
|
||||
const FiniteElement &trial_be = *trial_fes->GetBE(i);
|
||||
const FiniteElement &test_be = *test_fes->GetBE(i);
|
||||
ElementTransformation *eltrans = test_fes->GetBdrElementTransformation(i);
|
||||
boundary_integs[0]->AssembleElementMatrix2(trial_be, test_be, *eltrans,
|
||||
elmat);
|
||||
@@ -1735,9 +1933,191 @@ void MixedBilinearForm::ComputeBdrElementMatrix(int i, DenseMatrix &elmat)
|
||||
}
|
||||
else
|
||||
{
|
||||
trial_fes->GetBdrElementVDofs(i, trial_vdofs);
|
||||
test_fes->GetBdrElementVDofs(i, test_vdofs);
|
||||
elmat.SetSize(test_vdofs.Size(), trial_vdofs.Size());
|
||||
const int tr_dofs = trial_be.GetDof() * trial_fes->GetVDim();
|
||||
const int te_dofs = test_be.GetDof() * test_fes->GetVDim();
|
||||
|
||||
elmat.SetSize(te_dofs, tr_dofs);
|
||||
elmat = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void MixedBilinearForm::ComputeFaceMatrix(int i, DenseMatrix &elmat) const
|
||||
{
|
||||
FaceElementTransformations *ftr;
|
||||
Mesh *mesh = test_fes -> GetMesh();
|
||||
ftr = mesh->GetFaceElementTransformations(i);
|
||||
MFEM_ASSERT(ftr, "No associated face transformations.");
|
||||
|
||||
const FiniteElement *trial_fe1, *trial_fe2, *test_fe1, *test_fe2;
|
||||
|
||||
trial_fe1 = trial_fes->GetFE(ftr->Elem1No);
|
||||
test_fe1 = test_fes->GetFE(ftr->Elem1No);
|
||||
if (ftr->Elem2No >= 0)
|
||||
{
|
||||
trial_fe2 = trial_fes->GetFE(ftr->Elem2No);
|
||||
test_fe2 = test_fes->GetFE(ftr->Elem2No);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The test_fe2 object is really a dummy and not used on the
|
||||
// boundaries, but we can't dereference a NULL pointer, and we don't
|
||||
// want to actually make a fake element.
|
||||
trial_fe2 = trial_fe1;
|
||||
test_fe2 = test_fe1;
|
||||
}
|
||||
|
||||
if (interior_face_integs.Size())
|
||||
{
|
||||
interior_face_integs[0]->AssembleFaceMatrix(*trial_fe1, *test_fe1, *trial_fe2,
|
||||
*test_fe2,
|
||||
*ftr, elmat);
|
||||
for (int k = 1; k < interior_face_integs.Size(); k++)
|
||||
{
|
||||
interior_face_integs[k]->AssembleFaceMatrix(*trial_fe1, *test_fe1, *trial_fe2,
|
||||
*test_fe2,
|
||||
*ftr, elemmat);
|
||||
elmat += elemmat;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int tr_dofs = trial_fe1->GetDof() * trial_fes->GetVDim();
|
||||
int te_dofs = test_fe1->GetDof() * test_fes->GetVDim();
|
||||
if (ftr->Elem2No >= 0)
|
||||
{
|
||||
tr_dofs += trial_fe2->GetDof() * trial_fes->GetVDim();
|
||||
te_dofs += test_fe2->GetDof() * test_fes->GetVDim();
|
||||
}
|
||||
|
||||
elmat.SetSize(te_dofs, tr_dofs);
|
||||
elmat = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void MixedBilinearForm::ComputeBdrFaceMatrix(int i, DenseMatrix &elmat) const
|
||||
{
|
||||
FaceElementTransformations *ftr;
|
||||
Mesh *mesh = test_fes -> GetMesh();
|
||||
ftr = mesh->GetBdrFaceTransformations(i);
|
||||
MFEM_ASSERT(ftr, "No associated boundary face.");
|
||||
|
||||
const FiniteElement *trial_fe1, *trial_fe2, *test_fe1, *test_fe2;
|
||||
|
||||
trial_fe1 = trial_fes->GetFE(ftr->Elem1No);
|
||||
test_fe1 = test_fes->GetFE(ftr->Elem1No);
|
||||
// The test_fe2 object is really a dummy and not used on the
|
||||
// boundaries, but we can't dereference a NULL pointer, and we don't
|
||||
// want to actually make a fake element.
|
||||
trial_fe2 = trial_fe1;
|
||||
test_fe2 = test_fe1;
|
||||
|
||||
if (boundary_face_integs.Size())
|
||||
{
|
||||
boundary_face_integs[0]->AssembleFaceMatrix(*trial_fe1, *test_fe1, *trial_fe2,
|
||||
*test_fe2,
|
||||
*ftr, elmat);
|
||||
for (int k = 1; k < boundary_face_integs.Size(); k++)
|
||||
{
|
||||
boundary_face_integs[k]->AssembleFaceMatrix(*trial_fe1, *test_fe1, *trial_fe2,
|
||||
*test_fe2,
|
||||
*ftr, elemmat);
|
||||
elmat += elemmat;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const int tr_dofs = trial_fe1->GetDof() * trial_fes->GetVDim();
|
||||
const int te_dofs = test_fe1->GetDof() * test_fes->GetVDim();
|
||||
|
||||
elmat.SetSize(te_dofs, tr_dofs);
|
||||
elmat = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void MixedBilinearForm::ComputeTraceFaceMatrix(int i, DenseMatrix &elmat) const
|
||||
{
|
||||
FaceElementTransformations *ftr;
|
||||
Mesh *mesh = test_fes -> GetMesh();
|
||||
ftr = mesh->GetFaceElementTransformations(i);
|
||||
MFEM_ASSERT(ftr, "No associated face transformation.");
|
||||
|
||||
const FiniteElement *trial_face_fe, *test_fe1, *test_fe2;
|
||||
|
||||
trial_face_fe = trial_fes->GetFaceElement(i);
|
||||
test_fe1 = test_fes->GetFE(ftr->Elem1No);
|
||||
if (ftr->Elem2No >= 0)
|
||||
{
|
||||
test_fe2 = test_fes->GetFE(ftr->Elem2No);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The test_fe2 object is really a dummy and not used on the
|
||||
// boundaries, but we can't dereference a NULL pointer, and we don't
|
||||
// want to actually make a fake element.
|
||||
test_fe2 = test_fe1;
|
||||
}
|
||||
|
||||
if (trace_face_integs.Size())
|
||||
{
|
||||
trace_face_integs[0]->AssembleFaceMatrix(*trial_face_fe, *test_fe1, *test_fe2,
|
||||
*ftr, elmat);
|
||||
for (int k = 1; k < trace_face_integs.Size(); k++)
|
||||
{
|
||||
trace_face_integs[k]->AssembleFaceMatrix(*trial_face_fe, *test_fe1, *test_fe2,
|
||||
*ftr, elemmat);
|
||||
elmat += elemmat;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const int tr_face_dofs = trial_face_fe->GetDof() * trial_fes->GetVDim();
|
||||
int te_dofs = test_fe1->GetDof() * test_fes->GetVDim();
|
||||
if (ftr->Elem2No >= 0)
|
||||
{
|
||||
te_dofs += test_fe2->GetDof() * test_fes->GetVDim();
|
||||
}
|
||||
|
||||
elmat.SetSize(te_dofs, tr_face_dofs);
|
||||
elmat = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void MixedBilinearForm::ComputeBdrTraceFaceMatrix(int i,
|
||||
DenseMatrix &elmat) const
|
||||
{
|
||||
FaceElementTransformations *ftr;
|
||||
Mesh *mesh = test_fes -> GetMesh();
|
||||
ftr = mesh->GetBdrFaceTransformations(i);
|
||||
MFEM_ASSERT(ftr, "No associated boundary face.");
|
||||
|
||||
const FiniteElement *trial_face_fe, *test_fe1, *test_fe2;
|
||||
int iface = mesh->GetBdrElementFaceIndex(i);
|
||||
trial_face_fe = trial_fes->GetFaceElement(iface);
|
||||
test_fe1 = test_fes->GetFE(ftr->Elem1No);
|
||||
// The test_fe2 object is really a dummy and not used on the
|
||||
// boundaries, but we can't dereference a NULL pointer, and we don't
|
||||
// want to actually make a fake element.
|
||||
test_fe2 = test_fe1;
|
||||
|
||||
if (boundary_trace_face_integs.Size())
|
||||
{
|
||||
boundary_trace_face_integs[0]->AssembleFaceMatrix(*trial_face_fe, *test_fe1,
|
||||
*test_fe2,
|
||||
*ftr, elmat);
|
||||
for (int k = 1; k < boundary_trace_face_integs.Size(); k++)
|
||||
{
|
||||
boundary_trace_face_integs[k]->AssembleFaceMatrix(*trial_face_fe, *test_fe1,
|
||||
*test_fe2,
|
||||
*ftr, elemmat);
|
||||
elmat += elemmat;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const int tr_face_dofs = trial_face_fe->GetDof() * trial_fes->GetVDim();
|
||||
int te_dofs = test_fe1->GetDof() * test_fes->GetVDim();
|
||||
|
||||
elmat.SetSize(te_dofs, tr_face_dofs);
|
||||
elmat = 0.0;
|
||||
}
|
||||
}
|
||||
@@ -1780,36 +2160,59 @@ void MixedBilinearForm::AssembleBdrElementMatrix(
|
||||
mat->AddSubMatrix(test_vdofs_, trial_vdofs_, elmat, skip_zeros);
|
||||
}
|
||||
|
||||
void MixedBilinearForm::EliminateTrialDofs (
|
||||
void MixedBilinearForm::EliminateTrialEssentialBC(
|
||||
const Array<int> &bdr_attr_is_ess, const Vector &sol, Vector &rhs )
|
||||
{
|
||||
int i, j, k;
|
||||
Array<int> tr_vdofs, cols_marker (trial_fes -> GetVSize());
|
||||
|
||||
cols_marker = 0;
|
||||
for (i = 0; i < trial_fes -> GetNBE(); i++)
|
||||
if (bdr_attr_is_ess[trial_fes -> GetBdrAttribute (i)-1])
|
||||
{
|
||||
trial_fes -> GetBdrElementVDofs (i, tr_vdofs);
|
||||
for (j = 0; j < tr_vdofs.Size(); j++)
|
||||
{
|
||||
if ( (k = tr_vdofs[j]) < 0 )
|
||||
{
|
||||
k = -1-k;
|
||||
}
|
||||
cols_marker[k] = 1;
|
||||
}
|
||||
}
|
||||
mat -> EliminateCols (cols_marker, &sol, &rhs);
|
||||
Array<int> trial_ess_dofs;
|
||||
trial_fes->GetEssentialVDofs(bdr_attr_is_ess, trial_ess_dofs);
|
||||
mat->EliminateCols(trial_ess_dofs, &sol, &rhs);
|
||||
}
|
||||
|
||||
void MixedBilinearForm::EliminateEssentialBCFromTrialDofs (
|
||||
void MixedBilinearForm::EliminateTrialEssentialBC(const Array<int>
|
||||
&bdr_attr_is_ess)
|
||||
{
|
||||
Array<int> trial_ess_dofs;
|
||||
trial_fes->GetEssentialVDofs(bdr_attr_is_ess, trial_ess_dofs);
|
||||
mat->EliminateCols(trial_ess_dofs);
|
||||
}
|
||||
|
||||
void MixedBilinearForm::EliminateTrialVDofs(const Array<int> &trial_vdofs_,
|
||||
const Vector &sol, Vector &rhs)
|
||||
{
|
||||
Array<int> trial_vdofs_marker;
|
||||
FiniteElementSpace::ListToMarker(trial_vdofs_, mat->Width(),
|
||||
trial_vdofs_marker);
|
||||
mat->EliminateCols(trial_vdofs_marker, &sol, &rhs);
|
||||
}
|
||||
|
||||
void MixedBilinearForm::EliminateTrialVDofs(const Array<int> &trial_vdofs_)
|
||||
{
|
||||
if (mat_e == NULL)
|
||||
{
|
||||
mat_e = new SparseMatrix(mat->Height(), mat->Width());
|
||||
}
|
||||
|
||||
Array<int> trial_vdofs_marker;
|
||||
FiniteElementSpace::ListToMarker(trial_vdofs_, mat->Width(),
|
||||
trial_vdofs_marker);
|
||||
mat->EliminateCols(trial_vdofs_marker, *mat_e);
|
||||
mat_e->Finalize();
|
||||
}
|
||||
|
||||
void MixedBilinearForm::EliminateTrialVDofsInRHS(const Array<int> &trial_vdofs_,
|
||||
const Vector &x, Vector &b)
|
||||
{
|
||||
mat_e->AddMult(x, b, -1.);
|
||||
}
|
||||
|
||||
void MixedBilinearForm::EliminateEssentialBCFromTrialDofs(
|
||||
const Array<int> &marked_vdofs, const Vector &sol, Vector &rhs)
|
||||
{
|
||||
mat -> EliminateCols (marked_vdofs, &sol, &rhs);
|
||||
mat->EliminateCols(marked_vdofs, &sol, &rhs);
|
||||
}
|
||||
|
||||
void MixedBilinearForm::EliminateTestDofs (const Array<int> &bdr_attr_is_ess)
|
||||
void MixedBilinearForm::EliminateTestEssentialBC(const Array<int>
|
||||
&bdr_attr_is_ess)
|
||||
{
|
||||
int i, j, k;
|
||||
Array<int> te_vdofs;
|
||||
@@ -1829,6 +2232,14 @@ void MixedBilinearForm::EliminateTestDofs (const Array<int> &bdr_attr_is_ess)
|
||||
}
|
||||
}
|
||||
|
||||
void MixedBilinearForm::EliminateTestVDofs(const Array<int> &test_vdofs_)
|
||||
{
|
||||
for (int i=0; i<test_vdofs_.Size(); ++i)
|
||||
{
|
||||
mat->EliminateRow(test_vdofs_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void MixedBilinearForm::FormRectangularSystemMatrix(
|
||||
const Array<int> &trial_tdof_list,
|
||||
const Array<int> &test_tdof_list,
|
||||
@@ -1865,20 +2276,9 @@ void MixedBilinearForm::FormRectangularSystemMatrix(
|
||||
mat = m;
|
||||
}
|
||||
|
||||
Array<int> ess_trial_tdof_marker, ess_test_tdof_marker;
|
||||
FiniteElementSpace::ListToMarker(trial_tdof_list, trial_fes->GetTrueVSize(),
|
||||
ess_trial_tdof_marker);
|
||||
FiniteElementSpace::ListToMarker(test_tdof_list, test_fes->GetTrueVSize(),
|
||||
ess_test_tdof_marker);
|
||||
EliminateTrialVDofs(trial_tdof_list);
|
||||
EliminateTestVDofs(test_tdof_list);
|
||||
|
||||
mat_e = new SparseMatrix(mat->Height(), mat->Width());
|
||||
mat->EliminateCols(ess_trial_tdof_marker, *mat_e);
|
||||
|
||||
for (int i=0; i<test_tdof_list.Size(); ++i)
|
||||
{
|
||||
mat->EliminateRow(test_tdof_list[i]);
|
||||
}
|
||||
mat_e->Finalize();
|
||||
A.Reset(mat, false);
|
||||
}
|
||||
|
||||
@@ -1907,7 +2307,7 @@ void MixedBilinearForm::FormRectangularLinearSystem(
|
||||
A); // Set A = mat_e
|
||||
}
|
||||
// Eliminate essential BCs with B -= Ab xb
|
||||
mat_e->AddMult(X, B, -1.0);
|
||||
EliminateTrialVDofsInRHS(trial_tdof_list, X, B);
|
||||
|
||||
B.SetSubVector(test_tdof_list, 0.0);
|
||||
}
|
||||
@@ -1933,6 +2333,10 @@ MixedBilinearForm::~MixedBilinearForm()
|
||||
for (i = 0; i < domain_integs.Size(); i++) { delete domain_integs[i]; }
|
||||
for (i = 0; i < boundary_integs.Size(); i++)
|
||||
{ delete boundary_integs[i]; }
|
||||
for (i = 0; i < interior_face_integs.Size(); i++)
|
||||
{ delete interior_face_integs[i]; }
|
||||
for (i = 0; i < boundary_face_integs.Size(); i++)
|
||||
{ delete boundary_face_integs[i]; }
|
||||
for (i = 0; i < trace_face_integs.Size(); i++)
|
||||
{ delete trace_face_integs[i]; }
|
||||
for (i = 0; i < boundary_trace_face_integs.Size(); i++)
|
||||
|
||||
+164
-53
@@ -119,8 +119,8 @@ protected:
|
||||
Array<BilinearFormIntegrator*> boundary_face_integs;
|
||||
Array<Array<int>*> boundary_face_integs_marker; ///< Entries are not owned.
|
||||
|
||||
DenseMatrix elemmat;
|
||||
Array<int> vdofs;
|
||||
mutable DenseMatrix elemmat;
|
||||
mutable Array<int> vdofs;
|
||||
|
||||
DenseTensor *element_matrices; ///< Owned.
|
||||
|
||||
@@ -294,13 +294,13 @@ public:
|
||||
const real_t &operator()(int i, int j) { return (*mat)(i,j); }
|
||||
|
||||
/// Returns a reference to: $ M_{ij} $
|
||||
virtual real_t &Elem(int i, int j);
|
||||
real_t &Elem(int i, int j) override;
|
||||
|
||||
/// Returns constant reference to: $ M_{ij} $
|
||||
virtual const real_t &Elem(int i, int j) const;
|
||||
const real_t &Elem(int i, int j) const override;
|
||||
|
||||
/// Matrix vector multiplication: $ y = M x $
|
||||
virtual void Mult(const Vector &x, Vector &y) const;
|
||||
void Mult(const Vector &x, Vector &y) const override;
|
||||
|
||||
/** @brief Matrix vector multiplication with the original uneliminated
|
||||
matrix. The original matrix is $ M + M_e $ so we have:
|
||||
@@ -309,7 +309,7 @@ public:
|
||||
{ mat->Mult(x, y); mat_e->AddMult(x, y); }
|
||||
|
||||
/// Add the matrix vector multiple to a vector: $ y += a M x $
|
||||
virtual void AddMult(const Vector &x, Vector &y, const real_t a = 1.0) const
|
||||
void AddMult(const Vector &x, Vector &y, const real_t a = 1.0) const override
|
||||
{ mat -> AddMult (x, y, a); }
|
||||
|
||||
/** @brief Add the original uneliminated matrix vector multiple to a vector.
|
||||
@@ -319,8 +319,8 @@ public:
|
||||
{ mat->AddMult(x, y); mat_e->AddMult(x, y); }
|
||||
|
||||
/// Add the matrix transpose vector multiplication: $ y += a M^T x $
|
||||
virtual void AddMultTranspose(const Vector & x, Vector & y,
|
||||
const real_t a = 1.0) const
|
||||
void AddMultTranspose(const Vector & x, Vector & y,
|
||||
const real_t a = 1.0) const override
|
||||
{ mat->AddMultTranspose(x, y, a); }
|
||||
|
||||
/** @brief Add the original uneliminated matrix transpose vector
|
||||
@@ -330,7 +330,7 @@ public:
|
||||
{ mat->AddMultTranspose(x, y); mat_e->AddMultTranspose(x, y); }
|
||||
|
||||
/// Matrix transpose vector multiplication: $ y = M^T x $
|
||||
virtual void MultTranspose(const Vector & x, Vector & y) const;
|
||||
void MultTranspose(const Vector & x, Vector & y) const override;
|
||||
|
||||
/// Compute $ y^T M x $
|
||||
real_t InnerProduct(const Vector &x, const Vector &y) const
|
||||
@@ -338,13 +338,13 @@ public:
|
||||
|
||||
/** @brief Returns a pointer to (approximation) of the matrix inverse:
|
||||
$ M^{-1} $ (currently returns NULL) */
|
||||
virtual MatrixInverse *Inverse() const;
|
||||
MatrixInverse *Inverse() const override;
|
||||
|
||||
/** @brief Finalizes the matrix initialization if the ::AssemblyLevel is
|
||||
AssemblyLevel::LEGACY.
|
||||
The matrix that gets finalized is different if you are using static
|
||||
condensation or hybridization.*/
|
||||
virtual void Finalize(int skip_zeros = 1);
|
||||
void Finalize(int skip_zeros = 1) override;
|
||||
|
||||
/** @brief Returns a const reference to the sparse matrix: $ M $
|
||||
*
|
||||
@@ -458,18 +458,18 @@ public:
|
||||
conforming prolongation, and |.| denotes the entry-wise absolute value.
|
||||
In general, this is just an approximation of the exact diagonal for this
|
||||
case. */
|
||||
virtual void AssembleDiagonal(Vector &diag) const;
|
||||
void AssembleDiagonal(Vector &diag) const override;
|
||||
|
||||
/// Get the finite element space prolongation operator.
|
||||
virtual const Operator *GetProlongation() const
|
||||
const Operator *GetProlongation() const override
|
||||
{ return fes->GetConformingProlongation(); }
|
||||
|
||||
/// Get the finite element space restriction operator
|
||||
virtual const Operator *GetRestriction() const
|
||||
const Operator *GetRestriction() const override
|
||||
{ return fes->GetConformingRestriction(); }
|
||||
|
||||
/// Get the output finite element space prolongation matrix
|
||||
virtual const Operator *GetOutputProlongation() const
|
||||
const Operator *GetOutputProlongation() const override
|
||||
{ return GetProlongation(); }
|
||||
|
||||
/** @brief Returns the output fe space restriction matrix, transposed
|
||||
@@ -477,11 +477,11 @@ public:
|
||||
Logically, this is the transpose of GetOutputRestriction, but in
|
||||
practice it is convenient to have it in transposed form for
|
||||
construction of RAP operators in matrix-free methods. */
|
||||
virtual const Operator *GetOutputRestrictionTranspose() const
|
||||
const Operator *GetOutputRestrictionTranspose() const override
|
||||
{ return fes->GetRestrictionTransposeOperator(); }
|
||||
|
||||
/// Get the output finite element space restriction matrix
|
||||
virtual const Operator *GetOutputRestriction() const
|
||||
const Operator *GetOutputRestriction() const override
|
||||
{ return GetRestriction(); }
|
||||
|
||||
/// Compute serial RAP operator and store it in @a A as a SparseMatrix.
|
||||
@@ -566,7 +566,8 @@ public:
|
||||
FormLinearSystem() method to recover the solution as a GridFunction-size
|
||||
vector in @a x. Use the same arguments as in the FormLinearSystem() call.
|
||||
*/
|
||||
virtual void RecoverFEMSolution(const Vector &X, const Vector &b, Vector &x);
|
||||
void RecoverFEMSolution(const Vector &X, const Vector &b,
|
||||
Vector &x) override;
|
||||
|
||||
/// Compute and store internally all element matrices.
|
||||
void ComputeElementMatrices();
|
||||
@@ -580,10 +581,18 @@ public:
|
||||
or the one stored internally by a prior call of ComputeElementMatrices()
|
||||
is returned when available.
|
||||
*/
|
||||
void ComputeElementMatrix(int i, DenseMatrix &elmat);
|
||||
void ComputeElementMatrix(int i, DenseMatrix &elmat) const;
|
||||
|
||||
/// Compute the boundary element matrix of the given boundary element
|
||||
void ComputeBdrElementMatrix(int i, DenseMatrix &elmat);
|
||||
/** @note The boundary attribute markers of the integrators are ignored. */
|
||||
void ComputeBdrElementMatrix(int i, DenseMatrix &elmat) const;
|
||||
|
||||
/// Compute the face matrix of the given face element
|
||||
void ComputeFaceMatrix(int i, DenseMatrix &elmat) const;
|
||||
|
||||
/// Compute the boundary face matrix of the given boundary element
|
||||
/** @note The boundary attribute markers of the integrators are ignored. */
|
||||
void ComputeBdrFaceMatrix(int i, DenseMatrix &elmat) const;
|
||||
|
||||
/// Assemble the given element matrix
|
||||
/** The element matrix @a elmat is assembled for the element @a i, i.e.
|
||||
@@ -763,6 +772,14 @@ protected:
|
||||
/// Entries are not owned.
|
||||
Array<Array<int>*> boundary_integs_marker;
|
||||
|
||||
/// Interior face integrators.
|
||||
Array<BilinearFormIntegrator*> interior_face_integs;
|
||||
|
||||
/// Boundary face integrators.
|
||||
Array<BilinearFormIntegrator*> boundary_face_integs;
|
||||
/// Entries are not owned.
|
||||
Array<Array<int>*> boundary_face_integs_marker;
|
||||
|
||||
/// Trace face (skeleton) integrators.
|
||||
Array<BilinearFormIntegrator*> trace_face_integs;
|
||||
|
||||
@@ -771,8 +788,8 @@ protected:
|
||||
/// Entries are not owned.
|
||||
Array<Array<int>*> boundary_trace_face_integs_marker;
|
||||
|
||||
DenseMatrix elemmat;
|
||||
Array<int> trial_vdofs, test_vdofs;
|
||||
mutable DenseMatrix elemmat;
|
||||
mutable Array<int> trial_vdofs, test_vdofs;
|
||||
|
||||
private:
|
||||
/// Copy construction is not supported; body is undefined.
|
||||
@@ -803,32 +820,32 @@ public:
|
||||
MixedBilinearForm *mbf);
|
||||
|
||||
/// Returns a reference to: $ M_{ij} $
|
||||
virtual real_t &Elem(int i, int j);
|
||||
real_t &Elem(int i, int j) override;
|
||||
|
||||
/// Returns a reference to: $ M_{ij} $
|
||||
virtual const real_t &Elem(int i, int j) const;
|
||||
const real_t &Elem(int i, int j) const override;
|
||||
|
||||
/// Matrix multiplication: $ y = M x $
|
||||
virtual void Mult(const Vector & x, Vector & y) const;
|
||||
void Mult(const Vector & x, Vector & y) const override;
|
||||
|
||||
/// Add the matrix vector multiple to a vector: $ y += a M x $
|
||||
virtual void AddMult(const Vector & x, Vector & y,
|
||||
const real_t a = 1.0) const;
|
||||
void AddMult(const Vector & x, Vector & y,
|
||||
const real_t a = 1.0) const override;
|
||||
|
||||
/// Matrix transpose vector multiplication: $ y = M^T x $
|
||||
virtual void MultTranspose(const Vector & x, Vector & y) const;
|
||||
void MultTranspose(const Vector & x, Vector & y) const override;
|
||||
|
||||
/// Add the matrix transpose vector multiplication: $ y += a M^T x $
|
||||
virtual void AddMultTranspose(const Vector & x, Vector & y,
|
||||
const real_t a = 1.0) const;
|
||||
void AddMultTranspose(const Vector & x, Vector & y,
|
||||
const real_t a = 1.0) const override;
|
||||
|
||||
/** @brief Returns a pointer to (approximation) of the matrix inverse:
|
||||
$ M^{-1} $ (currently unimplemented and returns NULL)*/
|
||||
virtual MatrixInverse *Inverse() const;
|
||||
MatrixInverse *Inverse() const override;
|
||||
|
||||
/** @brief Finalizes the matrix initialization if the ::AssemblyLevel is
|
||||
AssemblyLevel::LEGACY.*/
|
||||
virtual void Finalize(int skip_zeros = 1);
|
||||
void Finalize(int skip_zeros = 1) override;
|
||||
|
||||
/** @brief Extract the associated matrix as SparseMatrix blocks. The number
|
||||
of block rows and columns is given by the vector dimensions (vdim) of the
|
||||
@@ -839,15 +856,37 @@ public:
|
||||
/** This will segfault if the usual sparse mat is not defined
|
||||
like when static condensation is being used or AllocMat() has
|
||||
not yet been called. */
|
||||
const SparseMatrix &SpMat() const { return *mat; }
|
||||
const SparseMatrix &SpMat() const
|
||||
{
|
||||
MFEM_VERIFY(mat, "mat is NULL and can't be dereferenced");
|
||||
return *mat;
|
||||
}
|
||||
|
||||
/// Returns a reference to the sparse matrix: $ M $
|
||||
SparseMatrix &SpMat() { return *mat; }
|
||||
SparseMatrix &SpMat()
|
||||
{
|
||||
MFEM_VERIFY(mat, "mat is NULL and can't be dereferenced");
|
||||
return *mat;
|
||||
}
|
||||
|
||||
/** @brief Nullifies the internal matrix $ M $ and returns a pointer
|
||||
to it. Used for transferring ownership. */
|
||||
SparseMatrix *LoseMat() { SparseMatrix *tmp = mat; mat = NULL; return tmp; }
|
||||
|
||||
/// Returns a const reference to the sparse matrix of eliminated b.c.: $ M_e $
|
||||
const SparseMatrix &SpMatElim() const
|
||||
{
|
||||
MFEM_VERIFY(mat_e, "mat_e is NULL and can't be dereferenced");
|
||||
return *mat_e;
|
||||
}
|
||||
|
||||
/// Returns a reference to the sparse matrix of eliminated b.c.: $ M_e $
|
||||
SparseMatrix &SpMatElim()
|
||||
{
|
||||
MFEM_VERIFY(mat_e, "mat_e is NULL and can't be dereferenced");
|
||||
return *mat_e;
|
||||
}
|
||||
|
||||
/// Adds a domain integrator. Assumes ownership of @a bfi.
|
||||
void AddDomainIntegrator(BilinearFormIntegrator *bfi);
|
||||
|
||||
@@ -862,6 +901,16 @@ public:
|
||||
void AddBoundaryIntegrator(BilinearFormIntegrator * bfi,
|
||||
Array<int> &bdr_marker);
|
||||
|
||||
/// Adds an interior face integrator. Assumes ownership of @a bfi.
|
||||
void AddInteriorFaceIntegrator(BilinearFormIntegrator *bfi);
|
||||
|
||||
/// Adds a boundary face integrator. Assumes ownership of @a bfi.
|
||||
void AddBdrFaceIntegrator(BilinearFormIntegrator *bfi);
|
||||
|
||||
/// Adds a boundary face integrator. Assumes ownership of @a bfi.
|
||||
void AddBdrFaceIntegrator(BilinearFormIntegrator *bfi,
|
||||
Array<int> &bdr_marker);
|
||||
|
||||
/** @brief Add a trace face integrator. Assumes ownership of @a bfi.
|
||||
|
||||
This type of integrator assembles terms over all faces of the mesh using
|
||||
@@ -892,6 +941,16 @@ public:
|
||||
corresponding pointer (to Array<int>) will be NULL. */
|
||||
Array<Array<int>*> *GetBBFI_Marker() { return &boundary_integs_marker; }
|
||||
|
||||
/// Access all integrators added with AddInteriorFaceIntegrator().
|
||||
Array<BilinearFormIntegrator*> *GetFBFI() { return &interior_face_integs; }
|
||||
|
||||
/// Access all integrators added with AddBdrFaceIntegrator().
|
||||
Array<BilinearFormIntegrator*> *GetBFBFI() { return &boundary_face_integs; }
|
||||
/** @brief Access all boundary markers added with AddBdrFaceIntegrator().
|
||||
If no marker was specified when the integrator was added, the
|
||||
corresponding pointer (to Array<int>) will be NULL. */
|
||||
Array<Array<int>*> *GetBFBFI_Marker() { return &boundary_face_integs_marker; }
|
||||
|
||||
/// Access all integrators added with AddTraceFaceIntegrator().
|
||||
Array<BilinearFormIntegrator*> *GetTFBFI() { return &trace_face_integs; }
|
||||
|
||||
@@ -920,19 +979,19 @@ public:
|
||||
void AssembleDiagonal_ADAt(const Vector &D, Vector &diag) const;
|
||||
|
||||
/// Get the input finite element space prolongation matrix
|
||||
virtual const Operator *GetProlongation() const
|
||||
const Operator *GetProlongation() const override
|
||||
{ return trial_fes->GetProlongationMatrix(); }
|
||||
|
||||
/// Get the input finite element space restriction matrix
|
||||
virtual const Operator *GetRestriction() const
|
||||
const Operator *GetRestriction() const override
|
||||
{ return trial_fes->GetRestrictionMatrix(); }
|
||||
|
||||
/// Get the test finite element space prolongation matrix
|
||||
virtual const Operator *GetOutputProlongation() const
|
||||
const Operator *GetOutputProlongation() const override
|
||||
{ return test_fes->GetProlongationMatrix(); }
|
||||
|
||||
/// Get the test finite element space restriction matrix
|
||||
virtual const Operator *GetOutputRestriction() const
|
||||
const Operator *GetOutputRestriction() const override
|
||||
{ return test_fes->GetRestrictionMatrix(); }
|
||||
|
||||
/** @brief For partially conforming trial and/or test FE spaces, complete the
|
||||
@@ -944,10 +1003,25 @@ public:
|
||||
void ConformingAssemble();
|
||||
|
||||
/// Compute the element matrix of the given element
|
||||
void ComputeElementMatrix(int i, DenseMatrix &elmat);
|
||||
void ComputeElementMatrix(int i, DenseMatrix &elmat) const;
|
||||
|
||||
/// Compute the boundary element matrix of the given boundary element
|
||||
void ComputeBdrElementMatrix(int i, DenseMatrix &elmat);
|
||||
/** @note The boundary attribute markers of the integrators are ignored. */
|
||||
void ComputeBdrElementMatrix(int i, DenseMatrix &elmat) const;
|
||||
|
||||
/// Compute the trace face matrix of the given face element
|
||||
void ComputeTraceFaceMatrix(int i, DenseMatrix &elmat) const;
|
||||
|
||||
/// Compute the boundary trace face matrix of the given boundary element
|
||||
/** @note The boundary attribute markers of the integrators are ignored. */
|
||||
void ComputeBdrTraceFaceMatrix(int i, DenseMatrix &elmat) const;
|
||||
|
||||
/// Compute the face matrix of the given face element
|
||||
void ComputeFaceMatrix(int i, DenseMatrix &elmat) const;
|
||||
|
||||
/// Compute the boundary face matrix of the given boundary element
|
||||
/** @note The boundary attribute markers of the integrators are ignored. */
|
||||
void ComputeBdrFaceMatrix(int i, DenseMatrix &elmat) const;
|
||||
|
||||
/// Assemble the given element matrix
|
||||
/** The element matrix @a elmat is assembled for the element @a i, i.e.
|
||||
@@ -989,24 +1063,61 @@ public:
|
||||
Array<int> &test_vdofs,
|
||||
int skip_zeros = 1);
|
||||
|
||||
/// Eliminate essential boundary DOFs from the columns of the system.
|
||||
/// Eliminate essential boundary trial DOFs from the system.
|
||||
/** The array @a bdr_attr_is_ess marks boundary attributes that constitute
|
||||
the essential part of the boundary. All entries in the columns will be
|
||||
set to 0.0 through elimination.*/
|
||||
void EliminateTrialDofs(const Array<int> &bdr_attr_is_ess,
|
||||
const Vector &sol, Vector &rhs);
|
||||
the essential part of the boundary. */
|
||||
void EliminateTrialEssentialBC(const Array<int> &bdr_attr_is_ess,
|
||||
const Vector &sol, Vector &rhs);
|
||||
|
||||
/// Eliminate the list of DOFs from the columns of the system.
|
||||
/** @a marked_vdofs is the of colunm numbers that will be eliminated. All
|
||||
entries in the columns will be set to 0.0 through elimination.*/
|
||||
/// Eliminate essential boundary trial DOFs from the system matrix.
|
||||
/** The array @a bdr_attr_is_ess marks boundary attributes that constitute
|
||||
the essential part of the boundary. */
|
||||
void EliminateTrialEssentialBC(const Array<int> &bdr_attr_is_ess);
|
||||
|
||||
/// (DEPRECATED) Eliminate essential boundary trial DOFs from the system.
|
||||
/** @see EliminateTrialEssentialBC() */
|
||||
MFEM_DEPRECATED void EliminateTrialDofs(const Array<int> &bdr_attr_is_ess,
|
||||
const Vector &sol, Vector &rhs)
|
||||
{ EliminateTrialEssentialBC(bdr_attr_is_ess, sol, rhs); }
|
||||
|
||||
/// Eliminate the given trial @a vdofs. NOTE: here, @a vdofs is a list of DOFs.
|
||||
/** In this case the eliminations are applied to the internal $ M $
|
||||
and @a rhs without storing the elimination matrix $ M_e $. */
|
||||
void EliminateTrialVDofs(const Array<int> &vdofs, const Vector &sol,
|
||||
Vector &rhs);
|
||||
|
||||
/// Eliminate the given trial @a vdofs, storing the eliminated part internally in $ M_e $.
|
||||
/** This method works in conjunction with EliminateTrialVDofsInRHS() and allows
|
||||
elimination of boundary conditions in multiple right-hand sides. In this
|
||||
method, @a vdofs is a list of DOFs. */
|
||||
void EliminateTrialVDofs(const Array<int> &vdofs);
|
||||
|
||||
/** @brief Use the stored eliminated part of the matrix (see
|
||||
EliminateTrialVDofs(const Array<int> &)) to modify the r.h.s.
|
||||
@a b; @a vdofs is a list of DOFs (non-directional, i.e. >= 0). */
|
||||
void EliminateTrialVDofsInRHS(const Array<int> &vdofs, const Vector &x,
|
||||
Vector &b);
|
||||
|
||||
/** @brief Similar to
|
||||
EliminateTrialVDofs(const Array<int> &, const Vector &, Vector &)
|
||||
but here @a ess_dofs is a marker (boolean) array on all vector-dofs
|
||||
(@a ess_dofs[i] < 0 is true). */
|
||||
void EliminateEssentialBCFromTrialDofs(const Array<int> &marked_vdofs,
|
||||
const Vector &sol, Vector &rhs);
|
||||
|
||||
/// Eliminate essential boundary DOFs from the rows of the system.
|
||||
/// Eliminate essential boundary test DOFs from the system matrix.
|
||||
/** The array @a bdr_attr_is_ess marks boundary attributes that constitute
|
||||
the essential part of the boundary. All entries in the rows will be
|
||||
set to 0.0 through elimination.*/
|
||||
virtual void EliminateTestDofs(const Array<int> &bdr_attr_is_ess);
|
||||
the essential part of the boundary. */
|
||||
void EliminateTestEssentialBC(const Array<int> &bdr_attr_is_ess);
|
||||
|
||||
/// (DEPRECATED) Eliminate essential boundary test DOFs from the system.
|
||||
/** @see EliminateTestEssentialBC() */
|
||||
MFEM_DEPRECATED virtual void EliminateTestDofs(const Array<int>
|
||||
&bdr_attr_is_ess)
|
||||
{ EliminateTestEssentialBC(bdr_attr_is_ess); }
|
||||
|
||||
/// Eliminate the given test @a vdofs. NOTE: here, @a vdofs is a list of DOFs.
|
||||
void EliminateTestVDofs(const Array<int> &vdofs);
|
||||
|
||||
/** @brief Return in @a A that is column-constrained.
|
||||
|
||||
@@ -1162,7 +1273,7 @@ public:
|
||||
|
||||
/** @brief Get the output finite element space restriction matrix in
|
||||
transposed form. */
|
||||
virtual const Operator *GetOutputRestrictionTranspose() const
|
||||
const Operator *GetOutputRestrictionTranspose() const override
|
||||
{ return test_fes->GetRestrictionTransposeOperator(); }
|
||||
};
|
||||
|
||||
|
||||
+50
-45
@@ -37,19 +37,19 @@ protected:
|
||||
public:
|
||||
BilinearFormExtension(BilinearForm *form);
|
||||
|
||||
virtual MemoryClass GetMemoryClass() const
|
||||
MemoryClass GetMemoryClass() const override
|
||||
{ return Device::GetDeviceMemoryClass(); }
|
||||
|
||||
/// Get the finite element space prolongation matrix
|
||||
virtual const Operator *GetProlongation() const;
|
||||
const Operator *GetProlongation() const override;
|
||||
|
||||
/// Get the finite element space restriction matrix
|
||||
virtual const Operator *GetRestriction() const;
|
||||
const Operator *GetRestriction() const override;
|
||||
|
||||
/// Assemble at the level given for the BilinearFormExtension subclass
|
||||
virtual void Assemble() = 0;
|
||||
|
||||
virtual void AssembleDiagonal(Vector &diag) const
|
||||
void AssembleDiagonal(Vector &diag) const override
|
||||
{
|
||||
MFEM_ABORT("AssembleDiagonal not implemented for this assembly level!");
|
||||
}
|
||||
@@ -83,16 +83,17 @@ protected:
|
||||
public:
|
||||
PABilinearFormExtension(BilinearForm*);
|
||||
|
||||
void Assemble();
|
||||
void AssembleDiagonal(Vector &diag) const;
|
||||
void FormSystemMatrix(const Array<int> &ess_tdof_list, OperatorHandle &A);
|
||||
void Assemble() override;
|
||||
void AssembleDiagonal(Vector &diag) const override;
|
||||
void FormSystemMatrix(const Array<int> &ess_tdof_list,
|
||||
OperatorHandle &A) override;
|
||||
void FormLinearSystem(const Array<int> &ess_tdof_list,
|
||||
Vector &x, Vector &b,
|
||||
OperatorHandle &A, Vector &X, Vector &B,
|
||||
int copy_interior = 0);
|
||||
void Mult(const Vector &x, Vector &y) const;
|
||||
void MultTranspose(const Vector &x, Vector &y) const;
|
||||
void Update();
|
||||
int copy_interior = 0) override;
|
||||
void Mult(const Vector &x, Vector &y) const override;
|
||||
void MultTranspose(const Vector &x, Vector &y) const override;
|
||||
void Update() override;
|
||||
|
||||
protected:
|
||||
void SetupRestrictionOperators(const L2FaceValues m);
|
||||
@@ -150,9 +151,9 @@ protected:
|
||||
public:
|
||||
EABilinearFormExtension(BilinearForm *form);
|
||||
|
||||
void Assemble();
|
||||
void Mult(const Vector &x, Vector &y) const;
|
||||
void MultTranspose(const Vector &x, Vector &y) const;
|
||||
void Assemble() override;
|
||||
void Mult(const Vector &x, Vector &y) const override;
|
||||
void MultTranspose(const Vector &x, Vector &y) const override;
|
||||
};
|
||||
|
||||
/// Data and methods for fully-assembled bilinear forms
|
||||
@@ -165,18 +166,19 @@ private:
|
||||
public:
|
||||
FABilinearFormExtension(BilinearForm *form);
|
||||
|
||||
void Assemble();
|
||||
void Assemble() override;
|
||||
void RAP(OperatorHandle &A);
|
||||
/** @note Always does `DIAG_ONE` policy to be consistent with
|
||||
`Operator::FormConstrainedSystemOperator`. */
|
||||
void EliminateBC(const Array<int> &ess_dofs, OperatorHandle &A);
|
||||
void FormSystemMatrix(const Array<int> &ess_tdof_list, OperatorHandle &A);
|
||||
void FormSystemMatrix(const Array<int> &ess_tdof_list,
|
||||
OperatorHandle &A) override;
|
||||
void FormLinearSystem(const Array<int> &ess_tdof_list,
|
||||
Vector &x, Vector &b,
|
||||
OperatorHandle &A, Vector &X, Vector &B,
|
||||
int copy_interior = 0);
|
||||
void Mult(const Vector &x, Vector &y) const;
|
||||
void MultTranspose(const Vector &x, Vector &y) const;
|
||||
int copy_interior = 0) override;
|
||||
void Mult(const Vector &x, Vector &y) const override;
|
||||
void MultTranspose(const Vector &x, Vector &y) const override;
|
||||
|
||||
/** DGMult and DGMultTranspose use the extended L-vector to perform the
|
||||
computation. */
|
||||
@@ -199,16 +201,17 @@ protected:
|
||||
public:
|
||||
MFBilinearFormExtension(BilinearForm *form);
|
||||
|
||||
void Assemble();
|
||||
void AssembleDiagonal(Vector &diag) const;
|
||||
void FormSystemMatrix(const Array<int> &ess_tdof_list, OperatorHandle &A);
|
||||
void Assemble() override;
|
||||
void AssembleDiagonal(Vector &diag) const override;
|
||||
void FormSystemMatrix(const Array<int> &ess_tdof_list,
|
||||
OperatorHandle &A) override;
|
||||
void FormLinearSystem(const Array<int> &ess_tdof_list,
|
||||
Vector &x, Vector &b,
|
||||
OperatorHandle &A, Vector &X, Vector &B,
|
||||
int copy_interior = 0);
|
||||
void Mult(const Vector &x, Vector &y) const;
|
||||
void MultTranspose(const Vector &x, Vector &y) const;
|
||||
void Update();
|
||||
int copy_interior = 0) override;
|
||||
void Mult(const Vector &x, Vector &y) const override;
|
||||
void MultTranspose(const Vector &x, Vector &y) const override;
|
||||
void Update() override;
|
||||
};
|
||||
|
||||
/// Class extending the MixedBilinearForm class to support different AssemblyLevels.
|
||||
@@ -225,20 +228,20 @@ protected:
|
||||
public:
|
||||
MixedBilinearFormExtension(MixedBilinearForm *form);
|
||||
|
||||
virtual MemoryClass GetMemoryClass() const
|
||||
MemoryClass GetMemoryClass() const override
|
||||
{ return Device::GetMemoryClass(); }
|
||||
|
||||
/// Get the finite element space prolongation matrix
|
||||
virtual const Operator *GetProlongation() const;
|
||||
const Operator *GetProlongation() const override;
|
||||
|
||||
/// Get the finite element space restriction matrix
|
||||
virtual const Operator *GetRestriction() const;
|
||||
const Operator *GetRestriction() const override;
|
||||
|
||||
/// Get the output finite element space restriction matrix
|
||||
virtual const Operator *GetOutputProlongation() const;
|
||||
const Operator *GetOutputProlongation() const override;
|
||||
|
||||
/// Get the output finite element space restriction matrix
|
||||
virtual const Operator *GetOutputRestriction() const;
|
||||
const Operator *GetOutputRestriction() const override;
|
||||
|
||||
virtual void Assemble() = 0;
|
||||
virtual void FormRectangularSystemOperator(const Array<int> &trial_tdof_list,
|
||||
@@ -273,7 +276,7 @@ public:
|
||||
PAMixedBilinearFormExtension(MixedBilinearForm *form);
|
||||
|
||||
/// Partial assembly of all internal integrators
|
||||
void Assemble();
|
||||
void Assemble() override;
|
||||
/**
|
||||
@brief Setup OperatorHandle A to contain constrained linear operator
|
||||
|
||||
@@ -283,7 +286,7 @@ public:
|
||||
*/
|
||||
void FormRectangularSystemOperator(const Array<int> &trial_tdof_list,
|
||||
const Array<int> &test_tdof_list,
|
||||
OperatorHandle &A);
|
||||
OperatorHandle &A) override;
|
||||
/**
|
||||
Setup OperatorHandle A to contain constrained linear operator and
|
||||
eliminate columns corresponding to essential dofs from system,
|
||||
@@ -292,20 +295,21 @@ public:
|
||||
void FormRectangularLinearSystem(const Array<int> &trial_tdof_list,
|
||||
const Array<int> &test_tdof_list,
|
||||
Vector &x, Vector &b,
|
||||
OperatorHandle &A, Vector &X, Vector &B);
|
||||
OperatorHandle &A, Vector &X, Vector &B) override;
|
||||
/// y = A*x
|
||||
void Mult(const Vector &x, Vector &y) const;
|
||||
void Mult(const Vector &x, Vector &y) const override;
|
||||
/// y += c*A*x
|
||||
void AddMult(const Vector &x, Vector &y, const real_t c=1.0) const;
|
||||
void AddMult(const Vector &x, Vector &y, const real_t c=1.0) const override;
|
||||
/// y = A^T*x
|
||||
void MultTranspose(const Vector &x, Vector &y) const;
|
||||
void MultTranspose(const Vector &x, Vector &y) const override;
|
||||
/// y += c*A^T*x
|
||||
void AddMultTranspose(const Vector &x, Vector &y, const real_t c=1.0) const;
|
||||
void AddMultTranspose(const Vector &x, Vector &y,
|
||||
const real_t c=1.0) const override;
|
||||
/// Assemble the diagonal of ADA^T for a diagonal vector D.
|
||||
void AssembleDiagonal_ADAt(const Vector &D, Vector &diag) const;
|
||||
void AssembleDiagonal_ADAt(const Vector &D, Vector &diag) const override;
|
||||
|
||||
/// Update internals for when a new MixedBilinearForm is given to this class
|
||||
void Update();
|
||||
void Update() override;
|
||||
};
|
||||
|
||||
|
||||
@@ -322,16 +326,17 @@ public:
|
||||
PADiscreteLinearOperatorExtension(DiscreteLinearOperator *linop);
|
||||
|
||||
/// Partial assembly of all internal integrators
|
||||
void Assemble();
|
||||
void Assemble() override;
|
||||
|
||||
void AddMult(const Vector &x, Vector &y, const real_t c=1.0) const;
|
||||
void AddMult(const Vector &x, Vector &y, const real_t c=1.0) const override;
|
||||
|
||||
void AddMultTranspose(const Vector &x, Vector &y, const real_t c=1.0) const;
|
||||
void AddMultTranspose(const Vector &x, Vector &y,
|
||||
const real_t c=1.0) const override;
|
||||
|
||||
void FormRectangularSystemOperator(const Array<int>&, const Array<int>&,
|
||||
OperatorHandle& A);
|
||||
OperatorHandle& A) override;
|
||||
|
||||
const Operator * GetOutputRestrictionTranspose() const;
|
||||
const Operator * GetOutputRestrictionTranspose() const override;
|
||||
|
||||
private:
|
||||
Vector test_multiplicity;
|
||||
|
||||
+285
-45
@@ -170,6 +170,16 @@ void BilinearFormIntegrator::AssembleFaceMatrix(
|
||||
" is not implemented for this class.");
|
||||
}
|
||||
|
||||
void BilinearFormIntegrator::AssembleFaceMatrix(
|
||||
const FiniteElement &trial_fe1, const FiniteElement &test_fe1,
|
||||
const FiniteElement &trial_fe2, const FiniteElement &test_fe2,
|
||||
FaceElementTransformations &Trans,
|
||||
DenseMatrix &elmat)
|
||||
{
|
||||
MFEM_ABORT("AssembleFaceMatrix (mixed form) is not implemented for this"
|
||||
" Integrator class.");
|
||||
}
|
||||
|
||||
void BilinearFormIntegrator::AssembleFaceMatrix(
|
||||
const FiniteElement &trial_face_fe, const FiniteElement &test_fe1,
|
||||
const FiniteElement &test_fe2, FaceElementTransformations &Trans,
|
||||
@@ -223,28 +233,38 @@ void TransposeIntegrator::SetIntRule(const IntegrationRule *ir)
|
||||
bfi->SetIntRule(ir);
|
||||
}
|
||||
|
||||
void TransposeIntegrator::AssembleElementMatrix (
|
||||
void TransposeIntegrator::AssembleElementMatrix(
|
||||
const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat)
|
||||
{
|
||||
bfi -> AssembleElementMatrix (el, Trans, bfi_elmat);
|
||||
bfi->AssembleElementMatrix(el, Trans, bfi_elmat);
|
||||
// elmat = bfi_elmat^t
|
||||
elmat.Transpose (bfi_elmat);
|
||||
}
|
||||
|
||||
void TransposeIntegrator::AssembleElementMatrix2 (
|
||||
void TransposeIntegrator::AssembleElementMatrix2(
|
||||
const FiniteElement &trial_fe, const FiniteElement &test_fe,
|
||||
ElementTransformation &Trans, DenseMatrix &elmat)
|
||||
{
|
||||
bfi -> AssembleElementMatrix2 (test_fe, trial_fe, Trans, bfi_elmat);
|
||||
bfi->AssembleElementMatrix2(test_fe, trial_fe, Trans, bfi_elmat);
|
||||
// elmat = bfi_elmat^t
|
||||
elmat.Transpose (bfi_elmat);
|
||||
}
|
||||
|
||||
void TransposeIntegrator::AssembleFaceMatrix (
|
||||
void TransposeIntegrator::AssembleFaceMatrix(
|
||||
const FiniteElement &el1, const FiniteElement &el2,
|
||||
FaceElementTransformations &Trans, DenseMatrix &elmat)
|
||||
{
|
||||
bfi -> AssembleFaceMatrix (el1, el2, Trans, bfi_elmat);
|
||||
bfi->AssembleFaceMatrix(el1, el2, Trans, bfi_elmat);
|
||||
// elmat = bfi_elmat^t
|
||||
elmat.Transpose (bfi_elmat);
|
||||
}
|
||||
|
||||
void TransposeIntegrator::AssembleFaceMatrix(
|
||||
const FiniteElement &tr_el1, const FiniteElement &te_el1,
|
||||
const FiniteElement &tr_el2, const FiniteElement &te_el2,
|
||||
FaceElementTransformations &Trans, DenseMatrix &elmat)
|
||||
{
|
||||
bfi->AssembleFaceMatrix(te_el1, tr_el1, te_el2, tr_el2, Trans, bfi_elmat);
|
||||
// elmat = bfi_elmat^t
|
||||
elmat.Transpose (bfi_elmat);
|
||||
}
|
||||
@@ -1222,7 +1242,8 @@ real_t DiffusionIntegrator::ComputeFluxEnergy
|
||||
for (int i = 0; i < ir->GetNPoints(); i++)
|
||||
{
|
||||
const IntegrationPoint &ip = ir->IntPoint(i);
|
||||
fluxelem.CalcShape(ip, shape);
|
||||
Trans.SetIntPoint(&ip);
|
||||
fluxelem.CalcPhysShape(Trans, shape);
|
||||
|
||||
pointflux = 0.0;
|
||||
for (int k = 0; k < spaceDim; k++)
|
||||
@@ -1233,7 +1254,6 @@ real_t DiffusionIntegrator::ComputeFluxEnergy
|
||||
}
|
||||
}
|
||||
|
||||
Trans.SetIntPoint(&ip);
|
||||
real_t w = Trans.Weight() * ip.weight;
|
||||
|
||||
if (MQ)
|
||||
@@ -1410,9 +1430,7 @@ void BoundaryMassIntegrator::AssembleFaceMatrix(
|
||||
// Set the integration point in the face and the neighboring element
|
||||
Trans.SetAllIntPoints(&ip);
|
||||
|
||||
// Access the neighboring element's integration point
|
||||
const IntegrationPoint &eip = Trans.GetElement1IntPoint();
|
||||
el1.CalcShape(eip, shape);
|
||||
el1.CalcPhysShape(*Trans.Elem1, shape);
|
||||
|
||||
w = Trans.Weight() * ip.weight;
|
||||
if (Q)
|
||||
@@ -1582,9 +1600,9 @@ void VectorMassIntegrator::AssembleElementMatrix
|
||||
for (int s = 0; s < ir->GetNPoints(); s++)
|
||||
{
|
||||
const IntegrationPoint &ip = ir->IntPoint(s);
|
||||
el.CalcShape(ip, shape);
|
||||
|
||||
Trans.SetIntPoint (&ip);
|
||||
el.CalcPhysShape(Trans, shape);
|
||||
|
||||
norm = ip.weight * Trans.Weight();
|
||||
|
||||
MultVVt(shape, partelmat);
|
||||
@@ -1666,10 +1684,10 @@ void VectorMassIntegrator::AssembleElementMatrix2(
|
||||
for (int s = 0; s < ir->GetNPoints(); s++)
|
||||
{
|
||||
const IntegrationPoint &ip = ir->IntPoint(s);
|
||||
trial_fe.CalcShape(ip, shape);
|
||||
test_fe.CalcShape(ip, te_shape);
|
||||
|
||||
Trans.SetIntPoint(&ip);
|
||||
trial_fe.CalcPhysShape(Trans, shape);
|
||||
test_fe.CalcPhysShape(Trans, te_shape);
|
||||
|
||||
norm = ip.weight * Trans.Weight();
|
||||
|
||||
MultVWt(te_shape, shape, partelmat);
|
||||
@@ -1897,12 +1915,12 @@ void VectorFECurlIntegrator::AssembleElementMatrix2(
|
||||
if ( trial_fe.GetMapType() == mfem::FiniteElement::H_CURL )
|
||||
{
|
||||
trial_fe.CalcCurlShape(ip, curlshapeTrial_dFT);
|
||||
test_fe.CalcShape(ip, shapeTest);
|
||||
test_fe.CalcPhysShape(Trans, shapeTest);
|
||||
}
|
||||
else
|
||||
{
|
||||
test_fe.CalcCurlShape(ip, curlshapeTrial_dFT);
|
||||
trial_fe.CalcShape(ip, shapeTest);
|
||||
trial_fe.CalcPhysShape(Trans, shapeTest);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1925,6 +1943,89 @@ void VectorFECurlIntegrator::AssembleElementMatrix2(
|
||||
}
|
||||
}
|
||||
|
||||
void VectorFEBoundaryFluxIntegrator::AssembleElementMatrix(
|
||||
const FiniteElement &el, ElementTransformation &Tr,
|
||||
DenseMatrix &elmat)
|
||||
{
|
||||
int nd = el.GetDof();
|
||||
real_t w;
|
||||
|
||||
#ifdef MFEM_THREAD_SAFE
|
||||
Vector shape;
|
||||
#endif
|
||||
elmat.SetSize(nd);
|
||||
shape.SetSize(nd);
|
||||
|
||||
const IntegrationRule *ir = IntRule;
|
||||
if (ir == NULL)
|
||||
{
|
||||
int intorder = 2*el.GetOrder() + Tr.OrderW(); // <----------
|
||||
ir = &IntRules.Get(el.GetGeomType(), intorder);
|
||||
}
|
||||
|
||||
elmat = 0.0;
|
||||
for (int i = 0; i < ir->GetNPoints(); i++)
|
||||
{
|
||||
const IntegrationPoint &ip = ir->IntPoint(i);
|
||||
el.CalcShape(ip, shape);
|
||||
|
||||
Tr.SetIntPoint (&ip);
|
||||
w = ip.weight / Tr.Weight();
|
||||
|
||||
if (Q)
|
||||
{
|
||||
w *= Q->Eval(Tr, ip);
|
||||
}
|
||||
|
||||
AddMult_a_VVt(w, shape, elmat);
|
||||
}
|
||||
}
|
||||
|
||||
void VectorFEBoundaryFluxIntegrator::AssembleElementMatrix2(
|
||||
const FiniteElement &trial_fe,
|
||||
const FiniteElement &test_fe,
|
||||
ElementTransformation &Tr,
|
||||
DenseMatrix &elmat)
|
||||
{
|
||||
int tr_nd = trial_fe.GetDof();
|
||||
int te_nd = test_fe.GetDof();
|
||||
real_t w;
|
||||
|
||||
#ifdef MFEM_THREAD_SAFE
|
||||
Vector shape, te_shape;
|
||||
#endif
|
||||
elmat.SetSize(te_nd, tr_nd);
|
||||
shape.SetSize(tr_nd);
|
||||
te_shape.SetSize(te_nd);
|
||||
|
||||
const IntegrationRule *ir = IntRule;
|
||||
if (ir == NULL)
|
||||
{
|
||||
int order = trial_fe.GetOrder() + test_fe.GetOrder() + Tr.OrderW();
|
||||
|
||||
ir = &IntRules.Get(trial_fe.GetGeomType(), order);
|
||||
}
|
||||
|
||||
elmat = 0.0;
|
||||
for (int i = 0; i < ir->GetNPoints(); i++)
|
||||
{
|
||||
const IntegrationPoint &ip = ir->IntPoint(i);
|
||||
trial_fe.CalcShape(ip, shape);
|
||||
test_fe.CalcShape(ip, te_shape);
|
||||
|
||||
Tr.SetIntPoint (&ip);
|
||||
w = ip.weight / Tr.Weight();
|
||||
|
||||
if (Q)
|
||||
{
|
||||
w *= Q->Eval(Tr, ip);
|
||||
}
|
||||
|
||||
te_shape *= w;
|
||||
AddMultVWt(te_shape, shape, elmat);
|
||||
}
|
||||
}
|
||||
|
||||
void DerivativeIntegrator::AssembleElementMatrix2 (
|
||||
const FiniteElement &trial_fe,
|
||||
const FiniteElement &test_fe,
|
||||
@@ -1981,7 +2082,7 @@ void DerivativeIntegrator::AssembleElementMatrix2 (
|
||||
det = Trans.Weight();
|
||||
Mult (dshape, invdfdx, dshapedxt);
|
||||
|
||||
test_fe.CalcShape(ip, shape);
|
||||
test_fe.CalcPhysShape(Trans, shape);
|
||||
|
||||
for (l = 0; l < trial_nd; l++)
|
||||
{
|
||||
@@ -2566,7 +2667,7 @@ void VectorFEMassIntegrator::AssembleElementMatrix2(
|
||||
Trans.SetIntPoint (&ip);
|
||||
|
||||
trial_fe.CalcVShape(Trans, trial_vshape);
|
||||
test_fe.CalcShape(ip, shape);
|
||||
test_fe.CalcPhysShape(Trans, shape);
|
||||
|
||||
w = ip.weight * Trans.Weight();
|
||||
if (DQ)
|
||||
@@ -2726,11 +2827,11 @@ void VectorDivergenceIntegrator::AssembleElementMatrix2(
|
||||
for (int i = 0; i < ir -> GetNPoints(); i++)
|
||||
{
|
||||
const IntegrationPoint &ip = ir->IntPoint(i);
|
||||
Trans.SetIntPoint (&ip);
|
||||
|
||||
trial_fe.CalcDShape (ip, dshape);
|
||||
test_fe.CalcShape (ip, shape);
|
||||
test_fe.CalcPhysShape (Trans, shape);
|
||||
|
||||
Trans.SetIntPoint (&ip);
|
||||
CalcAdjugate(Trans.Jacobian(), Jadj);
|
||||
|
||||
Mult (dshape, Jadj, gshape);
|
||||
@@ -3231,11 +3332,11 @@ real_t ElasticityIntegrator::ComputeFluxEnergy(const FiniteElement &fluxelem,
|
||||
for (int i = 0; i < ir->GetNPoints(); i++)
|
||||
{
|
||||
const IntegrationPoint &ip = ir->IntPoint(i);
|
||||
fluxelem.CalcShape(ip, shape);
|
||||
Trans.SetIntPoint(&ip);
|
||||
fluxelem.CalcPhysShape(Trans, shape);
|
||||
|
||||
flux_mat.MultTranspose(shape, pointstress);
|
||||
|
||||
Trans.SetIntPoint(&ip);
|
||||
real_t w = Trans.Weight() * ip.weight;
|
||||
|
||||
M = mu->Eval(Trans, ip);
|
||||
@@ -3342,7 +3443,7 @@ void DGTraceIntegrator::AssembleFaceMatrix(const FiniteElement &el1,
|
||||
const IntegrationPoint &eip1 = Trans.GetElement1IntPoint();
|
||||
const IntegrationPoint &eip2 = Trans.GetElement2IntPoint();
|
||||
|
||||
el1.CalcShape(eip1, shape1);
|
||||
el1.CalcPhysShape(*Trans.Elem1, shape1);
|
||||
|
||||
u->Eval(vu, *Trans.Elem1, eip1);
|
||||
|
||||
@@ -3389,7 +3490,7 @@ void DGTraceIntegrator::AssembleFaceMatrix(const FiniteElement &el1,
|
||||
|
||||
if (ndof2)
|
||||
{
|
||||
el2.CalcShape(eip2, shape2);
|
||||
el2.CalcPhysShape(*Trans.Elem2, shape2);
|
||||
|
||||
if (w != 0.0)
|
||||
for (int i = 0; i < ndof2; i++)
|
||||
@@ -3417,6 +3518,150 @@ void DGTraceIntegrator::AssembleFaceMatrix(const FiniteElement &el1,
|
||||
}
|
||||
}
|
||||
|
||||
void DGTraceIntegrator::AssembleFaceMatrix(const FiniteElement &trial_fe1,
|
||||
const FiniteElement &test_fe1,
|
||||
const FiniteElement &trial_fe2,
|
||||
const FiniteElement &test_fe2,
|
||||
FaceElementTransformations &Trans,
|
||||
DenseMatrix &elmat)
|
||||
{
|
||||
int tr_ndof1, te_ndof1, tr_ndof2, te_ndof2;
|
||||
|
||||
real_t un, a, b, w;
|
||||
|
||||
dim = test_fe1.GetDim();
|
||||
tr_ndof1 = trial_fe1.GetDof();
|
||||
te_ndof1 = test_fe1.GetDof();
|
||||
Vector vu(dim), nor(dim);
|
||||
|
||||
if (Trans.Elem2No >= 0)
|
||||
{
|
||||
tr_ndof2 = trial_fe2.GetDof();
|
||||
te_ndof2 = test_fe2.GetDof();
|
||||
}
|
||||
else
|
||||
{
|
||||
tr_ndof2 = 0;
|
||||
te_ndof2 = 0;
|
||||
}
|
||||
|
||||
tr_shape1.SetSize(tr_ndof1);
|
||||
te_shape1.SetSize(te_ndof1);
|
||||
tr_shape2.SetSize(tr_ndof2);
|
||||
te_shape2.SetSize(te_ndof2);
|
||||
elmat.SetSize(te_ndof1 + te_ndof2, tr_ndof1 + tr_ndof2);
|
||||
elmat = 0.0;
|
||||
|
||||
const IntegrationRule *ir = IntRule;
|
||||
if (ir == NULL)
|
||||
{
|
||||
int order;
|
||||
// Assuming order(u)==order(mesh)
|
||||
if (Trans.Elem2No >= 0)
|
||||
order = (min(Trans.Elem1->OrderW(), Trans.Elem2->OrderW()) +
|
||||
max(trial_fe1.GetOrder(), trial_fe2.GetOrder()) +
|
||||
max(test_fe1.GetOrder(), test_fe2.GetOrder()));
|
||||
else
|
||||
{
|
||||
order = Trans.Elem1->OrderW() + trial_fe1.GetOrder() + test_fe1.GetOrder();
|
||||
}
|
||||
if (trial_fe1.Space() == FunctionSpace::Pk)
|
||||
{
|
||||
order++;
|
||||
}
|
||||
ir = &IntRules.Get(Trans.FaceGeom, order);
|
||||
}
|
||||
|
||||
for (int p = 0; p < ir->GetNPoints(); p++)
|
||||
{
|
||||
const IntegrationPoint &ip = ir->IntPoint(p);
|
||||
IntegrationPoint eip1, eip2;
|
||||
Trans.Loc1.Transform(ip, eip1);
|
||||
Trans.Elem1->SetIntPoint(&eip1);
|
||||
if (tr_ndof2 && te_ndof2)
|
||||
{
|
||||
Trans.Loc2.Transform(ip, eip2);
|
||||
Trans.Elem2->SetIntPoint(&eip2);
|
||||
}
|
||||
trial_fe1.CalcPhysShape(*Trans.Elem1, tr_shape1);
|
||||
test_fe1.CalcPhysShape(*Trans.Elem1, te_shape1);
|
||||
|
||||
Trans.Face->SetIntPoint(&ip);
|
||||
|
||||
u->Eval(vu, *Trans.Elem1, eip1);
|
||||
|
||||
if (dim == 1)
|
||||
{
|
||||
nor(0) = 2*eip1.x - 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
CalcOrtho(Trans.Face->Jacobian(), nor);
|
||||
}
|
||||
|
||||
un = vu * nor;
|
||||
a = 0.5 * alpha * un;
|
||||
b = beta * fabs(un);
|
||||
// note: if |alpha/2|==|beta| then |a|==|b|, i.e. (a==b) or (a==-b)
|
||||
// and therefore two blocks in the element matrix contribution
|
||||
// (from the current quadrature point) are 0
|
||||
|
||||
if (rho)
|
||||
{
|
||||
real_t rho_p;
|
||||
if (un >= 0.0 && tr_ndof2 && te_ndof2)
|
||||
{
|
||||
Trans.Elem2->SetIntPoint(&eip2);
|
||||
rho_p = rho->Eval(*Trans.Elem2, eip2);
|
||||
}
|
||||
else
|
||||
{
|
||||
rho_p = rho->Eval(*Trans.Elem1, eip1);
|
||||
}
|
||||
a *= rho_p;
|
||||
b *= rho_p;
|
||||
}
|
||||
|
||||
w = ip.weight * (a+b);
|
||||
if (w != 0.0)
|
||||
{
|
||||
for (int i = 0; i < te_ndof1; i++)
|
||||
for (int j = 0; j < tr_ndof1; j++)
|
||||
{
|
||||
elmat(i, j) += w * te_shape1(i) * tr_shape1(j);
|
||||
}
|
||||
}
|
||||
|
||||
if (tr_ndof2 && te_ndof2)
|
||||
{
|
||||
trial_fe2.CalcPhysShape(*Trans.Elem2, tr_shape2);
|
||||
test_fe2.CalcPhysShape(*Trans.Elem2, te_shape2);
|
||||
|
||||
if (w != 0.0)
|
||||
for (int i = 0; i < te_ndof2; i++)
|
||||
for (int j = 0; j < tr_ndof1; j++)
|
||||
{
|
||||
elmat(te_ndof1+i, j) -= w * te_shape2(i) * tr_shape1(j);
|
||||
}
|
||||
|
||||
w = ip.weight * (b-a);
|
||||
if (w != 0.0)
|
||||
{
|
||||
for (int i = 0; i < te_ndof2; i++)
|
||||
for (int j = 0; j < tr_ndof2; j++)
|
||||
{
|
||||
elmat(te_ndof1+i, tr_ndof1+j) += w * te_shape2(i) * tr_shape2(j);
|
||||
}
|
||||
|
||||
for (int i = 0; i < te_ndof1; i++)
|
||||
for (int j = 0; j < tr_ndof2; j++)
|
||||
{
|
||||
elmat(i, tr_ndof1+j) -= w * te_shape1(i) * tr_shape2(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const IntegrationRule &DGTraceIntegrator::GetRule(
|
||||
Geometry::Type geom, int order, FaceElementTransformations &T)
|
||||
@@ -3939,19 +4184,14 @@ void TraceJumpIntegrator::AssembleFaceMatrix(
|
||||
// Set the integration point in the face and the neighboring elements
|
||||
Trans.SetAllIntPoints(&ip);
|
||||
|
||||
// Access the neighboring elements' integration points
|
||||
// Note: eip2 will only contain valid data if Elem2 exists
|
||||
const IntegrationPoint &eip1 = Trans.GetElement1IntPoint();
|
||||
const IntegrationPoint &eip2 = Trans.GetElement2IntPoint();
|
||||
|
||||
// Trace finite element shape function
|
||||
trial_face_fe.CalcShape(ip, face_shape);
|
||||
// Side 1 finite element shape function
|
||||
test_fe1.CalcShape(eip1, shape1);
|
||||
test_fe1.CalcPhysShape(*Trans.Elem1, shape1);
|
||||
if (ndof2)
|
||||
{
|
||||
// Side 2 finite element shape function
|
||||
test_fe2.CalcShape(eip2, shape2);
|
||||
test_fe2.CalcPhysShape(*Trans.Elem2, shape2);
|
||||
}
|
||||
w = ip.weight;
|
||||
if (trial_face_fe.GetMapType() == FiniteElement::VALUE)
|
||||
@@ -4314,8 +4554,8 @@ struct ShapeCoefficient : public VectorCoefficient
|
||||
: VectorCoefficient(fe_.GetDof()), Q(q), fe(fe_) { }
|
||||
|
||||
using VectorCoefficient::Eval;
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip)
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override
|
||||
{
|
||||
V.SetSize(vdim);
|
||||
fe.CalcPhysShape(T, V);
|
||||
@@ -4357,8 +4597,8 @@ ScalarVectorProductInterpolator::AssembleElementMatrix2(
|
||||
VShapeCoefficient(Coefficient &q, const FiniteElement &fe_, int sdim)
|
||||
: MatrixCoefficient(fe_.GetDof(), sdim), Q(q), fe(fe_) { }
|
||||
|
||||
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip)
|
||||
void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override
|
||||
{
|
||||
M.SetSize(height, width);
|
||||
fe.CalcPhysVShape(T, M);
|
||||
@@ -4394,8 +4634,8 @@ VectorScalarProductInterpolator::AssembleElementMatrix2(
|
||||
: MatrixCoefficient(fe_.GetDof(), vq.GetVDim()), VQ(vq), fe(fe_),
|
||||
vc(width), shape(height) { }
|
||||
|
||||
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip)
|
||||
void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override
|
||||
{
|
||||
M.SetSize(height, width);
|
||||
VQ.Eval(vc, T, ip);
|
||||
@@ -4434,8 +4674,8 @@ ScalarCrossProductInterpolator::AssembleElementMatrix2(
|
||||
vshape(vdim, vq.GetVDim()), vc(vq.GetVDim()) { }
|
||||
|
||||
using VectorCoefficient::Eval;
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip)
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override
|
||||
{
|
||||
V.SetSize(vdim);
|
||||
VQ.Eval(vc, T, ip);
|
||||
@@ -4478,8 +4718,8 @@ VectorCrossProductInterpolator::AssembleElementMatrix2(
|
||||
MFEM_ASSERT(width == 3, "");
|
||||
}
|
||||
|
||||
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip)
|
||||
void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override
|
||||
{
|
||||
M.SetSize(height, width);
|
||||
VQ.Eval(vc, T, ip);
|
||||
@@ -4527,8 +4767,8 @@ struct VDotVShapeCoefficient : public VectorCoefficient
|
||||
vshape(vdim, vq.GetVDim()), vc(vq.GetVDim()) { }
|
||||
|
||||
using VectorCoefficient::Eval;
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip)
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override
|
||||
{
|
||||
V.SetSize(vdim);
|
||||
VQ.Eval(vc, T, ip);
|
||||
|
||||
+555
-469
File diff suppressed because it is too large
Load Diff
+156
-156
@@ -90,12 +90,12 @@ public:
|
||||
explicit ConstantCoefficient(real_t c = 1.0) { constant=c; }
|
||||
|
||||
/// Evaluate the coefficient at @a ip.
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip)
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override
|
||||
{ return (constant); }
|
||||
|
||||
/// Fill the QuadratureFunction @a qf with the constant value.
|
||||
void Project(QuadratureFunction &qf);
|
||||
void Project(QuadratureFunction &qf) override;
|
||||
};
|
||||
|
||||
/** @brief A piecewise constant coefficient with the constants keyed
|
||||
@@ -130,8 +130,8 @@ public:
|
||||
int GetNConst() { return constants.Size(); }
|
||||
|
||||
/// Evaluate the coefficient.
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/** @brief A piecewise coefficient with the pieces keyed off the element
|
||||
@@ -195,7 +195,7 @@ public:
|
||||
{ InitMap(attr, coefs); }
|
||||
|
||||
/// Set the time for time dependent coefficients
|
||||
virtual void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Replace a set of coefficients
|
||||
void UpdateCoefficients(const Array<int> & attr,
|
||||
@@ -211,8 +211,8 @@ public:
|
||||
{ pieces.erase(attr); }
|
||||
|
||||
/// Evaluate the coefficient.
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/// A general function coefficient
|
||||
@@ -254,8 +254,8 @@ public:
|
||||
}
|
||||
|
||||
/// Evaluate the coefficient at @a ip.
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/// A common base class for returning individual components of the domain's
|
||||
@@ -271,8 +271,8 @@ protected:
|
||||
|
||||
public:
|
||||
/// Evaluate the coefficient at @a ip.
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/// Scalar coefficient which returns the x-component of the evaluation point
|
||||
@@ -307,8 +307,8 @@ public:
|
||||
CylindricalRadialCoefficient() : transip(3) {}
|
||||
|
||||
/// Evaluate the coefficient at @a ip.
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/// Scalar coefficient which returns the angular position or azimuth (often
|
||||
@@ -323,8 +323,8 @@ public:
|
||||
CylindricalAzimuthalCoefficient() : transip(3) {}
|
||||
|
||||
/// Evaluate the coefficient at @a ip.
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/// Scalar coefficient which returns the height or altitude of
|
||||
@@ -342,8 +342,8 @@ public:
|
||||
SphericalRadialCoefficient() : transip(3) {}
|
||||
|
||||
/// Evaluate the coefficient at @a ip.
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/// Scalar coefficient which returns the azimuthal angle (often denoted by phi)
|
||||
@@ -357,8 +357,8 @@ public:
|
||||
SphericalAzimuthalCoefficient() : transip(3) {}
|
||||
|
||||
/// Evaluate the coefficient at @a ip.
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/// Scalar coefficient which returns the polar angle (often denoted by theta)
|
||||
@@ -372,8 +372,8 @@ public:
|
||||
SphericalPolarCoefficient() : transip(3) {}
|
||||
|
||||
/// Evaluate the coefficient at @a ip.
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
class GridFunction;
|
||||
@@ -399,15 +399,15 @@ public:
|
||||
const GridFunction * GetGridFunction() const { return GridF; }
|
||||
|
||||
/// Evaluate the coefficient at @a ip.
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
|
||||
/// @brief Fill the QuadratureFunction @a qf by evaluating the coefficient at
|
||||
/// the quadrature points.
|
||||
///
|
||||
/// This function uses the efficient QuadratureFunction::ProjectGridFunction
|
||||
/// to fill the QuadratureFunction.
|
||||
virtual void Project(QuadratureFunction &qf);
|
||||
void Project(QuadratureFunction &qf) override;
|
||||
};
|
||||
|
||||
|
||||
@@ -433,10 +433,10 @@ public:
|
||||
: Q1(q1), Q2(q2), Transform2(std::move(F)) { Transform1 = 0; }
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Evaluate the coefficient at @a ip.
|
||||
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/** @brief Delta function coefficient optionally multiplied by a weight
|
||||
@@ -488,7 +488,7 @@ public:
|
||||
}
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Set the center location of the delta function.
|
||||
void SetDeltaCenter(const Vector& center);
|
||||
@@ -534,7 +534,7 @@ public:
|
||||
virtual real_t EvalDelta(ElementTransformation &T, const IntegrationPoint &ip);
|
||||
/** @brief A DeltaFunction cannot be evaluated. Calling this method will
|
||||
cause an MFEM error, terminating the application. */
|
||||
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip)
|
||||
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override
|
||||
{ mfem_error("DeltaCoefficient::Eval"); return 0.; }
|
||||
virtual ~DeltaCoefficient() { delete weight; }
|
||||
};
|
||||
@@ -555,10 +555,10 @@ public:
|
||||
{ c = &c_; attr.Copy(active_attr); }
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Evaluate the coefficient at @a ip.
|
||||
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip)
|
||||
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override
|
||||
{ return active_attr[T.Attribute-1] ? c->Eval(T, ip, GetTime()) : 0.0; }
|
||||
};
|
||||
|
||||
@@ -628,8 +628,8 @@ public:
|
||||
using VectorCoefficient::Eval;
|
||||
|
||||
/// Evaluate the vector coefficient at @a ip.
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) { V = vec; }
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override { V = vec; }
|
||||
|
||||
/// Return a reference to the constant vector in this class.
|
||||
const Vector& GetVec() const { return vec; }
|
||||
@@ -698,7 +698,7 @@ public:
|
||||
: VectorCoefficient(vd) { InitMap(attr, coefs); }
|
||||
|
||||
/// Set the time for time dependent coefficients
|
||||
virtual void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Replace a set of coefficients
|
||||
void UpdateCoefficients(const Array<int> & attr,
|
||||
@@ -713,8 +713,8 @@ public:
|
||||
{ pieces.erase(attr); }
|
||||
|
||||
/// Evaluate the coefficient.
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
using VectorCoefficient::Eval;
|
||||
};
|
||||
|
||||
@@ -728,8 +728,8 @@ public:
|
||||
|
||||
using VectorCoefficient::Eval;
|
||||
/// Evaluate the vector coefficient at @a ip.
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
|
||||
virtual ~PositionVectorCoefficient() { }
|
||||
};
|
||||
@@ -765,8 +765,8 @@ public:
|
||||
|
||||
using VectorCoefficient::Eval;
|
||||
/// Evaluate the vector coefficient at @a ip.
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
|
||||
virtual ~VectorFunctionCoefficient() { }
|
||||
};
|
||||
@@ -787,7 +787,7 @@ public:
|
||||
explicit VectorArrayCoefficient(int dim);
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Returns i'th coefficient.
|
||||
Coefficient* GetCoeff(int i) { return Coeff[i]; }
|
||||
@@ -806,8 +806,8 @@ public:
|
||||
using VectorCoefficient::Eval;
|
||||
/** @brief Evaluate the coefficient. Each element of vector V comes from the
|
||||
associated array of scalar coefficients. */
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
|
||||
/// Destroys vector coefficient.
|
||||
virtual ~VectorArrayCoefficient();
|
||||
@@ -836,21 +836,21 @@ public:
|
||||
const GridFunction * GetGridFunction() const { return GridFunc; }
|
||||
|
||||
/// Evaluate the vector coefficient at @a ip.
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
|
||||
/** @brief Evaluate the vector coefficients at all of the locations in the
|
||||
integration rule and write the vectors into the columns of matrix @a
|
||||
M. */
|
||||
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationRule &ir);
|
||||
void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationRule &ir) override;
|
||||
|
||||
/// @brief Fill the QuadratureFunction @a qf by evaluating the coefficient at
|
||||
/// the quadrature points.
|
||||
///
|
||||
/// This function uses the efficient QuadratureFunction::ProjectGridFunction
|
||||
/// to fill the QuadratureFunction.
|
||||
virtual void Project(QuadratureFunction &qf);
|
||||
void Project(QuadratureFunction &qf) override;
|
||||
|
||||
virtual ~VectorGridFunctionCoefficient() { }
|
||||
};
|
||||
@@ -874,14 +874,14 @@ public:
|
||||
const GridFunction * GetGridFunction() const { return GridFunc; }
|
||||
|
||||
/// Evaluate the gradient vector coefficient at @a ip.
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
|
||||
/** @brief Evaluate the gradient vector coefficient at all of the locations
|
||||
in the integration rule and write the vectors into columns of matrix @a
|
||||
M. */
|
||||
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationRule &ir);
|
||||
void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationRule &ir) override;
|
||||
|
||||
virtual ~GradientGridFunctionCoefficient() { }
|
||||
};
|
||||
@@ -905,8 +905,8 @@ public:
|
||||
|
||||
using VectorCoefficient::Eval;
|
||||
/// Evaluate the vector curl coefficient at @a ip.
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
|
||||
virtual ~CurlGridFunctionCoefficient() { }
|
||||
};
|
||||
@@ -929,8 +929,8 @@ public:
|
||||
const GridFunction * GetGridFunction() const { return GridFunc; }
|
||||
|
||||
/// Evaluate the scalar divergence coefficient at @a ip.
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
|
||||
virtual ~DivergenceGridFunctionCoefficient() { }
|
||||
};
|
||||
@@ -973,7 +973,7 @@ public:
|
||||
: VectorCoefficient(dir_.Size()), dir(dir_), d(x,y,z,s) { }
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Replace the associated DeltaCoefficient with a new DeltaCoefficient.
|
||||
/** The new DeltaCoefficient cannot have a specified weight Coefficient, i.e.
|
||||
@@ -998,8 +998,8 @@ public:
|
||||
using VectorCoefficient::Eval;
|
||||
/** @brief A VectorDeltaFunction cannot be evaluated. Calling this method
|
||||
will cause an MFEM error, terminating the application. */
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip)
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override
|
||||
{ mfem_error("VectorDeltaCoefficient::Eval"); }
|
||||
virtual ~VectorDeltaCoefficient() { }
|
||||
};
|
||||
@@ -1021,17 +1021,17 @@ public:
|
||||
{ c = &vc; attr.Copy(active_attr); }
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Evaluate the vector coefficient at @a ip.
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
|
||||
/** @brief Evaluate the vector coefficient at all of the locations in the
|
||||
integration rule and write the vectors into the columns of matrix @a
|
||||
M. */
|
||||
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationRule &ir);
|
||||
void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationRule &ir) override;
|
||||
};
|
||||
|
||||
typedef VectorCoefficient DiagonalMatrixCoefficient;
|
||||
@@ -1113,8 +1113,8 @@ public:
|
||||
: MatrixCoefficient(m.Height(), m.Width()), mat(m) { }
|
||||
using MatrixCoefficient::Eval;
|
||||
/// Evaluate the matrix coefficient at @a ip.
|
||||
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) { M = mat; }
|
||||
void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override { M = mat; }
|
||||
/// Return a reference to the constant matrix.
|
||||
const DenseMatrix& GetMatrix() { return mat; }
|
||||
};
|
||||
@@ -1207,7 +1207,7 @@ public:
|
||||
: MatrixCoefficient(h, w, symm) { InitMap(attr, coefs); }
|
||||
|
||||
/// Set the time for time dependent coefficients
|
||||
virtual void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Replace a set of coefficients
|
||||
void UpdateCoefficients(const Array<int> & attr,
|
||||
@@ -1222,8 +1222,8 @@ public:
|
||||
{ pieces.erase(attr); }
|
||||
|
||||
/// Evaluate the coefficient.
|
||||
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(DenseMatrix &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/** @brief A matrix coefficient with an optional scalar coefficient multiplier
|
||||
@@ -1280,16 +1280,16 @@ public:
|
||||
{ }
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Evaluate the matrix coefficient at @a ip.
|
||||
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(DenseMatrix &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
|
||||
/// (DEPRECATED) Evaluate the symmetric matrix coefficient at @a ip.
|
||||
/** @deprecated Use Eval() instead. */
|
||||
virtual void EvalSymmetric(Vector &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void EvalSymmetric(Vector &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
|
||||
virtual ~MatrixFunctionCoefficient() { }
|
||||
};
|
||||
@@ -1310,7 +1310,7 @@ public:
|
||||
explicit MatrixArrayCoefficient (int dim);
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Get the coefficient located at (i,j) in the matrix.
|
||||
Coefficient* GetCoeff (int i, int j) { return Coeff[i*width+j]; }
|
||||
@@ -1328,8 +1328,8 @@ public:
|
||||
{ return Coeff[i*width+j] ? Coeff[i*width+j] -> Eval(T, ip, GetTime()) : 0.0; }
|
||||
|
||||
/// Evaluate the matrix coefficient @a ip.
|
||||
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(DenseMatrix &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
|
||||
virtual ~MatrixArrayCoefficient();
|
||||
};
|
||||
@@ -1392,11 +1392,11 @@ public:
|
||||
{ c = &mc; attr.Copy(active_attr); }
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Evaluate the matrix coefficient at @a ip.
|
||||
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(DenseMatrix &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/// Coefficients based on sums, products, or other functions of coefficients.
|
||||
@@ -1425,7 +1425,7 @@ public:
|
||||
: aConst(0.0), a(&A), b(&B), alpha(alpha_), beta(beta_) { }
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Reset the first term in the linear combination as a constant
|
||||
void SetAConst(real_t A) { a = NULL; aConst = A; }
|
||||
@@ -1453,8 +1453,8 @@ public:
|
||||
real_t GetBeta() const { return beta; }
|
||||
|
||||
/// Evaluate the coefficient at @a ip.
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip)
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override
|
||||
{
|
||||
return alpha * ((a == NULL ) ? aConst : a->Eval(T, ip) )
|
||||
+ beta * b->Eval(T, ip);
|
||||
@@ -1502,8 +1502,8 @@ public:
|
||||
@note When this method is called, the caller must make sure that the
|
||||
IntegrationPoint associated with @a T is the same as @a ip. This can be
|
||||
achieved by calling T.SetIntPoint(&ip). */
|
||||
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(DenseMatrix &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
|
||||
|
||||
/// @deprecated Return a reference to the internal matrix used when evaluating this coefficient as a DenseMatrix.
|
||||
@@ -1525,8 +1525,8 @@ public:
|
||||
: SymmetricMatrixCoefficient(m.Height()), mat(m) { }
|
||||
using SymmetricMatrixCoefficient::Eval;
|
||||
/// Evaluate the matrix coefficient at @a ip.
|
||||
virtual void Eval(DenseSymmetricMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) { M = mat; }
|
||||
void Eval(DenseSymmetricMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override { M = mat; }
|
||||
|
||||
/// Return a reference to the constant matrix.
|
||||
const DenseSymmetricMatrix& GetMatrix() { return mat; }
|
||||
@@ -1576,12 +1576,12 @@ public:
|
||||
{ }
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
using SymmetricMatrixCoefficient::Eval;
|
||||
/// Evaluate the matrix coefficient at @a ip.
|
||||
virtual void Eval(DenseSymmetricMatrix &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(DenseSymmetricMatrix &K, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
|
||||
virtual ~SymmetricMatrixFunctionCoefficient() { }
|
||||
};
|
||||
@@ -1606,7 +1606,7 @@ public:
|
||||
: aConst(0.0), a(&A), b(&B) { }
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Reset the first term in the product as a constant
|
||||
void SetAConst(real_t A) { a = NULL; aConst = A; }
|
||||
@@ -1624,8 +1624,8 @@ public:
|
||||
Coefficient * GetBCoef() const { return b; }
|
||||
|
||||
/// Evaluate the coefficient at @a ip.
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip)
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override
|
||||
{ return ((a == NULL ) ? aConst : a->Eval(T, ip) ) * b->Eval(T, ip); }
|
||||
};
|
||||
|
||||
@@ -1654,7 +1654,7 @@ public:
|
||||
: aConst(0.0), bConst(B), a(&A), b(NULL) { }
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Reset the numerator in the ratio as a constant
|
||||
void SetAConst(real_t A) { a = NULL; aConst = A; }
|
||||
@@ -1677,8 +1677,8 @@ public:
|
||||
Coefficient * GetBCoef() const { return b; }
|
||||
|
||||
/// Evaluate the coefficient
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip)
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override
|
||||
{
|
||||
real_t den = (b == NULL ) ? bConst : b->Eval(T, ip);
|
||||
MFEM_ASSERT(den != 0.0, "Division by zero in RatioCoefficient");
|
||||
@@ -1700,7 +1700,7 @@ public:
|
||||
: a(&A), p(p_) { }
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Reset the base coefficient
|
||||
void SetACoef(Coefficient &A) { a = &A; }
|
||||
@@ -1713,8 +1713,8 @@ public:
|
||||
real_t GetExponent() const { return p; }
|
||||
|
||||
/// Evaluate the coefficient at @a ip.
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip)
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override
|
||||
{ return pow(a->Eval(T, ip), p); }
|
||||
};
|
||||
|
||||
@@ -1733,7 +1733,7 @@ public:
|
||||
InnerProductCoefficient(VectorCoefficient &A, VectorCoefficient &B);
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Reset the first vector in the inner product
|
||||
void SetACoef(VectorCoefficient &A) { a = &A; }
|
||||
@@ -1746,8 +1746,8 @@ public:
|
||||
VectorCoefficient * GetBCoef() const { return b; }
|
||||
|
||||
/// Evaluate the coefficient at @a ip.
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/// Scalar coefficient defined as a cross product of two vectors in the xy-plane.
|
||||
@@ -1765,7 +1765,7 @@ public:
|
||||
VectorRotProductCoefficient(VectorCoefficient &A, VectorCoefficient &B);
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Reset the first vector in the product
|
||||
void SetACoef(VectorCoefficient &A) { a = &A; }
|
||||
@@ -1778,8 +1778,8 @@ public:
|
||||
VectorCoefficient * GetBCoef() const { return b; }
|
||||
|
||||
/// Evaluate the coefficient at @a ip.
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/// Scalar coefficient defined as the determinant of a matrix coefficient
|
||||
@@ -1795,7 +1795,7 @@ public:
|
||||
DeterminantCoefficient(MatrixCoefficient &A);
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Reset the matrix coefficient
|
||||
void SetACoef(MatrixCoefficient &A) { a = &A; }
|
||||
@@ -1803,8 +1803,8 @@ public:
|
||||
MatrixCoefficient * GetACoef() const { return a; }
|
||||
|
||||
/// Evaluate the determinant coefficient at @a ip.
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/// Scalar coefficient defined as the trace of a matrix coefficient
|
||||
@@ -1820,7 +1820,7 @@ public:
|
||||
TraceCoefficient(MatrixCoefficient &A);
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Reset the matrix coefficient
|
||||
void SetACoef(MatrixCoefficient &A) { a = &A; }
|
||||
@@ -1828,8 +1828,8 @@ public:
|
||||
MatrixCoefficient * GetACoef() const { return a; }
|
||||
|
||||
/// Evaluate the trace coefficient at @a ip.
|
||||
virtual real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/// Vector coefficient defined as the linear combination of two vectors
|
||||
@@ -1866,7 +1866,7 @@ public:
|
||||
Coefficient &alpha_, Coefficient &beta_);
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Reset the first vector coefficient
|
||||
void SetACoef(VectorCoefficient &A_) { ACoef = &A_; }
|
||||
@@ -1909,8 +1909,8 @@ public:
|
||||
real_t GetBeta() const { return beta; }
|
||||
|
||||
/// Evaluate the coefficient at @a ip.
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
using VectorCoefficient::Eval;
|
||||
};
|
||||
|
||||
@@ -1930,7 +1930,7 @@ public:
|
||||
ScalarVectorProductCoefficient(Coefficient &A, VectorCoefficient &B);
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Reset the scalar factor as a constant
|
||||
void SetAConst(real_t A) { a = NULL; aConst = A; }
|
||||
@@ -1948,8 +1948,8 @@ public:
|
||||
VectorCoefficient * GetBCoef() const { return b; }
|
||||
|
||||
/// Evaluate the coefficient at @a ip.
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
using VectorCoefficient::Eval;
|
||||
};
|
||||
|
||||
@@ -1971,7 +1971,7 @@ public:
|
||||
NormalizedVectorCoefficient(VectorCoefficient &A, real_t tol = 1e-6);
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Reset the vector coefficient
|
||||
void SetACoef(VectorCoefficient &A) { a = &A; }
|
||||
@@ -1979,8 +1979,8 @@ public:
|
||||
VectorCoefficient * GetACoef() const { return a; }
|
||||
|
||||
/// Evaluate the coefficient at @a ip.
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
using VectorCoefficient::Eval;
|
||||
};
|
||||
|
||||
@@ -1999,7 +1999,7 @@ public:
|
||||
VectorCrossProductCoefficient(VectorCoefficient &A, VectorCoefficient &B);
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Reset the first term in the product
|
||||
void SetACoef(VectorCoefficient &A) { a = &A; }
|
||||
@@ -2012,8 +2012,8 @@ public:
|
||||
VectorCoefficient * GetBCoef() const { return b; }
|
||||
|
||||
/// Evaluate the coefficient at @a ip.
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
using VectorCoefficient::Eval;
|
||||
};
|
||||
|
||||
@@ -2033,7 +2033,7 @@ public:
|
||||
MatrixVectorProductCoefficient(MatrixCoefficient &A, VectorCoefficient &B);
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Reset the matrix coefficient
|
||||
void SetACoef(MatrixCoefficient &A) { a = &A; }
|
||||
@@ -2046,8 +2046,8 @@ public:
|
||||
VectorCoefficient * GetBCoef() const { return b; }
|
||||
|
||||
/// Evaluate the vector coefficient at @a ip.
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
using VectorCoefficient::Eval;
|
||||
};
|
||||
|
||||
@@ -2066,8 +2066,8 @@ public:
|
||||
: MatrixCoefficient(d, d), dim(d) { }
|
||||
|
||||
/// Evaluate the matrix coefficient at @a ip.
|
||||
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/// Matrix coefficient defined as the linear combination of two matrices
|
||||
@@ -2088,7 +2088,7 @@ public:
|
||||
real_t alpha_ = 1.0, real_t beta_ = 1.0);
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Reset the first matrix coefficient
|
||||
void SetACoef(MatrixCoefficient &A) { a = &A; }
|
||||
@@ -2111,8 +2111,8 @@ public:
|
||||
real_t GetBeta() const { return beta; }
|
||||
|
||||
/// Evaluate the matrix coefficient at @a ip.
|
||||
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/// Matrix coefficient defined as the product of two matrices
|
||||
@@ -2140,8 +2140,8 @@ public:
|
||||
MatrixCoefficient * GetBCoef() const { return b; }
|
||||
|
||||
/// Evaluate the matrix coefficient at @a ip.
|
||||
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/** @brief Matrix coefficient defined as a product of a scalar coefficient and a
|
||||
@@ -2161,7 +2161,7 @@ public:
|
||||
ScalarMatrixProductCoefficient(Coefficient &A, MatrixCoefficient &B);
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Reset the scalar factor as a constant
|
||||
void SetAConst(real_t A) { a = NULL; aConst = A; }
|
||||
@@ -2179,8 +2179,8 @@ public:
|
||||
MatrixCoefficient * GetBCoef() const { return b; }
|
||||
|
||||
/// Evaluate the matrix coefficient at @a ip.
|
||||
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/// Matrix coefficient defined as the transpose of a matrix coefficient
|
||||
@@ -2194,7 +2194,7 @@ public:
|
||||
TransposeMatrixCoefficient(MatrixCoefficient &A);
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Reset the matrix coefficient
|
||||
void SetACoef(MatrixCoefficient &A) { a = &A; }
|
||||
@@ -2202,8 +2202,8 @@ public:
|
||||
MatrixCoefficient * GetACoef() const { return a; }
|
||||
|
||||
/// Evaluate the matrix coefficient at @a ip.
|
||||
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/// Matrix coefficient defined as the inverse of a matrix coefficient.
|
||||
@@ -2217,7 +2217,7 @@ public:
|
||||
InverseMatrixCoefficient(MatrixCoefficient &A);
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Reset the matrix coefficient
|
||||
void SetACoef(MatrixCoefficient &A) { a = &A; }
|
||||
@@ -2225,8 +2225,8 @@ public:
|
||||
MatrixCoefficient * GetACoef() const { return a; }
|
||||
|
||||
/// Evaluate the matrix coefficient at @a ip.
|
||||
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/// Matrix coefficient defined as the exponential of a matrix coefficient.
|
||||
@@ -2240,7 +2240,7 @@ public:
|
||||
ExponentialMatrixCoefficient(MatrixCoefficient &A);
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Reset the matrix coefficient
|
||||
void SetACoef(MatrixCoefficient &A) { a = &A; }
|
||||
@@ -2248,8 +2248,8 @@ public:
|
||||
MatrixCoefficient * GetACoef() const { return a; }
|
||||
|
||||
/// Evaluate the matrix coefficient at @a ip.
|
||||
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/// Matrix coefficient defined as the outer product of two vector coefficients.
|
||||
@@ -2267,7 +2267,7 @@ public:
|
||||
OuterProductCoefficient(VectorCoefficient &A, VectorCoefficient &B);
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Reset the first vector in the outer product
|
||||
void SetACoef(VectorCoefficient &A) { a = &A; }
|
||||
@@ -2280,8 +2280,8 @@ public:
|
||||
VectorCoefficient * GetBCoef() const { return b; }
|
||||
|
||||
/// Evaluate the matrix coefficient at @a ip.
|
||||
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
|
||||
/** @brief Matrix coefficient defined as -a k x k x, for a vector k and scalar a
|
||||
@@ -2305,7 +2305,7 @@ public:
|
||||
CrossCrossCoefficient(Coefficient &A, VectorCoefficient &K);
|
||||
|
||||
/// Set the time for internally stored coefficients
|
||||
void SetTime(real_t t);
|
||||
void SetTime(real_t t) override;
|
||||
|
||||
/// Reset the scalar factor as a constant
|
||||
void SetAConst(real_t A) { a = NULL; aConst = A; }
|
||||
@@ -2323,8 +2323,8 @@ public:
|
||||
VectorCoefficient * GetKCoef() const { return k; }
|
||||
|
||||
/// Evaluate the matrix coefficient at @a ip.
|
||||
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(DenseMatrix &M, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
};
|
||||
///@}
|
||||
|
||||
@@ -2349,10 +2349,10 @@ public:
|
||||
const QuadratureFunction& GetQuadFunction() const { return QuadF; }
|
||||
|
||||
using VectorCoefficient::Eval;
|
||||
virtual void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip);
|
||||
void Eval(Vector &V, ElementTransformation &T,
|
||||
const IntegrationPoint &ip) override;
|
||||
|
||||
virtual void Project(QuadratureFunction &qf);
|
||||
void Project(QuadratureFunction &qf) override;
|
||||
|
||||
virtual ~VectorQuadratureFunctionCoefficient() { }
|
||||
};
|
||||
@@ -2371,9 +2371,9 @@ public:
|
||||
|
||||
const QuadratureFunction& GetQuadFunction() const { return QuadF; }
|
||||
|
||||
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
|
||||
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
|
||||
|
||||
virtual void Project(QuadratureFunction &qf);
|
||||
void Project(QuadratureFunction &qf) override;
|
||||
|
||||
virtual ~QuadratureFunctionCoefficient() { }
|
||||
};
|
||||
|
||||
@@ -943,6 +943,7 @@ void ParaViewDataCollection::Save()
|
||||
pvtu_out << "<PDataArray type=\"" << GetDataTypeString()
|
||||
<< "\" Name=\"" << field_it.first
|
||||
<< "\" NumberOfComponents=\"" << vec_dim << "\" "
|
||||
<< VTKComponentLabels(vec_dim) << " "
|
||||
<< "format=\"" << GetDataFormatString() << "\" />\n";
|
||||
}
|
||||
pvtu_out << "</PPointData>\n";
|
||||
@@ -977,6 +978,7 @@ void ParaViewDataCollection::Save()
|
||||
pvtu_out << "<PDataArray type=\"" << GetDataTypeString()
|
||||
<< "\" Name=\"" << q_field_name
|
||||
<< "\" NumberOfComponents=\"" << vec_dim << "\" "
|
||||
<< VTKComponentLabels(vec_dim) << " "
|
||||
<< "format=\"" << GetDataFormatString() << "\" />\n";
|
||||
pvtu_out << "</PPointData>\n";
|
||||
WritePVTUFooter(pvtu_out, q_field_name);
|
||||
@@ -1069,8 +1071,9 @@ void ParaViewDataCollection::SaveGFieldVTU(std::ostream &os, int ref_,
|
||||
int vec_dim = it->second->VectorDim();
|
||||
os << "<DataArray type=\"" << GetDataTypeString()
|
||||
<< "\" Name=\"" << it->first
|
||||
<< "\" NumberOfComponents=\"" << vec_dim << "\""
|
||||
<< " format=\"" << GetDataFormatString() << "\" >" << '\n';
|
||||
<< "\" NumberOfComponents=\"" << vec_dim << "\" "
|
||||
<< VTKComponentLabels(vec_dim) << " "
|
||||
<< "format=\"" << GetDataFormatString() << "\" >" << '\n';
|
||||
if (vec_dim == 1)
|
||||
{
|
||||
// scalar data
|
||||
|
||||
+11
-11
@@ -454,28 +454,28 @@ public:
|
||||
#endif
|
||||
|
||||
/// Set/change the mesh associated with the collection
|
||||
virtual void SetMesh(Mesh *new_mesh) override;
|
||||
void SetMesh(Mesh *new_mesh) override;
|
||||
|
||||
#ifdef MFEM_USE_MPI
|
||||
/// Set/change the mesh associated with the collection.
|
||||
virtual void SetMesh(MPI_Comm comm, Mesh *new_mesh) override;
|
||||
void SetMesh(MPI_Comm comm, Mesh *new_mesh) override;
|
||||
#endif
|
||||
|
||||
/// Add a grid function to the collection and update the root file
|
||||
virtual void RegisterField(const std::string& field_name,
|
||||
GridFunction *gf) override;
|
||||
void RegisterField(const std::string& field_name,
|
||||
GridFunction *gf) override;
|
||||
|
||||
/// Add a quadrature function to the collection and update the root file.
|
||||
/** Visualization of quadrature function is not supported in VisIt(3.12).
|
||||
A patch has been sent to VisIt developers in June 2020. */
|
||||
virtual void RegisterQField(const std::string& q_field_name,
|
||||
QuadratureFunction *qf) override;
|
||||
void RegisterQField(const std::string& q_field_name,
|
||||
QuadratureFunction *qf) override;
|
||||
|
||||
/// Set the number of digits used for both the cycle and the MPI rank
|
||||
/// @note VisIt seems to require 6 pad digits for the MPI rank. Therefore,
|
||||
/// this function uses this default value. This behavior can be overridden
|
||||
/// by calling SetPadDigitsCycle() and SetPadDigitsRank() instead.
|
||||
virtual void SetPadDigits(int digits) override
|
||||
void SetPadDigits(int digits) override
|
||||
{ pad_digits_cycle=digits; pad_digits_rank=6; }
|
||||
|
||||
/// Set VisIt parameter: default levels of detail for the MultiresControl
|
||||
@@ -489,13 +489,13 @@ public:
|
||||
void DeleteAll();
|
||||
|
||||
/// Save the collection and a VisIt root file
|
||||
virtual void Save() override;
|
||||
void Save() override;
|
||||
|
||||
/// Save a VisIt root file for the collection
|
||||
void SaveRootFile();
|
||||
|
||||
/// Load the collection based on its VisIt data (described in its root file)
|
||||
virtual void Load(int cycle_ = 0) override;
|
||||
void Load(int cycle_ = 0) override;
|
||||
|
||||
/// We will delete the mesh and fields if we own them
|
||||
virtual ~VisItDataCollection() {}
|
||||
@@ -546,7 +546,7 @@ public:
|
||||
|
||||
/// Save the collection - the directory name is constructed based on the
|
||||
/// cycle value
|
||||
virtual void Save() override;
|
||||
void Save() override;
|
||||
|
||||
/// Set the data format for the ParaView output files. Possible options are
|
||||
/// VTKFormat::ASCII, VTKFormat::BINARY, and VTKFormat::BINARY32.
|
||||
@@ -590,7 +590,7 @@ public:
|
||||
void UseRestartMode(bool restart_mode_);
|
||||
|
||||
/// Load the collection - not implemented in the ParaView writer
|
||||
virtual void Load(int cycle_ = 0) override;
|
||||
void Load(int cycle_ = 0) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+31
-16
@@ -52,6 +52,15 @@ protected:
|
||||
const DenseMatrix &EvalTransAdjugateJ();
|
||||
const DenseMatrix &EvalInverseJ();
|
||||
|
||||
/// @name Tolerance used for point comparisons
|
||||
///@{
|
||||
#ifdef MFEM_USE_DOUBLE
|
||||
static constexpr real_t tol_0 = 1e-15;
|
||||
#elif defined(MFEM_USE_SINGLE)
|
||||
static constexpr real_t tol_0 = 1e-7;
|
||||
#endif
|
||||
///@}
|
||||
|
||||
public:
|
||||
|
||||
/** This enumeration declares the values stored in
|
||||
@@ -176,7 +185,7 @@ public:
|
||||
returned. This method is not 100 percent reliable for non-linear
|
||||
transformations. */
|
||||
virtual int TransformBack(const Vector &pt, IntegrationPoint &ip,
|
||||
const real_t phys_tol = 1e-15) = 0;
|
||||
const real_t phys_tol = tol_0) = 0;
|
||||
|
||||
virtual ~ElementTransformation() { }
|
||||
};
|
||||
@@ -281,9 +290,15 @@ public:
|
||||
rel_qpts_order(-1),
|
||||
solver_type(NewtonElementProject),
|
||||
max_iter(16),
|
||||
#ifdef MFEM_USE_DOUBLE
|
||||
ref_tol(1e-15),
|
||||
phys_rtol(1e-15),
|
||||
ip_tol(1e-8),
|
||||
#elif defined(MFEM_USE_SINGLE)
|
||||
ref_tol(1e-7),
|
||||
phys_rtol(1e-7),
|
||||
ip_tol(1e-4),
|
||||
#endif
|
||||
print_level(-1)
|
||||
{ }
|
||||
|
||||
@@ -370,10 +385,10 @@ private:
|
||||
|
||||
/** @brief Evaluate the Jacobian of the transformation at the IntPoint and
|
||||
store it in dFdx. */
|
||||
virtual const DenseMatrix &EvalJacobian();
|
||||
const DenseMatrix &EvalJacobian() override;
|
||||
// Evaluate the Hessian of the transformation at the IntPoint and store it
|
||||
// in d2Fdx2.
|
||||
virtual const DenseMatrix &EvalHessian();
|
||||
const DenseMatrix &EvalHessian() override;
|
||||
|
||||
public:
|
||||
IsoparametricTransformation() : FElem(NULL) {}
|
||||
@@ -415,32 +430,32 @@ public:
|
||||
|
||||
/** @brief Transform integration point from reference coordinates to
|
||||
physical coordinates and store them in the vector. */
|
||||
virtual void Transform(const IntegrationPoint &, Vector &);
|
||||
void Transform(const IntegrationPoint &, Vector &) override;
|
||||
|
||||
/** @brief Transform all the integration points from the integration rule
|
||||
from reference coordinates to physical
|
||||
coordinates and store them as column vectors in the matrix. */
|
||||
virtual void Transform(const IntegrationRule &, DenseMatrix &);
|
||||
void Transform(const IntegrationRule &, DenseMatrix &) override;
|
||||
|
||||
/** @brief Transform all the integration points from the column vectors
|
||||
of @a matrix from reference coordinates to physical
|
||||
coordinates and store them as column vectors in @a result. */
|
||||
virtual void Transform(const DenseMatrix &matrix, DenseMatrix &result);
|
||||
void Transform(const DenseMatrix &matrix, DenseMatrix &result) override;
|
||||
|
||||
/// Return the order of the current element we are using for the transformation.
|
||||
virtual int Order() const { return FElem->GetOrder(); }
|
||||
int Order() const override { return FElem->GetOrder(); }
|
||||
|
||||
/// Return the order of the elements of the Jacobian of the transformation.
|
||||
virtual int OrderJ() const;
|
||||
int OrderJ() const override;
|
||||
|
||||
/** @brief Return the order of the determinant of the Jacobian (weight)
|
||||
of the transformation. */
|
||||
virtual int OrderW() const;
|
||||
int OrderW() const override;
|
||||
|
||||
/// Return the order of $ adj(J)^T \nabla fi $
|
||||
virtual int OrderGrad(const FiniteElement *fe) const;
|
||||
int OrderGrad(const FiniteElement *fe) const override;
|
||||
|
||||
virtual int GetSpaceDim() const { return PointMat.Height(); }
|
||||
int GetSpaceDim() const override { return PointMat.Height(); }
|
||||
|
||||
/** @brief Transform a point @a pt from physical space to a point @a ip in
|
||||
reference space and optionally can set a solver tolerance using @a phys_tol. */
|
||||
@@ -448,8 +463,8 @@ public:
|
||||
point in physical space. If the inversion fails a non-zero value is
|
||||
returned. This method is not 100 percent reliable for non-linear
|
||||
transformations. */
|
||||
virtual int TransformBack(const Vector & v, IntegrationPoint & ip,
|
||||
const real_t phys_rel_tol = 1e-15)
|
||||
int TransformBack (const Vector & v, IntegrationPoint & ip,
|
||||
const real_t phys_rel_tol = tol_0) override
|
||||
{
|
||||
InverseElementTransformation inv_tr(this);
|
||||
inv_tr.SetPhysicalRelTol(phys_rel_tol);
|
||||
@@ -589,9 +604,9 @@ public:
|
||||
has been configured. */
|
||||
const IntegrationPoint &GetElement2IntPoint() { return eip2; }
|
||||
|
||||
virtual void Transform(const IntegrationPoint &, Vector &);
|
||||
virtual void Transform(const IntegrationRule &, DenseMatrix &);
|
||||
virtual void Transform(const DenseMatrix &matrix, DenseMatrix &result);
|
||||
void Transform(const IntegrationPoint &, Vector &) override;
|
||||
void Transform(const IntegrationRule &, DenseMatrix &) override;
|
||||
void Transform(const DenseMatrix &matrix, DenseMatrix &result) override;
|
||||
|
||||
ElementTransformation & GetElement1Transformation();
|
||||
ElementTransformation & GetElement2Transformation();
|
||||
|
||||
+13
-13
@@ -172,10 +172,10 @@ public:
|
||||
void SetFluxAveraging(int fa) { flux_averaging = fa; }
|
||||
|
||||
/// Return the total error from the last error estimate.
|
||||
virtual real_t GetTotalError() const override { return total_error; }
|
||||
real_t GetTotalError() const override { return total_error; }
|
||||
|
||||
/// Get a Vector with all element errors.
|
||||
virtual const Vector &GetLocalErrors() override
|
||||
const Vector &GetLocalErrors() override
|
||||
{
|
||||
if (MeshIsModified()) { ComputeEstimates(); }
|
||||
return error_estimates;
|
||||
@@ -184,14 +184,14 @@ public:
|
||||
/** @brief Get an Array<int> with anisotropic flags for all mesh elements.
|
||||
Return an empty array when anisotropic estimates are not available or
|
||||
enabled. */
|
||||
virtual const Array<int> &GetAnisotropicFlags() override
|
||||
const Array<int> &GetAnisotropicFlags() override
|
||||
{
|
||||
if (MeshIsModified()) { ComputeEstimates(); }
|
||||
return aniso_flags;
|
||||
}
|
||||
|
||||
/// Reset the error estimator.
|
||||
virtual void Reset() override { current_sequence = -1; }
|
||||
void Reset() override { current_sequence = -1; }
|
||||
|
||||
/** @brief Destroy a ZienkiewiczZhuEstimator object. Destroys, if owned, the
|
||||
FiniteElementSpace, flux_space. */
|
||||
@@ -298,17 +298,17 @@ public:
|
||||
}
|
||||
|
||||
/// Return the total error from the last error estimate.
|
||||
virtual real_t GetTotalError() const override { return total_error; }
|
||||
real_t GetTotalError() const override { return total_error; }
|
||||
|
||||
/// Get a Vector with all element errors.
|
||||
virtual const Vector &GetLocalErrors() override
|
||||
const Vector &GetLocalErrors() override
|
||||
{
|
||||
if (MeshIsModified()) { ComputeEstimates(); }
|
||||
return error_estimates;
|
||||
}
|
||||
|
||||
/// Reset the error estimator.
|
||||
virtual void Reset() override { current_sequence = -1; }
|
||||
void Reset() override { current_sequence = -1; }
|
||||
|
||||
virtual ~LSZienkiewiczZhuEstimator() { }
|
||||
};
|
||||
@@ -411,17 +411,17 @@ public:
|
||||
void SetLocalErrorNormP(int p) { local_norm_p = p; }
|
||||
|
||||
/// Return the total error from the last error estimate.
|
||||
virtual real_t GetTotalError() const override { return total_error; }
|
||||
real_t GetTotalError() const override { return total_error; }
|
||||
|
||||
/// Get a Vector with all element errors.
|
||||
virtual const Vector &GetLocalErrors() override
|
||||
const Vector &GetLocalErrors() override
|
||||
{
|
||||
if (MeshIsModified()) { ComputeEstimates(); }
|
||||
return error_estimates;
|
||||
}
|
||||
|
||||
/// Reset the error estimator.
|
||||
virtual void Reset() override { current_sequence = -1; }
|
||||
void Reset() override { current_sequence = -1; }
|
||||
|
||||
/** @brief Destroy a L2ZienkiewiczZhuEstimator object. Destroys, if owned,
|
||||
the FiniteElementSpace, flux_space. */
|
||||
@@ -505,10 +505,10 @@ public:
|
||||
void SetCoef(VectorCoefficient &A) { vcoef = &A; }
|
||||
|
||||
/// Reset the error estimator.
|
||||
virtual void Reset() override { current_sequence = -1; }
|
||||
void Reset() override { current_sequence = -1; }
|
||||
|
||||
/// Get a Vector with all element errors.
|
||||
virtual const Vector &GetLocalErrors() override
|
||||
const Vector &GetLocalErrors() override
|
||||
{
|
||||
if (MeshIsModified()) { ComputeEstimates(); }
|
||||
return error_estimates;
|
||||
@@ -661,7 +661,7 @@ public:
|
||||
/// Reset the error estimator.
|
||||
void Reset() override { current_sequence = -1; };
|
||||
|
||||
virtual real_t GetTotalError() const override { return total_error; }
|
||||
real_t GetTotalError() const override { return total_error; }
|
||||
|
||||
/** @brief Change the method to compute hₑ on a per-element basis.
|
||||
@param compute_element_coefficient_
|
||||
|
||||
+26
-25
@@ -394,7 +394,32 @@ public:
|
||||
/// Get a const reference to the nodes of the element
|
||||
const IntegrationRule & GetNodes() const { return Nodes; }
|
||||
|
||||
// virtual functions for finite elements on vector spaces
|
||||
/** @brief Evaluate the Hessians of all shape functions of a scalar finite
|
||||
element in reference space at the given point @a ip. */
|
||||
/** Each row of the result DenseMatrix @a Hessian contains upper triangular
|
||||
part of the Hessian of one shape function.
|
||||
The order in 2D is {u_xx, u_xy, u_yy}.
|
||||
The size (#dof x (#dim (#dim+1)/2) of @a Hessian must be set in advance.*/
|
||||
virtual void CalcHessian(const IntegrationPoint &ip,
|
||||
DenseMatrix &Hessian) const;
|
||||
|
||||
/** @brief Evaluate the Hessian of all shape functions of a scalar finite
|
||||
element in physical space at the given point @a ip. */
|
||||
/** The size (#dof, #dim*(#dim+1)/2) of @a Hessian must be set in advance. */
|
||||
void CalcPhysHessian(ElementTransformation &Trans,
|
||||
DenseMatrix& Hessian) const;
|
||||
|
||||
/** @brief Evaluate the Laplacian of all shape functions of a scalar finite
|
||||
element in physical space at the given point @a ip. */
|
||||
/** The size (#dof) of @a Laplacian must be set in advance. */
|
||||
void CalcPhysLaplacian(ElementTransformation &Trans,
|
||||
Vector& Laplacian) const;
|
||||
|
||||
/** @brief Evaluate the Laplacian of all shape functions of a scalar finite
|
||||
element in physical space at the given point @a ip. */
|
||||
/** The size (#dof) of @a Laplacian must be set in advance. */
|
||||
void CalcPhysLinLaplacian(ElementTransformation &Trans,
|
||||
Vector& Laplacian) const;
|
||||
|
||||
/** @brief Evaluate the values of all shape functions of a *vector* finite
|
||||
element in reference space at the given point @a ip. */
|
||||
@@ -454,30 +479,6 @@ public:
|
||||
*/
|
||||
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const;
|
||||
|
||||
/** @brief Evaluate the Hessians of all shape functions of a scalar finite
|
||||
element in reference space at the given point @a ip. */
|
||||
/** Each row of the result DenseMatrix @a Hessian contains upper triangular
|
||||
part of the Hessian of one shape function.
|
||||
The order in 2D is {u_xx, u_xy, u_yy}.
|
||||
The size (#dof x (#dim (#dim+1)/2) of @a Hessian must be set in advance.*/
|
||||
virtual void CalcHessian(const IntegrationPoint &ip,
|
||||
DenseMatrix &Hessian) const;
|
||||
|
||||
/** @brief Evaluate the Hessian of all shape functions of a scalar finite
|
||||
element in reference space at the given point @a ip. */
|
||||
/** The size (#dof, #dim*(#dim+1)/2) of @a Hessian must be set in advance. */
|
||||
virtual void CalcPhysHessian(ElementTransformation &Trans,
|
||||
DenseMatrix& Hessian) const;
|
||||
|
||||
/** @brief Evaluate the Laplacian of all shape functions of a scalar finite
|
||||
element in reference space at the given point @a ip. */
|
||||
/** The size (#dof) of @a Laplacian must be set in advance. */
|
||||
virtual void CalcPhysLaplacian(ElementTransformation &Trans,
|
||||
Vector& Laplacian) const;
|
||||
|
||||
virtual void CalcPhysLinLaplacian(ElementTransformation &Trans,
|
||||
Vector& Laplacian) const;
|
||||
|
||||
/** @brief Return the local interpolation matrix @a I (Dof x Dof) where the
|
||||
fine element is the image of the base geometry under the given
|
||||
transformation. */
|
||||
|
||||
+324
-324
File diff suppressed because it is too large
Load Diff
+31
-31
@@ -28,12 +28,12 @@ private:
|
||||
public:
|
||||
/// Construct the H1_SegmentElement of order @a p and BasisType @a btype
|
||||
H1_SegmentElement(const int p, const int btype = BasisType::GaussLobatto);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void CalcHessian(const IntegrationPoint &ip,
|
||||
DenseMatrix &Hessian) const;
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void CalcHessian(const IntegrationPoint &ip,
|
||||
DenseMatrix &Hessian) const override;
|
||||
void ProjectDelta(int vertex, Vector &dofs) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -49,12 +49,12 @@ public:
|
||||
/// Construct the H1_QuadrilateralElement of order @a p and BasisType @a btype
|
||||
H1_QuadrilateralElement(const int p,
|
||||
const int btype = BasisType::GaussLobatto);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void CalcHessian(const IntegrationPoint &ip,
|
||||
DenseMatrix &Hessian) const;
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void CalcHessian(const IntegrationPoint &ip,
|
||||
DenseMatrix &Hessian) const override;
|
||||
void ProjectDelta(int vertex, Vector &dofs) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -70,12 +70,12 @@ private:
|
||||
public:
|
||||
/// Construct the H1_HexahedronElement of order @a p and BasisType @a btype
|
||||
H1_HexahedronElement(const int p, const int btype = BasisType::GaussLobatto);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void CalcHessian(const IntegrationPoint &ip,
|
||||
DenseMatrix &Hessian) const;
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void CalcHessian(const IntegrationPoint &ip,
|
||||
DenseMatrix &Hessian) const override;
|
||||
void ProjectDelta(int vertex, Vector &dofs) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -93,11 +93,11 @@ private:
|
||||
public:
|
||||
/// Construct the H1_TriangleElement of order @a p and BasisType @a btype
|
||||
H1_TriangleElement(const int p, const int btype = BasisType::GaussLobatto);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void CalcHessian(const IntegrationPoint &ip,
|
||||
DenseMatrix &ddshape) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void CalcHessian(const IntegrationPoint &ip,
|
||||
DenseMatrix &ddshape) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -117,11 +117,11 @@ public:
|
||||
/// Construct the H1_TetrahedronElement of order @a p and BasisType @a btype
|
||||
H1_TetrahedronElement(const int p,
|
||||
const int btype = BasisType::GaussLobatto);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void CalcHessian(const IntegrationPoint &ip,
|
||||
DenseMatrix &ddshape) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void CalcHessian(const IntegrationPoint &ip,
|
||||
DenseMatrix &ddshape) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -143,9 +143,9 @@ public:
|
||||
/// Construct the H1_WedgeElement of order @a p and BasisType @a btype
|
||||
H1_WedgeElement(const int p,
|
||||
const int btype = BasisType::GaussLobatto);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
};
|
||||
|
||||
} // namespace mfem
|
||||
|
||||
+49
-49
@@ -28,13 +28,13 @@ private:
|
||||
public:
|
||||
/// Construct the L2_SegmentElement of order @a p and BasisType @a btype
|
||||
L2_SegmentElement(const int p, const int btype = BasisType::GaussLegendre);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void ProjectDelta(int vertex, Vector &dofs) const override;
|
||||
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override
|
||||
{ ScalarLocalL2Restriction(Trans, R, *this); }
|
||||
|
||||
};
|
||||
@@ -52,25 +52,25 @@ public:
|
||||
/// Construct the L2_QuadrilateralElement of order @a p and BasisType @a btype
|
||||
L2_QuadrilateralElement(const int p,
|
||||
const int btype = BasisType::GaussLegendre);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
||||
virtual void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void ProjectDelta(int vertex, Vector &dofs) const override;
|
||||
void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const override
|
||||
{ ProjectCurl_2D(fe, Trans, curl); }
|
||||
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override
|
||||
{ ScalarLocalL2Restriction(Trans, R, *this); }
|
||||
|
||||
using FiniteElement::Project;
|
||||
virtual void ProjectDiv(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &div) const;
|
||||
virtual void Project(Coefficient &coeff,
|
||||
ElementTransformation &Trans, Vector &dofs) const;
|
||||
void ProjectDiv(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &div) const override;
|
||||
void Project(Coefficient &coeff,
|
||||
ElementTransformation &Trans, Vector &dofs) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -86,21 +86,21 @@ public:
|
||||
/// Construct the L2_HexahedronElement of order @a p and BasisType @a btype
|
||||
L2_HexahedronElement(const int p,
|
||||
const int btype = BasisType::GaussLegendre);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void ProjectDelta(int vertex, Vector &dofs) const override;
|
||||
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override
|
||||
{ ScalarLocalL2Restriction(Trans, R, *this); }
|
||||
|
||||
using FiniteElement::Project;
|
||||
virtual void ProjectDiv(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &div) const;
|
||||
virtual void Project(Coefficient &coeff,
|
||||
ElementTransformation &Trans, Vector &dofs) const;
|
||||
void ProjectDiv(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &div) const override;
|
||||
void Project(Coefficient &coeff,
|
||||
ElementTransformation &Trans, Vector &dofs) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -118,17 +118,17 @@ public:
|
||||
/// Construct the L2_TriangleElement of order @a p and BasisType @a btype
|
||||
L2_TriangleElement(const int p,
|
||||
const int btype = BasisType::GaussLegendre);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
||||
virtual void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void ProjectDelta(int vertex, Vector &dofs) const override;
|
||||
void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const override
|
||||
{ ProjectCurl_2D(fe, Trans, curl); }
|
||||
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override
|
||||
{ ScalarLocalL2Restriction(Trans, R, *this); }
|
||||
|
||||
};
|
||||
@@ -149,13 +149,13 @@ public:
|
||||
/// Construct the L2_TetrahedronElement of order @a p and BasisType @a btype
|
||||
L2_TetrahedronElement(const int p,
|
||||
const int btype = BasisType::GaussLegendre);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void ProjectDelta(int vertex, Vector &dofs) const override;
|
||||
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override
|
||||
{ ScalarLocalL2Restriction(Trans, R, *this); }
|
||||
|
||||
};
|
||||
@@ -178,9 +178,9 @@ public:
|
||||
/// Construct the L2_WedgeElement of order @a p and BasisType @a btype
|
||||
L2_WedgeElement(const int p,
|
||||
const int btype = BasisType::GaussLegendre);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
};
|
||||
|
||||
} // namespace mfem
|
||||
|
||||
+242
-235
@@ -36,62 +36,63 @@ public:
|
||||
const int cb_type = BasisType::GaussLobatto,
|
||||
const int ob_type = BasisType::GaussLegendre);
|
||||
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override
|
||||
{ CalcVShape_ND(Trans, shape); }
|
||||
|
||||
virtual void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const;
|
||||
void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const override;
|
||||
|
||||
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
|
||||
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override
|
||||
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
|
||||
|
||||
virtual void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
|
||||
|
||||
using FiniteElement::Project;
|
||||
|
||||
virtual void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const
|
||||
void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const override
|
||||
{
|
||||
if (obasis1d.IsIntegratedType()) { ProjectIntegrated(vc, Trans, dofs); }
|
||||
else { Project_ND(tk, dof2tk, vc, Trans, dofs); }
|
||||
}
|
||||
|
||||
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
|
||||
Vector &dofs) const
|
||||
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
|
||||
Vector &dofs) const override
|
||||
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
|
||||
|
||||
virtual void ProjectMatrixCoefficient(
|
||||
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
||||
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
|
||||
ElementTransformation &T,
|
||||
Vector &dofs) const override
|
||||
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
|
||||
|
||||
virtual void Project(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void Project(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ Project_ND(tk, dof2tk, fe, Trans, I); }
|
||||
|
||||
virtual void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const
|
||||
void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const override
|
||||
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
|
||||
|
||||
virtual void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const
|
||||
void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const override
|
||||
{ ProjectCurl_ND(tk, dof2tk, fe, Trans, curl); }
|
||||
|
||||
virtual void GetFaceMap(const int face_id, Array<int> &face_map) const;
|
||||
void GetFaceMap(const int face_id, Array<int> &face_map) const override;
|
||||
|
||||
protected:
|
||||
void ProjectIntegrated(VectorCoefficient &vc,
|
||||
@@ -118,46 +119,47 @@ public:
|
||||
ND_QuadrilateralElement(const int p,
|
||||
const int cb_type = BasisType::GaussLobatto,
|
||||
const int ob_type = BasisType::GaussLegendre);
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override
|
||||
{ CalcVShape_ND(Trans, shape); }
|
||||
virtual void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const;
|
||||
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const override;
|
||||
void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override
|
||||
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
|
||||
virtual void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
|
||||
using FiniteElement::Project;
|
||||
virtual void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const
|
||||
void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const override
|
||||
{
|
||||
if (obasis1d.IsIntegratedType()) { ProjectIntegrated(vc, Trans, dofs); }
|
||||
else { Project_ND(tk, dof2tk, vc, Trans, dofs); }
|
||||
}
|
||||
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
|
||||
Vector &dofs) const
|
||||
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
|
||||
Vector &dofs) const override
|
||||
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
|
||||
virtual void ProjectMatrixCoefficient(
|
||||
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
||||
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
|
||||
ElementTransformation &T,
|
||||
Vector &dofs) const override
|
||||
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
|
||||
virtual void Project(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void Project(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ Project_ND(tk, dof2tk, fe, Trans, I); }
|
||||
virtual void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const
|
||||
void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const override
|
||||
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
|
||||
|
||||
virtual void GetFaceMap(const int face_id, Array<int> &face_map) const;
|
||||
void GetFaceMap(const int face_id, Array<int> &face_map) const override;
|
||||
|
||||
protected:
|
||||
void ProjectIntegrated(VectorCoefficient &vc,
|
||||
@@ -184,47 +186,48 @@ class ND_TetrahedronElement : public VectorFiniteElement
|
||||
public:
|
||||
/// Construct the ND_TetrahedronElement of order @a p
|
||||
ND_TetrahedronElement(const int p);
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override
|
||||
{ CalcVShape_ND(Trans, shape); }
|
||||
virtual void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const;
|
||||
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const override;
|
||||
void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override
|
||||
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
|
||||
virtual void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
|
||||
virtual const StatelessDofTransformation *GetDofTransformation() const
|
||||
const StatelessDofTransformation *GetDofTransformation() const override
|
||||
{ return &doftrans; }
|
||||
using FiniteElement::Project;
|
||||
virtual void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const
|
||||
void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const override
|
||||
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
|
||||
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
|
||||
Vector &dofs) const
|
||||
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
|
||||
Vector &dofs) const override
|
||||
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
|
||||
virtual void ProjectMatrixCoefficient(
|
||||
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
||||
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
|
||||
ElementTransformation &T,
|
||||
Vector &dofs) const override
|
||||
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
|
||||
virtual void Project(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void Project(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ Project_ND(tk, dof2tk, fe, Trans, I); }
|
||||
virtual void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const
|
||||
void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const override
|
||||
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
|
||||
|
||||
virtual void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const
|
||||
void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const override
|
||||
{ ProjectCurl_ND(tk, dof2tk, fe, Trans, curl); }
|
||||
};
|
||||
|
||||
@@ -247,42 +250,43 @@ class ND_TriangleElement : public VectorFiniteElement
|
||||
public:
|
||||
/// Construct the ND_TriangleElement of order @a p
|
||||
ND_TriangleElement(const int p);
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override
|
||||
{ CalcVShape_ND(Trans, shape); }
|
||||
virtual void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const;
|
||||
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const override;
|
||||
void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override
|
||||
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
|
||||
virtual void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
|
||||
virtual const StatelessDofTransformation *GetDofTransformation() const
|
||||
const StatelessDofTransformation *GetDofTransformation() const override
|
||||
{ return &doftrans; }
|
||||
using FiniteElement::Project;
|
||||
virtual void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const
|
||||
void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const override
|
||||
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
|
||||
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
|
||||
Vector &dofs) const
|
||||
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
|
||||
Vector &dofs) const override
|
||||
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
|
||||
virtual void ProjectMatrixCoefficient(
|
||||
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
||||
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
|
||||
ElementTransformation &T,
|
||||
Vector &dofs) const override
|
||||
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
|
||||
virtual void Project(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void Project(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ Project_ND(tk, dof2tk, fe, Trans, I); }
|
||||
virtual void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const
|
||||
void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const override
|
||||
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
|
||||
};
|
||||
|
||||
@@ -298,39 +302,40 @@ public:
|
||||
/** @brief Construct the ND_SegmentElement of order @a p and open
|
||||
BasisType @a ob_type */
|
||||
ND_SegmentElement(const int p, const int ob_type = BasisType::GaussLegendre);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override
|
||||
{ obasis1d.Eval(ip.x, shape); }
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override
|
||||
{ CalcVShape_ND(Trans, shape); }
|
||||
// virtual void CalcCurlShape(const IntegrationPoint &ip,
|
||||
// void CalcCurlShape(const IntegrationPoint &ip,
|
||||
// DenseMatrix &curl_shape) const;
|
||||
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override
|
||||
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
|
||||
virtual void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
|
||||
using FiniteElement::Project;
|
||||
virtual void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const
|
||||
void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const override
|
||||
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
|
||||
virtual void ProjectMatrixCoefficient(
|
||||
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
||||
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
|
||||
ElementTransformation &T,
|
||||
Vector &dofs) const override
|
||||
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
|
||||
virtual void Project(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void Project(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ Project_ND(tk, dof2tk, fe, Trans, I); }
|
||||
virtual void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const
|
||||
void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const override
|
||||
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
|
||||
};
|
||||
|
||||
@@ -358,53 +363,54 @@ public:
|
||||
const int cb_type = BasisType::GaussLobatto,
|
||||
const int ob_type = BasisType::GaussLegendre);
|
||||
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override
|
||||
{ CalcVShape_ND(Trans, shape); }
|
||||
|
||||
virtual void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const;
|
||||
void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const override;
|
||||
|
||||
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override
|
||||
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
|
||||
virtual void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
|
||||
|
||||
virtual const StatelessDofTransformation *GetDofTransformation() const
|
||||
const StatelessDofTransformation *GetDofTransformation() const override
|
||||
{ return &doftrans; }
|
||||
|
||||
using FiniteElement::Project;
|
||||
|
||||
virtual void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const
|
||||
void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const override
|
||||
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
|
||||
|
||||
virtual void ProjectMatrixCoefficient(
|
||||
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
||||
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
|
||||
ElementTransformation &T,
|
||||
Vector &dofs) const override
|
||||
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
|
||||
|
||||
virtual void Project(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void Project(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ Project_ND(tk, dof2tk, fe, Trans, I); }
|
||||
|
||||
virtual void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const
|
||||
void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const override
|
||||
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
|
||||
|
||||
virtual void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const
|
||||
void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const override
|
||||
{ ProjectCurl_ND(tk, dof2tk, fe, Trans, curl); }
|
||||
};
|
||||
|
||||
@@ -423,11 +429,11 @@ public:
|
||||
|
||||
using FiniteElement::CalcVShape;
|
||||
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const;
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override;
|
||||
};
|
||||
|
||||
/// Arbitrary order, three component, Nedelec elements in 1D on a segment
|
||||
@@ -455,56 +461,57 @@ public:
|
||||
using FiniteElement::CalcVShape;
|
||||
using FiniteElement::CalcPhysCurlShape;
|
||||
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const;
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
virtual void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const;
|
||||
void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const override;
|
||||
|
||||
virtual void CalcPhysCurlShape(ElementTransformation &Trans,
|
||||
DenseMatrix &curl_shape) const;
|
||||
void CalcPhysCurlShape(ElementTransformation &Trans,
|
||||
DenseMatrix &curl_shape) const override;
|
||||
|
||||
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
|
||||
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override
|
||||
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
|
||||
|
||||
virtual void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
|
||||
|
||||
using FiniteElement::Project;
|
||||
|
||||
virtual void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const;
|
||||
void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const override;
|
||||
|
||||
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
|
||||
Vector &dofs) const
|
||||
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
|
||||
Vector &dofs) const override
|
||||
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
|
||||
|
||||
virtual void ProjectMatrixCoefficient(
|
||||
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
||||
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
|
||||
ElementTransformation &T,
|
||||
Vector &dofs) const override
|
||||
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
|
||||
|
||||
virtual void Project(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const;
|
||||
void Project(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override;
|
||||
|
||||
virtual void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const
|
||||
void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const override
|
||||
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
|
||||
|
||||
virtual void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const
|
||||
void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const override
|
||||
{ ProjectCurl_ND(tk, dof2tk, fe, Trans, curl); }
|
||||
};
|
||||
|
||||
@@ -535,32 +542,32 @@ public:
|
||||
const int cb_type = BasisType::GaussLobatto,
|
||||
const int ob_type = BasisType::GaussLegendre);
|
||||
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const;
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
virtual void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const;
|
||||
void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const override;
|
||||
|
||||
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation(*this, Trans, I); }
|
||||
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override
|
||||
{ MFEM_ABORT("method is not overloaded"); }
|
||||
|
||||
virtual void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation(CheckVectorFE(fe), Trans, I); }
|
||||
|
||||
using FiniteElement::Project;
|
||||
|
||||
virtual void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const;
|
||||
void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const override;
|
||||
};
|
||||
|
||||
class ND_R2D_FiniteElement : public VectorFiniteElement
|
||||
@@ -580,35 +587,35 @@ public:
|
||||
using FiniteElement::CalcVShape;
|
||||
using FiniteElement::CalcPhysCurlShape;
|
||||
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const;
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
virtual void CalcPhysCurlShape(ElementTransformation &Trans,
|
||||
DenseMatrix &curl_shape) const;
|
||||
void CalcPhysCurlShape(ElementTransformation &Trans,
|
||||
DenseMatrix &curl_shape) const override;
|
||||
|
||||
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation(*this, Trans, I); }
|
||||
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const;
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override;
|
||||
|
||||
virtual void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation(CheckVectorFE(fe), Trans, I); }
|
||||
|
||||
using FiniteElement::Project;
|
||||
|
||||
virtual void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const;
|
||||
void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const override;
|
||||
|
||||
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
||||
DenseMatrix &I) const;
|
||||
void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override;
|
||||
|
||||
virtual void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const;
|
||||
void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const override;
|
||||
};
|
||||
|
||||
/// Arbitrary order Nedelec 3D elements in 2D on a triangle
|
||||
@@ -635,10 +642,10 @@ public:
|
||||
using ND_R2D_FiniteElement::CalcVShape;
|
||||
using ND_R2D_FiniteElement::CalcPhysCurlShape;
|
||||
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
virtual void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const;
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -664,10 +671,10 @@ public:
|
||||
using ND_R2D_FiniteElement::CalcVShape;
|
||||
using ND_R2D_FiniteElement::CalcPhysCurlShape;
|
||||
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
virtual void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const;
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
+614
-1
@@ -398,8 +398,621 @@ void NURBS3DFiniteElement::CalcHessian (const IntegrationPoint &ip,
|
||||
hessian(o,5) = hessian(o,5)*sum
|
||||
- 2*du(o,1)*sum*dsum[1]
|
||||
+ u[o]*sum*(2*dsum[1]*dsum[1] - d2sum[5]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NURBS_HDiv2DFiniteElement::SetOrder() const
|
||||
{
|
||||
orders[0] = kv[0]->GetOrder();
|
||||
orders[1] = kv[1]->GetOrder();
|
||||
|
||||
if (kv1[0]) { delete kv1[0]; }
|
||||
if (kv1[1]) { delete kv1[1]; }
|
||||
|
||||
kv1[0] = kv[0]->DegreeElevate(1);
|
||||
kv1[1] = kv[1]->DegreeElevate(1);
|
||||
|
||||
shape_x.SetSize(orders[0]+1);
|
||||
shape_y.SetSize(orders[1]+1);
|
||||
|
||||
dshape_x.SetSize(orders[0]+1);
|
||||
dshape_y.SetSize(orders[1]+1);
|
||||
|
||||
d2shape_x.SetSize(orders[0]+1);
|
||||
d2shape_y.SetSize(orders[1]+1);
|
||||
|
||||
shape1_x.SetSize(orders[0]+2);
|
||||
shape1_y.SetSize(orders[1]+2);
|
||||
|
||||
dshape1_x.SetSize(orders[0]+2);
|
||||
dshape1_y.SetSize(orders[1]+2);
|
||||
|
||||
d2shape1_x.SetSize(orders[0]+2);
|
||||
d2shape1_y.SetSize(orders[1]+2);
|
||||
|
||||
order = max(orders[0]+1, orders[1]+1);
|
||||
dof = (orders[0] + 2)*(orders[1] + 1)
|
||||
+ (orders[1] + 1)*(orders[1] + 2);
|
||||
u.SetSize(dof);
|
||||
du.SetSize(dof);
|
||||
weights.SetSize(dof);
|
||||
}
|
||||
|
||||
void NURBS_HDiv2DFiniteElement::CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const
|
||||
{
|
||||
kv[0]->CalcShape(shape_x, ijk[0], ip.x);
|
||||
kv[1]->CalcShape(shape_y, ijk[1], ip.y);
|
||||
|
||||
kv1[0]->CalcShape(shape1_x, ijk[0], ip.x);
|
||||
kv1[1]->CalcShape(shape1_y, ijk[1], ip.y);
|
||||
|
||||
int o = 0;
|
||||
for (int j = 0; j <= orders[1]; j++)
|
||||
{
|
||||
const real_t sy = shape_y(j);
|
||||
for (int i = 0; i <= orders[0]+1; i++, o++)
|
||||
{
|
||||
shape(o,0) = shape1_x(i)*sy;
|
||||
shape(o,1) = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j <= orders[1]+1; j++)
|
||||
{
|
||||
const real_t sy1 = shape1_y(j);
|
||||
for (int i = 0; i <= orders[0]; i++, o++)
|
||||
{
|
||||
shape(o,0) = 0.0;
|
||||
shape(o,1) = shape_x(i)*sy1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NURBS_HDiv2DFiniteElement::CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const
|
||||
{
|
||||
CalcVShape(Trans.GetIntPoint(), shape);
|
||||
const DenseMatrix & J = Trans.Jacobian();
|
||||
MFEM_ASSERT(J.Width() == 2 && J.Height() == 2,
|
||||
"NURBS_HDiv2DFiniteElement cannot be embedded in "
|
||||
"3 dimensional spaces");
|
||||
for (int i=0; i<dof; i++)
|
||||
{
|
||||
real_t sx = shape(i, 0);
|
||||
real_t sy = shape(i, 1);
|
||||
shape(i, 0) = sx * J(0, 0) + sy * J(0, 1);
|
||||
shape(i, 1) = sx * J(1, 0) + sy * J(1, 1);
|
||||
}
|
||||
shape *= (1.0 / Trans.Weight());
|
||||
}
|
||||
|
||||
void NURBS_HDiv2DFiniteElement::CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const
|
||||
{
|
||||
kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
|
||||
kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
|
||||
|
||||
kv1[0]->CalcDShape(dshape1_x, ijk[0], ip.x);
|
||||
kv1[1]->CalcDShape(dshape1_y, ijk[1], ip.y);
|
||||
|
||||
int o = 0;
|
||||
for (int j = 0; j <= orders[1]; j++)
|
||||
{
|
||||
const real_t sy = shape_y(j);
|
||||
for (int i = 0; i <= orders[0]+1; i++, o++)
|
||||
{
|
||||
divshape(o) = dshape1_x(i)*sy;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j <= orders[1]+1; j++)
|
||||
{
|
||||
const real_t dsy1 = dshape1_y(j);
|
||||
for (int i = 0; i <= orders[0]; i++, o++)
|
||||
{
|
||||
divshape(o) = shape_x(i)*dsy1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NURBS_HDiv2DFiniteElement::~NURBS_HDiv2DFiniteElement()
|
||||
{
|
||||
if (kv1[0]) { delete kv1[0]; }
|
||||
if (kv1[1]) { delete kv1[1]; }
|
||||
}
|
||||
|
||||
|
||||
void NURBS_HDiv3DFiniteElement::SetOrder() const
|
||||
{
|
||||
orders[0] = kv[0]->GetOrder();
|
||||
orders[1] = kv[1]->GetOrder();
|
||||
orders[2] = kv[2]->GetOrder();
|
||||
|
||||
if (kv1[0]) { delete kv1[0]; }
|
||||
if (kv1[1]) { delete kv1[1]; }
|
||||
if (kv1[2]) { delete kv1[2]; }
|
||||
|
||||
kv1[0] = kv[0]->DegreeElevate(1);
|
||||
kv1[1] = kv[1]->DegreeElevate(1);
|
||||
kv1[2] = kv[2]->DegreeElevate(1);
|
||||
|
||||
shape_x.SetSize(orders[0]+1);
|
||||
shape_y.SetSize(orders[1]+1);
|
||||
shape_z.SetSize(orders[2]+1);
|
||||
|
||||
dshape_x.SetSize(orders[0]+1);
|
||||
dshape_y.SetSize(orders[1]+1);
|
||||
dshape_z.SetSize(orders[2]+1);
|
||||
|
||||
d2shape_x.SetSize(orders[0]+1);
|
||||
d2shape_y.SetSize(orders[1]+1);
|
||||
d2shape_z.SetSize(orders[2]+1);
|
||||
|
||||
shape1_x.SetSize(orders[0]+2);
|
||||
shape1_y.SetSize(orders[1]+2);
|
||||
shape1_z.SetSize(orders[2]+2);
|
||||
|
||||
dshape1_x.SetSize(orders[0]+2);
|
||||
dshape1_y.SetSize(orders[1]+2);
|
||||
dshape1_z.SetSize(orders[2]+2);
|
||||
|
||||
d2shape1_x.SetSize(orders[0]+2);
|
||||
d2shape1_y.SetSize(orders[1]+2);
|
||||
d2shape1_z.SetSize(orders[2]+2);
|
||||
|
||||
order = max(orders[0]+1, max( orders[1]+1, orders[2]+1));
|
||||
dof = (orders[0] + 2)*(orders[1] + 1)*(orders[2] + 1) +
|
||||
(orders[0] + 1)*(orders[1] + 2)*(orders[2] + 1) +
|
||||
(orders[0] + 1)*(orders[1] + 1)*(orders[2] + 2);
|
||||
u.SetSize(dof);
|
||||
du.SetSize(dof);
|
||||
weights.SetSize(dof);
|
||||
}
|
||||
|
||||
void NURBS_HDiv3DFiniteElement::CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const
|
||||
{
|
||||
kv[0]->CalcShape(shape_x, ijk[0], ip.x);
|
||||
kv[1]->CalcShape(shape_y, ijk[1], ip.y);
|
||||
kv[2]->CalcShape(shape_z, ijk[2], ip.z);
|
||||
|
||||
kv1[0]->CalcShape(shape1_x, ijk[0], ip.x);
|
||||
kv1[1]->CalcShape(shape1_y, ijk[1], ip.y);
|
||||
kv1[2]->CalcShape(shape1_z, ijk[2], ip.z);
|
||||
|
||||
shape = 0.0;
|
||||
int o = 0;
|
||||
for (int k = 0; k <= orders[2]; k++)
|
||||
{
|
||||
const real_t sz = shape_z(k);
|
||||
for (int j = 0; j <= orders[1]; j++)
|
||||
{
|
||||
const real_t sy_sz = shape_y(j)*sz;
|
||||
for (int i = 0; i <= orders[0]+1; i++, o++)
|
||||
{
|
||||
shape(o,0) = shape1_x(i)*sy_sz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int k = 0; k <= orders[2]; k++)
|
||||
{
|
||||
const real_t sz = shape_z(k);
|
||||
for (int j = 0; j <= orders[1]+1; j++)
|
||||
{
|
||||
const real_t sy1_sz = shape1_y(j)*sz;
|
||||
for (int i = 0; i <= orders[0]; i++, o++)
|
||||
{
|
||||
shape(o,1) = shape_x(i)*sy1_sz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int k = 0; k <= orders[2]+1; k++)
|
||||
{
|
||||
const real_t sz1 = shape1_z(k);
|
||||
for (int j = 0; j <= orders[1]; j++)
|
||||
{
|
||||
const real_t sy_sz1 = shape_y(j)*sz1;
|
||||
for (int i = 0; i <= orders[0]; i++, o++)
|
||||
{
|
||||
shape(o,2) = shape_x(i)*sy_sz1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NURBS_HDiv3DFiniteElement::CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const
|
||||
{
|
||||
CalcVShape(Trans.GetIntPoint(), shape);
|
||||
const DenseMatrix & J = Trans.Jacobian();
|
||||
MFEM_ASSERT(J.Width() == 3 && J.Height() == 3,
|
||||
"RT_R2D_FiniteElement cannot be embedded in "
|
||||
"3 dimensional spaces");
|
||||
for (int i=0; i<dof; i++)
|
||||
{
|
||||
real_t sx = shape(i, 0);
|
||||
real_t sy = shape(i, 1);
|
||||
real_t sz = shape(i, 2);
|
||||
shape(i, 0) = sx * J(0, 0) + sy * J(0, 1) + sz * J(0, 2);
|
||||
shape(i, 1) = sx * J(1, 0) + sy * J(1, 1) + sz * J(1, 2);
|
||||
shape(i, 2) = sx * J(2, 0) + sy * J(2, 1) + sz * J(2, 2);
|
||||
}
|
||||
shape *= (1.0 / Trans.Weight());
|
||||
}
|
||||
|
||||
void NURBS_HDiv3DFiniteElement::CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const
|
||||
{
|
||||
kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
|
||||
kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
|
||||
kv[2]->CalcShape ( shape_z, ijk[2], ip.z);
|
||||
|
||||
kv1[0]->CalcDShape(dshape1_x, ijk[0], ip.x);
|
||||
kv1[1]->CalcDShape(dshape1_y, ijk[1], ip.y);
|
||||
kv1[2]->CalcDShape(dshape1_z, ijk[2], ip.z);
|
||||
|
||||
int o = 0;
|
||||
for (int k = 0; k <= orders[2]; k++)
|
||||
{
|
||||
const real_t sz = shape_z(k);
|
||||
for (int j = 0; j <= orders[1]; j++)
|
||||
{
|
||||
const real_t sy_sz = shape_y(j)*sz;
|
||||
for (int i = 0; i <= orders[0]+1; i++, o++)
|
||||
{
|
||||
divshape(o) = dshape1_x(i)*sy_sz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int k = 0; k <= orders[2]; k++)
|
||||
{
|
||||
const real_t sz = shape_z(k);
|
||||
for (int j = 0; j <= orders[1]+1; j++)
|
||||
{
|
||||
const real_t dy1_sz = dshape1_y(j)*sz;
|
||||
for (int i = 0; i <= orders[0]; i++, o++)
|
||||
{
|
||||
divshape(o) = shape_x(i)*dy1_sz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int k = 0; k <= orders[2]+1; k++)
|
||||
{
|
||||
const real_t dz1 = dshape1_z(k);
|
||||
for (int j = 0; j <= orders[1]; j++)
|
||||
{
|
||||
const real_t sy_dz1 = shape_y(j)*dz1;
|
||||
for (int i = 0; i <= orders[0]; i++, o++)
|
||||
{
|
||||
divshape(o) = shape_x(i)*sy_dz1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NURBS_HDiv3DFiniteElement::~NURBS_HDiv3DFiniteElement()
|
||||
{
|
||||
if (kv1[0]) { delete kv1[0]; }
|
||||
if (kv1[1]) { delete kv1[1]; }
|
||||
if (kv1[2]) { delete kv1[2]; }
|
||||
}
|
||||
|
||||
void NURBS_HCurl2DFiniteElement::SetOrder() const
|
||||
{
|
||||
orders[0] = kv[0]->GetOrder();
|
||||
orders[1] = kv[1]->GetOrder();
|
||||
|
||||
if (kv1[0]) { delete kv1[0]; }
|
||||
if (kv1[1]) { delete kv1[1]; }
|
||||
|
||||
kv1[0] = kv[0]->DegreeElevate(1);
|
||||
kv1[1] = kv[1]->DegreeElevate(1);
|
||||
|
||||
shape_x.SetSize(orders[0]+1);
|
||||
shape_y.SetSize(orders[1]+1);
|
||||
|
||||
dshape_x.SetSize(orders[0]+1);
|
||||
dshape_y.SetSize(orders[1]+1);
|
||||
|
||||
d2shape_x.SetSize(orders[0]+1);
|
||||
d2shape_y.SetSize(orders[1]+1);
|
||||
|
||||
shape1_x.SetSize(orders[0]+2);
|
||||
shape1_y.SetSize(orders[1]+2);
|
||||
|
||||
dshape1_x.SetSize(orders[0]+2);
|
||||
dshape1_y.SetSize(orders[1]+2);
|
||||
|
||||
d2shape1_x.SetSize(orders[0]+2);
|
||||
d2shape1_y.SetSize(orders[1]+2);
|
||||
|
||||
order = max(orders[0]+1, orders[1]+1);
|
||||
dof = (orders[0] + 1)*(orders[1] + 2)
|
||||
+ (orders[1] + 2)*(orders[1] + 1);
|
||||
u.SetSize(dof);
|
||||
du.SetSize(dof);
|
||||
weights.SetSize(dof);
|
||||
}
|
||||
|
||||
void NURBS_HCurl2DFiniteElement::CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const
|
||||
{
|
||||
kv[0]->CalcShape(shape_x, ijk[0], ip.x);
|
||||
kv[1]->CalcShape(shape_y, ijk[1], ip.y);
|
||||
|
||||
kv1[0]->CalcShape(shape1_x, ijk[0], ip.x);
|
||||
kv1[1]->CalcShape(shape1_y, ijk[1], ip.y);
|
||||
|
||||
int o = 0;
|
||||
for (int j = 0; j <= orders[1]+1; j++)
|
||||
{
|
||||
const real_t sy1 = shape1_y(j);
|
||||
for (int i = 0; i <= orders[0]; i++, o++)
|
||||
{
|
||||
shape(o,0) = shape_x(i)*sy1;
|
||||
shape(o,1) = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j <= orders[1]; j++)
|
||||
{
|
||||
const real_t sy = shape_y(j);
|
||||
for (int i = 0; i <= orders[0]+1; i++, o++)
|
||||
{
|
||||
shape(o,0) = 0.0;
|
||||
shape(o,1) = shape1_x(i)*sy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NURBS_HCurl2DFiniteElement::CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const
|
||||
{
|
||||
CalcVShape(Trans.GetIntPoint(), shape);
|
||||
const DenseMatrix & JI = Trans.InverseJacobian();
|
||||
MFEM_ASSERT(JI.Width() == 2 && JI.Height() == 2,
|
||||
"NURBS_HCurl2DFiniteElement cannot be embedded in "
|
||||
"3 dimensional spaces");
|
||||
for (int i=0; i<dof; i++)
|
||||
{
|
||||
real_t sx = shape(i, 0);
|
||||
real_t sy = shape(i, 1);
|
||||
shape(i, 0) = sx * JI(0, 0) + sy * JI(1, 0);
|
||||
shape(i, 1) = sx * JI(0, 1) + sy * JI(1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void NURBS_HCurl2DFiniteElement::CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const
|
||||
{
|
||||
kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
|
||||
kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
|
||||
|
||||
kv1[0]->CalcDShape(dshape1_x, ijk[0], ip.x);
|
||||
kv1[1]->CalcDShape(dshape1_y, ijk[1], ip.y);
|
||||
|
||||
int o = 0;
|
||||
for (int j = 0; j <= orders[1]+1; j++)
|
||||
{
|
||||
const real_t dsy1 = dshape1_y(j);
|
||||
for (int i = 0; i <= orders[0]; i++, o++)
|
||||
{
|
||||
curl_shape(o,0) = -shape_x(i)*dsy1;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j <= orders[1]; j++)
|
||||
{
|
||||
const real_t sy = shape_y(j);
|
||||
for (int i = 0; i <= orders[0]+1; i++, o++)
|
||||
{
|
||||
curl_shape(o,0) = dshape1_x(i)*sy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NURBS_HCurl2DFiniteElement::~NURBS_HCurl2DFiniteElement()
|
||||
{
|
||||
if (kv1[0]) { delete kv1[0]; }
|
||||
if (kv1[1]) { delete kv1[1]; }
|
||||
}
|
||||
|
||||
|
||||
void NURBS_HCurl3DFiniteElement::SetOrder() const
|
||||
{
|
||||
orders[0] = kv[0]->GetOrder();
|
||||
orders[1] = kv[1]->GetOrder();
|
||||
orders[2] = kv[2]->GetOrder();
|
||||
|
||||
if (kv1[0]) { delete kv1[0]; }
|
||||
if (kv1[1]) { delete kv1[1]; }
|
||||
if (kv1[2]) { delete kv1[2]; }
|
||||
|
||||
kv1[0] = kv[0]->DegreeElevate(1);
|
||||
kv1[1] = kv[1]->DegreeElevate(1);
|
||||
kv1[2] = kv[2]->DegreeElevate(1);
|
||||
|
||||
shape_x.SetSize(orders[0]+1);
|
||||
shape_y.SetSize(orders[1]+1);
|
||||
shape_z.SetSize(orders[2]+1);
|
||||
|
||||
dshape_x.SetSize(orders[0]+1);
|
||||
dshape_y.SetSize(orders[1]+1);
|
||||
dshape_z.SetSize(orders[2]+1);
|
||||
|
||||
d2shape_x.SetSize(orders[0]+1);
|
||||
d2shape_y.SetSize(orders[1]+1);
|
||||
d2shape_z.SetSize(orders[2]+1);
|
||||
|
||||
shape1_x.SetSize(orders[0]+2);
|
||||
shape1_y.SetSize(orders[1]+2);
|
||||
shape1_z.SetSize(orders[2]+2);
|
||||
|
||||
dshape1_x.SetSize(orders[0]+2);
|
||||
dshape1_y.SetSize(orders[1]+2);
|
||||
dshape1_z.SetSize(orders[2]+2);
|
||||
|
||||
d2shape1_x.SetSize(orders[0]+2);
|
||||
d2shape1_y.SetSize(orders[1]+2);
|
||||
d2shape1_z.SetSize(orders[2]+2);
|
||||
|
||||
order = max(orders[0]+1, max( orders[1]+1, orders[2]+1));
|
||||
dof = (orders[0] + 1)*(orders[1] + 2)*(orders[2] + 2) +
|
||||
(orders[0] + 2)*(orders[1] + 1)*(orders[2] + 2) +
|
||||
(orders[0] + 2)*(orders[1] + 2)*(orders[2] + 1);
|
||||
u.SetSize(dof);
|
||||
du.SetSize(dof);
|
||||
weights.SetSize(dof);
|
||||
}
|
||||
|
||||
void NURBS_HCurl3DFiniteElement::CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const
|
||||
{
|
||||
kv[0]->CalcShape(shape_x, ijk[0], ip.x);
|
||||
kv[1]->CalcShape(shape_y, ijk[1], ip.y);
|
||||
kv[2]->CalcShape(shape_z, ijk[2], ip.z);
|
||||
|
||||
kv1[0]->CalcShape(shape1_x, ijk[0], ip.x);
|
||||
kv1[1]->CalcShape(shape1_y, ijk[1], ip.y);
|
||||
kv1[2]->CalcShape(shape1_z, ijk[2], ip.z);
|
||||
|
||||
shape = 0.0;
|
||||
int o = 0;
|
||||
for (int k = 0; k <= orders[2]+1; k++)
|
||||
{
|
||||
const real_t sz1 = shape1_z(k);
|
||||
for (int j = 0; j <= orders[1]+1; j++)
|
||||
{
|
||||
const real_t sy1_sz1 = shape1_y(j)*sz1;
|
||||
for (int i = 0; i <= orders[0]; i++, o++)
|
||||
{
|
||||
shape(o,0) = shape_x(i)*sy1_sz1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int k = 0; k <= orders[2]+1; k++)
|
||||
{
|
||||
const real_t sz1 = shape1_z(k);
|
||||
for (int j = 0; j <= orders[1]; j++)
|
||||
{
|
||||
const real_t sy_sz1 = shape_y(j)*sz1;
|
||||
for (int i = 0; i <= orders[0]+1; i++, o++)
|
||||
{
|
||||
shape(o,1) = shape1_x(i)*sy_sz1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int k = 0; k <= orders[2]; k++)
|
||||
{
|
||||
const real_t sz = shape_z(k);
|
||||
for (int j = 0; j <= orders[1]+1; j++)
|
||||
{
|
||||
const real_t sy1_sz = shape1_y(j)*sz;
|
||||
for (int i = 0; i <= orders[0]+1; i++, o++)
|
||||
{
|
||||
shape(o,2) = shape1_x(i)*sy1_sz;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NURBS_HCurl3DFiniteElement::CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const
|
||||
{
|
||||
CalcVShape(Trans.GetIntPoint(), shape);
|
||||
const DenseMatrix & JI = Trans.InverseJacobian();
|
||||
MFEM_ASSERT(JI.Width() == 3 && JI.Height() == 3,
|
||||
"NURBS_HCurl3DFiniteElement must be in a"
|
||||
"3 dimensional spaces");
|
||||
for (int i=0; i<dof; i++)
|
||||
{
|
||||
real_t sx = shape(i, 0);
|
||||
real_t sy = shape(i, 1);
|
||||
real_t sz = shape(i, 2);
|
||||
shape(i, 0) = sx * JI(0, 0) + sy * JI(1, 0) + sz * JI(2, 0);
|
||||
shape(i, 1) = sx * JI(0, 1) + sy * JI(1, 1) + sz * JI(2, 1);
|
||||
shape(i, 2) = sx * JI(0, 2) + sy * JI(1, 2) + sz * JI(2, 2);
|
||||
}
|
||||
}
|
||||
|
||||
void NURBS_HCurl3DFiniteElement::CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const
|
||||
{
|
||||
kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
|
||||
kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
|
||||
kv[2]->CalcShape ( shape_z, ijk[2], ip.z);
|
||||
|
||||
kv1[0]->CalcShape(shape1_x, ijk[0], ip.x);
|
||||
kv1[1]->CalcShape(shape1_y, ijk[1], ip.y);
|
||||
kv1[2]->CalcShape(shape1_z, ijk[2], ip.z);
|
||||
|
||||
kv1[0]->CalcDShape(dshape1_x, ijk[0], ip.x);
|
||||
kv1[1]->CalcDShape(dshape1_y, ijk[1], ip.y);
|
||||
kv1[2]->CalcDShape(dshape1_z, ijk[2], ip.z);
|
||||
|
||||
int o = 0;
|
||||
for (int k = 0; k <= orders[2]+1; k++)
|
||||
{
|
||||
const real_t sz1 = shape1_z(k), dsz1 = dshape1_z(k);
|
||||
for (int j = 0; j <= orders[1]+1; j++)
|
||||
{
|
||||
const real_t sy1_dsz1 = shape1_y(j)*dsz1,
|
||||
dsy1_sz1 = dshape1_y(j)*sz1;
|
||||
for (int i = 0; i <= orders[0]; i++, o++)
|
||||
{
|
||||
curl_shape(o,0) = 0.0;
|
||||
curl_shape(o,1) = shape_x(i)*sy1_dsz1;
|
||||
curl_shape(o,2) = -shape_x(i)*dsy1_sz1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int k = 0; k <= orders[2]+1; k++)
|
||||
{
|
||||
const real_t sz1 = shape1_z(k), dsz1 = dshape1_z(k);
|
||||
for (int j = 0; j <= orders[1]; j++)
|
||||
{
|
||||
const real_t sy_dsz1 = shape_y(j)*dsz1,
|
||||
sy_sz1 = shape_y(j)*sz1;
|
||||
for (int i = 0; i <= orders[0]+1; i++, o++)
|
||||
{
|
||||
curl_shape(o,0) = -shape1_x(i)*sy_dsz1;
|
||||
curl_shape(o,1) = 0.0;
|
||||
curl_shape(o,2) = dshape1_x(i)*sy_sz1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int k = 0; k <= orders[2]; k++)
|
||||
{
|
||||
const real_t sz = shape_z(k);
|
||||
for (int j = 0; j <= orders[1]+1; j++)
|
||||
{
|
||||
const real_t sy1_sz = shape1_y(j)*sz,
|
||||
dsy1_sz = dshape1_y(j)*sz;
|
||||
for (int i = 0; i <= orders[0]+1; i++, o++)
|
||||
{
|
||||
curl_shape(o,0) = shape1_x(i)*dsy1_sz;
|
||||
curl_shape(o,1) = -dshape1_x(i)*sy1_sz;
|
||||
curl_shape(o,2) = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NURBS_HCurl3DFiniteElement::~NURBS_HCurl3DFiniteElement()
|
||||
{
|
||||
if (kv1[0]) { delete kv1[0]; }
|
||||
if (kv1[1]) { delete kv1[1]; }
|
||||
if (kv1[2]) { delete kv1[2]; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+398
-41
@@ -20,7 +20,7 @@ namespace mfem
|
||||
class KnotVector;
|
||||
|
||||
/// An arbitrary order and dimension NURBS element
|
||||
class NURBSFiniteElement : public ScalarFiniteElement
|
||||
class NURBSFiniteElement
|
||||
{
|
||||
protected:
|
||||
mutable Array <const KnotVector*> kv;
|
||||
@@ -30,31 +30,34 @@ protected:
|
||||
|
||||
public:
|
||||
/** @brief Construct NURBSFiniteElement with given
|
||||
@param D Reference space dimension
|
||||
@param G Geometry type (of type Geometry::Type)
|
||||
@param Do Number of degrees of freedom in the FiniteElement
|
||||
@param O Order/degree of the FiniteElement
|
||||
@param F FunctionSpace type of the FiniteElement
|
||||
@param dim Reference space dimension
|
||||
*/
|
||||
NURBSFiniteElement(int D, Geometry::Type G, int Do, int O, int F)
|
||||
: ScalarFiniteElement(D, G, Do, O, F)
|
||||
NURBSFiniteElement(int dim)
|
||||
{
|
||||
ijk = NULL;
|
||||
patch = elem = -1;
|
||||
kv.SetSize(dim);
|
||||
weights.SetSize(dof);
|
||||
weights = 1.0;
|
||||
}
|
||||
|
||||
/// Resets the patch and element data stored in the element
|
||||
void Reset () const { patch = elem = -1; }
|
||||
/// Set which IJK in patch should be evaluated
|
||||
void SetIJK (const int *IJK) const { ijk = IJK; }
|
||||
/// Get which patch is currently considered
|
||||
int GetPatch () const { return patch; }
|
||||
/// Set which patch should be evaluated
|
||||
void SetPatch (int p) const { patch = p; }
|
||||
/// Set which elemenet should be evaluated
|
||||
int GetElement () const { return elem; }
|
||||
/// Get which element is currently considered
|
||||
void SetElement (int e) const { elem = e; }
|
||||
/// Get the KnotVectors
|
||||
Array <const KnotVector*> &KnotVectors() const { return kv; }
|
||||
/// Get the Weights
|
||||
Vector &Weights () const { return weights; }
|
||||
/// Update the NURBSFiniteElement according to the currently set knot vectors
|
||||
/// Update the polynomial order according to the currently set knotvectors
|
||||
/// Resizes all internal data members to have the correct size
|
||||
/// related to the polynomial order
|
||||
virtual void SetOrder () const { }
|
||||
|
||||
/// Returns the indices (i,j) in 2D or (i,j,k) in 3D of this element in the
|
||||
@@ -64,7 +67,8 @@ public:
|
||||
|
||||
|
||||
/// An arbitrary order 1D NURBS element on a segment
|
||||
class NURBS1DFiniteElement : public NURBSFiniteElement
|
||||
class NURBS1DFiniteElement : public ScalarFiniteElement,
|
||||
public NURBSFiniteElement
|
||||
{
|
||||
protected:
|
||||
mutable Vector shape_x;
|
||||
@@ -72,19 +76,21 @@ protected:
|
||||
public:
|
||||
/// Construct the NURBS1DFiniteElement of order @a p
|
||||
NURBS1DFiniteElement(int p)
|
||||
: NURBSFiniteElement(1, Geometry::SEGMENT, p + 1, p, FunctionSpace::Qk),
|
||||
: ScalarFiniteElement(1, Geometry::SEGMENT, p + 1, p, FunctionSpace::Qk),
|
||||
NURBSFiniteElement(1),
|
||||
shape_x(p + 1) { }
|
||||
|
||||
virtual void SetOrder() const;
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void CalcHessian (const IntegrationPoint &ip,
|
||||
DenseMatrix &hessian) const;
|
||||
void SetOrder() const override;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void CalcHessian (const IntegrationPoint &ip,
|
||||
DenseMatrix &hessian) const override;
|
||||
};
|
||||
|
||||
/// An arbitrary order 2D NURBS element on a square
|
||||
class NURBS2DFiniteElement : public NURBSFiniteElement
|
||||
class NURBS2DFiniteElement : public ScalarFiniteElement,
|
||||
public NURBSFiniteElement
|
||||
{
|
||||
protected:
|
||||
mutable Vector u, shape_x, shape_y, dshape_x, dshape_y, d2shape_x, d2shape_y;
|
||||
@@ -93,30 +99,33 @@ protected:
|
||||
public:
|
||||
/// Construct the NURBS2DFiniteElement of order @a p
|
||||
NURBS2DFiniteElement(int p)
|
||||
: NURBSFiniteElement(2, Geometry::SQUARE, (p + 1)*(p + 1), p,
|
||||
FunctionSpace::Qk),
|
||||
: ScalarFiniteElement(2, Geometry::SQUARE, (p + 1)*(p + 1), p,
|
||||
FunctionSpace::Qk),
|
||||
NURBSFiniteElement(2),
|
||||
u(dof), shape_x(p + 1), shape_y(p + 1), dshape_x(p + 1),
|
||||
dshape_y(p + 1), d2shape_x(p + 1), d2shape_y(p + 1), du(dof,2)
|
||||
{ orders[0] = orders[1] = p; }
|
||||
|
||||
/// Construct the NURBS2DFiniteElement with x-order @a px and y-order @a py
|
||||
NURBS2DFiniteElement(int px, int py)
|
||||
: NURBSFiniteElement(2, Geometry::SQUARE, (px + 1)*(py + 1),
|
||||
std::max(px, py), FunctionSpace::Qk),
|
||||
: ScalarFiniteElement(2, Geometry::SQUARE, (px + 1)*(py + 1),
|
||||
std::max(px, py), FunctionSpace::Qk),
|
||||
NURBSFiniteElement(2),
|
||||
u(dof), shape_x(px + 1), shape_y(py + 1), dshape_x(px + 1),
|
||||
dshape_y(py + 1), d2shape_x(px + 1), d2shape_y(py + 1), du(dof,2)
|
||||
{ orders[0] = px; orders[1] = py; }
|
||||
|
||||
virtual void SetOrder() const;
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void CalcHessian (const IntegrationPoint &ip,
|
||||
DenseMatrix &hessian) const;
|
||||
void SetOrder() const override;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void CalcHessian (const IntegrationPoint &ip,
|
||||
DenseMatrix &hessian) const override;
|
||||
};
|
||||
|
||||
/// An arbitrary order 3D NURBS element on a cube
|
||||
class NURBS3DFiniteElement : public NURBSFiniteElement
|
||||
class NURBS3DFiniteElement : public ScalarFiniteElement,
|
||||
public NURBSFiniteElement
|
||||
{
|
||||
protected:
|
||||
mutable Vector u, shape_x, shape_y, shape_z;
|
||||
@@ -127,8 +136,9 @@ protected:
|
||||
public:
|
||||
/// Construct the NURBS3DFiniteElement of order @a p
|
||||
NURBS3DFiniteElement(int p)
|
||||
: NURBSFiniteElement(3, Geometry::CUBE, (p + 1)*(p + 1)*(p + 1), p,
|
||||
FunctionSpace::Qk),
|
||||
: ScalarFiniteElement(3, Geometry::CUBE, (p + 1)*(p + 1)*(p + 1), p,
|
||||
FunctionSpace::Qk),
|
||||
NURBSFiniteElement(3),
|
||||
u(dof), shape_x(p + 1), shape_y(p + 1), shape_z(p + 1),
|
||||
dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1),
|
||||
d2shape_x(p + 1), d2shape_y(p + 1), d2shape_z(p + 1), du(dof,3)
|
||||
@@ -137,19 +147,366 @@ public:
|
||||
/// Construct the NURBS3DFiniteElement with x-order @a px and y-order @a py
|
||||
/// and z-order @a pz
|
||||
NURBS3DFiniteElement(int px, int py, int pz)
|
||||
: NURBSFiniteElement(3, Geometry::CUBE, (px + 1)*(py + 1)*(pz + 1),
|
||||
std::max(std::max(px,py),pz), FunctionSpace::Qk),
|
||||
: ScalarFiniteElement(3, Geometry::CUBE, (px + 1)*(py + 1)*(pz + 1),
|
||||
std::max(std::max(px,py),pz), FunctionSpace::Qk),
|
||||
NURBSFiniteElement(2),
|
||||
u(dof), shape_x(px + 1), shape_y(py + 1), shape_z(pz + 1),
|
||||
dshape_x(px + 1), dshape_y(py + 1), dshape_z(pz + 1),
|
||||
d2shape_x(px + 1), d2shape_y(py + 1), d2shape_z(pz + 1), du(dof,3)
|
||||
{ orders[0] = px; orders[1] = py; orders[2] = pz; }
|
||||
|
||||
virtual void SetOrder() const;
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void CalcHessian (const IntegrationPoint &ip,
|
||||
DenseMatrix &hessian) const;
|
||||
void SetOrder() const override;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void CalcHessian (const IntegrationPoint &ip,
|
||||
DenseMatrix &hessian) const override;
|
||||
};
|
||||
|
||||
|
||||
/** An arbitrary order H(div)-conforming 2D NURBS element on a square.
|
||||
More details in the following papers:
|
||||
|
||||
[1] Annalisa Buffa, Carlo De Falco, Giancarlo Sangalli
|
||||
"Isogeometric analysis: stable elements for the 2D Stokes equation."
|
||||
International Journal for Numerical Methods in Fluids 65 (11‐12) 1407-1422
|
||||
|
||||
[2] John A Evans, Thomas JR Hughes
|
||||
"Isogeometric divergence-conforming B-splines for the unsteady Navier–Stokes equations."
|
||||
Journal of Computational Physics (241) 141-167
|
||||
*/
|
||||
class NURBS_HDiv2DFiniteElement : public VectorFiniteElement,
|
||||
public NURBSFiniteElement
|
||||
{
|
||||
protected:
|
||||
mutable Vector shape_x, shape_y, dshape_x, dshape_y, d2shape_x, d2shape_y;
|
||||
mutable Vector shape1_x, shape1_y, dshape1_x, dshape1_y, d2shape1_x, d2shape1_y;
|
||||
mutable Vector u;
|
||||
mutable DenseMatrix du;
|
||||
mutable Array <const KnotVector*> kv1;
|
||||
|
||||
public:
|
||||
/// Construct the NURBS_HDiv2DFiniteElement of order @a p
|
||||
NURBS_HDiv2DFiniteElement(int p)
|
||||
: VectorFiniteElement(2, Geometry::SQUARE, 2*(p + 1)*(p + 2), p,
|
||||
H_DIV,FunctionSpace::Qk),
|
||||
NURBSFiniteElement(2),
|
||||
shape_x(p + 1), shape_y(p + 1), dshape_x(p + 1),
|
||||
dshape_y(p + 1), d2shape_x(p + 1), d2shape_y(p + 1),
|
||||
shape1_x(p + 2), shape1_y(p + 2), dshape1_x(p + 2),
|
||||
dshape1_y(p + 2), d2shape1_x(p + 2), d2shape1_y(p + 2),
|
||||
u(dof), du(dof,2)
|
||||
{
|
||||
orders[0] = orders[1] = p;
|
||||
kv1.SetSize(dim);
|
||||
kv1[0] = nullptr;
|
||||
kv1[1] = nullptr;
|
||||
}
|
||||
|
||||
/// Construct the NURBS_HDiv2DFiniteElement with x-order @a px and y-order @a py
|
||||
NURBS_HDiv2DFiniteElement(int px, int py)
|
||||
: VectorFiniteElement(2, Geometry::SQUARE,
|
||||
(px + 2)*(py + 1)+(px + 1)*(py + 2),
|
||||
std::max(px, py), H_DIV, FunctionSpace::Qk),
|
||||
NURBSFiniteElement(2),
|
||||
shape_x(px + 1), shape_y(py + 1), dshape_x(px + 1),
|
||||
dshape_y(py + 1), d2shape_x(px + 1), d2shape_y(py + 1),
|
||||
shape1_x(px + 2), shape1_y(py + 2), dshape1_x(px + 2),
|
||||
dshape1_y(py + 2), d2shape1_x(px + 2), d2shape1_y(py + 2),
|
||||
u(dof), du(dof,2)
|
||||
{
|
||||
orders[0] = px; orders[1] = py;
|
||||
kv1.SetSize(dim);
|
||||
kv1[0] = nullptr;
|
||||
kv1[1] = nullptr;
|
||||
}
|
||||
|
||||
void SetOrder() const override;
|
||||
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
/** @brief Evaluate the values of all shape functions of a *vector* finite
|
||||
element in physical space at the point described by @a Trans. */
|
||||
/** Each row of the result DenseMatrix @a shape contains the components of
|
||||
one vector shape function. The size (#dof x SDim) of @a shape must be set
|
||||
in advance, where SDim >= #dim is the physical space dimension as
|
||||
described by @a Trans. */
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
/** @brief Evaluate the divergence of all shape functions of a *vector*
|
||||
finite element in reference space at the given point @a ip. */
|
||||
/** The size (#dof) of the result Vector @a divshape must be set in advance.
|
||||
*/
|
||||
void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const override;
|
||||
|
||||
~NURBS_HDiv2DFiniteElement();
|
||||
};
|
||||
|
||||
|
||||
/** An arbitrary order H(div)-conforming 3D NURBS element on a cube
|
||||
More details in the following papers:
|
||||
|
||||
[1] Annalisa Buffa, Carlo De Falco, Giancarlo Sangalli
|
||||
"Isogeometric analysis: stable elements for the 2D Stokes equation."
|
||||
International Journal for Numerical Methods in Fluids 65 (11‐12) 1407-1422
|
||||
|
||||
[2] John A Evans, Thomas JR Hughes
|
||||
"Isogeometric divergence-conforming B-splines for the unsteady
|
||||
Navier–Stokes equations."
|
||||
Journal of Computational Physics (241) 141-167 */
|
||||
class NURBS_HDiv3DFiniteElement : public VectorFiniteElement,
|
||||
public NURBSFiniteElement
|
||||
{
|
||||
protected:
|
||||
mutable Vector shape_x, shape_y, shape_z;
|
||||
mutable Vector dshape_x, dshape_y, dshape_z;
|
||||
mutable Vector d2shape_x, d2shape_y, d2shape_z;
|
||||
mutable Vector shape1_x, shape1_y, shape1_z;
|
||||
mutable Vector dshape1_x, dshape1_y, dshape1_z;
|
||||
mutable Vector d2shape1_x, d2shape1_y, d2shape1_z;
|
||||
mutable Vector u;
|
||||
mutable DenseMatrix du;
|
||||
mutable Array <const KnotVector*> kv1;
|
||||
|
||||
public:
|
||||
/// Construct the NURBS_HDiv3DFiniteElement of order @a p
|
||||
NURBS_HDiv3DFiniteElement(int p)
|
||||
: VectorFiniteElement(3, Geometry::CUBE, 3*(p + 1)*(p + 1)*(p + 2),
|
||||
p, H_DIV,FunctionSpace::Qk),
|
||||
NURBSFiniteElement(3),
|
||||
shape_x(p + 1), shape_y(p + 1), shape_z(p + 1),
|
||||
dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1),
|
||||
d2shape_x(p + 1), d2shape_y(p + 1), d2shape_z(p + 1),
|
||||
shape1_x(p + 2), shape1_y(p + 2), shape1_z(p + 2),
|
||||
dshape1_x(p + 2), dshape1_y(p + 2),dshape1_z(p + 2),
|
||||
d2shape1_x(p + 2), d2shape1_y(p + 2), d2shape1_z(p + 2),
|
||||
u(dof), du(dof,3)
|
||||
{
|
||||
orders[0] = orders[1] = orders[2] = p;
|
||||
kv1.SetSize(dim);
|
||||
kv1[0] = nullptr;
|
||||
kv1[1] = nullptr;
|
||||
kv1[2] = nullptr;
|
||||
}
|
||||
|
||||
/// Construct the NURBS_HDiv3DFiniteElement with x-order @a px, y-order @a py and z-order @a pz
|
||||
NURBS_HDiv3DFiniteElement(int px, int py, int pz)
|
||||
: VectorFiniteElement(3, Geometry::CUBE,
|
||||
(px + 2)*(py + 1)*(pz + 1) +
|
||||
(px + 1)*(py + 2)*(pz + 1) +
|
||||
(px + 1)*(py + 1)*(pz + 2),
|
||||
std::max(px, py), H_DIV, FunctionSpace::Qk),
|
||||
NURBSFiniteElement(3),
|
||||
shape_x(px + 1), shape_y(py + 1), shape_z(pz + 1),
|
||||
dshape_x(px + 1), dshape_y(py + 1), dshape_z(pz + 1),
|
||||
d2shape_x(px + 1), d2shape_y(py + 1), d2shape_z(pz + 1),
|
||||
shape1_x(px + 2), shape1_y(py + 2), shape1_z(pz + 2),
|
||||
dshape1_x(px + 2), dshape1_y(py + 2),dshape1_z(pz + 2),
|
||||
d2shape1_x(px + 2), d2shape1_y(py + 2), d2shape1_z(pz + 2),
|
||||
u(dof), du(dof,3)
|
||||
{
|
||||
orders[0] = px; orders[1] = py; orders[2] = pz;
|
||||
kv1.SetSize(dim);
|
||||
kv1[0] = nullptr;
|
||||
kv1[1] = nullptr;
|
||||
kv1[2] = nullptr;
|
||||
}
|
||||
|
||||
void SetOrder() const override;
|
||||
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
/** @brief Evaluate the values of all shape functions of a *vector* finite
|
||||
element in physical space at the point described by @a Trans. */
|
||||
/** Each row of the result DenseMatrix @a shape contains the components of
|
||||
one vector shape function. The size (#dof x SDim) of @a shape must be set
|
||||
in advance, where SDim >= #dim is the physical space dimension as
|
||||
described by @a Trans. */
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
/** @brief Evaluate the divergence of all shape functions of a *vector*
|
||||
finite element in reference space at the given point @a ip. */
|
||||
/** The size (#dof) of the result Vector @a divshape must be set in advance.
|
||||
*/
|
||||
void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const override;
|
||||
|
||||
~NURBS_HDiv3DFiniteElement();
|
||||
};
|
||||
|
||||
|
||||
/** An arbitrary order H(curl)-conforming 2D NURBS element on a square
|
||||
More details in the following paper:
|
||||
|
||||
[1] Annalisa Buffa, Giancarlo Sangalli, Rafael Vázquez
|
||||
"Isogeometric analysis in electromagnetics: B-splines approximation."
|
||||
Computer Methods in Applied Mechanics and Engineering (199) 1143-1152 */
|
||||
class NURBS_HCurl2DFiniteElement : public VectorFiniteElement,
|
||||
public NURBSFiniteElement
|
||||
{
|
||||
protected:
|
||||
mutable Vector shape_x, shape_y, dshape_x, dshape_y, d2shape_x, d2shape_y;
|
||||
mutable Vector shape1_x, shape1_y, dshape1_x, dshape1_y, d2shape1_x, d2shape1_y;
|
||||
mutable Vector u;
|
||||
mutable DenseMatrix du;
|
||||
mutable Array <const KnotVector*> kv1;
|
||||
|
||||
public:
|
||||
/// Construct the NURBS_HCurl2DFiniteElement of order @a p
|
||||
NURBS_HCurl2DFiniteElement(int p)
|
||||
: VectorFiniteElement(2, Geometry::SQUARE, 2*(p + 1)*(p + 2), p,
|
||||
H_CURL,FunctionSpace::Qk),
|
||||
NURBSFiniteElement(2),
|
||||
shape_x(p + 1), shape_y(p + 1), dshape_x(p + 1),
|
||||
dshape_y(p + 1), d2shape_x(p + 1), d2shape_y(p + 1),
|
||||
shape1_x(p + 2), shape1_y(p + 2), dshape1_x(p + 2),
|
||||
dshape1_y(p + 2), d2shape1_x(p + 2), d2shape1_y(p + 2),
|
||||
u(dof), du(dof,2)
|
||||
{
|
||||
orders[0] = orders[1] = p;
|
||||
kv1.SetSize(dim);
|
||||
kv1[0] = nullptr;
|
||||
kv1[1] = nullptr;
|
||||
}
|
||||
|
||||
/// Construct the NURBS_HCurl2DFiniteElement with x-order @a px and y-order @a py
|
||||
NURBS_HCurl2DFiniteElement(int px, int py)
|
||||
: VectorFiniteElement(2, Geometry::SQUARE,
|
||||
(px + 1)*(py + 2)+(px + 2)*(py + 1),
|
||||
std::max(px, py), H_CURL, FunctionSpace::Qk),
|
||||
NURBSFiniteElement(2),
|
||||
shape_x(px + 1), shape_y(py + 1), dshape_x(px + 1),
|
||||
dshape_y(py + 1), d2shape_x(px + 1), d2shape_y(py + 1),
|
||||
shape1_x(px + 2), shape1_y(py + 2), dshape1_x(px + 2),
|
||||
dshape1_y(py + 2), d2shape1_x(px + 2), d2shape1_y(py + 2),
|
||||
u(dof), du(dof,2)
|
||||
{
|
||||
orders[0] = px; orders[1] = py;
|
||||
kv1.SetSize(dim);
|
||||
kv1[0] = nullptr;
|
||||
kv1[1] = nullptr;
|
||||
}
|
||||
|
||||
void SetOrder() const override;
|
||||
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
/** @brief Evaluate the values of all shape functions of a *vector* finite
|
||||
element in physical space at the point described by @a Trans. */
|
||||
/** Each row of the result DenseMatrix @a shape contains the components of
|
||||
one vector shape function. The size (#dof x SDim) of @a shape must be set
|
||||
in advance, where SDim >= #dim is the physical space dimension as
|
||||
described by @a Trans. */
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
/** @brief Evaluate the curl of all shape functions of a *vector* finite
|
||||
element in reference space at the given point @a ip. */
|
||||
/** Each row of the result DenseMatrix @a curl_shape contains the components
|
||||
of the curl of one vector shape function. The size (#dof x CDim) of
|
||||
@a curl_shape must be set in advance, where CDim = 3 for #dim = 3 and
|
||||
CDim = 1 for #dim = 2. */
|
||||
void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const override;
|
||||
|
||||
~NURBS_HCurl2DFiniteElement();
|
||||
};
|
||||
|
||||
|
||||
/** An arbitrary order H(curl)-conforming 3D NURBS element on a cube
|
||||
More details in the following paper:
|
||||
|
||||
[1] Annalisa Buffa, Giancarlo Sangalli, Rafael Vázquez
|
||||
"Isogeometric analysis in electromagnetics: B-splines approximation."
|
||||
Computer Methods in Applied Mechanics and Engineering (199) 1143-1152 */
|
||||
class NURBS_HCurl3DFiniteElement : public VectorFiniteElement,
|
||||
public NURBSFiniteElement
|
||||
{
|
||||
protected:
|
||||
mutable Vector shape_x, shape_y, shape_z;
|
||||
mutable Vector dshape_x, dshape_y, dshape_z;
|
||||
mutable Vector d2shape_x, d2shape_y, d2shape_z;
|
||||
mutable Vector shape1_x, shape1_y, shape1_z;
|
||||
mutable Vector dshape1_x, dshape1_y, dshape1_z;
|
||||
mutable Vector d2shape1_x, d2shape1_y, d2shape1_z;
|
||||
mutable Vector u;
|
||||
mutable DenseMatrix du;
|
||||
mutable Array <const KnotVector*> kv1;
|
||||
|
||||
public:
|
||||
/// Construct the NURBS_HCurl3DFiniteElement of order @a p
|
||||
NURBS_HCurl3DFiniteElement(int p)
|
||||
: VectorFiniteElement(3, Geometry::CUBE, 3*(p + 1)*(p + 2)*(p + 2), p,
|
||||
H_CURL,FunctionSpace::Qk),
|
||||
NURBSFiniteElement(3),
|
||||
shape_x(p + 1), shape_y(p + 1), shape_z(p + 1),
|
||||
dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1),
|
||||
d2shape_x(p + 1), d2shape_y(p + 1), d2shape_z(p + 1),
|
||||
shape1_x(p + 2), shape1_y(p + 2), shape1_z(p + 2),
|
||||
dshape1_x(p + 2), dshape1_y(p + 2),dshape1_z(p + 2),
|
||||
d2shape1_x(p + 2), d2shape1_y(p + 2), d2shape1_z(p + 2),
|
||||
u(dof), du(dof,3)
|
||||
{
|
||||
orders[0] = orders[1] = orders[2] = p;
|
||||
kv1.SetSize(dim);
|
||||
kv1[0] = nullptr;
|
||||
kv1[1] = nullptr;
|
||||
kv1[2] = nullptr;
|
||||
}
|
||||
|
||||
/// Construct the NURBS_HCurl3DFiniteElement with x-order @a px, y-order @a py and z-order @a pz
|
||||
NURBS_HCurl3DFiniteElement(int px, int py, int pz)
|
||||
: VectorFiniteElement(3, Geometry::CUBE,
|
||||
(px + 1)*(py + 2)*(pz + 2) +
|
||||
(px + 2)*(py + 1)*(pz + 2) +
|
||||
(px + 2)*(py + 2)*(pz + 1),
|
||||
std::max(std::max(px, py), pz), H_CURL, FunctionSpace::Qk),
|
||||
NURBSFiniteElement(3),
|
||||
shape_x(px + 1), shape_y(py + 1), shape_z(pz + 1),
|
||||
dshape_x(px + 1), dshape_y(py + 1), dshape_z(pz + 1),
|
||||
d2shape_x(px + 1), d2shape_y(py + 1), d2shape_z(pz + 1),
|
||||
shape1_x(px + 2), shape1_y(py + 2), shape1_z(pz + 2),
|
||||
dshape1_x(px + 2), dshape1_y(py + 2),dshape1_z(pz + 2),
|
||||
d2shape1_x(px + 2), d2shape1_y(py + 2), d2shape1_z(pz + 2),
|
||||
u(dof), du(dof,3)
|
||||
{
|
||||
orders[0] = px; orders[1] = py; orders[2] = pz;
|
||||
kv1.SetSize(dim);
|
||||
kv1[0] = nullptr;
|
||||
kv1[1] = nullptr;
|
||||
kv1[2] = nullptr;
|
||||
}
|
||||
|
||||
void SetOrder() const override;
|
||||
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
/** @brief Evaluate the values of all shape functions of a *vector* finite
|
||||
element in physical space at the point described by @a Trans. */
|
||||
/** Each row of the result DenseMatrix @a shape contains the components of
|
||||
one vector shape function. The size (#dof x SDim) of @a shape must be set
|
||||
in advance, where SDim >= #dim is the physical space dimension as
|
||||
described by @a Trans. */
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
/** @brief Evaluate the curl of all shape functions of a *vector* finite
|
||||
element in reference space at the given point @a ip. */
|
||||
/** Each row of the result DenseMatrix @a curl_shape contains the components
|
||||
of the curl of one vector shape function. The size (#dof x CDim) of
|
||||
@a curl_shape must be set in advance, where CDim = 3 for #dim = 3 and
|
||||
CDim = 1 for #dim = 2. */
|
||||
void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const override;
|
||||
|
||||
~NURBS_HCurl3DFiniteElement();
|
||||
};
|
||||
|
||||
} // namespace mfem
|
||||
|
||||
+70
-70
@@ -34,31 +34,31 @@ public:
|
||||
ScalarFiniteElement(D, G, Do, O, F)
|
||||
{ }
|
||||
|
||||
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ ScalarLocalInterpolation(Trans, I, *this); }
|
||||
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override
|
||||
{ ScalarLocalL2Restriction(Trans, R, *this); }
|
||||
|
||||
virtual void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ CheckScalarFE(fe).ScalarLocalInterpolation(Trans, I, *this); }
|
||||
|
||||
using FiniteElement::Project;
|
||||
|
||||
// Low-order monotone "projection" (actually it is not a projection): the
|
||||
// dofs are set to be the Coefficient values at the nodes.
|
||||
virtual void Project(Coefficient &coeff,
|
||||
ElementTransformation &Trans, Vector &dofs) const;
|
||||
void Project(Coefficient &coeff,
|
||||
ElementTransformation &Trans, Vector &dofs) const override;
|
||||
|
||||
virtual void Project (VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const;
|
||||
void Project (VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const override;
|
||||
|
||||
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
||||
DenseMatrix &I) const;
|
||||
void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -88,17 +88,17 @@ class BiQuadPos2DFiniteElement : public PositiveFiniteElement
|
||||
public:
|
||||
/// Construct the BiQuadPos2DFiniteElement
|
||||
BiQuadPos2DFiniteElement();
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override;
|
||||
using FiniteElement::Project;
|
||||
virtual void Project(Coefficient &coeff, ElementTransformation &Trans,
|
||||
Vector &dofs) const;
|
||||
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans,
|
||||
Vector &dofs) const;
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const
|
||||
void Project(Coefficient &coeff, ElementTransformation &Trans,
|
||||
Vector &dofs) const override;
|
||||
void Project(VectorCoefficient &vc, ElementTransformation &Trans,
|
||||
Vector &dofs) const override;
|
||||
void ProjectDelta(int vertex, Vector &dofs) const override
|
||||
{ dofs = 0.; dofs(vertex) = 1.; }
|
||||
};
|
||||
|
||||
@@ -109,9 +109,9 @@ class QuadPos1DFiniteElement : public PositiveFiniteElement
|
||||
public:
|
||||
/// Construct the QuadPos1DFiniteElement
|
||||
QuadPos1DFiniteElement();
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -131,10 +131,10 @@ private:
|
||||
public:
|
||||
/// Construct the H1Pos_SegmentElement of order @a p
|
||||
H1Pos_SegmentElement(const int p);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void ProjectDelta(int vertex, Vector &dofs) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -150,10 +150,10 @@ private:
|
||||
public:
|
||||
/// Construct the H1Pos_QuadrilateralElement of order @a p
|
||||
H1Pos_QuadrilateralElement(const int p);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void ProjectDelta(int vertex, Vector &dofs) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -169,10 +169,10 @@ private:
|
||||
public:
|
||||
/// Construct the H1Pos_HexahedronElement of order @a p
|
||||
H1Pos_HexahedronElement(const int p);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void ProjectDelta(int vertex, Vector &dofs) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -198,9 +198,9 @@ public:
|
||||
static void CalcDShape(const int p, const real_t x, const real_t y,
|
||||
real_t *dshape_1d, real_t *dshape);
|
||||
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -227,9 +227,9 @@ public:
|
||||
static void CalcDShape(const int p, const real_t x, const real_t y,
|
||||
const real_t z, real_t *dshape_1d, real_t *dshape);
|
||||
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -250,9 +250,9 @@ public:
|
||||
/// Construct the H1Pos_WedgeElement of order @a p
|
||||
H1Pos_WedgeElement(const int p);
|
||||
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -267,10 +267,10 @@ private:
|
||||
public:
|
||||
/// Construct the L2Pos_SegmentElement of order @a p
|
||||
L2Pos_SegmentElement(const int p);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void ProjectDelta(int vertex, Vector &dofs) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -285,10 +285,10 @@ private:
|
||||
public:
|
||||
/// Construct the L2Pos_QuadrilateralElement of order @a p
|
||||
L2Pos_QuadrilateralElement(const int p);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void ProjectDelta(int vertex, Vector &dofs) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -303,10 +303,10 @@ private:
|
||||
public:
|
||||
/// Construct the L2Pos_HexahedronElement of order @a p
|
||||
L2Pos_HexahedronElement(const int p);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void ProjectDelta(int vertex, Vector &dofs) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -321,10 +321,10 @@ private:
|
||||
public:
|
||||
/// Construct the L2Pos_TriangleElement of order @a p
|
||||
L2Pos_TriangleElement(const int p);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void ProjectDelta(int vertex, Vector &dofs) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -340,10 +340,10 @@ private:
|
||||
public:
|
||||
/// Construct the L2Pos_TetrahedronElement of order @a p
|
||||
L2Pos_TetrahedronElement(const int p);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void ProjectDelta(int vertex, Vector &dofs) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -364,9 +364,9 @@ public:
|
||||
/// Construct the L2Pos_WedgeElement of order @a p
|
||||
L2Pos_WedgeElement(const int p);
|
||||
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
};
|
||||
|
||||
} // namespace mfem
|
||||
|
||||
+182
-177
@@ -38,51 +38,52 @@ public:
|
||||
RT_QuadrilateralElement(const int p,
|
||||
const int cb_type = BasisType::GaussLobatto,
|
||||
const int ob_type = BasisType::GaussLegendre);
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override
|
||||
{ CalcVShape_RT(Trans, shape); }
|
||||
virtual void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const;
|
||||
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const override;
|
||||
void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_RT(*this, nk, dof2nk, Trans, I); }
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override
|
||||
{ LocalRestriction_RT(nk, dof2nk, Trans, R); }
|
||||
virtual void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_RT(CheckVectorFE(fe), nk, dof2nk, Trans, I); }
|
||||
using FiniteElement::Project;
|
||||
virtual void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const
|
||||
void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const override
|
||||
{
|
||||
if (obasis1d.IsIntegratedType()) { ProjectIntegrated(vc, Trans, dofs); }
|
||||
else { Project_RT(nk, dof2nk, vc, Trans, dofs); }
|
||||
}
|
||||
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
|
||||
Vector &dofs) const
|
||||
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
|
||||
Vector &dofs) const override
|
||||
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
|
||||
virtual void ProjectMatrixCoefficient(
|
||||
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
||||
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
|
||||
ElementTransformation &T,
|
||||
Vector &dofs) const override
|
||||
{ ProjectMatrixCoefficient_RT(nk, dof2nk, mc, T, dofs); }
|
||||
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ Project_RT(nk, dof2nk, fe, Trans, I); }
|
||||
// Gradient + rotation = Curl: H1 -> H(div)
|
||||
virtual void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const
|
||||
void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const override
|
||||
{ ProjectGrad_RT(nk, dof2nk, fe, Trans, grad); }
|
||||
// Curl = Gradient + rotation: H1 -> H(div)
|
||||
virtual void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const
|
||||
void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const override
|
||||
{ ProjectGrad_RT(nk, dof2nk, fe, Trans, curl); }
|
||||
|
||||
virtual void GetFaceMap(const int face_id, Array<int> &face_map) const;
|
||||
void GetFaceMap(const int face_id, Array<int> &face_map) const override;
|
||||
|
||||
protected:
|
||||
void ProjectIntegrated(VectorCoefficient &vc, ElementTransformation &Trans,
|
||||
@@ -109,48 +110,49 @@ public:
|
||||
const int cb_type = BasisType::GaussLobatto,
|
||||
const int ob_type = BasisType::GaussLegendre);
|
||||
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override
|
||||
{ CalcVShape_RT(Trans, shape); }
|
||||
virtual void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const;
|
||||
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const override;
|
||||
void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_RT(*this, nk, dof2nk, Trans, I); }
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override
|
||||
{ LocalRestriction_RT(nk, dof2nk, Trans, R); }
|
||||
virtual void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_RT(CheckVectorFE(fe), nk, dof2nk, Trans, I); }
|
||||
using FiniteElement::Project;
|
||||
virtual void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const
|
||||
void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const override
|
||||
{
|
||||
if (obasis1d.IsIntegratedType()) { ProjectIntegrated(vc, Trans, dofs); }
|
||||
else { Project_RT(nk, dof2nk, vc, Trans, dofs); }
|
||||
}
|
||||
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
|
||||
Vector &dofs) const
|
||||
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
|
||||
Vector &dofs) const override
|
||||
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
|
||||
virtual void ProjectMatrixCoefficient(
|
||||
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
||||
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
|
||||
ElementTransformation &T,
|
||||
Vector &dofs) const override
|
||||
{ ProjectMatrixCoefficient_RT(nk, dof2nk, mc, T, dofs); }
|
||||
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ Project_RT(nk, dof2nk, fe, Trans, I); }
|
||||
virtual void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const
|
||||
void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const override
|
||||
{ ProjectCurl_RT(nk, dof2nk, fe, Trans, curl); }
|
||||
|
||||
/// @brief Return the mapping from lexicographically ordered face DOFs to
|
||||
/// lexicographically ordered element DOFs corresponding to local face
|
||||
/// @a face_id.
|
||||
virtual void GetFaceMap(const int face_id, Array<int> &face_map) const;
|
||||
void GetFaceMap(const int face_id, Array<int> &face_map) const override;
|
||||
|
||||
protected:
|
||||
void ProjectIntegrated(VectorCoefficient &vc,
|
||||
@@ -176,45 +178,46 @@ class RT_TriangleElement : public VectorFiniteElement
|
||||
public:
|
||||
/// Construct the RT_TriangleElement of order @a p
|
||||
RT_TriangleElement(const int p);
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override
|
||||
{ CalcVShape_RT(Trans, shape); }
|
||||
virtual void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const;
|
||||
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const override;
|
||||
void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_RT(*this, nk, dof2nk, Trans, I); }
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override
|
||||
{ LocalRestriction_RT(nk, dof2nk, Trans, R); }
|
||||
virtual void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_RT(CheckVectorFE(fe), nk, dof2nk, Trans, I); }
|
||||
using FiniteElement::Project;
|
||||
virtual void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const
|
||||
void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const override
|
||||
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
|
||||
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
|
||||
Vector &dofs) const
|
||||
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
|
||||
Vector &dofs) const override
|
||||
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
|
||||
virtual void ProjectMatrixCoefficient(
|
||||
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
||||
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
|
||||
ElementTransformation &T,
|
||||
Vector &dofs) const override
|
||||
{ ProjectMatrixCoefficient_RT(nk, dof2nk, mc, T, dofs); }
|
||||
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ Project_RT(nk, dof2nk, fe, Trans, I); }
|
||||
// Gradient + rotation = Curl: H1 -> H(div)
|
||||
virtual void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const
|
||||
void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const override
|
||||
{ ProjectGrad_RT(nk, dof2nk, fe, Trans, grad); }
|
||||
// Curl = Gradient + rotation: H1 -> H(div)
|
||||
virtual void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const
|
||||
void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const override
|
||||
{ ProjectGrad_RT(nk, dof2nk, fe, Trans, curl); }
|
||||
};
|
||||
|
||||
@@ -236,39 +239,40 @@ class RT_TetrahedronElement : public VectorFiniteElement
|
||||
public:
|
||||
/// Construct the RT_TetrahedronElement of order @a p
|
||||
RT_TetrahedronElement(const int p);
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override
|
||||
{ CalcVShape_RT(Trans, shape); }
|
||||
virtual void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const;
|
||||
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const override;
|
||||
void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_RT(*this, nk, dof2nk, Trans, I); }
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override
|
||||
{ LocalRestriction_RT(nk, dof2nk, Trans, R); }
|
||||
virtual void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_RT(CheckVectorFE(fe), nk, dof2nk, Trans, I); }
|
||||
using FiniteElement::Project;
|
||||
virtual void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const
|
||||
void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const override
|
||||
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
|
||||
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
|
||||
Vector &dofs) const
|
||||
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
|
||||
Vector &dofs) const override
|
||||
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
|
||||
virtual void ProjectMatrixCoefficient(
|
||||
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
||||
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
|
||||
ElementTransformation &T,
|
||||
Vector &dofs) const override
|
||||
{ ProjectMatrixCoefficient_RT(nk, dof2nk, mc, T, dofs); }
|
||||
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ Project_RT(nk, dof2nk, fe, Trans, I); }
|
||||
virtual void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const
|
||||
void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const override
|
||||
{ ProjectCurl_RT(nk, dof2nk, fe, Trans, curl); }
|
||||
};
|
||||
|
||||
@@ -296,36 +300,37 @@ class RT_WedgeElement : public VectorFiniteElement
|
||||
|
||||
public:
|
||||
RT_WedgeElement(const int p);
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override
|
||||
{ CalcVShape_RT(Trans, shape); }
|
||||
virtual void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const;
|
||||
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const override;
|
||||
void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_RT(*this, nk, dof2nk, Trans, I); }
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override
|
||||
{ LocalRestriction_RT(nk, dof2nk, Trans, R); }
|
||||
virtual void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation_RT(CheckVectorFE(fe), nk, dof2nk, Trans, I); }
|
||||
using FiniteElement::Project;
|
||||
virtual void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const
|
||||
void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const override
|
||||
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
|
||||
virtual void ProjectMatrixCoefficient(
|
||||
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
||||
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
|
||||
ElementTransformation &T,
|
||||
Vector &dofs) const override
|
||||
{ ProjectMatrixCoefficient_RT(nk, dof2nk, mc, T, dofs); }
|
||||
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ Project_RT(nk, dof2nk, fe, Trans, I); }
|
||||
virtual void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const
|
||||
void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const override
|
||||
{ ProjectCurl_RT(nk, dof2nk, fe, Trans, curl); }
|
||||
};
|
||||
|
||||
@@ -353,27 +358,27 @@ public:
|
||||
const int cb_type = BasisType::GaussLobatto,
|
||||
const int ob_type = BasisType::GaussLegendre);
|
||||
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const;
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
virtual void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const;
|
||||
void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const override;
|
||||
|
||||
using FiniteElement::Project;
|
||||
|
||||
virtual void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const;
|
||||
void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const override;
|
||||
|
||||
virtual void Project(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const;
|
||||
void Project(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override;
|
||||
|
||||
virtual void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const;
|
||||
void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -401,26 +406,26 @@ public:
|
||||
RT_R2D_SegmentElement(const int p,
|
||||
const int ob_type = BasisType::GaussLegendre);
|
||||
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const;
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
virtual void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &div_shape) const;
|
||||
void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &div_shape) const override;
|
||||
|
||||
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation(*this, Trans, I); }
|
||||
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override
|
||||
{ MFEM_ABORT("method is not overloaded"); }
|
||||
|
||||
virtual void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation(CheckVectorFE(fe), Trans, I); }
|
||||
};
|
||||
|
||||
@@ -440,32 +445,32 @@ private:
|
||||
public:
|
||||
using FiniteElement::CalcVShape;
|
||||
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const;
|
||||
void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation(*this, Trans, I); }
|
||||
|
||||
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const;
|
||||
void GetLocalRestriction(ElementTransformation &Trans,
|
||||
DenseMatrix &R) const override;
|
||||
|
||||
virtual void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const
|
||||
void GetTransferMatrix(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override
|
||||
{ LocalInterpolation(CheckVectorFE(fe), Trans, I); }
|
||||
|
||||
using FiniteElement::Project;
|
||||
|
||||
virtual void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const;
|
||||
void Project(VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const override;
|
||||
|
||||
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
||||
DenseMatrix &I) const;
|
||||
void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override;
|
||||
|
||||
virtual void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const;
|
||||
void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const override;
|
||||
};
|
||||
|
||||
/// Arbitrary order Raviart-Thomas 3D elements in 2D on a triangle
|
||||
@@ -489,11 +494,11 @@ public:
|
||||
|
||||
using RT_R2D_FiniteElement::CalcVShape;
|
||||
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
|
||||
virtual void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const;
|
||||
void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const override;
|
||||
};
|
||||
|
||||
/// Arbitrary order Raviart-Thomas 3D elements in 2D on a square
|
||||
@@ -518,10 +523,10 @@ public:
|
||||
|
||||
using RT_R2D_FiniteElement::CalcVShape;
|
||||
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
virtual void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const;
|
||||
void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const override;
|
||||
void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
+5
-5
@@ -23,11 +23,11 @@ class H1Ser_QuadrilateralElement : public ScalarFiniteElement
|
||||
public:
|
||||
/// Construct the H1Ser_QuadrilateralElement of order @a p
|
||||
H1Ser_QuadrilateralElement(const int p);
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const;
|
||||
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
|
||||
void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const override;
|
||||
void GetLocalInterpolation(ElementTransformation &Trans,
|
||||
DenseMatrix &I) const override;
|
||||
using FiniteElement::Project;
|
||||
};
|
||||
|
||||
|
||||
+214
@@ -344,6 +344,32 @@ FiniteElementCollection *FiniteElementCollection::New(const char *name)
|
||||
{
|
||||
fec = new Local_FECollection(name + 6);
|
||||
}
|
||||
else if (!strncmp(name, "NURBS_HDiv", 10))
|
||||
{
|
||||
if (name[10] != '\0')
|
||||
{
|
||||
// "NURBS" + "number" --> fixed order nurbs collection
|
||||
fec = new NURBS_HDivFECollection(atoi(name + 10));
|
||||
}
|
||||
else
|
||||
{
|
||||
// "NURBS" --> variable order nurbs collection
|
||||
fec = new NURBS_HDivFECollection();
|
||||
}
|
||||
}
|
||||
else if (!strncmp(name, "NURBS_HCurl", 11))
|
||||
{
|
||||
if (name[11] != '\0')
|
||||
{
|
||||
// "NURBS" + "number" --> fixed order nurbs collection
|
||||
fec = new NURBS_HCurlFECollection(atoi(name + 11));
|
||||
}
|
||||
else
|
||||
{
|
||||
// "NURBS" --> variable order nurbs collection
|
||||
fec = new NURBS_HCurlFECollection();
|
||||
}
|
||||
}
|
||||
else if (!strncmp(name, "NURBS", 5))
|
||||
{
|
||||
if (name[5] != '\0')
|
||||
@@ -3533,4 +3559,192 @@ FiniteElementCollection *NURBSFECollection::GetTraceCollection() const
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
NURBS_HDivFECollection::NURBS_HDivFECollection(int Order, const int dim)
|
||||
: NURBSFECollection((Order == VariableOrder) ? 1 : Order)
|
||||
{
|
||||
const int order = (Order == VariableOrder) ? 1 : Order;
|
||||
|
||||
SegmentFE = new NURBS1DFiniteElement(order);
|
||||
QuadrilateralFE = new NURBS2DFiniteElement(order);
|
||||
|
||||
QuadrilateralVFE = new NURBS_HDiv2DFiniteElement(order);
|
||||
ParallelepipedVFE = new NURBS_HDiv3DFiniteElement(order);
|
||||
|
||||
if (dim != -1) { SetDim(dim); }
|
||||
SetOrder(Order);
|
||||
}
|
||||
|
||||
void NURBS_HDivFECollection::SetDim(int dim)
|
||||
{
|
||||
if (dim == 2)
|
||||
{
|
||||
sFE = SegmentFE;
|
||||
qFE = QuadrilateralVFE;
|
||||
hFE = nullptr;
|
||||
}
|
||||
else if (dim == 3)
|
||||
{
|
||||
sFE = nullptr;
|
||||
qFE = QuadrilateralFE;
|
||||
hFE = ParallelepipedVFE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mfem::err<<"Dimension = "<<dim<<endl;
|
||||
mfem_error ("NURBS_HDivFECollection: wrong dimension!");
|
||||
}
|
||||
}
|
||||
|
||||
NURBS_HDivFECollection::~NURBS_HDivFECollection()
|
||||
{
|
||||
delete SegmentFE;
|
||||
delete QuadrilateralFE;
|
||||
delete QuadrilateralVFE;
|
||||
delete ParallelepipedVFE;
|
||||
}
|
||||
|
||||
const FiniteElement *
|
||||
NURBS_HDivFECollection::FiniteElementForGeometry(Geometry::Type GeomType) const
|
||||
{
|
||||
switch (GeomType)
|
||||
{
|
||||
case Geometry::SEGMENT: return sFE;
|
||||
case Geometry::SQUARE: return qFE;
|
||||
case Geometry::CUBE: return hFE;
|
||||
default:
|
||||
if (error_mode == RETURN_NULL) { return nullptr; }
|
||||
mfem_error ("NURBS_HDivFECollection: unknown geometry type.");
|
||||
}
|
||||
return QuadrilateralFE; // Make some compilers happy
|
||||
}
|
||||
|
||||
void NURBS_HDivFECollection::SetOrder(int Order) const
|
||||
{
|
||||
mOrder = Order;
|
||||
if (Order != VariableOrder)
|
||||
{
|
||||
snprintf(name, 16, "NURBS_HDiv%i", Order);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(name, 16, "NURBS_HDiv");
|
||||
}
|
||||
}
|
||||
|
||||
int NURBS_HDivFECollection::DofForGeometry(Geometry::Type GeomType) const
|
||||
{
|
||||
mfem_error("NURBS_HDivFECollection::DofForGeometry");
|
||||
return 0; // Make some compilers happy
|
||||
}
|
||||
|
||||
const int *NURBS_HDivFECollection::DofOrderForOrientation(
|
||||
Geometry::Type GeomType,
|
||||
int Or) const
|
||||
{
|
||||
mfem_error("NURBS_HDivFECollection::DofOrderForOrientation");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FiniteElementCollection *NURBS_HDivFECollection::GetTraceCollection() const
|
||||
{
|
||||
MFEM_ABORT("NURBS finite elements can not be statically condensed!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NURBS_HCurlFECollection::NURBS_HCurlFECollection(int Order, const int dim)
|
||||
: NURBSFECollection((Order == VariableOrder) ? 1 : Order)
|
||||
{
|
||||
const int order = (Order == VariableOrder) ? 1 : Order;
|
||||
|
||||
SegmentFE = new NURBS1DFiniteElement(order+1);
|
||||
QuadrilateralFE = new NURBS2DFiniteElement(order+1);
|
||||
|
||||
QuadrilateralVFE = new NURBS_HCurl2DFiniteElement(order);
|
||||
ParallelepipedVFE = new NURBS_HCurl3DFiniteElement(order);
|
||||
if (dim != -1) { SetDim(dim); }
|
||||
SetOrder(Order);
|
||||
}
|
||||
|
||||
void NURBS_HCurlFECollection::SetDim(int dim)
|
||||
{
|
||||
if (dim == 2)
|
||||
{
|
||||
sFE = SegmentFE;
|
||||
qFE = QuadrilateralVFE;
|
||||
hFE = nullptr;
|
||||
}
|
||||
else if (dim == 3)
|
||||
{
|
||||
sFE = nullptr;
|
||||
qFE = QuadrilateralFE;
|
||||
hFE = ParallelepipedVFE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mfem::err<<"Dimension = "<<dim<<endl;
|
||||
mfem_error ("NURBS_HCurlFECollection: wrong dimension!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
NURBS_HCurlFECollection::~NURBS_HCurlFECollection()
|
||||
{
|
||||
delete SegmentFE;
|
||||
delete QuadrilateralFE;
|
||||
delete QuadrilateralVFE;
|
||||
delete ParallelepipedVFE;
|
||||
}
|
||||
|
||||
const FiniteElement *
|
||||
NURBS_HCurlFECollection::FiniteElementForGeometry(Geometry::Type GeomType) const
|
||||
{
|
||||
switch (GeomType)
|
||||
{
|
||||
case Geometry::SEGMENT: return sFE;
|
||||
case Geometry::SQUARE: return qFE;
|
||||
case Geometry::CUBE: return hFE;
|
||||
default:
|
||||
if (error_mode == RETURN_NULL) { return nullptr; }
|
||||
mfem_error ("NURBS_HCurlFECollection: unknown geometry type.");
|
||||
}
|
||||
return QuadrilateralFE; // Make some compilers happy
|
||||
}
|
||||
|
||||
void NURBS_HCurlFECollection::SetOrder(int Order) const
|
||||
{
|
||||
mOrder = Order;
|
||||
if (Order != VariableOrder)
|
||||
{
|
||||
snprintf(name, 16, "NURBS_HCurl%i", Order);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(name, 16, "NURBS_HCurl");
|
||||
}
|
||||
}
|
||||
|
||||
int NURBS_HCurlFECollection::DofForGeometry(Geometry::Type GeomType) const
|
||||
{
|
||||
mfem_error("NURBS_HCurlFECollection::DofForGeometry");
|
||||
return 0; // Make some compilers happy
|
||||
}
|
||||
|
||||
const int *NURBS_HCurlFECollection::DofOrderForOrientation(
|
||||
Geometry::Type GeomType,
|
||||
int Or) const
|
||||
{
|
||||
mfem_error("NURBS_HCurlFECollection::DofOrderForOrientation");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FiniteElementCollection *NURBS_HCurlFECollection::GetTraceCollection() const
|
||||
{
|
||||
MFEM_ABORT("NURBS finite elements can not be statically condensed!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
+109
-4
@@ -680,8 +680,8 @@ public:
|
||||
/// Arbitrary order non-uniform rational B-splines (NURBS) finite elements.
|
||||
class NURBSFECollection : public FiniteElementCollection
|
||||
{
|
||||
private:
|
||||
PointFiniteElement *PointFE;
|
||||
protected:
|
||||
PointFiniteElement *PointFE;
|
||||
NURBS1DFiniteElement *SegmentFE;
|
||||
NURBS2DFiniteElement *QuadrilateralFE;
|
||||
NURBS3DFiniteElement *ParallelepipedFE;
|
||||
@@ -701,13 +701,15 @@ public:
|
||||
order, or VariableOrder (default). */
|
||||
explicit NURBSFECollection(int Order = VariableOrder);
|
||||
|
||||
void Reset() const
|
||||
virtual void Reset() const
|
||||
{
|
||||
SegmentFE->Reset();
|
||||
QuadrilateralFE->Reset();
|
||||
ParallelepipedFE->Reset();
|
||||
}
|
||||
|
||||
virtual void SetDim(const int dim) {};
|
||||
|
||||
/** @brief Get the order of the NURBS collection: either a positive number,
|
||||
when using fixed order, or VariableOrder. */
|
||||
/** @note Not to be confused with FiniteElementCollection::GetOrder(). */
|
||||
@@ -715,7 +717,7 @@ public:
|
||||
|
||||
/** @brief Set the order and the name, based on the given @a Order: either a
|
||||
positive number for fixed order, or VariableOrder. */
|
||||
void SetOrder(int Order) const;
|
||||
virtual void SetOrder(int Order) const;
|
||||
|
||||
const FiniteElement *
|
||||
FiniteElementForGeometry(Geometry::Type GeomType) const override;
|
||||
@@ -734,6 +736,109 @@ public:
|
||||
virtual ~NURBSFECollection();
|
||||
};
|
||||
|
||||
/// Arbitrary order H(div) NURBS finite elements.
|
||||
class NURBS_HDivFECollection : public NURBSFECollection
|
||||
{
|
||||
private:
|
||||
|
||||
NURBS1DFiniteElement *SegmentFE;
|
||||
NURBS2DFiniteElement *QuadrilateralFE;
|
||||
|
||||
NURBS_HDiv2DFiniteElement *QuadrilateralVFE;
|
||||
NURBS_HDiv3DFiniteElement *ParallelepipedVFE;
|
||||
|
||||
FiniteElement *sFE;
|
||||
FiniteElement *qFE;
|
||||
FiniteElement *hFE;
|
||||
|
||||
public:
|
||||
|
||||
/** @brief The parameter @a Order must be either a positive number, for fixed
|
||||
order, or VariableOrder (default). */
|
||||
explicit NURBS_HDivFECollection(int Order = VariableOrder, const int vdim = -1);
|
||||
|
||||
void Reset() const override
|
||||
{
|
||||
SegmentFE->Reset();
|
||||
QuadrilateralFE->Reset();
|
||||
QuadrilateralVFE->Reset();
|
||||
ParallelepipedVFE->Reset();
|
||||
}
|
||||
|
||||
void SetDim(const int dim) override;
|
||||
|
||||
/** @brief Set the order and the name, based on the given @a Order: either a
|
||||
positive number for fixed order, or VariableOrder. */
|
||||
void SetOrder(int Order) const override;
|
||||
|
||||
const FiniteElement *
|
||||
FiniteElementForGeometry(Geometry::Type GeomType) const override;
|
||||
|
||||
int DofForGeometry(Geometry::Type GeomType) const override;
|
||||
|
||||
const int *DofOrderForOrientation(Geometry::Type GeomType,
|
||||
int Or) const override;
|
||||
|
||||
const char *Name() const override { return name; }
|
||||
|
||||
int GetContType() const override { return CONTINUOUS; }
|
||||
|
||||
FiniteElementCollection *GetTraceCollection() const override;
|
||||
|
||||
virtual ~NURBS_HDivFECollection();
|
||||
};
|
||||
|
||||
/// Arbitrary order H(curl) NURBS finite elements.
|
||||
class NURBS_HCurlFECollection : public NURBSFECollection
|
||||
{
|
||||
private:
|
||||
NURBS1DFiniteElement *SegmentFE;
|
||||
NURBS2DFiniteElement *QuadrilateralFE;
|
||||
|
||||
NURBS_HCurl2DFiniteElement *QuadrilateralVFE;
|
||||
NURBS_HCurl3DFiniteElement *ParallelepipedVFE;
|
||||
|
||||
FiniteElement *sFE;
|
||||
FiniteElement *qFE;
|
||||
FiniteElement *hFE;
|
||||
public:
|
||||
|
||||
/** @brief The parameter @a Order must be either a positive number, for fixed
|
||||
order, or VariableOrder (default). */
|
||||
explicit NURBS_HCurlFECollection(int Order = VariableOrder,
|
||||
const int vdim = -1);
|
||||
|
||||
void Reset() const override
|
||||
{
|
||||
SegmentFE->Reset();
|
||||
QuadrilateralFE->Reset();
|
||||
QuadrilateralVFE->Reset();
|
||||
ParallelepipedVFE->Reset();
|
||||
}
|
||||
|
||||
void SetDim(const int dim) override;
|
||||
|
||||
/** @brief Set the order and the name, based on the given @a Order: either a
|
||||
positive number for fixed order, or VariableOrder. */
|
||||
void SetOrder(int Order) const override;
|
||||
|
||||
const FiniteElement *
|
||||
FiniteElementForGeometry(Geometry::Type GeomType) const override;
|
||||
|
||||
int DofForGeometry(Geometry::Type GeomType) const override;
|
||||
|
||||
const int *DofOrderForOrientation(Geometry::Type GeomType,
|
||||
int Or) const override;
|
||||
|
||||
const char *Name() const override { return name; }
|
||||
|
||||
int GetContType() const override { return CONTINUOUS; }
|
||||
|
||||
FiniteElementCollection *GetTraceCollection() const override;
|
||||
|
||||
virtual ~NURBS_HCurlFECollection();
|
||||
};
|
||||
|
||||
/// Piecewise-(bi/tri)linear continuous finite elements.
|
||||
class LinearFECollection : public FiniteElementCollection
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user