Compare commits
918 Commits
release/20
...
release/20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
828fe797f0 | ||
|
|
8f24032612 | ||
|
|
ee6bfbd76f | ||
|
|
54ee583112 | ||
|
|
b69010cfc9 | ||
|
|
2859980cb4 | ||
|
|
3ffefd8098 | ||
|
|
852fdd7ac4 | ||
|
|
47a43daeac | ||
|
|
b562bef1af | ||
|
|
414b6820b4 | ||
|
|
5dbc22484e | ||
|
|
8b838264dd | ||
|
|
c533e1206f | ||
|
|
d87f9edf60 | ||
|
|
dbff25f79b | ||
|
|
4b657fc4cf | ||
|
|
a4e66a5484 | ||
|
|
226bfbe524 | ||
|
|
164ab30fa1 | ||
|
|
d5ce2b6a76 | ||
|
|
2997338eb2 | ||
|
|
ebedc9b0b6 | ||
|
|
ac58d8428c | ||
|
|
ba58cbc166 | ||
|
|
bd0c0f6356 | ||
|
|
de9a93377c | ||
|
|
55057540e2 | ||
|
|
fe1272a2e6 | ||
|
|
c25275d0ee | ||
|
|
ffba48d7f2 | ||
|
|
dbfad81253 | ||
|
|
a0aafc5d5b | ||
|
|
9afaa32ca7 | ||
|
|
68a254ffdc | ||
|
|
4dafe9456a | ||
|
|
8e49c35c18 | ||
|
|
25d7b538aa | ||
|
|
877ff028be | ||
|
|
c5eca4b1e4 | ||
|
|
b4915e7b55 | ||
|
|
b2a37d1e54 | ||
|
|
466341fa0f | ||
|
|
c279184229 | ||
|
|
bd73bb6c55 | ||
|
|
78170ccfce | ||
|
|
7852e584f9 | ||
|
|
a9bb73559d | ||
|
|
be36439600 | ||
|
|
9e40f3be4f | ||
|
|
0d172c9a1c | ||
|
|
ad6c98e0da | ||
|
|
8fb0e1e222 | ||
|
|
d7bd8d25cd | ||
|
|
d0d6d57472 | ||
|
|
0923ffeef2 | ||
|
|
7a158fc45c | ||
|
|
fdac0f576c | ||
|
|
e6aecbd7ac | ||
|
|
5083db3715 | ||
|
|
1247309b3f | ||
|
|
a1365ffc99 | ||
|
|
4b62303f36 | ||
|
|
d7249ea6e6 | ||
|
|
810aa6970b | ||
|
|
598b5b1ff4 | ||
|
|
5734923b1e | ||
|
|
4eb41c569e | ||
|
|
85f13c3e64 | ||
|
|
01090a8722 | ||
|
|
2b4212bac0 | ||
|
|
4bee03be6f | ||
|
|
7360755c63 | ||
|
|
f7cf50830d | ||
|
|
21dbd82bb9 | ||
|
|
0a730d949f | ||
|
|
ba1f9e882b | ||
|
|
745720ef99 | ||
|
|
3595eb7c82 | ||
|
|
75d28fc6ce | ||
|
|
ade0cd059e | ||
|
|
daf9337599 | ||
|
|
9bff0094f1 | ||
|
|
c3e992f996 | ||
|
|
d9c81da18c | ||
|
|
94fae0da30 | ||
|
|
6cd420ed9b | ||
|
|
19dde5e6d3 | ||
|
|
5b1065df45 | ||
|
|
e452058b4e | ||
|
|
e84edae209 | ||
|
|
a3f08ca6ea | ||
|
|
858e06044e | ||
|
|
1812acccec | ||
|
|
1d402bdca3 | ||
|
|
d24c327a90 | ||
|
|
fe12e48b5c | ||
|
|
088f8ff9e0 | ||
|
|
57c1c2d984 | ||
|
|
7335d72e8b | ||
|
|
b741a73957 | ||
|
|
bf971c0ede | ||
|
|
c910a51359 | ||
|
|
a73e82110c | ||
|
|
daa67dc8d6 | ||
|
|
eb15695ed0 | ||
|
|
75e196cdd8 | ||
|
|
00cc2b9075 | ||
|
|
53c29e56d4 | ||
|
|
205c4a94db | ||
|
|
25522dc424 | ||
|
|
5421efd79d | ||
|
|
c5935c97f6 | ||
|
|
fa77187871 | ||
|
|
345452109f | ||
|
|
4d8f75e24d | ||
|
|
c9821faddc | ||
|
|
ef5f90c12b | ||
|
|
066dca43ba | ||
|
|
16c9d7d04d | ||
|
|
2a07a2e8a2 | ||
|
|
118f4dd3de | ||
|
|
7a2c1157a0 | ||
|
|
0caf039bcb | ||
|
|
f80b220b44 | ||
|
|
3542d43c72 | ||
|
|
8c6cfdc704 | ||
|
|
f38e1511b5 | ||
|
|
130208b20e | ||
|
|
094f17532d | ||
|
|
f4196ff25e | ||
|
|
25d7e99413 | ||
|
|
b4edd0acda | ||
|
|
9c5acbb304 | ||
|
|
1ecd62d98d | ||
|
|
f293bcfc3c | ||
|
|
7e70d85c83 | ||
|
|
595efe7e48 | ||
|
|
04d42c2f4e | ||
|
|
f700053736 | ||
|
|
ccba767b24 | ||
|
|
568506627e | ||
|
|
585447fd22 | ||
|
|
fa2e0efd17 | ||
|
|
c244625865 | ||
|
|
15a7d7597d | ||
|
|
c7368949dd | ||
|
|
9b383db145 | ||
|
|
201978c9b2 | ||
|
|
8058167310 | ||
|
|
dcdbf36ec3 | ||
|
|
3e03a7d93f | ||
|
|
db0139e842 | ||
|
|
6df9cf66ea | ||
|
|
8967c13d3e | ||
|
|
167b344506 | ||
|
|
6b8e04460c | ||
|
|
184ba02df8 | ||
|
|
6eff5158df | ||
|
|
af7693ef6b | ||
|
|
03a2bbdf80 | ||
|
|
43cc132651 | ||
|
|
f55d3e1578 | ||
|
|
3dc347f894 | ||
|
|
275cf03f0d | ||
|
|
6ff4d8b136 | ||
|
|
010dd03c6d | ||
|
|
6bf64b18fe | ||
|
|
a91d47f191 | ||
|
|
228aacd390 | ||
|
|
40aad6d64e | ||
|
|
7425f8b988 | ||
|
|
945438b210 | ||
|
|
f0eed83b12 | ||
|
|
b02578655d | ||
|
|
19988494c0 | ||
|
|
b5542c4e56 | ||
|
|
40bd7b86b0 | ||
|
|
ab737ab4d3 | ||
|
|
732c5ae4d2 | ||
|
|
999b06b0eb | ||
|
|
e27933270a | ||
|
|
e00a5d5fa9 | ||
|
|
785d80b677 | ||
|
|
ef19a67617 | ||
|
|
10a225785e | ||
|
|
4e8352dabb | ||
|
|
1617d2b434 | ||
|
|
946d1cb877 | ||
|
|
a1b8303ac3 | ||
|
|
4c0c394b77 | ||
|
|
5b86ef115c | ||
|
|
1fee73481e | ||
|
|
c914b7e07c | ||
|
|
ff68195c4f | ||
|
|
a1c7e8f5d4 | ||
|
|
a27b39ff05 | ||
|
|
1be3e88f58 | ||
|
|
7c3aacd118 | ||
|
|
159ffeaef3 | ||
|
|
c345aa3f4e | ||
|
|
a51d18cab0 | ||
|
|
0d0b8b257f | ||
|
|
c9331d7fed | ||
|
|
849eb80e41 | ||
|
|
e685eccdc9 | ||
|
|
169ec76605 | ||
|
|
b311fbb9d0 | ||
|
|
bfe2507184 | ||
|
|
466693f1d0 | ||
|
|
ecca78af85 | ||
|
|
551f1f8c76 | ||
|
|
9e97dde466 | ||
|
|
b3cfb4ee78 | ||
|
|
bed76c330b | ||
|
|
8f2a36593d | ||
|
|
5736dd6e9c | ||
|
|
ff1b245b8f | ||
|
|
e77bd172c5 | ||
|
|
0301d402a4 | ||
|
|
fde95a69d1 | ||
|
|
75d93f196d | ||
|
|
62b826e14f | ||
|
|
96c02c9d35 | ||
|
|
3d4b467a2f | ||
|
|
7451e6618f | ||
|
|
cf0b7db534 | ||
|
|
7986e99e61 | ||
|
|
6cc65ada59 | ||
|
|
7bf635ef59 | ||
|
|
c138e78ddb | ||
|
|
1bca0f6480 | ||
|
|
16f6e3ee0c | ||
|
|
d6a9ea162d | ||
|
|
b900441ac6 | ||
|
|
65b629e423 | ||
|
|
76f709aa70 | ||
|
|
57d19c9cdb | ||
|
|
e9756c3ee5 | ||
|
|
19c81fad9c | ||
|
|
ecca175ccd | ||
|
|
2caf82baff | ||
|
|
d82be29745 | ||
|
|
8eb10b33ce | ||
|
|
42d08db25b | ||
|
|
d7d3d2538a | ||
|
|
e0fad15f0a | ||
|
|
4c2105f85c | ||
|
|
981e6c9b22 | ||
|
|
4e83b63a0d | ||
|
|
4c1333fb4f | ||
|
|
6db8a45d88 | ||
|
|
c33f69fd1b | ||
|
|
92b1b34dca | ||
|
|
bb5b2f4232 | ||
|
|
ebe2f28c67 | ||
|
|
414661b898 | ||
|
|
4e00897117 | ||
|
|
98133f44fc | ||
|
|
1574d7714d | ||
|
|
3c41d4c17a | ||
|
|
ef606711f2 | ||
|
|
ed9827bfcf | ||
|
|
fcadc69e49 | ||
|
|
27eaeb2ec9 | ||
|
|
420b66822b | ||
|
|
9913cb8600 | ||
|
|
c874c8b6ea | ||
|
|
6ca6f27640 | ||
|
|
bd4e872230 | ||
|
|
3a9bab6285 | ||
|
|
30e2577f31 | ||
|
|
959502e8cd | ||
|
|
4a3c6b2058 | ||
|
|
29db657757 | ||
|
|
91734f13c4 | ||
|
|
b4c86e73af | ||
|
|
f3a82ddd70 | ||
|
|
4174602da2 | ||
|
|
749353a4b0 | ||
|
|
a8db1f155c | ||
|
|
59b4ca4b20 | ||
|
|
261f7c3c03 | ||
|
|
a1214ba49e | ||
|
|
d9585d6585 | ||
|
|
a668248aa1 | ||
|
|
d40177dacb | ||
|
|
67acaaa637 | ||
|
|
33c5b79d98 | ||
|
|
7790fe743e | ||
|
|
40a2e848cb | ||
|
|
7f6fd34fd3 | ||
|
|
586f296de0 | ||
|
|
8a2c2304e7 | ||
|
|
9df659370c | ||
|
|
66650a20fb | ||
|
|
eae4a080cd | ||
|
|
eb5454aeaf | ||
|
|
dc0ccc010a | ||
|
|
aa63d772d7 | ||
|
|
91afb0b656 | ||
|
|
666cc9210b | ||
|
|
bdd82445d2 | ||
|
|
bf9a142b6d | ||
|
|
9bbacfe710 | ||
|
|
982b221753 | ||
|
|
a4d0bb685b | ||
|
|
3429db8fc1 | ||
|
|
fc0e61518b | ||
|
|
b7eefe8b18 | ||
|
|
0d5b3a5285 | ||
|
|
3eef43b904 | ||
|
|
db90ecd88c | ||
|
|
68769e5b1d | ||
|
|
85949d44ac | ||
|
|
690e00a079 | ||
|
|
cf42146d84 | ||
|
|
23cbe9035b | ||
|
|
2cd6fa2f49 | ||
|
|
1b1f7b807d | ||
|
|
bf52e6d123 | ||
|
|
c6bbe5d24b | ||
|
|
ad001df804 | ||
|
|
69e921b33a | ||
|
|
875626b738 | ||
|
|
7e05d51e6f | ||
|
|
0dc80689c0 | ||
|
|
ae8b81c7ae | ||
|
|
ba0675997a | ||
|
|
15c473e3bb | ||
|
|
6465b5b23c | ||
|
|
9e93dc5af2 | ||
|
|
481123ed25 | ||
|
|
4968c35ad8 | ||
|
|
f6136e69fe | ||
|
|
6832788eef | ||
|
|
4c0776e3d2 | ||
|
|
00d1607347 | ||
|
|
142c0a12c3 | ||
|
|
25fbff2632 | ||
|
|
1833ee2c43 | ||
|
|
f5851bcb92 | ||
|
|
5632fc6662 | ||
|
|
8375516c82 | ||
|
|
bf6732559f | ||
|
|
3b951985ec | ||
|
|
9c98b5ceb4 | ||
|
|
161f555bc0 | ||
|
|
39a6871b1d | ||
|
|
175da3d436 | ||
|
|
cf61068ad1 | ||
|
|
bf7b2697ee | ||
|
|
9098316775 | ||
|
|
1249ef0dd2 | ||
|
|
2b2d4901d1 | ||
|
|
d4740ae249 | ||
|
|
49eda9fc72 | ||
|
|
3ea522d7ba | ||
|
|
70172f5771 | ||
|
|
91306c12f4 | ||
|
|
67f96f4996 | ||
|
|
39bb94c2c8 | ||
|
|
7955805dd5 | ||
|
|
74c06ea703 | ||
|
|
71b0c2883f | ||
|
|
334dbe4e1f | ||
|
|
53252e6694 | ||
|
|
e27df951f6 | ||
|
|
1062fb836b | ||
|
|
343d060118 | ||
|
|
b15fab221b | ||
|
|
88b16f981c | ||
|
|
dc3f1cbf40 | ||
|
|
01e3aa377c | ||
|
|
44102f83a0 | ||
|
|
2c13cdfa18 | ||
|
|
1d22e3b0ed | ||
|
|
2add79d122 | ||
|
|
0cfbfb9957 | ||
|
|
92f65b7958 | ||
|
|
79037f93b2 | ||
|
|
633a5883f7 | ||
|
|
63590f95b0 | ||
|
|
e783eaafc0 | ||
|
|
e341bd1c08 | ||
|
|
f9ce82547c | ||
|
|
b349b3b217 | ||
|
|
983ed5fcb8 | ||
|
|
f414f5b8ad | ||
|
|
7c52f6f5a8 | ||
|
|
188eb23911 | ||
|
|
72ad2eaa7f | ||
|
|
92870dc1e9 | ||
|
|
2d43ccaf8f | ||
|
|
b2e0eb2507 | ||
|
|
5085fb35c0 | ||
|
|
8d33ec55bd | ||
|
|
d70b86484d | ||
|
|
0089fa9287 | ||
|
|
6b80dd10e6 | ||
|
|
f4a9298cf4 | ||
|
|
7de217b8fb | ||
|
|
039fdb70de | ||
|
|
2f7a0bc532 | ||
|
|
fda1719eab | ||
|
|
c0e9b71eec | ||
|
|
d93bd35b8e | ||
|
|
afab0103e3 | ||
|
|
62f39dacce | ||
|
|
1d7a12442e | ||
|
|
d69bf47a28 | ||
|
|
7064b96260 | ||
|
|
e0d5711f8e | ||
|
|
3677f470fb | ||
|
|
44409c7a30 | ||
|
|
7c1e868973 | ||
|
|
0768c5a8b3 | ||
|
|
ea7cb8d2c6 | ||
|
|
6858bd4578 | ||
|
|
1b8680df7d | ||
|
|
316324a78e | ||
|
|
2bf33c30d8 | ||
|
|
862b3450d3 | ||
|
|
082476f840 | ||
|
|
49655b464c | ||
|
|
1432367e07 | ||
|
|
e4912d4fcf | ||
|
|
d0e5f8f470 | ||
|
|
65ef90f471 | ||
|
|
bcb852e8f2 | ||
|
|
927bf09688 | ||
|
|
6921801eec | ||
|
|
f21e2035c4 | ||
|
|
c1ffeeef53 | ||
|
|
e27abdd1a0 | ||
|
|
8b8285ae2b | ||
|
|
bdcb227a53 | ||
|
|
88f043645a | ||
|
|
ad55655a08 | ||
|
|
6af3194c6c | ||
|
|
bb96eb9b70 | ||
|
|
baae4a3faf | ||
|
|
36c3080f85 | ||
|
|
c35832b155 | ||
|
|
ca9da29c53 | ||
|
|
1ba51534ae | ||
|
|
01abada947 | ||
|
|
212a1fde5f | ||
|
|
0b8adcbee3 | ||
|
|
1d755859a6 | ||
|
|
5d3125c532 | ||
|
|
971d300243 | ||
|
|
199b7d710a | ||
|
|
d60787188e | ||
|
|
819ad1bf9e | ||
|
|
3cbc40bd4d | ||
|
|
8e92a84c09 | ||
|
|
ff8ab1c1dc | ||
|
|
9d45632628 | ||
|
|
089b58f101 | ||
|
|
967e3ad3af | ||
|
|
e2d748906e | ||
|
|
95179f393c | ||
|
|
6fee172f16 | ||
|
|
a241a1bd07 | ||
|
|
4348438044 | ||
|
|
8e801a1fae | ||
|
|
2d5d0953ee | ||
|
|
9df3bea857 | ||
|
|
056d6bccb4 | ||
|
|
68e6926355 | ||
|
|
2df9779a62 | ||
|
|
60fb68d3fc | ||
|
|
ae9d5e97c7 | ||
|
|
d958da6542 | ||
|
|
b8c5d8c129 | ||
|
|
e7660b0613 | ||
|
|
7ebadbb055 | ||
|
|
0f485c7801 | ||
|
|
a6ec18cd4e | ||
|
|
af8f8c6bfd | ||
|
|
258bcbc186 | ||
|
|
2260efaad9 | ||
|
|
624dec542a | ||
|
|
7ca8b46167 | ||
|
|
8fbb93497a | ||
|
|
ef5465dcfc | ||
|
|
f9eb32a235 | ||
|
|
f275fd6089 | ||
|
|
decd0b10a9 | ||
|
|
10c9da1a36 | ||
|
|
47141dfabf | ||
|
|
613aafe4ae | ||
|
|
f867d7f82c | ||
|
|
fe060c7f48 | ||
|
|
80154e8f5f | ||
|
|
ae0cb3e5ad | ||
|
|
133f89198f | ||
|
|
03bb4da004 | ||
|
|
e356a16ab2 | ||
|
|
eea23abedd | ||
|
|
5f620f7451 | ||
|
|
c76ee877aa | ||
|
|
fd36bf88fb | ||
|
|
24bd410313 | ||
|
|
984a308e24 | ||
|
|
6ea7a1796d | ||
|
|
ee0d256a12 | ||
|
|
42d7587e1b | ||
|
|
c75a50796b | ||
|
|
1190260d7d | ||
|
|
5b8882d6f0 | ||
|
|
f8e711246f | ||
|
|
5283611695 | ||
|
|
ca8e2f279b | ||
|
|
c49b51ab23 | ||
|
|
7c65850894 | ||
|
|
7279fd5ea8 | ||
|
|
f279c7e374 | ||
|
|
7b1595d0b2 | ||
|
|
8c8290f614 | ||
|
|
3819910396 | ||
|
|
72b39e513a | ||
|
|
04a9e710d5 | ||
|
|
1c771a66fc | ||
|
|
c938765224 | ||
|
|
a37625b2cf | ||
|
|
83331033b5 | ||
|
|
58a5a4e371 | ||
|
|
3655213c40 | ||
|
|
2844aa4468 | ||
|
|
c81e5027c9 | ||
|
|
23950403f1 | ||
|
|
33372a3337 | ||
|
|
c067e48276 | ||
|
|
5d398565c2 | ||
|
|
a9a82e3814 | ||
|
|
3f94b580a2 | ||
|
|
cfc1b29c08 | ||
|
|
264d451d56 | ||
|
|
21eddfbdf2 | ||
|
|
22b38f1031 | ||
|
|
34b9cbcaa4 | ||
|
|
8721385104 | ||
|
|
fa85844a9b | ||
|
|
e3bc8a6ad7 | ||
|
|
564f064392 | ||
|
|
5477711420 | ||
|
|
23c1aa9308 | ||
|
|
0e2dbf737e | ||
|
|
5a2eec25b2 | ||
|
|
ae7c7fdf74 | ||
|
|
ddf6f153f7 | ||
|
|
9f7b9be7f4 | ||
|
|
0b85652c35 | ||
|
|
4bb0ede6b4 | ||
|
|
d847e10d96 | ||
|
|
5fb0c91c05 | ||
|
|
ff53a2334c | ||
|
|
776d851b26 | ||
|
|
2884d02a71 | ||
|
|
90459cac7e | ||
|
|
b03ccdc6e1 | ||
|
|
fa9275f1af | ||
|
|
ef6e0b084d | ||
|
|
a3b37eee4f | ||
|
|
980f55271f | ||
|
|
335b070564 | ||
|
|
d42c98223c | ||
|
|
2f868a7325 | ||
|
|
96f2528083 | ||
|
|
38c4d07282 | ||
|
|
77904d6aab | ||
|
|
6688a9286f | ||
|
|
9637109ca8 | ||
|
|
41d0a56967 | ||
|
|
9d32793796 | ||
|
|
13e849140c | ||
|
|
0e1e4e08e7 | ||
|
|
3fb7149226 | ||
|
|
2889a829f8 | ||
|
|
ccb223521f | ||
|
|
409a497396 | ||
|
|
5cf35e03c7 | ||
|
|
4f9f952e77 | ||
|
|
a41596004a | ||
|
|
6ea83724d6 | ||
|
|
0a96fc012e | ||
|
|
5d860f8b03 | ||
|
|
9ea6c034e2 | ||
|
|
17966d098b | ||
|
|
9d0604ad99 | ||
|
|
36de4a4a31 | ||
|
|
690fe11e58 | ||
|
|
bce55f7087 | ||
|
|
dc64b6eb86 | ||
|
|
c720c48ba0 | ||
|
|
5b1ec7b5b0 | ||
|
|
439bc30ea3 | ||
|
|
888326b32c | ||
|
|
6ed9c356a9 | ||
|
|
d9adf7ccc2 | ||
|
|
c5a1b30dc1 | ||
|
|
cedadaf649 | ||
|
|
949fb3d944 | ||
|
|
86ca704d75 | ||
|
|
53d19e8a44 | ||
|
|
f7d975920b | ||
|
|
531581762f | ||
|
|
402a5f0965 | ||
|
|
79d0081369 | ||
|
|
0f26e2e958 | ||
|
|
9cf9bf310d | ||
|
|
a284acc3ed | ||
|
|
19bb0e0077 | ||
|
|
89b11dfd26 | ||
|
|
2552750bed | ||
|
|
7b2c36bde5 | ||
|
|
b9bb0ae60a | ||
|
|
4c6d4ee201 | ||
|
|
906ff3f4b5 | ||
|
|
238d3ddb58 | ||
|
|
42745e0bfc | ||
|
|
4e593da140 | ||
|
|
662d673c44 | ||
|
|
fdc4b0142e | ||
|
|
142994dde6 | ||
|
|
d58001f608 | ||
|
|
7dccd13c50 | ||
|
|
fb5e1229ef | ||
|
|
d30fc975e3 | ||
|
|
36af2aadb5 | ||
|
|
cf754c499d | ||
|
|
9d7ec59e9e | ||
|
|
eded8bacfc | ||
|
|
87e3beb601 | ||
|
|
079d946723 | ||
|
|
492a240f09 | ||
|
|
e6c0ccb5bf | ||
|
|
71d92c3dc8 | ||
|
|
2ea1b7860f | ||
|
|
9fd5ce396b | ||
|
|
bff3c0bff1 | ||
|
|
7cd29ea7d7 | ||
|
|
a3c9943a5e | ||
|
|
552c390465 | ||
|
|
9f9041dcae | ||
|
|
c870172a30 | ||
|
|
80918f030b | ||
|
|
1d55e923f9 | ||
|
|
cb525c5c75 | ||
|
|
4a5b71d8c1 | ||
|
|
ff939b44f2 | ||
|
|
9e8110e67b | ||
|
|
b877c8b340 | ||
|
|
7a034ffd01 | ||
|
|
6e0c31bed4 | ||
|
|
ef63206925 | ||
|
|
0b6d36658d | ||
|
|
44f3b86547 | ||
|
|
bee4590aaa | ||
|
|
5aa0bfadf0 | ||
|
|
e1948ccf99 | ||
|
|
45e81a02fa | ||
|
|
085bbc263b | ||
|
|
3e95d3f42b | ||
|
|
6b93051616 | ||
|
|
d3249d965f | ||
|
|
4a10023c0d | ||
|
|
065b9c9c9f | ||
|
|
ae3c4e0d8c | ||
|
|
4d5ef337ec | ||
|
|
a2394c06f5 | ||
|
|
43e4f0ca87 | ||
|
|
cdf876fa15 | ||
|
|
12402916a7 | ||
|
|
0183fa884a | ||
|
|
e407e65b54 | ||
|
|
e072365234 | ||
|
|
070acf4bef | ||
|
|
451d52c18a | ||
|
|
bbb5e27e90 | ||
|
|
37ddd82545 | ||
|
|
3c90adeea9 | ||
|
|
903118736a | ||
|
|
18a22d8f68 | ||
|
|
46be17cf58 | ||
|
|
ce5c617f41 | ||
|
|
ca1833e6ed | ||
|
|
bb2e5e0370 | ||
|
|
f6cc04a4ab | ||
|
|
d6c56982cc | ||
|
|
ee6fab7395 | ||
|
|
93b8d26f86 | ||
|
|
0627a9f8ef | ||
|
|
3c88335852 | ||
|
|
ef3ef3142a | ||
|
|
9c6a0cc5d9 | ||
|
|
4502333751 | ||
|
|
64e5d123a2 | ||
|
|
f80644b616 | ||
|
|
6d58f519fd | ||
|
|
4a5333887b | ||
|
|
760d0d70b4 | ||
|
|
563c053d3a | ||
|
|
cbd44ff67a | ||
|
|
32dabd6572 | ||
|
|
3d61162e29 | ||
|
|
3fabf2aad3 | ||
|
|
3fa0064e5b | ||
|
|
62f267cf89 | ||
|
|
f16b45eeed | ||
|
|
7b301cb300 | ||
|
|
34b1b3a073 | ||
|
|
20d0565220 | ||
|
|
1695dfe78b | ||
|
|
387be05c77 | ||
|
|
349ee4657e | ||
|
|
7d7ec8efca | ||
|
|
5c1aa3657d | ||
|
|
bf58a16e33 | ||
|
|
84739c3bed | ||
|
|
1c21ec9d5c | ||
|
|
03b3be48b0 | ||
|
|
b9c68bdc6e | ||
|
|
7680d1900f | ||
|
|
0be3f2c76f | ||
|
|
d4c49398c5 | ||
|
|
687f108285 | ||
|
|
48047f8c7a | ||
|
|
3466776c1a | ||
|
|
efb2904beb | ||
|
|
d7c855906f | ||
|
|
19afcbf769 | ||
|
|
e4d39dc722 | ||
|
|
c7c2480c01 | ||
|
|
90cbad1163 | ||
|
|
5b5d895380 | ||
|
|
c38100a491 | ||
|
|
b5ff9bc393 | ||
|
|
3186a2d01a | ||
|
|
13d1ce4fbf | ||
|
|
4144d761dd | ||
|
|
71961c21b4 | ||
|
|
1b8e1b3197 | ||
|
|
1e4e565380 | ||
|
|
fa002c4408 | ||
|
|
9d5a43d4e6 | ||
|
|
6eb363e8e1 | ||
|
|
98e3bbcf1d | ||
|
|
976bfdab35 | ||
|
|
ca79b16b26 | ||
|
|
65639b0a03 | ||
|
|
986abc1bdc | ||
|
|
5c68a0aaa8 | ||
|
|
7a91bebd61 | ||
|
|
102bd6b728 | ||
|
|
fc3bc714fc | ||
|
|
89e95b0789 | ||
|
|
ffa4a8ef7b | ||
|
|
1f7a2d5459 | ||
|
|
3ffcff1773 | ||
|
|
cfb3d34467 | ||
|
|
b109ab7822 | ||
|
|
5c55957718 | ||
|
|
4d3c143af4 | ||
|
|
3a46555b6d | ||
|
|
a5cc1cfe48 | ||
|
|
6095fda39f | ||
|
|
a8d1545947 | ||
|
|
c212af9253 | ||
|
|
6461cc2a81 | ||
|
|
8895ee171a | ||
|
|
90f6b46837 | ||
|
|
04a3a9ada5 | ||
|
|
7a790a33bb | ||
|
|
d72c45cd62 | ||
|
|
bcfb195a83 | ||
|
|
0327393951 | ||
|
|
15dd449354 | ||
|
|
ad2af10c5a | ||
|
|
5bce16c4e9 | ||
|
|
9d16cc8ec4 | ||
|
|
1f1ecebec5 | ||
|
|
fd3000cd31 | ||
|
|
363b8589e6 | ||
|
|
93f7f50eb7 | ||
|
|
f3d82437fd | ||
|
|
d52d4cc3a6 | ||
|
|
7332ee4b18 | ||
|
|
2cb5f62591 | ||
|
|
08994de897 | ||
|
|
b8605532f4 | ||
|
|
2356cc35e5 | ||
|
|
83b63213f4 | ||
|
|
32722f3b9c | ||
|
|
d0580c2180 | ||
|
|
c3a11a2fb5 | ||
|
|
a50c823873 | ||
|
|
ba04fbb1ad | ||
|
|
acef0e411d | ||
|
|
aa04fee73f | ||
|
|
fa3d6029b3 | ||
|
|
f7950ca458 | ||
|
|
197b34d9ec | ||
|
|
c839f8dac7 | ||
|
|
7cedf056d7 | ||
|
|
261f6ac270 | ||
|
|
d1d9e214ce | ||
|
|
d2d9128e6a | ||
|
|
b22e00b92d | ||
|
|
6c7f6d7afb | ||
|
|
dc318f731f | ||
|
|
d4d2b813dd | ||
|
|
501b1dc760 | ||
|
|
bfbcd3e470 | ||
|
|
2574dc7542 | ||
|
|
fb0272f343 | ||
|
|
3085243117 | ||
|
|
c6536c0b2f | ||
|
|
5dba20496a | ||
|
|
97bb1c3413 | ||
|
|
0d0e123735 | ||
|
|
768326527a | ||
|
|
df289d455b | ||
|
|
6b9e0c5ef8 | ||
|
|
3975db2ff3 | ||
|
|
d39db2f0db | ||
|
|
b3eb6b58eb | ||
|
|
088ba8a19a | ||
|
|
d168e9ff67 | ||
|
|
46ab6dd8e1 | ||
|
|
66de108c68 | ||
|
|
58e4e5263e | ||
|
|
8fda1e036a | ||
|
|
3327d17c3f | ||
|
|
d299e003b7 | ||
|
|
37da204eb6 | ||
|
|
ccb7e5df3e | ||
|
|
1ee597206c | ||
|
|
163c3d435a | ||
|
|
3ad0b1c5ca | ||
|
|
476bfa1046 | ||
|
|
24f28e8a5d | ||
|
|
59bb98d312 | ||
|
|
f945032405 | ||
|
|
62c7706f30 | ||
|
|
a7ec8b1d53 | ||
|
|
d39ba17190 | ||
|
|
e654cba898 | ||
|
|
47d06c526f | ||
|
|
61b7977406 | ||
|
|
0b4f830d28 | ||
|
|
f6c795bed0 | ||
|
|
ab365481a7 | ||
|
|
6883c8ae21 | ||
|
|
b338e56730 | ||
|
|
28b7781017 | ||
|
|
56da8cd8f9 | ||
|
|
6168a35512 | ||
|
|
9a17457e6f | ||
|
|
aecf3f6470 | ||
|
|
3b84678db5 | ||
|
|
23ca927249 | ||
|
|
7163807296 | ||
|
|
5008501318 | ||
|
|
3c18add696 | ||
|
|
b9d2a08930 | ||
|
|
eb001a1e67 | ||
|
|
593af1c678 | ||
|
|
e6f318aa28 | ||
|
|
d078a96eae | ||
|
|
fea57c5031 | ||
|
|
fadab53590 | ||
|
|
b4ef14dfc0 | ||
|
|
b28527c0ec | ||
|
|
429c4e475c | ||
|
|
fcbcc9cda4 | ||
|
|
675858f1e0 | ||
|
|
427833b089 | ||
|
|
ba573b5834 | ||
|
|
6a8e7a9a05 | ||
|
|
580a64563f | ||
|
|
e6b57fa422 | ||
|
|
ba107498a1 | ||
|
|
183fd4eabb | ||
|
|
f2cb5fe9de | ||
|
|
5dd34b1308 | ||
|
|
8cfd477d3e | ||
|
|
bfb6553828 | ||
|
|
49edd1e54d | ||
|
|
6b78115229 | ||
|
|
901a44e92b | ||
|
|
01f87ea750 | ||
|
|
9303771a73 | ||
|
|
be9744ef68 | ||
|
|
6ec82f8947 | ||
|
|
ef29518fab | ||
|
|
cd9afa6aec | ||
|
|
bdef0ddfb0 | ||
|
|
e79b5bbc8c | ||
|
|
d0979638bc | ||
|
|
38640bffd6 | ||
|
|
464d557c80 | ||
|
|
1d02191178 | ||
|
|
51933168eb | ||
|
|
d0542ba9fe | ||
|
|
a2f27bd62d | ||
|
|
17767fab3a | ||
|
|
ce1f66b4e5 | ||
|
|
e864031bf4 | ||
|
|
76f678bf82 | ||
|
|
b5a2454d2c | ||
|
|
36c166cdc9 | ||
|
|
122158d713 | ||
|
|
a1e587ef09 | ||
|
|
a4228efc66 | ||
|
|
62b9548167 |
@@ -7,6 +7,12 @@ set(OPM_MACROS_ROOT ${PROJECT_SOURCE_DIR})
|
||||
|
||||
option(ENABLE_ECL_INPUT "Enable eclipse input support?" ON)
|
||||
option(ENABLE_ECL_OUTPUT "Enable eclipse output support?" ON)
|
||||
option(ENABLE_MOCKSIM "Build the mock simulator for io testing" ON)
|
||||
option(ENABLE_WELL_TEST "Enable testing of well code when building Schedule object" OFF)
|
||||
|
||||
if (ENABLE_WELL_TEST)
|
||||
add_definitions(-DWELL_TEST)
|
||||
endif()
|
||||
|
||||
# Output implies input
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
@@ -18,24 +24,31 @@ if(NOT ENABLE_ECL_INPUT)
|
||||
set(ENABLE_ECL_OUTPUT OFF)
|
||||
endif()
|
||||
|
||||
|
||||
# not the same location as most of the other projects; this hook overrides
|
||||
macro (dir_hook)
|
||||
endmacro (dir_hook)
|
||||
|
||||
# We need to define this variable in the installed cmake config file.
|
||||
set(OPM_PROJECT_EXTRA_CODE_INSTALLED "set(OPM_MACROS_ROOT ${CMAKE_INSTALL_PREFIX}/share/opm)
|
||||
list(APPEND CMAKE_MODULE_PATH \${OPM_MACROS_ROOT}/cmake/Modules)")
|
||||
set(OPM_PROJECT_EXTRA_CODE_INSTALLED "#ENABLE_ECL_INPUT is needed by opm-common-prereq.cmake
|
||||
set(ENABLE_ECL_INPUT ${ENABLE_ECL_INPUT})
|
||||
set(OPM_MACROS_ROOT ${CMAKE_INSTALL_PREFIX}/share/opm)
|
||||
list(APPEND CMAKE_MODULE_PATH \${OPM_MACROS_ROOT}/cmake/Modules)
|
||||
include(OpmPackage) #Make macros availabe after find_package(opm-common)")
|
||||
|
||||
set(OPM_PROJECT_EXTRA_CODE_INTREE "set(OPM_MACROS_ROOT ${OPM_MACROS_ROOT})
|
||||
list(APPEND CMAKE_MODULE_PATH \${OPM_MACROS_ROOT}/cmake/Modules)")
|
||||
set(OPM_PROJECT_EXTRA_CODE_INTREE "#ENABLE_ECL_INPUT is needed by opm-common-prereq.cmake
|
||||
set(ENABLE_ECL_INPUT ${ENABLE_ECL_INPUT})
|
||||
set(OPM_MACROS_ROOT ${OPM_MACROS_ROOT})
|
||||
list(APPEND CMAKE_MODULE_PATH \${OPM_MACROS_ROOT}/cmake/Modules)
|
||||
include(OpmPackage) #Make macros availabe after find_package(opm-common)")
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
set(OPM_PROJECT_EXTRA_CODE_INSTALLED "${OPM_PROJECT_EXTRA_CODE_INSTALLED}
|
||||
set(COMPARE_SUMMARY_COMMAND ${CMAKE_INSTALL_PREFIX}/bin${${name}_VER_DIR}/compareSummary)
|
||||
set(COMPARE_ECL_COMMAND ${CMAKE_INSTALL_PREFIX}/bin${${name}_VER_DIR}/compareECL)")
|
||||
set(COMPARE_ECL_COMMAND ${CMAKE_INSTALL_PREFIX}/bin${${name}_VER_DIR}/compareECL)
|
||||
set(OPM_PACK_COMMAND ${CMAKE_INSTALL_PREFIX}/bin${${name}_VER_DIR}/opmpack)")
|
||||
|
||||
set(OPM_PROJECT_EXTRA_CODE_INTREE "${OPM_PROJECT_EXTRA_CODE_INTREE}
|
||||
set(COMPARE_SUMMARY_COMMAND ${PROJECT_BINARY_DIR}/bin/compareSummary)
|
||||
set(COMPARE_ECL_COMMAND ${PROJECT_BINARY_DIR}/bin/compareECL)")
|
||||
set(COMPARE_ECL_COMMAND ${PROJECT_BINARY_DIR}/bin/compareECL)
|
||||
set(OPM_PACK_COMMAND ${PROJECT_BINARY_DIR}/bin/opmpack)")
|
||||
endif()
|
||||
|
||||
# project information is in dune.module. Read this file and set variables.
|
||||
@@ -124,5 +137,49 @@ endmacro (install_hook)
|
||||
# all setup common to the OPM library modules is done here
|
||||
include (OpmLibMain)
|
||||
|
||||
if (ENABLE_MOCKSIM)
|
||||
add_library(mocksim
|
||||
msim/src/msim.cpp)
|
||||
target_link_libraries(mocksim opmcommon)
|
||||
target_include_directories(mocksim PUBLIC msim/include)
|
||||
add_executable(msim examples/msim.cpp)
|
||||
target_link_libraries(msim mocksim)
|
||||
|
||||
set(_libs mocksim opmcommon
|
||||
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
|
||||
|
||||
foreach( test test_msim test_msim_ACTIONX )
|
||||
opm_add_test(${test} SOURCES tests/msim/${test}
|
||||
LIBRARIES ${_libs}
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/tests)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# Build the compare utilities
|
||||
if(ENABLE_ECL_INPUT)
|
||||
add_library(testutil STATIC
|
||||
examples/test_util/EclFilesComparator.cpp
|
||||
examples/test_util/EclIntegrationTest.cpp
|
||||
examples/test_util/EclRegressionTest.cpp
|
||||
examples/test_util/summaryComparator.cpp
|
||||
examples/test_util/summaryIntegrationTest.cpp
|
||||
examples/test_util/summaryRegressionTest.cpp)
|
||||
target_link_libraries(testutil ecl)
|
||||
add_executable(compareECL examples/test_util/compareECL.cpp)
|
||||
target_link_libraries(compareECL testutil opmcommon)
|
||||
|
||||
# Add the tests
|
||||
set(_libs testutil opmcommon
|
||||
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
|
||||
foreach(test test_compareSummary test_EclFilesComparator)
|
||||
opm_add_test(${test} CONDITION ENABLE_ECL_INPUT
|
||||
LIBRARIES ${_libs})
|
||||
endforeach()
|
||||
install(TARGETS compareECL DESTINATION bin)
|
||||
endif()
|
||||
|
||||
# Install build system files
|
||||
install(DIRECTORY cmake DESTINATION share/opm)
|
||||
|
||||
# Install tab completion skeleton
|
||||
install(FILES etc/opm_bash_completion.sh.in DESTINATION share/opm/etc)
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
# the library needs it.
|
||||
|
||||
list (APPEND MAIN_SOURCE_FILES
|
||||
examples/test_util/EclFile.cpp
|
||||
src/opm/common/data/SimulationDataContainer.cpp
|
||||
src/opm/common/OpmLog/CounterLog.cpp
|
||||
src/opm/common/OpmLog/EclipsePRTLog.cpp
|
||||
@@ -46,12 +47,14 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/parser/eclipse/Deck/DeckOutput.cpp
|
||||
src/opm/parser/eclipse/Deck/Section.cpp
|
||||
src/opm/parser/eclipse/EclipseState/AquiferCT.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Aquifetp.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Aquancon.cpp
|
||||
src/opm/parser/eclipse/EclipseState/checkDeck.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Eclipse3DProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/EclipseConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/EclipseState.cpp
|
||||
src/opm/parser/eclipse/EclipseState/EndpointScaling.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Edit/EDITNNC.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/Box.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/BoxManager.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/EclipseGrid.cpp
|
||||
@@ -73,26 +76,42 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/parser/eclipse/EclipseState/IOConfig/IOConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Runspec.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Completion.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/CompletionSet.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionAST.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionContext.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/Actions.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionParser.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionValue.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/ASTNode.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Events.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Group.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/GroupTree.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/injection.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MessageLimits.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/Compsegs.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/SegmentSet.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/updatingCompletionsWithSegments.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/WellSegments.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/updatingConnectionsWithSegments.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/OilVaporizationProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/RFTConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/SummaryState.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/TimeMap.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Tuning.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellEconProductionLimits.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellInjectionProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellPolymerProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/Connection.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/Well.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WList.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WListManager.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellEconProductionLimits.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellInjectionProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellPolymerProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellTracerProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellTestConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellTestState.cpp
|
||||
src/opm/parser/eclipse/EclipseState/SimulationConfig/SimulationConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/SimulationConfig/ThresholdPressure.cpp
|
||||
src/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp
|
||||
@@ -100,17 +119,30 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/parser/eclipse/EclipseState/Tables/JFunc.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/PvtxTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/SimpleTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/PolyInjTables.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/TableColumn.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/TableContainer.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/TableIndex.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/TableManager.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/TableSchema.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/Tables.cpp
|
||||
src/opm/parser/eclipse/EclipseState/UDQConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQExpression.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/Rock2dTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/Rock2dtrTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQASTNode.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParser.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQWellSet.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQAssign.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQContext.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunction.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunctionTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.cpp
|
||||
src/opm/parser/eclipse/Parser/ErrorGuard.cpp
|
||||
src/opm/parser/eclipse/Parser/ParseContext.cpp
|
||||
src/opm/parser/eclipse/Parser/Parser.cpp
|
||||
src/opm/parser/eclipse/Parser/ParserEnums.cpp
|
||||
@@ -132,22 +164,33 @@ if(ENABLE_ECL_INPUT)
|
||||
endif()
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
list( APPEND MAIN_SOURCE_FILES
|
||||
src/opm/test_util/summaryIntegrationTest.cpp
|
||||
src/opm/test_util/summaryRegressionTest.cpp
|
||||
src/opm/test_util/summaryComparator.cpp
|
||||
src/opm/test_util/EclFilesComparator.cpp
|
||||
src/opm/output/eclipse/AggregateConnectionData.cpp
|
||||
src/opm/output/eclipse/AggregateGroupData.cpp
|
||||
src/opm/output/eclipse/AggregateMSWData.cpp
|
||||
src/opm/output/eclipse/AggregateWellData.cpp
|
||||
src/opm/output/eclipse/CreateDoubHead.cpp
|
||||
src/opm/output/eclipse/CreateInteHead.cpp
|
||||
src/opm/output/eclipse/CreateLogiHead.cpp
|
||||
src/opm/output/eclipse/WellDataSerializers.cpp
|
||||
src/opm/output/eclipse/DoubHEAD.cpp
|
||||
src/opm/output/eclipse/EclipseGridInspector.cpp
|
||||
src/opm/output/eclipse/EclipseIO.cpp
|
||||
src/opm/output/eclipse/InteHEAD.cpp
|
||||
src/opm/output/eclipse/libECLRestart.cpp
|
||||
src/opm/output/eclipse/LinearisedOutputTable.cpp
|
||||
src/opm/output/eclipse/LoadRestart.cpp
|
||||
src/opm/output/eclipse/LogiHEAD.cpp
|
||||
src/opm/output/eclipse/RestartIO.cpp
|
||||
src/opm/output/eclipse/Summary.cpp
|
||||
src/opm/output/eclipse/Tables.cpp
|
||||
src/opm/output/eclipse/RegionCache.cpp
|
||||
src/opm/output/eclipse/RestartValue.cpp
|
||||
src/opm/output/data/Solution.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
list (APPEND TEST_SOURCE_FILES
|
||||
tests/test_EclFile.cpp
|
||||
tests/test_calculateCellVol.cpp
|
||||
tests/test_cmp.cpp
|
||||
tests/test_cubic.cpp
|
||||
@@ -161,13 +204,15 @@ list (APPEND TEST_SOURCE_FILES
|
||||
)
|
||||
if(ENABLE_ECL_INPUT)
|
||||
list(APPEND TEST_SOURCE_FILES
|
||||
tests/parser/ACTIONX.cpp
|
||||
tests/parser/ADDREGTests.cpp
|
||||
tests/parser/AquiferCTTests.cpp
|
||||
tests/parser/AquifetpTests.cpp
|
||||
tests/parser/AqudimsTests.cpp
|
||||
tests/parser/AquanconTests.cpp
|
||||
tests/parser/BoxTests.cpp
|
||||
tests/parser/ColumnSchemaTests.cpp
|
||||
tests/parser/CompletionTests.cpp
|
||||
tests/parser/ConnectionTests.cpp
|
||||
tests/parser/COMPSEGUnits.cpp
|
||||
tests/parser/CopyRegTests.cpp
|
||||
tests/parser/DeckTests.cpp
|
||||
@@ -191,9 +236,11 @@ if(ENABLE_ECL_INPUT)
|
||||
tests/parser/MULTREGTScannerTests.cpp
|
||||
tests/parser/OrderedMapTests.cpp
|
||||
tests/parser/ParseContextTests.cpp
|
||||
tests/parser/ParseContext_EXIT1.cpp
|
||||
tests/parser/PORVTests.cpp
|
||||
tests/parser/RawKeywordTests.cpp
|
||||
tests/parser/RestartConfigTests.cpp
|
||||
tests/parser/RockTableTests.cpp
|
||||
tests/parser/RunspecTests.cpp
|
||||
tests/parser/SatfuncPropertyInitializersTests.cpp
|
||||
tests/parser/ScheduleTests.cpp
|
||||
@@ -216,22 +263,35 @@ if(ENABLE_ECL_INPUT)
|
||||
tests/parser/UnitTests.cpp
|
||||
tests/parser/ValueTests.cpp
|
||||
tests/parser/WellSolventTests.cpp
|
||||
tests/parser/WellTests.cpp)
|
||||
tests/parser/WellTracerTests.cpp
|
||||
tests/parser/WellTests.cpp
|
||||
tests/parser/WLIST.cpp
|
||||
tests/parser/WTEST.cpp)
|
||||
endif()
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
list (APPEND TEST_SOURCE_FILES
|
||||
tests/test_compareSummary.cpp
|
||||
tests/test_EclFilesComparator.cpp
|
||||
tests/test_AggregateWellData.cpp
|
||||
tests/test_AggregateGroupData.cpp
|
||||
tests/test_AggregateMSWData.cpp
|
||||
tests/test_AggregateConnectionData.cpp
|
||||
tests/test_ArrayDimChecker.cpp
|
||||
tests/test_CharArrayNullTerm.cpp
|
||||
tests/test_EclipseIO.cpp
|
||||
tests/test_DoubHEAD.cpp
|
||||
tests/test_InteHEAD.cpp
|
||||
tests/test_LinearisedOutputTable.cpp
|
||||
tests/test_LogiHEAD.cpp
|
||||
tests/test_regionCache.cpp
|
||||
tests/test_Restart.cpp
|
||||
tests/test_RFT.cpp
|
||||
tests/test_Solution.cpp
|
||||
tests/test_Summary.cpp
|
||||
tests/test_Tables.cpp
|
||||
tests/test_Wells.cpp
|
||||
tests/test_WindowedArray.cpp
|
||||
tests/test_writenumwells.cpp
|
||||
tests/test_Solution.cpp
|
||||
tests/test_regionCache.cpp
|
||||
tests/test_serialize_ICON.cpp
|
||||
tests/test_serialize_SCON.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -240,7 +300,9 @@ list (APPEND TEST_DATA_FILES
|
||||
)
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
list (APPEND TEST_DATA_FILES
|
||||
tests/expect-wdims.err.out
|
||||
tests/FIRST_SIM.DATA
|
||||
tests/FIRST_SIM_THPRES.DATA
|
||||
tests/summary_deck.DATA
|
||||
tests/group_group.DATA
|
||||
tests/testblackoilstate3.DATA
|
||||
@@ -248,6 +310,10 @@ if(ENABLE_ECL_OUTPUT)
|
||||
tests/table_deck.DATA
|
||||
tests/summary_deck_non_constant_porosity.DATA
|
||||
tests/SUMMARY_EFF_FAC.DATA
|
||||
tests/SPE1CASE1.DATA
|
||||
tests/SPE1CASE1.SMSPEC
|
||||
tests/SPE9_CP_PACKED.DATA
|
||||
tests/SOFR_TEST.DATA
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -256,14 +322,10 @@ list (APPEND EXAMPLE_SOURCE_FILES
|
||||
if(ENABLE_ECL_INPUT)
|
||||
list (APPEND EXAMPLE_SOURCE_FILES
|
||||
examples/opmi.cpp
|
||||
examples/opmpack.cpp
|
||||
examples/opmhash.cpp
|
||||
)
|
||||
endif()
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
list(APPEND EXAMPLE_SOURCE_FILES
|
||||
examples/test_util/compareECL.cpp
|
||||
examples/test_util/compareSummary.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
# programs listed here will not only be compiled, but also marked for
|
||||
# installation
|
||||
@@ -272,16 +334,14 @@ list (APPEND PROGRAM_SOURCE_FILES
|
||||
if(ENABLE_ECL_INPUT)
|
||||
list (APPEND PROGRAM_SOURCE_FILES
|
||||
examples/opmi.cpp
|
||||
examples/opmpack.cpp
|
||||
examples/opmhash.cpp
|
||||
)
|
||||
endif()
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
list(APPEND PROGRAM_SOURCE_FILES
|
||||
examples/test_util/compareECL.cpp
|
||||
examples/test_util/compareSummary.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
list( APPEND PUBLIC_HEADER_FILES
|
||||
examples/test_util/EclFile.hpp
|
||||
examples/test_util/data/EclIOdata.hpp
|
||||
opm/common/ErrorMacros.hpp
|
||||
opm/common/Exceptions.hpp
|
||||
opm/common/data/SimulationDataContainer.hpp
|
||||
@@ -327,6 +387,7 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/Units/UnitSystem.hpp
|
||||
opm/parser/eclipse/Units/Units.hpp
|
||||
opm/parser/eclipse/Units/Dimension.hpp
|
||||
opm/parser/eclipse/Parser/ErrorGuard.hpp
|
||||
opm/parser/eclipse/Parser/ParserItem.hpp
|
||||
opm/parser/eclipse/Parser/Parser.hpp
|
||||
opm/parser/eclipse/Parser/ParserRecord.hpp
|
||||
@@ -340,6 +401,7 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/Util/Value.hpp
|
||||
opm/parser/eclipse/EclipseState/Util/OrderedMap.hpp
|
||||
opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Edit/EDITNNC.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/GridDims.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/TransMult.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp
|
||||
@@ -359,6 +421,7 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/EndpointScaling.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SimpleTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PolyInjTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PdvdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/TlpmixpaTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PvdgTable.hpp
|
||||
@@ -368,8 +431,11 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/Tables/Eqldims.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SpecrockTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PlydhflfTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PlymwinjTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PlyshlogTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/RsvdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SkprwatTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SkprpolyTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SpecheatTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SgcwmisTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/Sof2Table.hpp
|
||||
@@ -407,6 +473,10 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/Tables/SgwfnTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PvdsTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PvtoTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/Rock2dTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/Rock2dtrTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/RockwnodTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/OverburdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/ColumnSchema.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PmiscTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/RtempvdTable.hpp
|
||||
@@ -419,15 +489,31 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/EclipseConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Aquancon.hpp
|
||||
opm/parser/eclipse/EclipseState/AquiferCT.hpp
|
||||
opm/parser/eclipse/EclipseState/Aquifetp.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/ActionAST.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/ActionContext.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/Actions.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellInjectionProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellInjectionProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WList.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WListManager.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellEconProductionLimits.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellPolymerProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellTracerProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellTestConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellTestState.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/DynamicVector.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/RFTConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellEconProductionLimits.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellPolymerProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Tuning.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MessageLimits.hpp
|
||||
@@ -435,22 +521,27 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/OilVaporizationProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/GroupTree.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Completion.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/SegmentSet.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/updatingCompletionsWithSegments.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/CompletionSet.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/WellSegments.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/updatingConnectionsWithSegments.hpp
|
||||
opm/parser/eclipse/EclipseState/SimulationConfig/ThresholdPressure.hpp
|
||||
opm/parser/eclipse/EclipseState/SimulationConfig/SimulationConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/checkDeck.hpp
|
||||
opm/parser/eclipse/EclipseState/Runspec.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ.hpp
|
||||
opm/parser/eclipse/EclipseState/UDQConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQExpression.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQAssign.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQContext.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQWellSet.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunction.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunctionTable.hpp
|
||||
opm/parser/eclipse/Deck/DeckItem.hpp
|
||||
opm/parser/eclipse/Deck/Deck.hpp
|
||||
opm/parser/eclipse/Deck/Section.hpp
|
||||
@@ -465,23 +556,34 @@ if(ENABLE_ECL_INPUT)
|
||||
endif()
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
list(APPEND PUBLIC_HEADER_FILES
|
||||
opm/output/OutputWriter.hpp
|
||||
opm/output/data/Wells.hpp
|
||||
opm/output/data/Cells.hpp
|
||||
opm/test_util/summaryRegressionTest.hpp
|
||||
opm/test_util/summaryIntegrationTest.hpp
|
||||
opm/test_util/summaryComparator.hpp
|
||||
opm/output/data/Solution.hpp
|
||||
opm/output/data/Wells.hpp
|
||||
opm/output/eclipse/VectorItems/connection.hpp
|
||||
opm/output/eclipse/VectorItems/group.hpp
|
||||
opm/output/eclipse/VectorItems/intehead.hpp
|
||||
opm/output/eclipse/VectorItems/msw.hpp
|
||||
opm/output/eclipse/VectorItems/well.hpp
|
||||
opm/output/eclipse/AggregateGroupData.hpp
|
||||
opm/output/eclipse/AggregateConnectionData.hpp
|
||||
opm/output/eclipse/AggregateMSWData.hpp
|
||||
opm/output/eclipse/AggregateWellData.hpp
|
||||
opm/output/eclipse/CharArrayNullTerm.hpp
|
||||
opm/output/eclipse/DoubHEAD.hpp
|
||||
opm/output/eclipse/EclipseGridInspector.hpp
|
||||
opm/output/eclipse/EclipseIOUtil.hpp
|
||||
opm/output/eclipse/EclipseIO.hpp
|
||||
opm/output/eclipse/EclipseIOUtil.hpp
|
||||
opm/output/eclipse/InteHEAD.hpp
|
||||
opm/output/eclipse/libECLRestart.hpp
|
||||
opm/output/eclipse/LinearisedOutputTable.hpp
|
||||
opm/output/eclipse/LogiHEAD.hpp
|
||||
opm/output/eclipse/RegionCache.hpp
|
||||
opm/output/eclipse/RestartIO.hpp
|
||||
opm/output/eclipse/RestartValue.hpp
|
||||
opm/output/eclipse/Summary.hpp
|
||||
opm/output/eclipse/Tables.hpp
|
||||
opm/output/eclipse/RegionCache.hpp
|
||||
opm/output/data/Solution.hpp
|
||||
opm/test_util/EclFilesComparator.hpp
|
||||
opm/test_util/summaryRegressionTest.hpp
|
||||
opm/test_util/summaryComparator.hpp)
|
||||
opm/output/eclipse/WindowedArray.hpp
|
||||
opm/output/eclipse/WriteRestartHelpers.hpp
|
||||
opm/output/OutputWriter.hpp
|
||||
)
|
||||
endif()
|
||||
|
||||
21
CopyHeaders.cmake
Normal file
21
CopyHeaders.cmake
Normal file
@@ -0,0 +1,21 @@
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${BASE_DIR}/tmp_gen/ParserKeywords.cpp
|
||||
${BASE_DIR}/ParserKeywords.cpp)
|
||||
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${BASE_DIR}/tmp_gen/inlinekw.cpp
|
||||
${BASE_DIR}/inlinekw.cpp)
|
||||
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${BASE_DIR}/tmp_gen/include/opm/parser/eclipse/Parser/ParserKeywords.hpp
|
||||
${BASE_DIR}/include/opm/parser/eclipse/Parser/ParserKeywords.hpp)
|
||||
|
||||
|
||||
file(GLOB HDRS ${BASE_DIR}/tmp_gen/include/opm/parser/eclipse/Parser/ParserKeywords/*.hpp)
|
||||
|
||||
foreach(HDR ${HDRS})
|
||||
file(RELATIVE_PATH hdr ${BASE_DIR}/tmp_gen/include/opm/parser/eclipse/Parser/ParserKeywords ${HDR})
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${HDR}
|
||||
${BASE_DIR}/include/opm/parser/eclipse/Parser/ParserKeywords/${hdr})
|
||||
endforeach()
|
||||
@@ -48,8 +48,8 @@ list(APPEND EXTRA_TESTS EclipseStateTests)
|
||||
|
||||
foreach (test BoxTest
|
||||
CheckDeckValidity
|
||||
CompletionsFromDeck
|
||||
EclipseGridCreateFromDeck
|
||||
EDITNNCTests
|
||||
IncludeTest
|
||||
IntegrationTests
|
||||
IOConfigIntegrationTest
|
||||
|
||||
@@ -7,6 +7,7 @@ set(genkw_SOURCES src/opm/json/JsonObject.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckOutput.cpp
|
||||
src/opm/parser/eclipse/Generator/KeywordGenerator.cpp
|
||||
src/opm/parser/eclipse/Generator/KeywordLoader.cpp
|
||||
src/opm/parser/eclipse/Parser/ErrorGuard.cpp
|
||||
src/opm/parser/eclipse/Parser/ParseContext.cpp
|
||||
src/opm/parser/eclipse/Parser/ParserEnums.cpp
|
||||
src/opm/parser/eclipse/Parser/ParserItem.cpp
|
||||
@@ -38,11 +39,17 @@ configure_file(src/opm/parser/eclipse/keyword_list.argv.in keyword_list.argv)
|
||||
|
||||
# Generate keyword source
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_BINARY_DIR}/ParserKeywords.cpp ${PROJECT_BINARY_DIR}/inlinekw.cpp
|
||||
OUTPUT ${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords.cpp ${PROJECT_BINARY_DIR}/tmp_gen/inlinekw.cpp
|
||||
COMMAND genkw keyword_list.argv
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords.cpp
|
||||
${PROJECT_BINARY_DIR}/include/
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/include/
|
||||
opm/parser/eclipse/Parser/ParserKeywords
|
||||
${PROJECT_BINARY_DIR}/inlinekw.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/inlinekw.cpp
|
||||
DEPENDS genkw ${keyword_files} src/opm/parser/eclipse/share/keywords/keyword_list.cmake
|
||||
)
|
||||
|
||||
# To avoid some rebuilds
|
||||
add_custom_command(OUTPUT ParserKeywords.cpp inlinekw.cpp
|
||||
DEPENDS ${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords.cpp
|
||||
COMMAND ${CMAKE_COMMAND} -DBASE_DIR=${PROJECT_BINARY_DIR}
|
||||
-P ${PROJECT_SOURCE_DIR}/CopyHeaders.cmake)
|
||||
|
||||
@@ -78,7 +78,17 @@ function (configure_vars obj syntax filename verb)
|
||||
# write a CMake statements that warns if the value has changed
|
||||
if ("${syntax}" STREQUAL "CMAKE")
|
||||
set (_db "\${") # to avoid parsing problems
|
||||
file (APPEND "${filename}" "if (DEFINED ${_var} AND NOT \"${_db}${_var}}\" STREQUAL \"${${_var}}\")\n")
|
||||
# special case: if we have a truth variable HAVE_ and this is
|
||||
# either just defined (as is), or set to 1 explicitly, then both
|
||||
# of these count as "true", so put in a check that also accepts
|
||||
# both of these values.
|
||||
if (("${_var}" MATCHES "^HAVE_.*") AND
|
||||
(("${${_var}}" STREQUAL "") OR ("${${_var}}" STREQUAL "1")))
|
||||
set (_cond "(\"${_db}${_var}}\" STREQUAL \"\") OR (\"${_db}${_var}}\" STREQUAL \"1\")")
|
||||
else ()
|
||||
set (_cond "\"${_db}${_var}}\" STREQUAL \"${${_var}}\"")
|
||||
endif ()
|
||||
file (APPEND "${filename}" "if (DEFINED ${_var} AND NOT (${_cond}))\n")
|
||||
file (APPEND "${filename}" "\tmessage (WARNING \"Incompatible value \\\"${_db}${_var}}\\\" of variable \\\"${_var}\\\"\")\n")
|
||||
file (APPEND "${filename}" "endif ()\n")
|
||||
endif ()
|
||||
|
||||
46
cmake/Modules/FindAlberta.cmake
Normal file
46
cmake/Modules/FindAlberta.cmake
Normal file
@@ -0,0 +1,46 @@
|
||||
find_library(ALBERTA_LTDL_LIB
|
||||
NAMES ltdl
|
||||
PATH_SUFFIXES lib lib32 lib64
|
||||
)
|
||||
find_path(ALBERTA_INCLUDE_DIR
|
||||
NAMES alberta/alberta.h
|
||||
PATHS ${ALBERTA_ROOT}
|
||||
PATH_SUFFIXES alberta include NO_DEFAULT_PATH
|
||||
DOC "Include path of Alberta")
|
||||
find_path(ALBERTA_INCLUDE_DIR
|
||||
NAMES
|
||||
alberta/alberta.h
|
||||
PATHS /usr/local /opt
|
||||
PATH_SUFFIXES alberta)
|
||||
#look for libraries
|
||||
find_library(ALBERTA_UTIL_LIB
|
||||
NAMES alberta_util alberta_utilities
|
||||
PATHS ${ALBERTA_ROOT}
|
||||
PATH_SUFFIXES lib lib32 lib64
|
||||
NO_DEFAULT_PATH)
|
||||
find_library(ALBERTA_UTIL_LIB
|
||||
NAMES alberta_util alberta_utilities
|
||||
PATH_SUFFIXES lib lib32 lib64)
|
||||
|
||||
foreach(dim RANGE 1 9)
|
||||
find_library(ALBERTA_${dim}D_LIB alberta_${dim}d
|
||||
PATHS ${ALBERTA_ROOT}
|
||||
PATH_SUFFIXES lib lib32 lib64
|
||||
Cache FILEPATH DOC "Alberta lib for ${dim}D" NO_DEFAULT_PATH)
|
||||
find_library(ALBERTA_${dim}D_LIB alberta_${dim}d PATH_SUFFIXES lib lib32 lib64)
|
||||
if(ALBERTA_${dim}D_LIB)
|
||||
set(ALBERTA_LIBRARIES ${ALBERTA_LIBRARIES} ${ALBERTA_${dim}D_LIB})
|
||||
endif()
|
||||
endforeach(dim RANGE 1 9)
|
||||
|
||||
if(ALBERTA_LIBRARIES AND ALBERTA_INCLUDE_DIR)
|
||||
set(ALBERTA_INCLUDE_DIRS ${ALBERTA_INCLUDE_DIR})
|
||||
set(ALBERTA_LIBRARIES ${ALBERTA_LIBRARIES} ${ALBERTA_UTIL_LIB} ${ALBERTA_LTDL_LIB})
|
||||
set(ALBERTA_FOUND ON)
|
||||
set(Alberta_FOUND ON)
|
||||
set(HAVE_ALBERTA 1)
|
||||
set(DUNE_ALBERTA_VERSION 0x300)
|
||||
else()
|
||||
set(ALBERTA_FOUND OFF)
|
||||
set(Alberta_FOUND OFF)
|
||||
endif()
|
||||
@@ -27,7 +27,8 @@ find_opm_package (
|
||||
dune-geometry REQUIRED;
|
||||
dune-uggrid;
|
||||
MPI;
|
||||
UG
|
||||
UG;
|
||||
Alberta
|
||||
"
|
||||
# header to search for
|
||||
"dune/grid/onedgrid.hh"
|
||||
@@ -55,7 +56,8 @@ int main (void) {
|
||||
HAVE_AMIRAMESH;
|
||||
HAVE_ALBERTA;
|
||||
HAVE_STDINT_H;
|
||||
DUNE_GRID_EXPERIMENTAL_GRID_EXTENSIONS
|
||||
DUNE_GRID_EXPERIMENTAL_GRID_EXTENSIONS;
|
||||
DUNE_ALBERTA_VERSION
|
||||
")
|
||||
|
||||
#debug_find_vars ("dune-grid")
|
||||
|
||||
@@ -52,6 +52,7 @@ int main (void) {
|
||||
HAVE_PARMETIS;
|
||||
HAVE_SUPERLU;
|
||||
HAVE_UMFPACK;
|
||||
HAVE_SUITESPARSE_UMFPACK;
|
||||
SUPERLU_INT_TYPE;
|
||||
HAVE_SLU_CDEFS_H;
|
||||
HAVE_SLU_DDEFS_H;
|
||||
|
||||
@@ -123,7 +123,7 @@ function (configure_la name target)
|
||||
mark_as_advanced (libtool_MAIN)
|
||||
# notify the user if it not found after we explicitly searched
|
||||
if (NOT libtool_MAIN)
|
||||
message (STATUS "Libtool not found!")
|
||||
message (STATUS "Not generating libtool archive (.la) since libtool was not found")
|
||||
endif (NOT libtool_MAIN)
|
||||
endif (NOT libtool_MAIN)
|
||||
if (libtool_MAIN)
|
||||
|
||||
6
cmake/Modules/OpmBashCompletion.cmake
Normal file
6
cmake/Modules/OpmBashCompletion.cmake
Normal file
@@ -0,0 +1,6 @@
|
||||
# Installs bash tab completion for a product
|
||||
macro(opm_add_bash_completion binary)
|
||||
set(PRODUCT ${binary})
|
||||
configure_file(${OPM_MACROS_ROOT}/etc/opm_bash_completion.sh.in ${binary}_bash_completion.sh @ONLY)
|
||||
install(FILES ${PROJECT_BINARY_DIR}/${binary}_bash_completion.sh DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/bash_completion.d)
|
||||
endmacro()
|
||||
@@ -47,7 +47,7 @@ macro (opm_defaults opm)
|
||||
endif(NOT PRECOMPILE_HEADERS)
|
||||
|
||||
# Use of OpenMP is considered experimental
|
||||
set (USE_OPENMP_DEFAULT OFF)
|
||||
set (USE_OPENMP_DEFAULT ON)
|
||||
|
||||
# if we are on a system where CMake 2.6 is the default (Hi RHEL 6!),
|
||||
# the configuration files for Boost will trip up the library paths
|
||||
|
||||
@@ -139,6 +139,12 @@ macro (find_and_append_package_to prefix name)
|
||||
set (${name}_FOUND FALSE)
|
||||
set (${NAME}_FOUND FALSE)
|
||||
else ()
|
||||
# List of components might differ for every module. Therefore we will
|
||||
# need to research for a library multiple times. _search_components
|
||||
# will hold the index of the string COMPONENTS in the list
|
||||
set(_ARGN_LIST ${ARGN}) # Create a real list to use with list commands
|
||||
list(FIND _ARGN_LIST "COMPONENTS" _search_components)
|
||||
|
||||
# using config mode is better than using module (aka. find) mode
|
||||
# because then the package has already done all its probes and
|
||||
# stored them in the config file for us
|
||||
@@ -147,8 +153,8 @@ macro (find_and_append_package_to prefix name)
|
||||
# We even need to repeat the search for opm-common once as this is done
|
||||
# in the top most CMakeLists.txt without querying defines, setting dependencies
|
||||
# and the likes which is only done via opm_find_package
|
||||
if (NOT DEFINED ${name}_FOUND AND NOT DEFINED ${NAME}_FOUND
|
||||
OR ("${name}" STREQUAL "opm-common" AND NOT _opm_common_deps_processed))
|
||||
if ( (NOT DEFINED ${name}_FOUND AND NOT DEFINED ${NAME}_FOUND )
|
||||
OR _search_components GREATER -1)
|
||||
string(REGEX MATCH "(dune|opm)-.*" _is_opm ${name})
|
||||
if(NOT _is_opm)
|
||||
string(REGEX MATCH "ewoms" _is_opm ${name})
|
||||
@@ -164,11 +170,8 @@ macro (find_and_append_package_to prefix name)
|
||||
find_package (${name} ${ARGN_NO_REQUIRED} NO_CMAKE_SYSTEM_PACKAGE_REGISTRY NO_CMAKE_PACKAGE_REGISTRY)
|
||||
if(TARGET ecl)
|
||||
# Need to grab from target to enable transitional depends
|
||||
get_target_property(ecl_INCLUDE_DIRS ecl INTERFACE_INCLUDE_DIRECTORIES)
|
||||
get_target_property(ecl_LIBRARIES ecl INTERFACE_LINK_LIBRARIES)
|
||||
get_target_property(ecl_lib ecl LOCATION)
|
||||
set(ecl_LIBRARIES ecl ${ecl_lib} ${ecl_LIBRARIES})
|
||||
set(ecl_FOUND 1)
|
||||
#get_target_property(ecl_INCLUDE_DIRS ecl INTERFACE_INCLUDE_DIRECTORIES)
|
||||
set(ecl_LIBRARIES ecl)
|
||||
set(HAVE_ERT 1)
|
||||
endif()
|
||||
elseif(_${name}_exempted LESS 0 AND NOT _is_opm)
|
||||
@@ -197,10 +200,6 @@ macro (find_and_append_package_to prefix name)
|
||||
if (NOT DEFINED ${NAME}_FOUND)
|
||||
set (${NAME}_FOUND "${${name}_FOUND}")
|
||||
endif ()
|
||||
|
||||
if("${name}" STREQUAL "opm-common")
|
||||
set(_opm_common_deps_processed ON)
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
# the variable "NAME" may be replaced during find_package (as this is
|
||||
|
||||
@@ -59,11 +59,7 @@ macro (find_opm_package module deps header lib defs prog conf)
|
||||
# top most CMakeLists.txt but we still need to search for its
|
||||
# dependencies
|
||||
if (${MODULE}_FOUND OR ${module}_FOUND)
|
||||
if (${module} STREQUAL "opm-common" AND NOT _opm_common_deps_processed)
|
||||
set(_opm_common_deps_processed ON)
|
||||
else()
|
||||
return ()
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
# variables to pass on to other packages
|
||||
@@ -84,31 +80,11 @@ macro (find_opm_package module deps header lib defs prog conf)
|
||||
# ${module}_CONFIG_VARS for dune modules.
|
||||
find_package(${module} ${_${module}_quiet} ${_${module}_required} CONFIG)
|
||||
|
||||
|
||||
# period because it should be something that evaluates to true
|
||||
# in find_package_handle_standard_args
|
||||
set (${module}_ALL_PREREQS ".")
|
||||
foreach (_dep IN ITEMS ${deps})
|
||||
separate_arguments (_${module}_args UNIX_COMMAND ${_dep})
|
||||
if (_${module}_args)
|
||||
# keep REQUIRED in the arguments only if we were required ourself
|
||||
# "required-ness" is not transitive as far as CMake is concerned
|
||||
# (i.e. if an optional package requests a package to be required,
|
||||
# the build will fail if it's not found)
|
||||
string (REPLACE "REQUIRED" "${_${module}_required}" _args_req "${_${module}_args}")
|
||||
find_and_append_package_to (${module} ${_args_req} ${_${module}_quiet})
|
||||
list (GET _${module}_args 0 _name_only)
|
||||
string (TOUPPER "${_name_only}" _NAME_ONLY)
|
||||
string (REPLACE "-" "_" _NAME_ONLY "${_NAME_ONLY}")
|
||||
# check manually if it was found if REQUIRED; otherwise poison the
|
||||
# dependency list which is checked later (so that it will fail)
|
||||
if (("${_${module}_args}" MATCHES "REQUIRED") AND NOT (${_name_only}_FOUND OR ${_NAME_ONLY}_FOUND))
|
||||
list (APPEND ${module}_ALL_PREREQS "${_name_only}-NOTFOUND")
|
||||
endif ()
|
||||
else ()
|
||||
message (WARNING "Empty dependency in find module for ${module} (check for trailing semi-colon)")
|
||||
endif ()
|
||||
endforeach (_dep)
|
||||
if(NOT ${module}_DEPS)
|
||||
# set the dependencies used in find_package_deps
|
||||
set(${module}_DEPS "${deps}")
|
||||
endif()
|
||||
find_package_deps(${module})
|
||||
|
||||
# since find_and_append_package_to is a macro, this variable have
|
||||
# probably been overwritten (due to its common name); it is now
|
||||
@@ -181,6 +157,11 @@ macro (find_package_deps module)
|
||||
foreach (_dep IN ITEMS ${${module}_DEPS})
|
||||
separate_arguments (_${module}_args UNIX_COMMAND "${_dep}")
|
||||
if (_${module}_args)
|
||||
# keep REQUIRED in the arguments only if we were required ourself
|
||||
# "required-ness" is not transitive as far as CMake is concerned
|
||||
# (i.e. if an optional package requests a package to be required,
|
||||
# the build will fail if it's not found)
|
||||
string (REPLACE "REQUIRED" "${_${module}_required}" _args_req "${_${module}_args}")
|
||||
if(_dep MATCHES "opm-" OR _dep MATCHES "ewoms")
|
||||
set(deplist ${_dep})
|
||||
string(STRIP "${_dep}" _dep)
|
||||
|
||||
@@ -76,6 +76,7 @@ function (opm_cmake_config name)
|
||||
set (template_dir "${OPM_MACROS_ROOT}/cmake/Templates")
|
||||
|
||||
# write configuration file to locate library
|
||||
set(DUNE_PREFIX ${PROJECT_SOURCE_DIR})
|
||||
set(OPM_PROJECT_EXTRA_CODE ${OPM_PROJECT_EXTRA_CODE_INTREE})
|
||||
set(PREREQ_LOCATION "${PROJECT_SOURCE_DIR}")
|
||||
configure_cmake_file (${name} "config" "")
|
||||
@@ -123,6 +124,7 @@ function (opm_cmake_config name)
|
||||
# of the build directory (using the same input template)
|
||||
set(OPM_PROJECT_EXTRA_CODE ${OPM_PROJECT_EXTRA_CODE_INSTALLED})
|
||||
set(PREREQ_LOCATION "${CMAKE_INSTALL_PREFIX}/share/opm/cmake/Modules")
|
||||
set(DUNE_PREFIX ${CMAKE_INSTALL_PREFIX})
|
||||
configure_cmake_file (${name} "install" "")
|
||||
configure_vars (
|
||||
FILE CMAKE "${PROJECT_BINARY_DIR}/${${name}_NAME}-install.cmake"
|
||||
|
||||
@@ -65,7 +65,7 @@ macro (opm_compile_satellites opm satellite excl_all test_regexp)
|
||||
set_target_properties (${_sat_NAME} PROPERTIES
|
||||
LINK_FLAGS "${${opm}_LINKER_FLAGS_STR}"
|
||||
)
|
||||
if(HAVE_DYNAMIC_BOOST_TEST AND NOT (${opm} STREQUAL "opm-parser" AND NOT BUILD_SHARED_LIBS))
|
||||
if(HAVE_DYNAMIC_BOOST_TEST)
|
||||
set_target_properties (${_sat_NAME} PROPERTIES
|
||||
COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK
|
||||
)
|
||||
@@ -192,6 +192,7 @@ endmacro (opm_data satellite target dirname files)
|
||||
# Parameters:
|
||||
# TestName Name of test
|
||||
# ONLY_COMPILE Only build test but do not run it (optional)
|
||||
# DEFAULT_ENABLE_IF Only enable by default if a given condition is true (optional)
|
||||
# ALWAYS_ENABLE Force enabling test even if -DBUILD_TESTING=OFF was set (optional)
|
||||
# EXE_NAME Name of test executable (optional, default: ./bin/${TestName})
|
||||
# CONDITION Condition to enable test (optional, cmake code)
|
||||
@@ -218,7 +219,7 @@ macro(opm_add_test TestName)
|
||||
cmake_parse_arguments(CURTEST
|
||||
"NO_COMPILE;ONLY_COMPILE;ALWAYS_ENABLE" # flags
|
||||
"EXE_NAME;PROCESSORS;WORKING_DIRECTORY" # one value args
|
||||
"CONDITION;TEST_DEPENDS;DRIVER;DRIVER_ARGS;DEPENDS;TEST_ARGS;SOURCES;LIBRARIES" # multi-value args
|
||||
"CONDITION;DEFAULT_ENABLE_IF;TEST_DEPENDS;DRIVER;DRIVER_ARGS;DEPENDS;TEST_ARGS;SOURCES;LIBRARIES" # multi-value args
|
||||
${ARGN})
|
||||
|
||||
set(BUILD_TESTING "${BUILD_TESTING}")
|
||||
@@ -228,6 +229,13 @@ macro(opm_add_test TestName)
|
||||
set(CURTEST_EXE_NAME ${TestName})
|
||||
endif()
|
||||
|
||||
# Strip test_ prefix from name
|
||||
if ("${TestName}" MATCHES "^test_([^/]*)$")
|
||||
string (REGEX REPLACE "^test_([^/]*)$" "\\1" _FANCY "${TestName}")
|
||||
else()
|
||||
set(_FANCY ${TestName})
|
||||
endif()
|
||||
|
||||
# try to auto-detect the name of the source file if SOURCES are not
|
||||
# explicitly specified.
|
||||
if (NOT CURTEST_SOURCES)
|
||||
@@ -259,6 +267,11 @@ macro(opm_add_test TestName)
|
||||
# case. They can still be build using 'make test-suite' and they can
|
||||
# be build and run using 'make check'
|
||||
set(CURTEST_EXCLUDE_FROM_ALL "")
|
||||
if (NOT "AND OR ${CURTEST_DEFAULT_ENABLE_IF}" STREQUAL "AND OR ")
|
||||
if (NOT ${CURTEST_DEFAULT_ENABLE_IF})
|
||||
set(CURTEST_EXCLUDE_FROM_ALL "EXCLUDE_FROM_ALL")
|
||||
endif()
|
||||
endif()
|
||||
if (NOT BUILD_TESTING AND NOT CURTEST_ALWAYS_ENABLE)
|
||||
set(CURTEST_EXCLUDE_FROM_ALL "EXCLUDE_FROM_ALL")
|
||||
endif()
|
||||
@@ -309,6 +322,11 @@ macro(opm_add_test TestName)
|
||||
# run-only case occurs if the binary is already compiled by an
|
||||
# earlier test.)
|
||||
add_executable("${CURTEST_EXE_NAME}" ${CURTEST_EXCLUDE_FROM_ALL} ${CURTEST_SOURCES})
|
||||
if(HAVE_DYNAMIC_BOOST_TEST)
|
||||
set_target_properties (${CURTEST_EXE_NAME} PROPERTIES
|
||||
COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK
|
||||
)
|
||||
endif()
|
||||
target_link_libraries (${CURTEST_EXE_NAME} ${CURTEST_LIBRARIES})
|
||||
|
||||
if(CURTEST_DEPENDS)
|
||||
@@ -331,18 +349,18 @@ macro(opm_add_test TestName)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_test(NAME ${TestName}
|
||||
add_test(NAME ${_FANCY}
|
||||
WORKING_DIRECTORY "${CURTEST_WORKING_DIRECTORY}"
|
||||
COMMAND ${CURTEST_COMMAND})
|
||||
|
||||
# specify the dependencies between the tests
|
||||
if (CURTEST_TEST_DEPENDS)
|
||||
set_tests_properties(${TestName} PROPERTIES DEPENDS "${CURTEST_TEST_DEPENDS}")
|
||||
set_tests_properties(${_FANCY} PROPERTIES DEPENDS "${CURTEST_TEST_DEPENDS}")
|
||||
endif()
|
||||
|
||||
# tell ctest how many cores it should reserve to run the test
|
||||
if (CURTEST_PROCESSORS)
|
||||
set_tests_properties(${TestName} PROPERTIES PROCESSORS "${CURTEST_PROCESSORS}")
|
||||
set_tests_properties(${_FANCY} PROPERTIES PROCESSORS "${CURTEST_PROCESSORS}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -359,7 +377,7 @@ macro(opm_add_test TestName)
|
||||
# CDash dashboard. it this is removed, the test is just silently
|
||||
# ignored.
|
||||
if (NOT CURTEST_ONLY_COMPILE AND ADD_DISABLED_CTESTS)
|
||||
add_test(${TestName} skip_test_dummy)
|
||||
add_test(${_FANCY} skip_test_dummy)
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
@@ -21,10 +21,28 @@ if (CXX_COMPAT_GCC)
|
||||
# disabled due to widespread bugs in the linker plugin
|
||||
option (WHOLE_PROG_OPTIM "Whole program optimization (lto)" OFF)
|
||||
if (WHOLE_PROG_OPTIM)
|
||||
check_cxx_accepts_flag ("-flto" HAVE_LINK_OPTS)
|
||||
if (HAVE_LINK_OPTS)
|
||||
list (APPEND _opt_flags "-flto")
|
||||
endif (HAVE_LINK_OPTS)
|
||||
check_cxx_accepts_flag ("-flto" HAVE_LINK_OPTS)
|
||||
check_cxx_accepts_flag ("-fuse-linker-plugin" HAVE_LINK_PLUGIN)
|
||||
if (HAVE_LINK_OPTS)
|
||||
list (APPEND _opt_flags "-flto")
|
||||
endif (HAVE_LINK_OPTS)
|
||||
if (HAVE_LINK_PLUGIN)
|
||||
list (APPEND _opt_flags "-fuse-linker-plugin")
|
||||
endif (HAVE_LINK_PLUGIN)
|
||||
if(HAVE_LINK_OPTS AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
string(REPLACE "." ";" VERSION_LIST "${CMAKE_C_COMPILER_VERSION}")
|
||||
list(GET VERSION_LIST 0 VER_MAJOR)
|
||||
find_program(LTO_AR_COMMAND NAMES ${CMAKE_C_COMPILER}-ar gcc-ar-${VER_MAJOR} gcc-ar)
|
||||
find_program(LTO_RANLIB_COMMAND NAMES ${CMAKE_C_COMPILER}-ranlib gcc-ranlib-${VER_MAJOR} gcc-ranlib)
|
||||
if(LTO_AR_COMMAND)
|
||||
set(CMAKE_AR ${LTO_AR_COMMAND})
|
||||
message(STATUS "Using LTO-enabled ar: ${CMAKE_AR}")
|
||||
endif()
|
||||
if(LTO_RANLIB_COMMAND)
|
||||
set(CMAKE_RANLIB ${LTO_RANLIB_COMMAND})
|
||||
message(STATUS "Using LTO-enabled ranlib: ${CMAKE_RANLIB}")
|
||||
endif()
|
||||
endif()
|
||||
endif (WHOLE_PROG_OPTIM)
|
||||
|
||||
# native instruction set tuning
|
||||
|
||||
@@ -21,20 +21,42 @@
|
||||
|
||||
# Prevent multiple inclusions
|
||||
if(NOT @opm-project_NAME@_FOUND)
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" @PREREQ_LOCATION@)
|
||||
include(@opm-project_NAME@-prereqs)
|
||||
# propagate these properties from one build system to the other
|
||||
set (@opm-project_NAME@_PREFIX "@DUNE_PREFIX@")
|
||||
set (@opm-project_NAME@_VERSION "@opm-project_VERSION@")
|
||||
set (@opm-project_NAME@_DEFINITIONS "@opm-project_DEFINITIONS@")
|
||||
set (@opm-project_NAME@_INCLUDE_DIRS "@opm-project_INCLUDE_DIRS@")
|
||||
set (@opm-project_NAME@_LIBRARY_DIRS "@opm-project_LIBRARY_DIRS@" "@CMAKE_LIBRARY_OUTPUT_DIRECTORY@")
|
||||
set (@opm-project_NAME@_LINKER_FLAGS "@opm-project_LINKER_FLAGS@")
|
||||
set (@opm-project_NAME@_CONFIG_VARS "@opm-project_CONFIG_VARS@")
|
||||
set (HAVE_@opm-project_NAME_UC@ 1)
|
||||
|
||||
# libraries come from the build tree where this file was generated
|
||||
set (@opm-project_NAME@_LIBRARY "@opm-project_LIBRARY@")
|
||||
set (@opm-project_NAME@_LIBRARIES ${@opm-project_NAME@_LIBRARY} "@opm-project_LIBRARIES@")
|
||||
|
||||
# The purpose of this string replacement operation is to enable use of the
|
||||
# generated opm-project-config.cmake file also in the situation where 'make
|
||||
# install' has been invoked with the DESTDIR option:
|
||||
#
|
||||
# opm-common/build> cmake .. -DCMAKE_INSTALL_PREFIX=/real/prefix
|
||||
# opm-common/budil> make install DESTDIR=/tmp/prefix
|
||||
#
|
||||
# downstream/build> cmake .. -DDEST_PREFIX=/tmp/prefix -DCMAKE_PREFIX_PATH=/tmp/prefix
|
||||
# downstream/build> make install
|
||||
#
|
||||
# That way the downstream dependency can still use find_package( opm-common )
|
||||
# even though the opm-common-config.cmake file is not internally consistent
|
||||
# with it's own location in the filesystem.
|
||||
|
||||
if(DEST_PREFIX)
|
||||
set(DEST_PREFIX "${DEST_PREFIX}${@opm-project_NAME@_PREFIX}")
|
||||
string(REPLACE ${@opm-project_NAME@_PREFIX} ${DEST_PREFIX} @opm-project_NAME@_INCLUDE_DIRS "${@opm-project_NAME@_INCLUDE_DIRS}")
|
||||
string(REPLACE ${@opm-project_NAME@_PREFIX} ${DEST_PREFIX} @opm-project_NAME@_LIBRARY_DIRS "${@opm-project_NAME@_LIBRARY_DIRS}")
|
||||
string(REPLACE ${@opm-project_NAME@_PREFIX} ${DEST_PREFIX} @opm-project_NAME@_LIBRARY "${@opm-project_NAME@_LIBRARY}")
|
||||
endif()
|
||||
|
||||
|
||||
set (HAVE_@opm-project_NAME_UC@ 1)
|
||||
mark_as_advanced (@opm-project_NAME@_LIBRARY)
|
||||
|
||||
# not all projects have targets; conditionally add this part
|
||||
@@ -72,6 +94,17 @@ if(NOT @opm-project_NAME@_FOUND)
|
||||
|
||||
# this is the contents of config.h as far as our probes can tell:
|
||||
|
||||
# extra code
|
||||
@OPM_PROJECT_EXTRA_CODE@
|
||||
|
||||
# The settings in this block do not mix well with the DEST_PREFIX
|
||||
# setting.
|
||||
if (NOT DEST_PREFIX)
|
||||
# This is required to include OpmPackage
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" @PREREQ_LOCATION@)
|
||||
|
||||
# extra code from variable OPM_PROJECT_EXTRA_CODE
|
||||
@OPM_PROJECT_EXTRA_CODE@
|
||||
# end extra code
|
||||
|
||||
include(@opm-project_NAME@-prereqs)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
2
debian/changelog
vendored
2
debian/changelog
vendored
@@ -1,4 +1,4 @@
|
||||
opm-common (2018.04-rfinal-1~xenial) xenial; urgency=medium
|
||||
opm-common (2019.04-rc2-1~xenial) xenial; urgency=medium
|
||||
|
||||
* New release
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
Module: opm-common
|
||||
Description: Open Porous Media Initiative shared infrastructure
|
||||
Version: 2018.04
|
||||
Label: 2018.04
|
||||
Version: 2019.04-rc2
|
||||
Label: 2019.04-rc2
|
||||
Maintainer: opm@opm-project.org
|
||||
MaintainerName: OPM community
|
||||
Url: http://opm-project.org
|
||||
|
||||
60
etc/opm_bash_completion.sh.in
Normal file
60
etc/opm_bash_completion.sh.in
Normal file
@@ -0,0 +1,60 @@
|
||||
# this snippet enables parameter completion via the tabulator key
|
||||
# for bash for opm products.
|
||||
|
||||
# this is a bash readline completer for the case where a binary is
|
||||
# already known to be an eWoms simulator.
|
||||
_ewoms_parameter_completor()
|
||||
{
|
||||
if test "$COMP_WORDS" == ""; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
cmd="${COMP_WORDS[0]}"
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
fullcmd="$(which "$cmd" 2> /dev/null)"
|
||||
ALL_OPTS=$("$fullcmd" --help 2> /dev/null | grep '^ *--' | sed 's/ *\(--[a-zA-Z0-9\-]*\)=.*/\1=/')
|
||||
ALL_OPTS=$(echo "$ALL_OPTS" | sed 's/^ *--help.*/--help/')
|
||||
COMPREPLY=( $(compgen -A file -W "$ALL_OPTS" -- "${cur}") )
|
||||
}
|
||||
|
||||
# this is a bash readline default completer which attempts to find out
|
||||
# if a given binary is an eWoms simulation. this needs to be set as a
|
||||
# default completer because the name of eWoms binaries cannot be known
|
||||
# a-priori.
|
||||
_ewoms_generic_parameter_completor()
|
||||
{
|
||||
if test "$COMP_WORDS" == ""; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
COMPREPLY=()
|
||||
local cmd cur ALL_OPTS
|
||||
cmd="${COMP_WORDS[0]}"
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
|
||||
fullcmd="$(which "$cmd" 2> /dev/null)"
|
||||
if test -z "$fullcmd" || \
|
||||
! test -x "$fullcmd" || \
|
||||
(! test -f "$fullcmd" && ! test -h "$fullcmd" ) || \
|
||||
! test -r "$fullcmd" || \
|
||||
! grep -q "Ewoms[a-zA-Z0-9]*Simulator[a-zA-Z0-0]" "$fullcmd"
|
||||
then
|
||||
if test -n "$DEFAULT_COMPLETION_LOADER"; then
|
||||
"$DEFAULT_COMPLETION_LOADER" $@
|
||||
elif type -t _completion_loader 2>&1 > /dev/null; then
|
||||
# the default DEFAULT_COMPLETION_LOADER variable has not
|
||||
# been set and the _completion_loader function exists, so
|
||||
# we use _completion_loader as the default completer.
|
||||
_completion_loader $@
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
||||
return $?
|
||||
fi
|
||||
|
||||
_ewoms_parameter_completor $@
|
||||
return 0
|
||||
}
|
||||
|
||||
complete -o nospace -F _ewoms_parameter_completor @PRODUCT@
|
||||
53
examples/msim.cpp
Normal file
53
examples/msim.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright 2013 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <opm/output/eclipse/EclipseIO.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
|
||||
|
||||
#include <opm/msim/msim.hpp>
|
||||
|
||||
|
||||
int main(int /* argc */, char** argv) {
|
||||
std::string deck_file = argv[1];
|
||||
Opm::Parser parser;
|
||||
Opm::ParseContext parse_context;
|
||||
Opm::ErrorGuard error_guard;
|
||||
|
||||
Opm::Deck deck = parser.parseFile(deck_file, parse_context, error_guard);
|
||||
Opm::EclipseState state(deck, parse_context, error_guard);
|
||||
Opm::Schedule schedule(deck, state.getInputGrid(), state.get3DProperties(), state.runspec(), parse_context, error_guard);
|
||||
Opm::SummaryConfig summary_config(deck, schedule, state.getTableManager(), parse_context, error_guard);
|
||||
|
||||
if (error_guard) {
|
||||
error_guard.dump();
|
||||
error_guard.terminate();
|
||||
}
|
||||
|
||||
Opm::msim msim(state);
|
||||
Opm::EclipseIO io(state, state.getInputGrid(), schedule, summary_config);
|
||||
msim.run(schedule, io);
|
||||
}
|
||||
|
||||
157
examples/opmhash.cpp
Normal file
157
examples/opmhash.cpp
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
Copyright 2019 Equinor ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
|
||||
|
||||
struct keyword {
|
||||
keyword(const std::string& name, const std::string& filename, std::size_t line_number, std::size_t content_hash) :
|
||||
name(name),
|
||||
filename(filename),
|
||||
line_number(line_number),
|
||||
content_hash(content_hash)
|
||||
{}
|
||||
|
||||
|
||||
std::string name;
|
||||
std::string filename;
|
||||
std::size_t line_number;
|
||||
std::size_t content_hash;
|
||||
};
|
||||
|
||||
|
||||
std::vector<keyword> load_deck(const char * deck_file) {
|
||||
Opm::ParseContext parseContext;
|
||||
Opm::ErrorGuard errors;
|
||||
Opm::Parser parser;
|
||||
std::vector<keyword> keywords;
|
||||
|
||||
/* Use the same default ParseContext as flow. */
|
||||
parseContext.update(Opm::ParseContext::PARSE_RANDOM_SLASH, Opm::InputError::IGNORE);
|
||||
parseContext.update(Opm::ParseContext::PARSE_MISSING_DIMS_KEYWORD, Opm::InputError::WARN);
|
||||
parseContext.update(Opm::ParseContext::SUMMARY_UNKNOWN_WELL, Opm::InputError::WARN);
|
||||
parseContext.update(Opm::ParseContext::SUMMARY_UNKNOWN_GROUP, Opm::InputError::WARN);
|
||||
|
||||
auto deck = parser.parseFile(deck_file, parseContext, errors);
|
||||
for (const auto& kw : deck) {
|
||||
std::stringstream ss;
|
||||
ss << kw;
|
||||
|
||||
keywords.emplace_back(kw.name(), kw.getFileName(), kw.getLineNumber(), std::hash<std::string>{}(ss.str()));
|
||||
}
|
||||
return keywords;
|
||||
}
|
||||
|
||||
|
||||
std::size_t deck_hash(const std::vector<keyword>& keywords) {
|
||||
std::stringstream ss;
|
||||
for (const auto& kw : keywords)
|
||||
ss << kw.content_hash;
|
||||
|
||||
return std::hash<std::string>{}(ss.str());
|
||||
}
|
||||
|
||||
|
||||
void print_keywords(const std::vector<keyword>& keywords, bool location_info) {
|
||||
for (const auto& kw : keywords) {
|
||||
if (location_info)
|
||||
std::cout << std::setw(8) << std::left << kw.name << " : " << kw.filename << ":" << kw.line_number << " " << kw.content_hash << std::endl;
|
||||
else
|
||||
std::cout << std::setw(8) << std::left << kw.name << " : " << kw.content_hash << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
std::cout << std::setw(8) << std::left << "Total" << " : " << deck_hash(keywords) << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void print_help_and_exit() {
|
||||
const char * help_text = R"(The purpose of the opmhash program is to load a deck and create a summary, by
|
||||
diffing two such summaries it is simple to determine if two decks are similar.
|
||||
For each keyword a hash of the normalized content is calculated. The output of
|
||||
the program will look like this:
|
||||
|
||||
RUNSPEC : 13167205945009276792
|
||||
TITLE : 16047371705964514902
|
||||
DIMENS : 1264233216877515756
|
||||
NONNC : 10052807539267647959
|
||||
OIL : 6013609912232720008
|
||||
WATER : 14106203893673265964
|
||||
|
||||
Total : 7362809723723482303
|
||||
|
||||
Where the 'random' integer following each keyword is the hash of the content of
|
||||
that keyword. The hashing is insensitive to changes in white-space and comments
|
||||
and file location. At the bottom comes a total hash of the complete content. The
|
||||
hash of each keyword is insensitive to shuffling of keywords, but the total hash
|
||||
depends on the keyword order.
|
||||
|
||||
Options:
|
||||
|
||||
-l : Add filename and linenumber information to each keyword.
|
||||
-s : Short form - only print the hash of the complete deck.
|
||||
|
||||
)";
|
||||
std::cerr << help_text << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int arg_offset = 1;
|
||||
bool location_info = false;
|
||||
bool short_form = false;
|
||||
|
||||
while (true) {
|
||||
int c;
|
||||
c = getopt(argc, argv, "ls");
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch(c) {
|
||||
case 'l':
|
||||
location_info = true;
|
||||
break;
|
||||
case 's':
|
||||
short_form = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
arg_offset = optind;
|
||||
if (arg_offset >= argc)
|
||||
print_help_and_exit();
|
||||
|
||||
auto keywords = load_deck(argv[arg_offset]);
|
||||
if (short_form)
|
||||
std::cout << deck_hash(keywords) << std::endl;
|
||||
else
|
||||
print_keywords(keywords, location_info);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
@@ -30,16 +31,16 @@
|
||||
|
||||
inline void loadDeck( const char * deck_file) {
|
||||
Opm::ParseContext parseContext;
|
||||
Opm::ErrorGuard errors;
|
||||
Opm::Parser parser;
|
||||
|
||||
std::cout << "Loading deck: " << deck_file << " ..... "; std::cout.flush();
|
||||
auto deck = parser.parseFile(deck_file, parseContext);
|
||||
auto deck = parser.parseFile(deck_file, parseContext, errors);
|
||||
std::cout << "parse complete - creating EclipseState .... "; std::cout.flush();
|
||||
Opm::EclipseState state( deck, parseContext );
|
||||
Opm::Schedule schedule( deck, state.getInputGrid(), state.get3DProperties(), state.runspec().phases(), parseContext);
|
||||
Opm::SummaryConfig summary( deck, schedule, state.getTableManager( ), parseContext );
|
||||
Opm::EclipseState state( deck, parseContext, errors );
|
||||
Opm::Schedule schedule( deck, state.getInputGrid(), state.get3DProperties(), state.runspec(), parseContext, errors);
|
||||
Opm::SummaryConfig summary( deck, schedule, state.getTableManager( ), parseContext, errors );
|
||||
std::cout << "complete." << std::endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
110
examples/opmpack.cpp
Normal file
110
examples/opmpack.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
Copyright 2018 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <getopt.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/parser/eclipse/Parser/InputErrorAction.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
|
||||
|
||||
inline void pack_deck( const char * deck_file, std::ostream& os) {
|
||||
Opm::ParseContext parseContext(Opm::InputError::WARN);
|
||||
Opm::ErrorGuard errors;
|
||||
Opm::Parser parser;
|
||||
|
||||
auto deck = parser.parseFile(deck_file, parseContext, errors);
|
||||
os << deck;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void print_help_and_exit() {
|
||||
const char * help_text = R"(
|
||||
The opmpack program will load a deck, resolve all include
|
||||
files and then print it out again on stdout. All comments
|
||||
will be stripped and the value types will be validated.
|
||||
|
||||
By passing the option -o you can redirect the output to a file
|
||||
or a directory.
|
||||
|
||||
Print on stdout:
|
||||
|
||||
opmpack /path/to/case/CASE.DATA
|
||||
|
||||
|
||||
Print MY_CASE.DATA in /tmp:
|
||||
|
||||
opmpack -o /tmp /path/to/MY_CASE.DATA
|
||||
|
||||
|
||||
Print NEW_CASE in cwd:
|
||||
|
||||
opmpack -o NEW_CASE.DATA path/to/MY_CASE.DATA
|
||||
|
||||
|
||||
)";
|
||||
std::cerr << help_text << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int arg_offset = 1;
|
||||
bool stdout_output = true;
|
||||
const char * coutput_arg;
|
||||
|
||||
while (true) {
|
||||
int c;
|
||||
c = getopt(argc, argv, "o:");
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch(c) {
|
||||
case 'o':
|
||||
stdout_output = false;
|
||||
coutput_arg = optarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
arg_offset = optind;
|
||||
if (arg_offset >= argc)
|
||||
print_help_and_exit();
|
||||
|
||||
if (stdout_output)
|
||||
pack_deck(argv[arg_offset], std::cout);
|
||||
else {
|
||||
std::ofstream os;
|
||||
using path = boost::filesystem::path;
|
||||
path input_arg(argv[arg_offset]);
|
||||
path output_arg(coutput_arg);
|
||||
if (boost::filesystem::is_directory(output_arg)) {
|
||||
path output_path = output_arg / input_arg.filename();
|
||||
os.open(output_path.string());
|
||||
} else
|
||||
os.open(output_arg.string());
|
||||
|
||||
pack_deck(argv[arg_offset], os);
|
||||
}
|
||||
}
|
||||
|
||||
32
examples/test_util/Deviation.hpp
Normal file
32
examples/test_util/Deviation.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DEVIATION_HPP
|
||||
#define DEVIATION_HPP
|
||||
|
||||
/*! \brief Deviation struct.
|
||||
\details The member variables are default initialized to -1,
|
||||
which is an invalid deviation value.
|
||||
*/
|
||||
struct Deviation {
|
||||
double abs = -1; //!< Absolute deviation
|
||||
double rel = -1; //!< Relative deviation
|
||||
};
|
||||
|
||||
#endif
|
||||
505
examples/test_util/EclFile.cpp
Normal file
505
examples/test_util/EclFile.cpp
Normal file
@@ -0,0 +1,505 @@
|
||||
/*
|
||||
Copyright 2019 Equinor ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <sstream>
|
||||
#include <iterator>
|
||||
#include <iomanip>
|
||||
#include <algorithm>
|
||||
|
||||
#include "EclFile.hpp"
|
||||
|
||||
|
||||
// anonymous namespace for EclFile
|
||||
|
||||
namespace {
|
||||
|
||||
bool isEOF(std::fstream *fileH){
|
||||
|
||||
/* try to read 4 byte (integer), if passed eof of, return true.
|
||||
if not, seek back to current file possition */
|
||||
|
||||
int num;
|
||||
long int pos=fileH->tellg();
|
||||
fileH->read((char *)&num, sizeof(num));
|
||||
|
||||
if (fileH->eof()){
|
||||
return true;
|
||||
} else {
|
||||
fileH->seekg (pos);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int flipEndianInt(const int &num) {
|
||||
|
||||
unsigned int tmp=__builtin_bswap32(num);
|
||||
|
||||
return (int)tmp;
|
||||
}
|
||||
|
||||
float flipEndianFloat(const float &num) {
|
||||
|
||||
float value=num;
|
||||
|
||||
char *floatToConvert = reinterpret_cast<char*>(&value);
|
||||
std::reverse(floatToConvert, floatToConvert+4);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
double flipEndianDouble(const double &num) {
|
||||
double value=num;
|
||||
|
||||
char *doubleToConvert = reinterpret_cast<char*>(&value);
|
||||
std::reverse(doubleToConvert, doubleToConvert+8);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
std::tuple<const int, const int> block_size_data(EIOD::eclArrType arrType){
|
||||
|
||||
switch(arrType) {
|
||||
case EIOD::INTE : return std::make_tuple(EIOD::sizeOfInte,EIOD::MaxBlockSizeInte); break;
|
||||
case EIOD::REAL : return std::make_tuple(EIOD::sizeOfReal,EIOD::MaxBlockSizeReal); break;
|
||||
case EIOD::DOUB : return std::make_tuple(EIOD::sizeOfDoub,EIOD::MaxBlockSizeDoub); break;
|
||||
case EIOD::LOGI : return std::make_tuple(EIOD::sizeOfLogi,EIOD::MaxBlockSizeLogi); break;
|
||||
case EIOD::CHAR : return std::make_tuple(EIOD::sizeOfChar,EIOD::MaxBlockSizeChar); break;
|
||||
case EIOD::MESS : throw std::invalid_argument("Type 'MESS' have not assosiated data") ; break;
|
||||
default : throw std::invalid_argument("Unknown type"); break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string trimr(const std::string &str1) {
|
||||
|
||||
std::string tmpStr=str1;
|
||||
|
||||
while (tmpStr.back()==' '){
|
||||
tmpStr.pop_back();
|
||||
}
|
||||
|
||||
return std::move(tmpStr);
|
||||
}
|
||||
|
||||
|
||||
void readBinaryHeader(std::fstream &fileH, std::string &arrName, int &size, EIOD::eclArrType &arrType){
|
||||
|
||||
int bhead;
|
||||
std::string tmpStrName(8,' ');
|
||||
std::string tmpStrType(4,' ');
|
||||
|
||||
if (!fileH.is_open()){
|
||||
std::string message="fstream fileH not open for reading";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
fileH.read((char *)&bhead, sizeof(bhead));
|
||||
bhead=flipEndianInt(bhead);
|
||||
|
||||
if (bhead!=16){
|
||||
std::string message="Error reading binary header. Expected 16 bytes of header data, found " + std::to_string(bhead);
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
fileH.read(&tmpStrName[0], 8);
|
||||
|
||||
fileH.read((char *)&size, sizeof(size));
|
||||
size=flipEndianInt(size);
|
||||
|
||||
fileH.read(&tmpStrType[0], 4);
|
||||
|
||||
fileH.read((char *)&bhead, sizeof(bhead));
|
||||
bhead=flipEndianInt(bhead);
|
||||
|
||||
if (bhead!=16){
|
||||
std::string message="Error reading binary header. Expected 16 bytes of header data, found " + std::to_string(bhead);
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
arrName=tmpStrName;
|
||||
|
||||
if (tmpStrType=="INTE")
|
||||
arrType=EIOD::INTE;
|
||||
else if (tmpStrType=="REAL")
|
||||
arrType=EIOD::REAL;
|
||||
else if (tmpStrType=="DOUB")
|
||||
arrType=EIOD::DOUB;
|
||||
else if (tmpStrType=="CHAR")
|
||||
arrType=EIOD::CHAR;
|
||||
else if (tmpStrType=="LOGI")
|
||||
arrType=EIOD::LOGI;
|
||||
else if (tmpStrType=="MESS")
|
||||
arrType=EIOD::MESS;
|
||||
else
|
||||
throw std::runtime_error("Error, unknown array type '" + tmpStrType +"'");
|
||||
|
||||
}
|
||||
|
||||
|
||||
unsigned long int sizeOnDisk(const int num, const EIOD::eclArrType &arrType){
|
||||
|
||||
unsigned long int size=0;
|
||||
|
||||
if (arrType==EIOD::MESS){
|
||||
if (num>0) {
|
||||
std::string message="In routine calcSizeOfArray, type MESS can not have size > 0";
|
||||
throw std::invalid_argument(message);
|
||||
}
|
||||
} else {
|
||||
|
||||
auto sizeData = block_size_data(arrType);
|
||||
|
||||
int sizeOfElement = std::get<0>(sizeData);
|
||||
int maxBlockSize = std::get<1>(sizeData);
|
||||
int maxNumberOfElements=maxBlockSize/sizeOfElement;
|
||||
|
||||
size=num*sizeOfElement;
|
||||
size=size + ((num-1) / maxNumberOfElements)*2*EIOD::sizeOfInte; // 8 byte (two integers) every 1000 element
|
||||
|
||||
if (num>0){
|
||||
size=size+2*EIOD::sizeOfInte;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
std::vector<int> readBinaryInteArray(std::fstream &fileH, const int size){
|
||||
|
||||
std::vector<int> arr;
|
||||
int rest=size;
|
||||
|
||||
auto sizeData = block_size_data(EIOD::INTE);
|
||||
|
||||
int sizeOfElement = std::get<0>(sizeData);
|
||||
int maxBlockSize = std::get<1>(sizeData);
|
||||
int maxNumberOfElements=maxBlockSize/sizeOfElement;
|
||||
|
||||
arr.reserve(size);
|
||||
|
||||
if (!fileH.is_open()){
|
||||
std::string message="fstream fileH not open for reading";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
while (rest > 0) {
|
||||
|
||||
int num,dhead,dtail;
|
||||
|
||||
fileH.read((char *)&dhead, sizeof(dhead));
|
||||
dhead=flipEndianInt(dhead);
|
||||
|
||||
num=dhead/sizeOfElement;
|
||||
|
||||
if ((num > maxNumberOfElements) || (num < 0)){
|
||||
std::string message="Error reading binary inte data, inconsistent header data or incorrect number of elements";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
for (int i=0;i<num;i++){
|
||||
int value;
|
||||
fileH.read((char *)&value, sizeOfElement);
|
||||
value=flipEndianInt(value);
|
||||
arr.push_back(value);
|
||||
}
|
||||
|
||||
rest=rest-num;
|
||||
|
||||
if (((num < maxNumberOfElements) && (rest!=0)) || ((num==maxNumberOfElements) && (rest < 0))) {
|
||||
std::string message="Error reading binary integer data, incorrect number of elements";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
fileH.read((char *)&dtail, sizeof(dtail));
|
||||
dtail=flipEndianInt(dtail);
|
||||
|
||||
if (dhead!=dtail){
|
||||
std::string message="Error reading binary real data, tail not matching header.";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
std::vector<float> readBinaryRealArray(std::fstream &fileH, const int size){
|
||||
|
||||
std::vector<float> arr;
|
||||
arr.reserve(size);
|
||||
|
||||
auto sizeData = block_size_data(EIOD::REAL);
|
||||
|
||||
int sizeOfElement = std::get<0>(sizeData);
|
||||
int maxBlockSize = std::get<1>(sizeData);
|
||||
int maxNumberOfElements=maxBlockSize/sizeOfElement;
|
||||
|
||||
|
||||
if (!fileH.is_open()){
|
||||
std::string message="fstream fileH not open for reading";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
int rest=size;
|
||||
|
||||
while (rest > 0) {
|
||||
|
||||
int num,dhead,dtail;
|
||||
|
||||
fileH.read((char *)&dhead, sizeof(dhead));
|
||||
dhead=flipEndianInt(dhead);
|
||||
|
||||
num=dhead/sizeOfElement;
|
||||
|
||||
if ((num > maxNumberOfElements) || (num < 0)){
|
||||
std::string message="Error reading binary real data, inconsistent header data or incorrect number of elements";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
for (int i=0;i<num;i++){
|
||||
float value;
|
||||
fileH.read((char *)&value, sizeOfElement);
|
||||
value=flipEndianFloat(value);
|
||||
arr.push_back(value);
|
||||
}
|
||||
|
||||
rest=rest-num;
|
||||
|
||||
if (((num < maxNumberOfElements) && (rest!=0)) || ((num==maxNumberOfElements) && (rest < 0))) {
|
||||
std::string message="Error reading binary real data, incorrect number of elements";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
fileH.read((char *)&dtail, sizeof(dtail));
|
||||
dtail=flipEndianInt(dtail);
|
||||
|
||||
if (dhead!=dtail){
|
||||
std::string message="Error reading binary real data, tail not matching header.";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
std::vector<double> readBinaryDoubArray(std::fstream &fileH, const int size){
|
||||
|
||||
std::vector<double> arr;
|
||||
arr.reserve(size);
|
||||
|
||||
auto sizeData = block_size_data(EIOD::DOUB);
|
||||
|
||||
int sizeOfElement = std::get<0>(sizeData);
|
||||
int maxBlockSize = std::get<1>(sizeData);
|
||||
int maxNumberOfElements=maxBlockSize/sizeOfElement;
|
||||
|
||||
if (!fileH.is_open()){
|
||||
std::string message="fstream fileH not open for reading";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
int rest=size;
|
||||
|
||||
while (rest > 0) {
|
||||
|
||||
int num,dhead,dtail;
|
||||
|
||||
fileH.read((char *)&dhead, sizeof(dhead));
|
||||
dhead=flipEndianInt(dhead);
|
||||
|
||||
num=dhead/sizeOfElement;
|
||||
|
||||
if ((num > maxNumberOfElements) || (num < 0)){
|
||||
std::string message="Error reading binary doub data, inconsistent header data or incorrect number of elements";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
for (int i=0;i<num;i++){
|
||||
double value;
|
||||
fileH.read((char *)&value, sizeOfElement);
|
||||
value=flipEndianDouble(value);
|
||||
arr.push_back(value);
|
||||
}
|
||||
|
||||
rest=rest-num;
|
||||
|
||||
if (((num < maxNumberOfElements) && (rest!=0)) || ((num==maxNumberOfElements) && (rest < 0))) {
|
||||
std::string message="Error reading binary doub data, incorrect number of elements";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
fileH.read((char *)&dtail, sizeof(dtail));
|
||||
dtail=flipEndianInt(dtail);
|
||||
|
||||
if (dhead!=dtail){
|
||||
std::string message="Error reading binary doub data, tail not matching header.";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
std::vector<bool> readBinaryLogiArray(std::fstream &fileH, const int size){
|
||||
|
||||
std::vector<bool> arr;
|
||||
arr.reserve(size);
|
||||
|
||||
int rest=size;
|
||||
|
||||
auto sizeData = block_size_data(EIOD::LOGI);
|
||||
|
||||
int sizeOfElement = std::get<0>(sizeData);
|
||||
int maxBlockSize = std::get<1>(sizeData);
|
||||
int maxNumberOfElements=maxBlockSize/sizeOfElement;
|
||||
|
||||
if (!fileH.is_open()){
|
||||
std::string message="fstream fileH not open for reading";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
while (rest > 0) {
|
||||
|
||||
int num,dhead,dtail;
|
||||
|
||||
fileH.read((char *)&dhead, sizeof(dhead));
|
||||
dhead=flipEndianInt(dhead);
|
||||
|
||||
num=dhead/sizeOfElement;
|
||||
|
||||
if ((num > maxNumberOfElements) || (num < 0)){
|
||||
std::string message="This ?? Error reading binary logi data, inconsistent header data or incorrect number of elements";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
for (int i=0;i<num;i++){
|
||||
|
||||
bool value;
|
||||
unsigned int intVal;
|
||||
|
||||
fileH.read((char *)&intVal, sizeOfElement);
|
||||
|
||||
if (intVal==EIOD::true_value){
|
||||
value=true;
|
||||
} else if (intVal==EIOD::false_value){
|
||||
value=false;
|
||||
} else {
|
||||
std::string message="Error reading log value from element " + std::to_string(i);
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
arr.push_back(value);
|
||||
}
|
||||
|
||||
rest=rest-num;
|
||||
|
||||
if (((num < maxNumberOfElements) && (rest!=0)) || ((num==maxNumberOfElements) && (rest < 0))) {
|
||||
std::string message="Error reading binary logi data, incorrect number of elements";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
fileH.read((char *)&dtail, sizeof(dtail));
|
||||
dtail=flipEndianInt(dtail);
|
||||
|
||||
if (dhead!=dtail){
|
||||
std::string message="Error reading binary logi data, tail not matching header.";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> readBinaryCharArray(std::fstream &fileH, const int size){
|
||||
|
||||
std::vector<std::string> arr;
|
||||
arr.reserve(size);
|
||||
|
||||
int rest=size;
|
||||
|
||||
auto sizeData = block_size_data(EIOD::CHAR);
|
||||
|
||||
int sizeOfElement = std::get<0>(sizeData);
|
||||
int maxBlockSize = std::get<1>(sizeData);
|
||||
int maxNumberOfElements=maxBlockSize/sizeOfElement;
|
||||
|
||||
if (!fileH.is_open()){
|
||||
std::string message="fstream fileH not open for reading";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
while (rest > 0) {
|
||||
|
||||
int num,dhead,dtail;
|
||||
|
||||
fileH.read((char *)&dhead, sizeof(dhead));
|
||||
dhead=flipEndianInt(dhead);
|
||||
|
||||
num=dhead/sizeOfElement;
|
||||
|
||||
if ((num > maxNumberOfElements) || (num < 0)){
|
||||
std::string message="Error reading binary char data, inconsistent header data or incorrect number of elements";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
for (int i=0;i<num;i++){
|
||||
std::string str8(8,' ');
|
||||
fileH.read(&str8[0], sizeOfElement);
|
||||
arr.push_back(trimr(str8));
|
||||
}
|
||||
|
||||
rest=rest-num;
|
||||
|
||||
if ((num < maxNumberOfElements) && (rest!=0)){
|
||||
std::string message="Error reading binary char data, incorrect number of elements";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
fileH.read((char *)&dtail, sizeof(dtail));
|
||||
dtail=flipEndianInt(dtail);
|
||||
|
||||
if (dhead!=dtail){
|
||||
std::string message="Error reading binary char data, tail not matching header.";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
EclFile::EclFile(const std::string& filename){
|
||||
|
||||
std::fstream fileH;
|
||||
|
||||
fileH.open(filename, std::ios::in | std::ios::binary);
|
||||
|
||||
if (!fileH.good()) {
|
||||
std::string message="Could not open file";
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
fileH.close();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
41
examples/test_util/EclFile.hpp
Normal file
41
examples/test_util/EclFile.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright 2019 Equinor ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
//#include "EclIO.hpp"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <ctime>
|
||||
#include <map>
|
||||
|
||||
#include <examples/test_util/data/EclIOdata.hpp>
|
||||
|
||||
namespace EIOD = Opm::ecl;
|
||||
|
||||
class EclFile
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
explicit EclFile(const std::string& filename);
|
||||
|
||||
};
|
||||
|
||||
|
||||
300
examples/test_util/EclFilesComparator.cpp
Normal file
300
examples/test_util/EclFilesComparator.cpp
Normal file
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "EclFilesComparator.hpp"
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <opm/common/utility/numeric/calculateCellVol.hpp>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <numeric>
|
||||
|
||||
#include <ert/ecl/ecl_file.h>
|
||||
#include <ert/ecl/ecl_grid.h>
|
||||
#include <ert/ecl/ecl_type.h>
|
||||
|
||||
#include <ert/ecl_well/well_info.h>
|
||||
|
||||
|
||||
// helper macro to handle error throws or not
|
||||
#define HANDLE_ERROR(type, message) \
|
||||
{ \
|
||||
if (throwOnError) \
|
||||
OPM_THROW(type, message); \
|
||||
else { \
|
||||
std::cerr << message << std::endl; \
|
||||
++num_errors; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
/*
|
||||
This is just a basic survival test; we verify that the ERT well
|
||||
loader which is used in Resinsight can load the well description
|
||||
from the restart file.
|
||||
*/
|
||||
|
||||
void loadWells( const ecl_grid_type * grid , ecl_file_type * rst_file ) {
|
||||
well_info_type * well_info = well_info_alloc( grid );
|
||||
well_info_add_UNRST_wells2( well_info , ecl_file_get_global_view( rst_file ), true );
|
||||
well_info_free( well_info );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ECLFilesComparator::keywordValidForComparing(const std::string& keyword) const {
|
||||
auto it = std::find(keywords1.begin(), keywords1.end(), keyword);
|
||||
if (it == keywords1.end()) {
|
||||
OPM_THROW(std::runtime_error, "Keyword " << keyword << " does not exist in first file.");
|
||||
}
|
||||
it = find(keywords2.begin(), keywords2.end(), keyword);
|
||||
if (it == keywords2.end()) {
|
||||
OPM_THROW(std::runtime_error, "Keyword " << keyword << " does not exist in second file.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned int ECLFilesComparator::getEclKeywordData(ecl_kw_type*& ecl_kw1, ecl_kw_type*& ecl_kw2, const std::string& keyword, int occurrence1, int occurrence2) const {
|
||||
ecl_kw1 = ecl_file_iget_named_kw(ecl_file1, keyword.c_str(), occurrence1);
|
||||
ecl_kw2 = ecl_file_iget_named_kw(ecl_file2, keyword.c_str(), occurrence2);
|
||||
const unsigned int numCells1 = ecl_kw_get_size(ecl_kw1);
|
||||
const unsigned int numCells2 = ecl_kw_get_size(ecl_kw2);
|
||||
if (numCells1 != numCells2) {
|
||||
OPM_THROW(std::runtime_error, "For keyword " << keyword << ":"
|
||||
<< "\nOccurrence in first file " << occurrence1
|
||||
<< "\nOccurrence in second file " << occurrence2
|
||||
<< "\nCells in first file: " << numCells1
|
||||
<< "\nCells in second file: " << numCells2
|
||||
<< "\nThe number of cells differ.");
|
||||
}
|
||||
return numCells1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
void ECLFilesComparator::printValuesForCell(const std::string& /*keyword*/, int occurrence1, int occurrence2, size_t kw_size, size_t cell, const T& value1, const T& value2) const {
|
||||
if (kw_size == static_cast<size_t>(ecl_grid_get_active_size(ecl_grid1))) {
|
||||
int i, j, k;
|
||||
ecl_grid_get_ijk1A(ecl_grid1, cell, &i, &j, &k);
|
||||
// Coordinates from this function are zero-based, hence incrementing
|
||||
i++, j++, k++;
|
||||
std::cout << std::endl
|
||||
<< "Occurrence in first file = " << occurrence1 << "\n"
|
||||
<< "Occurrence in second file = " << occurrence2 << "\n"
|
||||
<< "Value index = " << cell << "\n"
|
||||
<< "Grid coordinate = (" << i << ", " << j << ", " << k << ")" << "\n"
|
||||
<< "(first value, second value) = (" << value1 << ", " << value2 << ")\n\n";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (kw_size == static_cast<size_t>(ecl_grid_get_global_size(ecl_grid1))) {
|
||||
int i, j, k;
|
||||
ecl_grid_get_ijk1(ecl_grid1, cell, &i, &j, &k);
|
||||
// Coordinates from this function are zero-based, hence incrementing
|
||||
i++, j++, k++;
|
||||
std::cout << std::endl
|
||||
<< "Occurrence in first file = " << occurrence1 << "\n"
|
||||
<< "Occurrence in second file = " << occurrence2 << "\n"
|
||||
<< "Value index = " << cell << "\n"
|
||||
<< "Grid coordinate = (" << i << ", " << j << ", " << k << ")" << "\n"
|
||||
<< "(first value, second value) = (" << value1 << ", " << value2 << ")\n\n";
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << std::endl
|
||||
<< "Occurrence in first file = " << occurrence1 << "\n"
|
||||
<< "Occurrence in second file = " << occurrence2 << "\n"
|
||||
<< "Value index = " << cell << "\n"
|
||||
<< "(first value, second value) = (" << value1 << ", " << value2 << ")\n\n";
|
||||
}
|
||||
|
||||
template void ECLFilesComparator::printValuesForCell<bool> (const std::string& keyword, int occurrence1, int occurrence2, size_t kw_size, size_t cell, const bool& value1, const bool& value2) const;
|
||||
template void ECLFilesComparator::printValuesForCell<int> (const std::string& keyword, int occurrence1, int occurrence2, size_t kw_size, size_t cell, const int& value1, const int& value2) const;
|
||||
template void ECLFilesComparator::printValuesForCell<double> (const std::string& keyword, int occurrence1, int occurrence2, size_t kw_size, size_t cell, const double& value1, const double& value2) const;
|
||||
template void ECLFilesComparator::printValuesForCell<std::string>(const std::string& keyword, int occurrence1, int occurrence2, size_t kw_size, size_t cell, const std::string& value1, const std::string& value2) const;
|
||||
|
||||
|
||||
ECLFilesComparator::ECLFilesComparator(int file_type_arg, const std::string& basename1,
|
||||
const std::string& basename2,
|
||||
double absToleranceArg, double relToleranceArg) :
|
||||
file_type(file_type_arg), absTolerance(absToleranceArg), relTolerance(relToleranceArg) {
|
||||
|
||||
std::string file1, file2;
|
||||
if (file_type == ECL_UNIFIED_RESTART_FILE) {
|
||||
file1 = basename1 + ".UNRST";
|
||||
file2 = basename2 + ".UNRST";
|
||||
}
|
||||
else if (file_type == ECL_INIT_FILE) {
|
||||
file1 = basename1 + ".INIT";
|
||||
file2 = basename2 + ".INIT";
|
||||
}
|
||||
else if (file_type == ECL_RFT_FILE) {
|
||||
file1 = basename1 + ".RFT";
|
||||
file2 = basename2 + ".RFT";
|
||||
}
|
||||
else {
|
||||
OPM_THROW(std::invalid_argument, "Unsupported filetype sent to ECLFilesComparator's constructor."
|
||||
<< "Only unified restart (.UNRST), initial (.INIT) and .RFT files are supported.");
|
||||
}
|
||||
ecl_file1 = ecl_file_open(file1.c_str(), 0);
|
||||
ecl_file2 = ecl_file_open(file2.c_str(), 0);
|
||||
ecl_grid1 = ecl_grid_load_case(basename1.c_str());
|
||||
ecl_grid2 = ecl_grid_load_case(basename2.c_str());
|
||||
if (ecl_file1 == nullptr) {
|
||||
OPM_THROW(std::invalid_argument, "Error opening first file: " << file1);
|
||||
}
|
||||
if (ecl_file2 == nullptr) {
|
||||
OPM_THROW(std::invalid_argument, "Error opening second file: " << file2);
|
||||
}
|
||||
if (ecl_grid1 == nullptr) {
|
||||
OPM_THROW(std::invalid_argument, "Error opening first grid file: " << basename1);
|
||||
}
|
||||
if (ecl_grid2 == nullptr) {
|
||||
OPM_THROW(std::invalid_argument, "Error opening second grid file. " << basename2);
|
||||
}
|
||||
unsigned int numKeywords1 = ecl_file_get_num_distinct_kw(ecl_file1);
|
||||
unsigned int numKeywords2 = ecl_file_get_num_distinct_kw(ecl_file2);
|
||||
keywords1.reserve(numKeywords1);
|
||||
keywords2.reserve(numKeywords2);
|
||||
for (unsigned int i = 0; i < numKeywords1; ++i) {
|
||||
std::string keyword(ecl_file_iget_distinct_kw(ecl_file1, i));
|
||||
keywords1.push_back(keyword);
|
||||
}
|
||||
for (unsigned int i = 0; i < numKeywords2; ++i) {
|
||||
std::string keyword(ecl_file_iget_distinct_kw(ecl_file2, i));
|
||||
keywords2.push_back(keyword);
|
||||
}
|
||||
|
||||
if (file_type == ECL_UNIFIED_RESTART_FILE) {
|
||||
loadWells( ecl_grid1 , ecl_file1 );
|
||||
loadWells( ecl_grid2 , ecl_file2 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ECLFilesComparator::~ECLFilesComparator() {
|
||||
ecl_file_close(ecl_file1);
|
||||
ecl_file_close(ecl_file2);
|
||||
ecl_grid_free(ecl_grid1);
|
||||
ecl_grid_free(ecl_grid2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLFilesComparator::printKeywords() const {
|
||||
std::cout << "\nKeywords in the first file:\n";
|
||||
for (const auto& it : keywords1) {
|
||||
std::cout << std::setw(15) << std::left << it << " of type " << ecl_type_get_name( ecl_file_iget_named_data_type(ecl_file1, it.c_str(), 0)) << std::endl;
|
||||
}
|
||||
std::cout << "\nKeywords in second file:\n";
|
||||
for (const auto& it : keywords2) {
|
||||
std::cout << std::setw(15) << std::left << it << " of type " << ecl_type_get_name( ecl_file_iget_named_data_type(ecl_file2, it.c_str(), 0)) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLFilesComparator::printKeywordsDifference() const {
|
||||
std::vector<std::string> common;
|
||||
std::vector<std::string> uncommon;
|
||||
const std::vector<std::string>* keywordsShort = &keywords1;
|
||||
const std::vector<std::string>* keywordsLong = &keywords2;
|
||||
if (keywords1.size() > keywords2.size()) {
|
||||
keywordsLong = &keywords1;
|
||||
keywordsShort = &keywords2;
|
||||
}
|
||||
for (const auto& it : *keywordsLong) {
|
||||
const auto position = std::find(keywordsShort->begin(), keywordsShort->end(), it);
|
||||
if (position != keywordsShort->end()) {
|
||||
common.push_back(*position);
|
||||
}
|
||||
else {
|
||||
uncommon.push_back(it);
|
||||
}
|
||||
}
|
||||
std::cout << "\nCommon keywords for the two cases:\n";
|
||||
for (const auto& it : common) std::cout << it << std::endl;
|
||||
std::cout << "\nUncommon keywords for the two cases:\n";
|
||||
for (const auto& it : uncommon) std::cout << it << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Deviation ECLFilesComparator::calculateDeviations(double val1, double val2) {
|
||||
val1 = std::abs(val1);
|
||||
val2 = std::abs(val2);
|
||||
Deviation deviation;
|
||||
if (val1 != 0 || val2 != 0) {
|
||||
deviation.abs = std::abs(val1 - val2);
|
||||
if (val1 != 0 && val2 != 0) {
|
||||
deviation.rel = deviation.abs/(std::max(val1, val2));
|
||||
}
|
||||
}
|
||||
return deviation;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double ECLFilesComparator::median(std::vector<double> vec) {
|
||||
if (vec.empty()) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
size_t n = vec.size()/2;
|
||||
nth_element(vec.begin(), vec.begin() + n, vec.end());
|
||||
if (vec.size() % 2 == 0) {
|
||||
return 0.5*(vec[n-1]+vec[n]);
|
||||
}
|
||||
else {
|
||||
return vec[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
double ECLFilesComparator::average(const std::vector<double>& vec) {
|
||||
if (vec.empty()) {
|
||||
return 0;
|
||||
}
|
||||
double sum = std::accumulate(vec.begin(), vec.end(), 0.0);
|
||||
return sum/vec.size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
double ECLFilesComparator::getCellVolume(const ecl_grid_type* ecl_grid,
|
||||
const int globalIndex) {
|
||||
std::vector<double> x(8, 0.0);
|
||||
std::vector<double> y(8, 0.0);
|
||||
std::vector<double> z(8, 0.0);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
ecl_grid_get_cell_corner_xyz1(ecl_grid, globalIndex, i, &x.data()[i], &y.data()[i], &z.data()[i]);
|
||||
}
|
||||
return calculateCellVol(x,y,z);
|
||||
}
|
||||
127
examples/test_util/EclFilesComparator.hpp
Normal file
127
examples/test_util/EclFilesComparator.hpp
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ECLFILESCOMPARATOR_HPP
|
||||
#define ECLFILESCOMPARATOR_HPP
|
||||
|
||||
#include "Deviation.hpp"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
struct ecl_file_struct; //!< Prototype for eclipse file struct, from ERT library.
|
||||
typedef struct ecl_file_struct ecl_file_type;
|
||||
|
||||
struct ecl_grid_struct; //!< Prototype for eclipse grid struct, from ERT library.
|
||||
typedef struct ecl_grid_struct ecl_grid_type;
|
||||
struct ecl_kw_struct; //!< Prototype for eclipse keyword struct, from ERT library.
|
||||
typedef struct ecl_kw_struct ecl_kw_type;
|
||||
|
||||
|
||||
/*! \brief A class for comparing ECLIPSE files.
|
||||
\details ECLFilesComparator opens ECLIPSE files
|
||||
(unified restart, initial and RFT in addition to grid file)
|
||||
from two simulations. This class has only the functions
|
||||
printKeywords() and printKeywordsDifference(), in addition to a
|
||||
couple of get-functions: the comparison logic is implemented in
|
||||
the subclasses RegressionTest and IntegrationTest. */
|
||||
class ECLFilesComparator {
|
||||
private:
|
||||
int file_type;
|
||||
double absTolerance = 0;
|
||||
double relTolerance = 0;
|
||||
protected:
|
||||
ecl_file_type* ecl_file1 = nullptr;
|
||||
ecl_grid_type* ecl_grid1 = nullptr;
|
||||
ecl_file_type* ecl_file2 = nullptr;
|
||||
ecl_grid_type* ecl_grid2 = nullptr;
|
||||
std::vector<std::string> keywords1, keywords2;
|
||||
bool throwOnError = true; //!< Throw on first error
|
||||
bool analysis = false; //!< Perform full error analysis
|
||||
std::map<std::string, std::vector<Deviation>> deviations;
|
||||
mutable size_t num_errors = 0;
|
||||
|
||||
//! \brief Checks if the keyword exists in both cases.
|
||||
//! \param[in] keyword Keyword to check.
|
||||
//! \details If the keyword does not exist in one of the cases, the function throws an exception.
|
||||
void keywordValidForComparing(const std::string& keyword) const;
|
||||
//! \brief Stores keyword data for a given occurrence
|
||||
//! \param[out] ecl_kw1 Pointer to a ecl_kw_type, which stores keyword data for first case given the occurrence.
|
||||
//! \param[out] ecl_kw2 Pointer to a ecl_kw_type, which stores keyword data for second case given the occurrence.
|
||||
//! \param[in] keyword Which keyword to consider.
|
||||
//! \param[in] occurrence Which keyword occurrence to consider.
|
||||
//! \details This function stores keyword data for the given keyword and occurrence in #ecl_kw1 and #ecl_kw2, and returns the number of cells (for which the keyword has a value at the occurrence). If the number of cells differ for the two cases, an exception is thrown.
|
||||
unsigned int getEclKeywordData(ecl_kw_type*& ecl_kw1, ecl_kw_type*& ecl_kw2, const std::string& keyword, int occurrence1, int occurrence2) const;
|
||||
//! \brief Prints values for a given keyword, occurrence and cell
|
||||
//! \param[in] keyword Which keyword to consider.
|
||||
//! \param[in] occurrence Which keyword occurrence to consider.
|
||||
//! \param[in] cell Which cell occurrence to consider (numbered by global index).
|
||||
//! \param[in] value1 Value for first file, the data type can be bool, int, double or std::string.
|
||||
//! \param[in] value2 Value for second file, the data type can be bool, int, double or std::string.
|
||||
//! \details Templatefunction for printing values when exceptions are thrown. The function is defined for bool, int, double and std::string.
|
||||
template <typename T>
|
||||
void printValuesForCell(const std::string& keyword, int occurrence1, int occurrence2, size_t kw_size, size_t cell, const T& value1, const T& value2) const;
|
||||
|
||||
public:
|
||||
//! \brief Open ECLIPSE files and set tolerances and keywords.
|
||||
//! \param[in] file_type Specifies which filetype to be compared, possible inputs are UNRSTFILE, INITFILE and RFTFILE.
|
||||
//! \param[in] basename1 Full path without file extension to the first case.
|
||||
//! \param[in] basename2 Full path without file extension to the second case.
|
||||
//! \param[in] absTolerance Tolerance for absolute deviation.
|
||||
//! \param[in] relTolerance Tolerance for relative deviation.
|
||||
//! \details The content of the ECLIPSE files specified in the input is stored in the ecl_file_type and ecl_grid_type member variables. In addition the keywords and absolute and relative tolerances (member variables) are set. If the constructor is unable to open one of the ECLIPSE files, an exception will be thrown.
|
||||
ECLFilesComparator(int file_type, const std::string& basename1, const std::string& basename2, double absTolerance, double relTolerance);
|
||||
//! \brief Closing the ECLIPSE files.
|
||||
~ECLFilesComparator();
|
||||
|
||||
//! \brief Set whether to throw on errors or not.
|
||||
void throwOnErrors(bool dothrow) { throwOnError = dothrow; }
|
||||
|
||||
//! \brief Set whether to perform a full error analysis.
|
||||
void doAnalysis(bool analize) { analysis = analize; }
|
||||
|
||||
//! \brief Returns the number of errors encountered in the performed comparisons.
|
||||
size_t getNoErrors() const { return num_errors; }
|
||||
|
||||
//! \brief Returns the ECLIPSE filetype of this
|
||||
int getFileType() const {return file_type;}
|
||||
//! \brief Returns the absolute tolerance stored as a private member variable in the class
|
||||
double getAbsTolerance() const {return absTolerance;}
|
||||
//! \brief Returns the relative tolerance stored as a private member variable in the class
|
||||
double getRelTolerance() const {return relTolerance;}
|
||||
|
||||
//! \brief Print all keywords and their respective Eclipse type for the two input cases.
|
||||
void printKeywords() const;
|
||||
//! \brief Print common and uncommon keywords for the two input cases.
|
||||
void printKeywordsDifference() const;
|
||||
|
||||
//! \brief Calculate deviations for two values.
|
||||
//! \details Using absolute values of the input arguments: If one of the values are non-zero, the Deviation::abs returned is the difference between the two input values. In addition, if both values are non-zero, the Deviation::rel returned is the absolute deviation divided by the largest value.
|
||||
static Deviation calculateDeviations(double val1, double val2);
|
||||
//! \brief Calculate median of a vector.
|
||||
//! \details Returning the median of the input vector, i.e. the middle value of the sorted vector if the number of elements is odd or the mean of the two middle values if the number of elements are even.
|
||||
static double median(std::vector<double> vec);
|
||||
//! \brief Calculate average of a vector.
|
||||
//! \details Returning the average of the input vector, i.e. the sum of all values divided by the number of elements.
|
||||
static double average(const std::vector<double>& vec);
|
||||
//! \brief Obtain the volume of a cell.
|
||||
static double getCellVolume(const ecl_grid_type* ecl_grid, const int globalIndex);
|
||||
};
|
||||
|
||||
#endif
|
||||
199
examples/test_util/EclIntegrationTest.cpp
Normal file
199
examples/test_util/EclIntegrationTest.cpp
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "EclIntegrationTest.hpp"
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
#include <ert/ecl/ecl_file.h>
|
||||
#include <ert/ecl/ecl_grid.h>
|
||||
#include <ert/ecl/ecl_type.h>
|
||||
|
||||
#include <ert/ecl_well/well_info.h>
|
||||
|
||||
|
||||
// helper macro to handle error throws or not
|
||||
#define HANDLE_ERROR(type, message) \
|
||||
{ \
|
||||
if (throwOnError) \
|
||||
OPM_THROW(type, message); \
|
||||
else { \
|
||||
std::cerr << message << std::endl; \
|
||||
++num_errors; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
void ECLIntegrationTest::setCellVolumes() {
|
||||
double absTolerance = getAbsTolerance();
|
||||
double relTolerance = getRelTolerance();
|
||||
const unsigned int globalGridCount1 = ecl_grid_get_global_size(ecl_grid1);
|
||||
const unsigned int activeGridCount1 = ecl_grid_get_active_size(ecl_grid1);
|
||||
const unsigned int globalGridCount2 = ecl_grid_get_global_size(ecl_grid2);
|
||||
const unsigned int activeGridCount2 = ecl_grid_get_active_size(ecl_grid2);
|
||||
if (globalGridCount1 != globalGridCount2) {
|
||||
OPM_THROW(std::runtime_error, "In grid file:"
|
||||
<< "\nCells in first file: " << globalGridCount1
|
||||
<< "\nCells in second file: " << globalGridCount2
|
||||
<< "\nThe number of global cells differ.");
|
||||
}
|
||||
if (activeGridCount1 != activeGridCount2) {
|
||||
OPM_THROW(std::runtime_error, "In grid file:"
|
||||
<< "\nCells in first file: " << activeGridCount1
|
||||
<< "\nCells in second file: " << activeGridCount2
|
||||
<< "\nThe number of active cells differ.");
|
||||
}
|
||||
for (unsigned int cell = 0; cell < globalGridCount1; ++cell) {
|
||||
const double cellVolume1 = getCellVolume(ecl_grid1, cell);
|
||||
const double cellVolume2 = getCellVolume(ecl_grid2, cell);
|
||||
Deviation dev = calculateDeviations(cellVolume1, cellVolume2);
|
||||
if (dev.abs > absTolerance && dev.rel > relTolerance) {
|
||||
int i, j, k;
|
||||
ecl_grid_get_ijk1(ecl_grid1, cell, &i, &j, &k);
|
||||
// Coordinates from this function are zero-based, hence incrementing
|
||||
i++, j++, k++;
|
||||
OPM_THROW(std::runtime_error, "In grid file: Deviations of cell volume exceed tolerances. "
|
||||
<< "\nFor cell with coordinate (" << i << ", " << j << ", " << k << "):"
|
||||
<< "\nCell volume in first file: " << cellVolume1
|
||||
<< "\nCell volume in second file: " << cellVolume2
|
||||
<< "\nThe absolute deviation is " << dev.abs << ", and the tolerance limit is " << absTolerance << "."
|
||||
<< "\nThe relative deviation is " << dev.rel << ", and the tolerance limit is " << relTolerance << ".");
|
||||
} // The second input case is used as reference.
|
||||
cellVolumes.push_back(cellVolume2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLIntegrationTest::initialOccurrenceCompare(const std::string& keyword) {
|
||||
ecl_kw_type* ecl_kw1 = nullptr;
|
||||
ecl_kw_type* ecl_kw2 = nullptr;
|
||||
const unsigned int numCells = getEclKeywordData(ecl_kw1, ecl_kw2, keyword, 0, 0);
|
||||
std::vector<double> values1(numCells);
|
||||
initialCellValues.resize(numCells);
|
||||
|
||||
ecl_kw_get_data_as_double(ecl_kw1, values1.data());
|
||||
ecl_kw_get_data_as_double(ecl_kw2, initialCellValues.data());
|
||||
|
||||
// This variable sums up the difference between the keyword value for the first case and the keyword value for the second case, for each cell. The sum is weighted with respect to the cell volume of each cell.
|
||||
double weightedDifference = 0;
|
||||
// This variable sums up the keyword value for the first case for each cell. The sum is weighted with respect to the cell volume of each cell.
|
||||
double weightedTotal = 0;
|
||||
for (size_t cell = 0; cell < initialCellValues.size(); ++cell) {
|
||||
weightedTotal += initialCellValues[cell]*cellVolumes[cell];
|
||||
weightedDifference += std::abs(values1[cell] - initialCellValues[cell])*cellVolumes[cell];
|
||||
}
|
||||
if (weightedTotal != 0) {
|
||||
double ratioValue = weightedDifference/weightedTotal;
|
||||
if ((ratioValue) > getRelTolerance()) {
|
||||
OPM_THROW(std::runtime_error, "\nFor keyword " << keyword << " and occurrence 0:"
|
||||
<< "\nThe ratio of the deviation and the total value is " << ratioValue
|
||||
<< ", which exceeds the relative tolerance of " << getRelTolerance() << "."
|
||||
<< "\nSee the docs for more information about how the ratio is computed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLIntegrationTest::occurrenceCompare(const std::string& keyword, int occurrence) const {
|
||||
ecl_kw_type* ecl_kw1 = nullptr;
|
||||
ecl_kw_type* ecl_kw2 = nullptr;
|
||||
const unsigned int numCells = getEclKeywordData(ecl_kw1, ecl_kw2, keyword, occurrence, occurrence);
|
||||
std::vector<double> values1(numCells), values2(numCells);
|
||||
ecl_kw_get_data_as_double(ecl_kw1, values1.data());
|
||||
ecl_kw_get_data_as_double(ecl_kw2, values2.data());
|
||||
|
||||
// This variable sums up the difference between the keyword value for the first case and the keyword value for the second case, for each cell. The sum is weighted with respect to the cell volume of each cell.
|
||||
double weightedDifference = 0;
|
||||
// This variable sums up the difference between the keyword value for the occurrence and the initial keyword value for each cell. The sum is weighted with respect to the cell volume of each cell.
|
||||
double relativeWeightedTotal = 0;
|
||||
|
||||
for (size_t cell = 0; cell < values1.size(); ++cell) {
|
||||
relativeWeightedTotal += std::abs(values1[cell] - initialCellValues[cell])*cellVolumes[cell];
|
||||
weightedDifference += std::abs(values1[cell] - values2[cell])*cellVolumes[cell];
|
||||
}
|
||||
|
||||
if (relativeWeightedTotal != 0) {
|
||||
double ratioValue = weightedDifference/relativeWeightedTotal;
|
||||
if ((ratioValue) > getRelTolerance()) {
|
||||
OPM_THROW(std::runtime_error, "\nFor keyword " << keyword << " and occurrence " << occurrence << ":"
|
||||
<< "\nThe ratio of the deviation and the total value is " << ratioValue
|
||||
<< ", which exceeds the relative tolerance of " << getRelTolerance() << "."
|
||||
<< "\nSee the docs for more information about how the ratio is computed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ECLIntegrationTest::ECLIntegrationTest(const std::string& basename1,
|
||||
const std::string& basename2,
|
||||
double absTolerance, double relTolerance) :
|
||||
ECLFilesComparator(ECL_UNIFIED_RESTART_FILE, basename1, basename2, absTolerance, relTolerance) {
|
||||
std::cout << "\nUsing cell volumes and keyword values from case " << basename2
|
||||
<< " as reference." << std::endl << std::endl;
|
||||
setCellVolumes();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool ECLIntegrationTest::elementInWhitelist(const std::string& keyword) const {
|
||||
auto it = std::find(keywordWhitelist.begin(), keywordWhitelist.end(), keyword);
|
||||
return it != keywordWhitelist.end();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLIntegrationTest::equalNumKeywords() const {
|
||||
if (keywords1.size() != keywords2.size()) {
|
||||
OPM_THROW(std::runtime_error, "\nKeywords in first file: " << keywords1.size()
|
||||
<< "\nKeywords in second file: " << keywords2.size()
|
||||
<< "\nThe number of keywords differ.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLIntegrationTest::results() {
|
||||
for (const auto& it : keywordWhitelist)
|
||||
resultsForKeyword(it);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLIntegrationTest::resultsForKeyword(const std::string& keyword) {
|
||||
std::cout << "Comparing " << keyword << "...";
|
||||
keywordValidForComparing(keyword);
|
||||
const unsigned int occurrences1 = ecl_file_get_num_named_kw(ecl_file1, keyword.c_str());
|
||||
const unsigned int occurrences2 = ecl_file_get_num_named_kw(ecl_file2, keyword.c_str());
|
||||
if (occurrences1 != occurrences2) {
|
||||
OPM_THROW(std::runtime_error, "For keyword " << keyword << ":"
|
||||
<< "\nKeyword occurrences in first file: " << occurrences1
|
||||
<< "\nKeyword occurrences in second file: " << occurrences2
|
||||
<< "\nThe number of occurrences differ.");
|
||||
}
|
||||
initialOccurrenceCompare(keyword);
|
||||
for (unsigned int occurrence = 1; occurrence < occurrences1; ++occurrence) {
|
||||
occurrenceCompare(keyword, occurrence);
|
||||
}
|
||||
std::cout << "done." << std::endl;
|
||||
}
|
||||
78
examples/test_util/EclIntegrationTest.hpp
Normal file
78
examples/test_util/EclIntegrationTest.hpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ECLINTEGRATIONTEST_HPP
|
||||
#define ECLINTEGRATIONTEST_HPP
|
||||
|
||||
#include "EclFilesComparator.hpp"
|
||||
|
||||
/*! \brief A class for executing a integration test for two ECLIPSE files.
|
||||
\details This class inherits from ECLFilesComparator, which opens and closes
|
||||
the input cases and stores keywordnames. The three public functions
|
||||
equalNumKeywords(), results() and resultsForKeyword() can be invoked
|
||||
to compare griddata or keyworddata for all keywords or a given
|
||||
keyword (resultsForKeyword()).
|
||||
*/
|
||||
class ECLIntegrationTest: public ECLFilesComparator {
|
||||
private:
|
||||
std::vector<double> cellVolumes; //!< Vector of cell volumes in second input case (indexed by global index)
|
||||
std::vector<double> initialCellValues; //!< Keyword values for all cells at first occurrence (index by global index)
|
||||
|
||||
// These are the only keywords which are compared, since SWAT should be "1 - SOIL - SGAS", this keyword is omitted.
|
||||
const std::vector<std::string> keywordWhitelist = {"SGAS", "SWAT", "PRESSURE"};
|
||||
|
||||
void setCellVolumes();
|
||||
void initialOccurrenceCompare(const std::string& keyword);
|
||||
void occurrenceCompare(const std::string& keyword, int occurrence) const;
|
||||
public:
|
||||
//! \brief Sets up the integration test.
|
||||
//! \param[in] basename1 Full path without file extension to the first case.
|
||||
//! \param[in] basename2 Full path without file extension to the second case.
|
||||
//! \param[in] absTolerance Tolerance for absolute deviation.
|
||||
//! \param[in] relTolerance Tolerance for relative deviation.
|
||||
//! \details This constructor calls the constructor of the superclass, with input filetype unified restart. See the docs for ECLFilesComparator for more information.
|
||||
ECLIntegrationTest(const std::string& basename1, const std::string& basename2, double absTolerance, double relTolerance);
|
||||
|
||||
//! \brief Checks if a keyword is supported for comparison.
|
||||
//! \param[in] keyword Keyword to check.
|
||||
bool elementInWhitelist(const std::string& keyword) const;
|
||||
//! \brief Checks if the number of keywords equal in the two input cases.
|
||||
//! \param[in] keyword Keyword to check.
|
||||
void equalNumKeywords() const;
|
||||
|
||||
//! \brief Finds deviations for all supported keywords.
|
||||
//! \details results() loops through all supported keywords for integration test (defined in keywordWhitelist -- this is SGAS, SWAT and PRESSURE) and calls resultsForKeyword() for each keyword.
|
||||
void results();
|
||||
//! \brief Finds deviations for a specific keyword.
|
||||
//! \param[in] keyword Keyword to check.
|
||||
/*! \details First, resultsForKeyword() checks if the keyword exits in both cases, and if the number of keyword occurrences in the two cases differ. If these tests fail, an exception is thrown. Then deviaitons are calculated as described below for each occurrence, and an exception is thrown if the relative error ratio \f$E\f$ is larger than the relative tolerance.
|
||||
* Calculation:\n
|
||||
* Let the keyword values for occurrence \f$n\f$ and cell \f$i\f$ be \f$p_{n,i}\f$ and \f$q_{n,i}\f$ for input case 1 and 2, respectively.
|
||||
* Consider first the initial occurrence (\f$n=0\f$). The function uses the second cases as reference, and calculates the volume weighted sum of \f$q_{0,i}\f$ over all cells \f$i\f$:
|
||||
* \f[ S_0 = \sum_{i} q_{0,i} v_i \f]
|
||||
* where \f$v_{i}\f$ is the volume of cell \f$i\f$ in case 2. Then, the deviations between the cases for each cell are calculated:
|
||||
* \f[ \Delta = \sum_{i} |p_{0,i} - q_{0,i}| v_i.\f]
|
||||
* The error ratio is then \f$E = \Delta/S_0\f$.\n
|
||||
* For all other occurrences \f$n\f$, the deviation value \f$\Delta\f$ is calculated the same way, but the total value \f$S\f$ is calculated relative to the initial occurrence total \f$S_0\f$:
|
||||
* \f[ S = \sum_{i} |q_{n,i} - q_{0,i}| v_i. \f]
|
||||
* The error ratio is \f$ E = \Delta/S\f$. */
|
||||
void resultsForKeyword(const std::string& keyword);
|
||||
};
|
||||
|
||||
#endif
|
||||
352
examples/test_util/EclRegressionTest.cpp
Normal file
352
examples/test_util/EclRegressionTest.cpp
Normal file
@@ -0,0 +1,352 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "EclRegressionTest.hpp"
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
#include <ert/ecl/ecl_file.h>
|
||||
#include <ert/ecl/ecl_grid.h>
|
||||
#include <ert/ecl/ecl_type.h>
|
||||
|
||||
#include <ert/ecl_well/well_info.h>
|
||||
|
||||
|
||||
// helper macro to handle error throws or not
|
||||
#define HANDLE_ERROR(type, message) \
|
||||
{ \
|
||||
if (throwOnError) \
|
||||
OPM_THROW(type, message); \
|
||||
else { \
|
||||
std::cerr << message << std::endl; \
|
||||
++num_errors; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
void ECLRegressionTest::printResultsForKeyword(const std::string& keyword) const {
|
||||
std::cout << "Deviation results for keyword " << keyword << " of type "
|
||||
<< ecl_type_get_name(ecl_file_iget_named_data_type(ecl_file1, keyword.c_str(), 0))
|
||||
<< ":\n";
|
||||
const double absDeviationAverage = average(absDeviation);
|
||||
const double relDeviationAverage = average(relDeviation);
|
||||
std::cout << "Average absolute deviation = " << absDeviationAverage << std::endl;
|
||||
std::cout << "Median absolute deviation = " << median(absDeviation) << std::endl;
|
||||
std::cout << "Average relative deviation = " << relDeviationAverage << std::endl;
|
||||
std::cout << "Median relative deviation = " << median(relDeviation) << "\n\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::boolComparisonForOccurrence(const std::string& keyword,
|
||||
int occurrence1, int occurrence2) const {
|
||||
ecl_kw_type* ecl_kw1 = nullptr;
|
||||
ecl_kw_type* ecl_kw2 = nullptr;
|
||||
const unsigned int numCells = getEclKeywordData(ecl_kw1, ecl_kw2, keyword, occurrence1, occurrence2);
|
||||
for (size_t cell = 0; cell < numCells; cell++) {
|
||||
bool data1 = ecl_kw_iget_bool(ecl_kw1, cell);
|
||||
bool data2 = ecl_kw_iget_bool(ecl_kw2, cell);
|
||||
if (data1 != data2) {
|
||||
printValuesForCell(keyword, occurrence1, occurrence2, numCells, cell, data1, data2);
|
||||
HANDLE_ERROR(std::runtime_error, "Values of bool type differ.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::charComparisonForOccurrence(const std::string& keyword,
|
||||
int occurrence1, int occurrence2) const {
|
||||
ecl_kw_type* ecl_kw1 = nullptr;
|
||||
ecl_kw_type* ecl_kw2 = nullptr;
|
||||
const unsigned int numCells = getEclKeywordData(ecl_kw1, ecl_kw2, keyword, occurrence1, occurrence2);
|
||||
for (size_t cell = 0; cell < numCells; cell++) {
|
||||
std::string data1(ecl_kw_iget_char_ptr(ecl_kw1, cell));
|
||||
std::string data2(ecl_kw_iget_char_ptr(ecl_kw2, cell));
|
||||
if (data1.compare(data2) != 0) {
|
||||
printValuesForCell(keyword, occurrence1, occurrence2, numCells, cell, data1, data2);
|
||||
HANDLE_ERROR(std::runtime_error, "Values of char type differ.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::intComparisonForOccurrence(const std::string& keyword,
|
||||
int occurrence1, int occurrence2) const {
|
||||
ecl_kw_type* ecl_kw1 = nullptr;
|
||||
ecl_kw_type* ecl_kw2 = nullptr;
|
||||
const unsigned int numCells = getEclKeywordData(ecl_kw1, ecl_kw2, keyword, occurrence1, occurrence2);
|
||||
std::vector<int> values1(numCells), values2(numCells);
|
||||
ecl_kw_get_memcpy_int_data(ecl_kw1, values1.data());
|
||||
ecl_kw_get_memcpy_int_data(ecl_kw2, values2.data());
|
||||
for (size_t cell = 0; cell < values1.size(); cell++) {
|
||||
if (values1[cell] != values2[cell]) {
|
||||
printValuesForCell(keyword, occurrence1, occurrence2, values1.size(), cell, values1[cell], values2[cell]);
|
||||
HANDLE_ERROR(std::runtime_error, "Values of int type differ.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::doubleComparisonForOccurrence(const std::string& keyword,
|
||||
int occurrence1, int occurrence2) {
|
||||
ecl_kw_type* ecl_kw1 = nullptr;
|
||||
ecl_kw_type* ecl_kw2 = nullptr;
|
||||
const unsigned int numCells = getEclKeywordData(ecl_kw1, ecl_kw2, keyword, occurrence1, occurrence2);
|
||||
std::vector<double> values1(numCells), values2(numCells);
|
||||
ecl_kw_get_data_as_double(ecl_kw1, values1.data());
|
||||
ecl_kw_get_data_as_double(ecl_kw2, values2.data());
|
||||
|
||||
auto it = std::find(keywordDisallowNegatives.begin(), keywordDisallowNegatives.end(), keyword);
|
||||
for (size_t cell = 0; cell < values1.size(); cell++) {
|
||||
deviationsForCell(values1[cell], values2[cell], keyword, occurrence1, occurrence2, cell, it == keywordDisallowNegatives.end());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::deviationsForCell(double val1, double val2,
|
||||
const std::string& keyword,
|
||||
int occurrence1, int occurrence2,
|
||||
size_t kw_size, size_t cell,
|
||||
bool allowNegativeValues) {
|
||||
double absTolerance = getAbsTolerance();
|
||||
double relTolerance = getRelTolerance();
|
||||
if (!allowNegativeValues) {
|
||||
if (val1 < 0) {
|
||||
if (std::abs(val1) > absTolerance) {
|
||||
printValuesForCell(keyword, occurrence1, occurrence2, kw_size, cell, val1, val2);
|
||||
HANDLE_ERROR(std::runtime_error, "Negative value in first file, "
|
||||
<< "which in absolute value exceeds the absolute tolerance of " << absTolerance << ".");
|
||||
}
|
||||
val1 = 0;
|
||||
}
|
||||
if (val2 < 0) {
|
||||
if (std::abs(val2) > absTolerance) {
|
||||
printValuesForCell(keyword, occurrence1, occurrence2, kw_size, cell, val1, val2);
|
||||
HANDLE_ERROR(std::runtime_error, "Negative value in second file, "
|
||||
<< "which in absolute value exceeds the absolute tolerance of " << absTolerance << ".");
|
||||
}
|
||||
val2 = 0;
|
||||
}
|
||||
}
|
||||
Deviation dev = calculateDeviations(val1, val2);
|
||||
if (dev.abs > absTolerance && dev.rel > relTolerance) {
|
||||
if (analysis) {
|
||||
deviations[keyword].push_back(dev);
|
||||
} else {
|
||||
printValuesForCell(keyword, occurrence1, occurrence2, kw_size, cell, val1, val2);
|
||||
HANDLE_ERROR(std::runtime_error, "Deviations exceed tolerances."
|
||||
<< "\nThe absolute deviation is " << dev.abs << ", and the tolerance limit is " << absTolerance << "."
|
||||
<< "\nThe relative deviation is " << dev.rel << ", and the tolerance limit is " << relTolerance << ".");
|
||||
}
|
||||
}
|
||||
if (dev.abs != -1) {
|
||||
absDeviation.push_back(dev.abs);
|
||||
}
|
||||
if (dev.rel != -1) {
|
||||
relDeviation.push_back(dev.rel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::gridCompare(const bool volumecheck) const {
|
||||
double absTolerance = getAbsTolerance();
|
||||
double relTolerance = getRelTolerance();
|
||||
const unsigned int globalGridCount1 = ecl_grid_get_global_size(ecl_grid1);
|
||||
const unsigned int activeGridCount1 = ecl_grid_get_active_size(ecl_grid1);
|
||||
const unsigned int globalGridCount2 = ecl_grid_get_global_size(ecl_grid2);
|
||||
const unsigned int activeGridCount2 = ecl_grid_get_active_size(ecl_grid2);
|
||||
if (globalGridCount1 != globalGridCount2) {
|
||||
OPM_THROW(std::runtime_error, "In grid file:"
|
||||
<< "\nCells in first file: " << globalGridCount1
|
||||
<< "\nCells in second file: " << globalGridCount2
|
||||
<< "\nThe number of global cells differ.");
|
||||
}
|
||||
if (activeGridCount1 != activeGridCount2) {
|
||||
OPM_THROW(std::runtime_error, "In grid file:"
|
||||
<< "\nCells in first file: " << activeGridCount1
|
||||
<< "\nCells in second file: " << activeGridCount2
|
||||
<< "\nThe number of active cells differ.");
|
||||
}
|
||||
|
||||
if (!volumecheck) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned int cell = 0; cell < globalGridCount1; ++cell) {
|
||||
const bool active1 = ecl_grid_cell_active1(ecl_grid1, cell);
|
||||
const bool active2 = ecl_grid_cell_active1(ecl_grid2, cell);
|
||||
if (active1 != active2) {
|
||||
int i, j, k;
|
||||
ecl_grid_get_ijk1(ecl_grid1, cell, &i, &j, &k);
|
||||
// Coordinates from this function are zero-based, hence incrementing
|
||||
i++, j++, k++;
|
||||
HANDLE_ERROR(std::runtime_error, "Grid cell with one-based indices ( "
|
||||
<< i << ", " << j << ", " << k << " ) is "
|
||||
<< (active1 ? "active" : "inactive") << " in first grid, but "
|
||||
<< (active2 ? "active" : "inactive") << " in second grid.");
|
||||
}
|
||||
const double cellVolume1 = getCellVolume(ecl_grid1, cell);
|
||||
const double cellVolume2 = getCellVolume(ecl_grid2, cell);
|
||||
Deviation dev = calculateDeviations(cellVolume1, cellVolume2);
|
||||
if (dev.abs > absTolerance && dev.rel > relTolerance) {
|
||||
int i, j, k;
|
||||
ecl_grid_get_ijk1(ecl_grid1, cell, &i, &j, &k);
|
||||
// Coordinates from this function are zero-based, hence incrementing
|
||||
i++, j++, k++;
|
||||
HANDLE_ERROR(std::runtime_error, "In grid file: Deviations of cell volume exceed tolerances. "
|
||||
<< "\nFor cell with one-based indices (" << i << ", " << j << ", " << k << "):"
|
||||
<< "\nCell volume in first file: " << cellVolume1
|
||||
<< "\nCell volume in second file: " << cellVolume2
|
||||
<< "\nThe absolute deviation is " << dev.abs << ", and the tolerance limit is " << absTolerance << "."
|
||||
<< "\nThe relative deviation is " << dev.rel << ", and the tolerance limit is " << relTolerance << "."
|
||||
<< "\nCell 1 active: " << active1
|
||||
<< "\nCell 2 active: " << active2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::results() {
|
||||
if (!this->acceptExtraKeywords) {
|
||||
if (keywords1.size() != keywords2.size()) {
|
||||
std::set<std::string> keys(keywords1.begin() , keywords1.end());
|
||||
for (const auto& key2: keywords2)
|
||||
keys.insert( key2 );
|
||||
|
||||
for (const auto& key : keys)
|
||||
fprintf(stderr," %8s:%3d %8s:%3d \n",key.c_str() , ecl_file_get_num_named_kw( ecl_file1 , key.c_str()),
|
||||
key.c_str() , ecl_file_get_num_named_kw( ecl_file2 , key.c_str()));
|
||||
|
||||
|
||||
OPM_THROW(std::runtime_error, "\nKeywords in first file: " << keywords1.size()
|
||||
<< "\nKeywords in second file: " << keywords2.size()
|
||||
<< "\nThe number of keywords differ.");
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& it : keywords1)
|
||||
resultsForKeyword(it);
|
||||
|
||||
if (analysis) {
|
||||
std::cout << deviations.size() << " keyword"
|
||||
<< (deviations.size() > 1 ? "s":"") << " exhibit failures" << std::endl;
|
||||
for (const auto& iter : deviations) {
|
||||
std::cout << "\t" << iter.first << std::endl;
|
||||
std::cout << "\t\tFails for " << iter.second.size() << " entries" << std::endl;
|
||||
std::cout.precision(7);
|
||||
double absErr = std::max_element(iter.second.begin(), iter.second.end(),
|
||||
[](const Deviation& a, const Deviation& b)
|
||||
{
|
||||
return a.abs < b.abs;
|
||||
})->abs;
|
||||
double relErr = std::max_element(iter.second.begin(), iter.second.end(),
|
||||
[](const Deviation& a, const Deviation& b)
|
||||
{
|
||||
return a.rel < b.rel;
|
||||
})->rel;
|
||||
std::cout << "\t\tLargest absolute error: "
|
||||
<< std::scientific << absErr << std::endl;
|
||||
std::cout << "\t\tLargest relative error: "
|
||||
<< std::scientific << relErr << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::resultsForKeyword(const std::string& keyword) {
|
||||
keywordValidForComparing(keyword);
|
||||
const unsigned int occurrences1 = ecl_file_get_num_named_kw(ecl_file1, keyword.c_str());
|
||||
const unsigned int occurrences2 = ecl_file_get_num_named_kw(ecl_file2, keyword.c_str());
|
||||
if (!onlyLastOccurrence && occurrences1 != occurrences2) {
|
||||
OPM_THROW(std::runtime_error, "For keyword " << keyword << ":"
|
||||
<< "\nKeyword occurrences in first file: " << occurrences1
|
||||
<< "\nKeyword occurrences in second file: " << occurrences2
|
||||
<< "\nThe number of occurrences differ.");
|
||||
}
|
||||
// Assuming keyword type is constant for every occurrence:
|
||||
const ecl_type_enum kw_type = ecl_type_get_type( ecl_file_iget_named_data_type(ecl_file1, keyword.c_str(), 0) );
|
||||
switch(kw_type) {
|
||||
case ECL_DOUBLE_TYPE:
|
||||
case ECL_FLOAT_TYPE:
|
||||
std::cout << "Comparing " << keyword << "...";
|
||||
if (onlyLastOccurrence) {
|
||||
doubleComparisonForOccurrence(keyword, occurrences1 - 1, occurrences2 - 1);
|
||||
}
|
||||
else {
|
||||
for (unsigned int occurrence = 0; occurrence < occurrences1; ++occurrence) {
|
||||
doubleComparisonForOccurrence(keyword, occurrence, occurrence);
|
||||
}
|
||||
}
|
||||
std::cout << "done." << std::endl;
|
||||
printResultsForKeyword(keyword);
|
||||
absDeviation.clear();
|
||||
relDeviation.clear();
|
||||
return;
|
||||
case ECL_INT_TYPE:
|
||||
std::cout << "Comparing " << keyword << "...";
|
||||
if (onlyLastOccurrence) {
|
||||
intComparisonForOccurrence(keyword, occurrences1 - 1, occurrences2 - 1);
|
||||
}
|
||||
else {
|
||||
for (unsigned int occurrence = 0; occurrence < occurrences1; ++occurrence) {
|
||||
intComparisonForOccurrence(keyword, occurrence, occurrence);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ECL_CHAR_TYPE:
|
||||
std::cout << "Comparing " << keyword << "...";
|
||||
if (onlyLastOccurrence) {
|
||||
charComparisonForOccurrence(keyword, occurrences1 - 1, occurrences2 - 1);
|
||||
}
|
||||
else {
|
||||
for (unsigned int occurrence = 0; occurrence < occurrences1; ++occurrence) {
|
||||
charComparisonForOccurrence(keyword, occurrence, occurrence);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ECL_BOOL_TYPE:
|
||||
std::cout << "Comparing " << keyword << "...";
|
||||
if (onlyLastOccurrence) {
|
||||
boolComparisonForOccurrence(keyword, occurrences1 - 1, occurrences2 - 1);
|
||||
}
|
||||
else {
|
||||
for (unsigned int occurrence = 0; occurrence < occurrences1; ++occurrence) {
|
||||
boolComparisonForOccurrence(keyword, occurrence, occurrence);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ECL_MESS_TYPE:
|
||||
std::cout << "\nKeyword " << keyword << " is of type MESS"
|
||||
<< ", which is not supported in regression test." << "\n\n";
|
||||
return;
|
||||
default:
|
||||
std::cout << "\nKeyword " << keyword << "has undefined type." << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout << "done." << std::endl;
|
||||
}
|
||||
93
examples/test_util/EclRegressionTest.hpp
Normal file
93
examples/test_util/EclRegressionTest.hpp
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ECLREGRESSIONTEST_HPP
|
||||
#define ECLREGRESSIONTEST_HPP
|
||||
|
||||
#include "EclFilesComparator.hpp"
|
||||
|
||||
/*! \brief A class for executing a regression test for two ECLIPSE files.
|
||||
\details This class inherits from ECLFilesComparator, which opens and
|
||||
closes the input cases and stores keywordnames.
|
||||
The three public functions gridCompare(), results() and
|
||||
resultsForKeyword() can be invoked to compare griddata
|
||||
or keyworddata for all keywords or a given keyword (resultsForKeyword()).
|
||||
*/
|
||||
|
||||
class ECLRegressionTest: public ECLFilesComparator {
|
||||
private:
|
||||
// These vectors store absolute and relative deviations, respecively. Note that they are whiped clean for every new keyword comparison.
|
||||
std::vector<double> absDeviation, relDeviation;
|
||||
// Keywords which should not contain negative values, i.e. uses allowNegativeValues = false in deviationsForCell():
|
||||
const std::vector<std::string> keywordDisallowNegatives = {"SGAS", "SWAT", "PRESSURE"};
|
||||
|
||||
// Only compare last occurrence
|
||||
bool onlyLastOccurrence = false;
|
||||
|
||||
// Accept extra keywords in the restart file of the 'new' simulation.
|
||||
bool acceptExtraKeywords = false;
|
||||
|
||||
|
||||
// Prints results stored in absDeviation and relDeviation.
|
||||
void printResultsForKeyword(const std::string& keyword) const;
|
||||
|
||||
// Function which compares data at specific occurrences and for a specific keyword type. The functions takes two occurrence inputs to also be able to
|
||||
// compare keywords which are shifted relative to each other in the two files. This is for instance handy when running flow with restart from different timesteps,
|
||||
// and comparing the last timestep from the two runs.
|
||||
void boolComparisonForOccurrence(const std::string& keyword, int occurrence1, int occurrence2) const;
|
||||
void charComparisonForOccurrence(const std::string& keyword, int occurrence1, int occurrence2) const;
|
||||
void intComparisonForOccurrence(const std::string& keyword, int occurrence1, int occurrence2) const;
|
||||
void doubleComparisonForOccurrence(const std::string& keyword, int occurrence1, int occurrence2);
|
||||
// deviationsForCell throws an exception if both the absolute deviation AND the relative deviation
|
||||
// are larger than absTolerance and relTolerance, respectively. In addition,
|
||||
// if allowNegativeValues is passed as false, an exception will be thrown when the absolute value
|
||||
// of a negative value exceeds absTolerance. If no exceptions are thrown, the absolute and relative deviations are added to absDeviation and relDeviation.
|
||||
void deviationsForCell(double val1, double val2, const std::string& keyword, int occurrence1, int occurrence2, size_t kw_size, size_t cell, bool allowNegativeValues = true);
|
||||
public:
|
||||
//! \brief Sets up the regression test.
|
||||
//! \param[in] file_type Specifies which filetype to be compared, possible inputs are UNRSTFILE, INITFILE and RFTFILE.
|
||||
//! \param[in] basename1 Full path without file extension to the first case.
|
||||
//! \param[in] basename2 Full path without file extension to the second case.
|
||||
//! \param[in] absTolerance Tolerance for absolute deviation.
|
||||
//! \param[in] relTolerance Tolerance for relative deviation.
|
||||
//! \details This constructor only calls the constructor of the superclass, see the docs for ECLFilesComparator for more information.
|
||||
ECLRegressionTest(int file_type, const std::string& basename1, const std::string& basename2, double absTolerance, double relTolerance):
|
||||
ECLFilesComparator(file_type, basename1, basename2, absTolerance, relTolerance) {}
|
||||
|
||||
//! \brief Option to only compare last occurrence
|
||||
void setOnlyLastOccurrence(bool onlyLastOccurrenceArg) {this->onlyLastOccurrence = onlyLastOccurrenceArg;}
|
||||
|
||||
// Accept extra keywords: If this switch is set to true the comparison
|
||||
// of restart files will ignore extra keywords which are only present
|
||||
// in the new simulation.
|
||||
void setAcceptExtraKeywords(bool acceptExtraKeywordsArg) { this->acceptExtraKeywords = acceptExtraKeywordsArg; }
|
||||
|
||||
//! \brief Compares grid properties of the two cases.
|
||||
// gridCompare() checks if both the number of active and global cells in the two cases are the same. If they are, and volumecheck is true, all cells are looped over to calculate the cell volume deviation for the two cases. If the both the relative and absolute deviation exceeds the tolerances, an exception is thrown.
|
||||
void gridCompare(const bool volumecheck) const;
|
||||
//! \brief Calculates deviations for all keywords.
|
||||
// This function checks if the number of keywords of the two cases are equal, and if it is, resultsForKeyword() is called for every keyword. If not, an exception is thrown.
|
||||
void results();
|
||||
//! \brief Calculates deviations for a specific keyword.
|
||||
//! \param[in] keyword Keyword which should be compared, if this keyword is absent in one of the cases, an exception will be thrown.
|
||||
//! \details This function loops through every report step and every cell and compares the values for the given keyword from the two input cases. If the absolute or relative deviation between the two values for each step exceeds both the absolute tolerance and the relative tolerance (stored in ECLFilesComparator), an exception is thrown. In addition, some keywords are marked for "disallow negative values" -- these are SGAS, SWAT and PRESSURE. An exception is thrown if a value of one of these keywords is both negative and has an absolute value larger than the absolute tolerance. If no exceptions are thrown, resultsForKeyword() uses the private member funtion printResultsForKeyword to print the average and median deviations.
|
||||
void resultsForKeyword(const std::string& keyword);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -16,7 +16,11 @@
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <opm/test_util/EclFilesComparator.hpp>
|
||||
#include "EclIntegrationTest.hpp"
|
||||
#include "EclRegressionTest.hpp"
|
||||
#include "summaryIntegrationTest.hpp"
|
||||
#include "summaryRegressionTest.hpp"
|
||||
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
|
||||
#include <ert/util/util.h>
|
||||
@@ -29,32 +33,40 @@
|
||||
#include <getopt.h>
|
||||
|
||||
static void printHelp() {
|
||||
std::cout << "\ncompareECL compares ECLIPSE files (restart (.RST), unified restart (.UNRST), initial (.INIT) or .RFT) and gridsizes (from .EGRID or .GRID file) from two simulations.\n"
|
||||
std::cout << "\ncompareECL compares ECLIPSE files (restart (.RST), unified restart (.UNRST), initial (.INIT), summary (.SMRY), unified summary (.UNSMRY) or .RFT) and gridsizes (from .EGRID or .GRID file) from two simulations.\n"
|
||||
<< "The program takes four arguments:\n\n"
|
||||
<< "1. Case number 1 (full path without extension)\n"
|
||||
<< "2. Case number 2 (full path without extension)\n"
|
||||
<< "3. Absolute tolerance\n"
|
||||
<< "4. Relative tolerance (between 0 and 1)\n\n"
|
||||
<< "In addition, the program takes these options (which must be given before the arguments):\n\n"
|
||||
<< "-a Run a full analysis of errors.\n"
|
||||
<< "-g Will print the vector with the greatest error ratio.\n"
|
||||
<< "-h Print help and exit.\n"
|
||||
<< "-i Execute integration test (regression test is default).\n"
|
||||
<< " The integration test compares SGAS, SWAT and PRESSURE in unified restart files, so this option can not be used in combination with -t.\n"
|
||||
<< "-I Same as -i, but throws an exception when the number of keywords in the two cases differ. Can not be used in combination with -t.\n"
|
||||
<< "-k Specify specific keyword to compare (capitalized), for example -k PRESSURE.\n"
|
||||
<< "-K Will not allow different amount of keywords in the two files. Throws an exception if the amount are different.\n"
|
||||
<< "-l Only do comparison for the last occurrence. This option is only for the regression test, and can therefore not be used in combination with -i or -I.\n"
|
||||
<< "-m mainVar. Will calculate the error ratio for one main variable. Valid input is WOPR, WWPR, WGPR or WBHP.\n"
|
||||
<< "-n Do not throw on errors.\n"
|
||||
<< "-p Print keywords in both cases and exit. Can not be used in combination with -P.\n"
|
||||
<< "-P Print common and uncommon keywords in both cases and exit. Can not be used in combination with -p.\n"
|
||||
<< "-R Will allow comparison between a restarted simulation and a normal simulation for summary regression tests. The files must end at the same time.\n"
|
||||
<< "-s int Sets the number of spikes that are allowed for each keyword in summary integration tests.\n"
|
||||
<< "-t Specify ECLIPSE filetype to compare (unified restart is default). Can not be used in combination with -i or -I. Different possible arguments are:\n"
|
||||
<< " -t UNRST \t Compare two unified restart files (.UNRST). This the default value, so it is the same as not passing option -t.\n"
|
||||
<< " -t INIT \t Compare two initial files (.INIT).\n"
|
||||
<< " -t RFT \t Compare two RFT files (.RFT).\n"
|
||||
<< " -t RST \t Compare two cases consisting of restart files (.Xnnnn).\n"
|
||||
<< " -t SMRY \t Compare two cases consistent of (unified) summary files.\n"
|
||||
<< " -t RST1 \t Compare two cases where the first case consists of restart files (.Xnnnn), and the second case consists of a unified restart file (.UNRST).\n"
|
||||
<< " -t RST2 \t Compare two cases where the first case consists of a unified restart file (.UNRST), and the second case consists of restart files (.Xnnnn).\n"
|
||||
<< " Note that when dealing with restart files (.Xnnnn), the program concatenates all of them into one unified restart file, which is used for comparison and stored in the same directory as the restart files.\n"
|
||||
<< " This will overwrite any existing unified restart file in that directory.\n\n"
|
||||
<< "Example usage of the program: \n\n"
|
||||
<< "-v For the rate keywords WOPR, WGPR, WWPR and WBHP. Calculates the error volume of the two summary files. This is printed to screen.\n"
|
||||
<< "\nExample usage of the program: \n\n"
|
||||
<< "compareECL -k PRESSURE <path to first casefile> <path to second casefile> 1e-3 1e-5\n"
|
||||
<< "compareECL -t INIT -k PORO <path to first casefile> <path to second casefile> 1e-3 1e-5\n"
|
||||
<< "compareECL -i <path to first casefile> <path to second casefile> 0.01 1e-6\n\n"
|
||||
@@ -107,19 +119,37 @@ int main(int argc, char** argv) {
|
||||
ecl_file_enum file_type = ECL_UNIFIED_RESTART_FILE;
|
||||
// RegressionTest is default
|
||||
bool integrationTest = false;
|
||||
bool allowDifferentAmount = true;
|
||||
bool checkNumKeywords = false;
|
||||
bool findGreatestErrorRatio = false;
|
||||
bool findVolumeError = false;
|
||||
bool onlyLastOccurrence = false;
|
||||
bool printKeywords = false;
|
||||
bool printKeywordsDifference = false;
|
||||
bool restartFile = false;
|
||||
bool specificKeyword = false;
|
||||
bool specificFileType = false;
|
||||
bool allowSpikes = false;
|
||||
bool throwOnError = true;
|
||||
bool throwTooGreatErrorRatio = true;
|
||||
bool acceptExtraKeywords = false;
|
||||
bool analysis = false;
|
||||
bool volumecheck = true;
|
||||
char* keyword = nullptr;
|
||||
char* fileTypeCstr = nullptr;
|
||||
const char* mainVariable = nullptr;
|
||||
int c = 0;
|
||||
int spikeLimit = -1;
|
||||
|
||||
while ((c = getopt(argc, argv, "hiIk:lnpPt:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "hiIk:alnpPt:VRgs:m:vKx")) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
analysis = true;
|
||||
break;
|
||||
case 'g':
|
||||
findGreatestErrorRatio = true;
|
||||
throwTooGreatErrorRatio = false;
|
||||
break;
|
||||
case 'h':
|
||||
printHelp();
|
||||
return 0;
|
||||
@@ -130,29 +160,51 @@ int main(int argc, char** argv) {
|
||||
integrationTest = true;
|
||||
checkNumKeywords = true;
|
||||
break;
|
||||
case 'n':
|
||||
throwOnError = false;
|
||||
break;
|
||||
case 'k':
|
||||
specificKeyword = true;
|
||||
keyword = optarg;
|
||||
break;
|
||||
case 'K':
|
||||
allowDifferentAmount = false;
|
||||
break;
|
||||
case 'l':
|
||||
onlyLastOccurrence = true;
|
||||
break;
|
||||
case 'm':
|
||||
mainVariable = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
throwOnError = false;
|
||||
break;
|
||||
case 'p':
|
||||
printKeywords = true;
|
||||
break;
|
||||
case 'P':
|
||||
printKeywordsDifference = true;
|
||||
break;
|
||||
case 'R':
|
||||
restartFile = true;
|
||||
break;
|
||||
case 's':
|
||||
allowSpikes = true;
|
||||
spikeLimit = atof(optarg);
|
||||
break;
|
||||
case 't':
|
||||
specificFileType = true;
|
||||
fileTypeCstr = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
findVolumeError = true;
|
||||
break;
|
||||
case 'V':
|
||||
volumecheck = false;
|
||||
break;
|
||||
case 'x':
|
||||
acceptExtraKeywords = true;
|
||||
break;
|
||||
case '?':
|
||||
if (optopt == 'k') {
|
||||
std::cerr << "Option k requires a keyword as argument, see manual (-h) for more information." << std::endl;
|
||||
if (optopt == 'k' || optopt == 'm' || optopt == 's') {
|
||||
std::cerr << "Option " << optopt << " requires a keyword as argument, see manual (-h) for more information." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else if (optopt == 't') {
|
||||
@@ -181,6 +233,7 @@ int main(int argc, char** argv) {
|
||||
<< "Please run compareECL -h to see manual." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::string basename1 = argv[argOffset];
|
||||
std::string basename2 = argv[argOffset + 1];
|
||||
double absTolerance = strtod(argv[argOffset + 2], nullptr);
|
||||
@@ -206,15 +259,68 @@ int main(int argc, char** argv) {
|
||||
else if (fileTypeString == "RFT") {
|
||||
file_type = ECL_RFT_FILE;
|
||||
}
|
||||
else if (fileTypeString == "SMRY")
|
||||
file_type = ECL_SUMMARY_FILE;
|
||||
else {
|
||||
std::cerr << "Unknown ECLIPSE filetype specified with option -t. Please run compareECL -h to see manual." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (restartFile && (file_type != ECL_SUMMARY_FILE || integrationTest)) {
|
||||
std::cerr << "Error: -R can only be used in for summary regression tests." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::cout << "Comparing '" << basename1 << "' to '" << basename2 << "'." << std::endl;
|
||||
try {
|
||||
if (integrationTest) {
|
||||
IntegrationTest comparator(basename1, basename2, absTolerance, relTolerance);
|
||||
if (file_type == ECL_SUMMARY_FILE) {
|
||||
if(!integrationTest){
|
||||
SummaryRegressionTest compare(basename1,basename2,absTolerance,relTolerance);
|
||||
compare.throwOnErrors(throwOnError);
|
||||
compare.doAnalysis(analysis);
|
||||
compare.setPrintKeywords(printKeywords);
|
||||
compare.setIsRestartFile(restartFile);
|
||||
compare.setAllowDifferentNumberOfKeywords(acceptExtraKeywords);
|
||||
if(specificKeyword){
|
||||
compare.getRegressionTest(keyword);
|
||||
}
|
||||
else{
|
||||
compare.setPrintKeywords(printKeywords);
|
||||
compare.getRegressionTest();
|
||||
}
|
||||
} else {
|
||||
SummaryIntegrationTest compare(basename1,basename2,absTolerance,relTolerance);
|
||||
compare.throwOnErrors(throwOnError);
|
||||
compare.setFindVectorWithGreatestErrorRatio(findGreatestErrorRatio);
|
||||
compare.setAllowSpikes(allowSpikes);
|
||||
if (mainVariable) {
|
||||
compare.setOneOfTheMainVariables(true);
|
||||
std::string str(mainVariable);
|
||||
std::transform(str.begin(), str.end(),str.begin(), ::toupper);
|
||||
if(str == "WOPR" ||str=="WWPR" ||str=="WGPR" || str == "WBHP"){
|
||||
compare.setMainVariable(str);
|
||||
}else{
|
||||
throw std::invalid_argument("The input is not a main variable. -m option requires a valid main variable.");
|
||||
}
|
||||
}
|
||||
compare.setFindVolumeError(findVolumeError);
|
||||
if (spikeLimit != -1) {
|
||||
compare.setSpikeLimit(spikeLimit);
|
||||
}
|
||||
compare.setAllowDifferentAmountOfKeywords(allowDifferentAmount);
|
||||
compare.setPrintKeywords(printKeywords);
|
||||
compare.setThrowExceptionForTooGreatErrorRatio(throwTooGreatErrorRatio);
|
||||
if(specificKeyword){
|
||||
compare.setPrintSpecificKeyword(specificKeyword);
|
||||
compare.getIntegrationTest(keyword);
|
||||
return 0;
|
||||
}
|
||||
compare.getIntegrationTest();
|
||||
}
|
||||
}
|
||||
else if (integrationTest) {
|
||||
ECLIntegrationTest comparator(basename1, basename2, absTolerance, relTolerance);
|
||||
if (printKeywords) {
|
||||
comparator.printKeywords();
|
||||
return 0;
|
||||
@@ -240,8 +346,10 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
RegressionTest comparator(file_type, basename1, basename2, absTolerance, relTolerance);
|
||||
ECLRegressionTest comparator(file_type, basename1, basename2, absTolerance, relTolerance);
|
||||
comparator.throwOnErrors(throwOnError);
|
||||
comparator.doAnalysis(analysis);
|
||||
comparator.setAcceptExtraKeywords(acceptExtraKeywords);
|
||||
if (printKeywords) {
|
||||
comparator.printKeywords();
|
||||
return 0;
|
||||
@@ -254,11 +362,11 @@ int main(int argc, char** argv) {
|
||||
comparator.setOnlyLastOccurrence(true);
|
||||
}
|
||||
if (specificKeyword) {
|
||||
comparator.gridCompare();
|
||||
comparator.gridCompare(volumecheck);
|
||||
comparator.resultsForKeyword(keyword);
|
||||
}
|
||||
else {
|
||||
comparator.gridCompare();
|
||||
comparator.gridCompare(volumecheck);
|
||||
comparator.results();
|
||||
}
|
||||
if (comparator.getNoErrors() > 0)
|
||||
|
||||
@@ -1,223 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify it under the terms
|
||||
of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <opm/test_util/summaryRegressionTest.hpp>
|
||||
#include <opm/test_util/summaryIntegrationTest.hpp>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <getopt.h>
|
||||
|
||||
void printHelp(){
|
||||
std::cout << "\n\nThe program can handle both unified and non-unified summary files."<< std::endl;
|
||||
std::cout <<"In the case of non-unified summary files all the files must be located in the same directory. Only the basename (full path without extension) is needed as input." << std::endl << std::endl;
|
||||
std::cout << "\nThe program takes four arguments" << std::endl;
|
||||
std::cout << "1) <path to file1>/<base_name>, basename without extension" << std::endl;
|
||||
std::cout << "2) <path to file2>/<base_name>, basename without extension" << std::endl;
|
||||
std::cout << "3) absolute tolerance" << std::endl;
|
||||
std::cout << "4) relative tolerance (between 0 and 1)" << std::endl;
|
||||
std::cout << "The program will only throw an exception when both the absolute and relative tolerance are exceeded." << std::endl;
|
||||
std::cout << "The program is capable of performing both a regression test and an integration test, \nhowever only one type of test at a time. ";
|
||||
std::cout << "By default the program will run a regression test."<< std::endl;
|
||||
std::cout << "\nThe program have command line options:" << std::endl;
|
||||
std::cout << "-h \t\tPrint help message." << std::endl << std::endl;
|
||||
std::cout << "For the regression test: " << std::endl;
|
||||
std::cout << "-r \t\tChoosing regression test (this is default)."<< std::endl;
|
||||
std::cout << "-k keyword \tSpecify a specific keyword to compare, for example - k WOPR:PRODU1."<< std::endl;
|
||||
std::cout << "-p \t\tWill print the keywords of the files." << std::endl;
|
||||
std::cout << "-R \t\tWill allow comparison between a restarted simulation and a normal simulation. The files must end at the same time." << std::endl << std::endl;
|
||||
std::cout << "For the integration test:"<< std::endl;
|
||||
std::cout << "-i \t\tChoosing integration test." << std::endl;
|
||||
std::cout << "-d \t\tThe program will not throw an exception when the volume error ratio exceeds the limit." << std::endl;
|
||||
std::cout << "-g \t\tWill print the vector with the greatest error ratio." << std::endl;
|
||||
std::cout << "-k keyword \tSpecify a specific keyword to compare, for example - k WOPR:PRODU1."<< std::endl;
|
||||
std::cout << "-K \t\tWill not allow different amount of keywords in the two files. Throws an exception if the amount are different." << std::endl;
|
||||
std::cout << "-m mainVar \tWill calculate the error ratio for one main variable. Valid input is WOPR, WWPR, WGPR or WBHP." << std::endl;
|
||||
std::cout << "-n \tDo not throw on errors." << std::endl;
|
||||
std::cout << "-p \t\tWill print the keywords of the files." << std::endl;
|
||||
std::cout << "-P keyword \tWill print the summary vectors of a specified kewyord, for example -P WOPR:B-3H." << std::endl;
|
||||
std::cout << "-s int \t\tSets the number of spikes that are allowed for each keyword, for example: -s 5." << std::endl;
|
||||
std::cout << "-v \t\tFor the rate keywords WOPR, WGPR, WWPR and WBHP. Calculates the error volume of \n\t\tthe two summary files. This is printed to screen." << std::endl;
|
||||
std::cout << "-V keyword \tWill calculate the error rate for a specific keyword." << std::endl << std::endl;
|
||||
std::cout << "Suggested combination of command line options:"<< std::endl;
|
||||
std::cout << " -i -g -m mainVariable, will print the vector which have the greatest error ratio of the main variable of interest.\n"<< std::endl;
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
|
||||
|
||||
int main (int argc, char ** argv){
|
||||
|
||||
//------------------------------------------------
|
||||
//Defines some constants
|
||||
bool specificKeyword = false;
|
||||
bool allowSpikes = false;
|
||||
bool findVolumeError = false;
|
||||
bool integrationTest = false;
|
||||
bool regressionTest = true;
|
||||
bool allowDifferentAmountOfKeywords = true;
|
||||
bool printKeywords = false;
|
||||
bool printSpecificKeyword = false;
|
||||
bool findVectorWithGreatestErrorRatio = false;
|
||||
bool oneOfTheMainVariables = false;
|
||||
bool throwExceptionForTooGreatErrorRatio = true;
|
||||
bool isRestartFile = false;
|
||||
bool throwOnError = true;
|
||||
const char* keyword = nullptr;
|
||||
const char* mainVariable = nullptr;
|
||||
int c = 0;
|
||||
int limit = -1;
|
||||
//------------------------------------------------
|
||||
|
||||
//------------------------------------------------
|
||||
//For setting the options selected
|
||||
while ((c = getopt(argc, argv, "dghik:Km:npP:rRs:vV:")) != -1) {
|
||||
switch (c) {
|
||||
case 'd':
|
||||
throwExceptionForTooGreatErrorRatio = false;
|
||||
break;
|
||||
case 'g':
|
||||
findVectorWithGreatestErrorRatio = true;
|
||||
throwExceptionForTooGreatErrorRatio = false;
|
||||
break;
|
||||
case 'h':
|
||||
printHelp();
|
||||
return 0;
|
||||
case 'i':
|
||||
integrationTest = true;
|
||||
regressionTest = false;
|
||||
break;
|
||||
case 'k':
|
||||
specificKeyword = true;
|
||||
keyword = optarg;
|
||||
break;
|
||||
case 'K':
|
||||
allowDifferentAmountOfKeywords = false;
|
||||
break;
|
||||
case 'm':
|
||||
oneOfTheMainVariables = true;
|
||||
mainVariable = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
throwOnError = false;
|
||||
break;
|
||||
case 'p':
|
||||
printKeywords = true;
|
||||
break;
|
||||
case 'P':
|
||||
specificKeyword = true;
|
||||
printSpecificKeyword = true;
|
||||
keyword = optarg;
|
||||
break;
|
||||
case 'r':
|
||||
integrationTest = false;
|
||||
regressionTest = true;
|
||||
break;
|
||||
case 'R':
|
||||
isRestartFile = true;
|
||||
break;
|
||||
case 's':
|
||||
allowSpikes = true;
|
||||
limit = atof(optarg);
|
||||
break;
|
||||
case 'v':
|
||||
findVolumeError = true;
|
||||
break;
|
||||
case 'V':
|
||||
findVolumeError = true;
|
||||
specificKeyword = true;
|
||||
keyword = optarg;
|
||||
break;
|
||||
case '?':
|
||||
if (optopt == 'k' || optopt == 'm' || optopt == 'P'
|
||||
|| optopt == 's' || optopt == 'V') {
|
||||
std::cout << "Option -"<<optopt<<" requires an keyword." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else {
|
||||
std::cout << "Unknown option." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
default:
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------
|
||||
|
||||
int argOffset = optind;
|
||||
if (argc != argOffset + 4) {
|
||||
printHelp();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
const char * basename1 = argv[argOffset];
|
||||
const char * basename2 = argv[argOffset+1];
|
||||
double absoluteTolerance = strtod(argv[argOffset+2], nullptr);
|
||||
double relativeTolerance = strtod(argv[argOffset+3], nullptr);
|
||||
|
||||
std::cout << "Comparing '" << basename1 << "' to '" << basename2 << "'." << std::endl;
|
||||
|
||||
try {
|
||||
if(regressionTest){
|
||||
RegressionTest compare(basename1,basename2, absoluteTolerance, relativeTolerance);
|
||||
compare.throwOnErrors(throwOnError);
|
||||
if(printKeywords){compare.setPrintKeywords(true);}
|
||||
if(isRestartFile){compare.setIsRestartFile(true);}
|
||||
if(specificKeyword){
|
||||
compare.getRegressionTest(keyword);
|
||||
}
|
||||
else{
|
||||
if(printKeywords){compare.setPrintKeywords(true);}
|
||||
compare.getRegressionTest();
|
||||
}
|
||||
}
|
||||
if(integrationTest){
|
||||
IntegrationTest compare(basename1,basename2, absoluteTolerance, relativeTolerance);
|
||||
compare.throwOnErrors(throwOnError);
|
||||
if(findVectorWithGreatestErrorRatio){compare.setFindVectorWithGreatestErrorRatio(true);}
|
||||
if(allowSpikes){compare.setAllowSpikes(true);}
|
||||
if(oneOfTheMainVariables){
|
||||
compare.setOneOfTheMainVariables(true);
|
||||
std::string str(mainVariable);
|
||||
std::transform(str.begin(), str.end(),str.begin(), ::toupper);
|
||||
if(str == "WOPR" ||str=="WWPR" ||str=="WGPR" || str == "WBHP"){
|
||||
compare.setMainVariable(str);
|
||||
}else{
|
||||
throw std::invalid_argument("The input is not a main variable. -m option requires a valid main variable.");
|
||||
}
|
||||
}
|
||||
if(findVolumeError){compare.setFindVolumeError(true);}
|
||||
if(limit != -1){compare.setSpikeLimit(limit);}
|
||||
if(!allowDifferentAmountOfKeywords){compare.setAllowDifferentAmountOfKeywords(false);}
|
||||
if(printKeywords){compare.setPrintKeywords(true);}
|
||||
if(!throwExceptionForTooGreatErrorRatio){compare.setThrowExceptionForTooGreatErrorRatio(false);}
|
||||
if(specificKeyword){
|
||||
if(printSpecificKeyword){compare.setPrintSpecificKeyword(true);}
|
||||
compare.getIntegrationTest(keyword);
|
||||
return 0;
|
||||
}
|
||||
compare.getIntegrationTest();
|
||||
}
|
||||
}
|
||||
catch(const std::exception& e) {
|
||||
std::cerr << "Program threw an exception: " << e.what() << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
54
examples/test_util/data/EclIOdata.hpp
Normal file
54
examples/test_util/data/EclIOdata.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright 2019 Equinor ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_ECLIO_DATA_HPP
|
||||
#define OPM_ECLIO_DATA_HPP
|
||||
|
||||
#include <tuple>
|
||||
|
||||
|
||||
namespace Opm {
|
||||
|
||||
namespace ecl {
|
||||
|
||||
// type MESS have no assisiated data
|
||||
|
||||
enum eclArrType {
|
||||
INTE, REAL, DOUB, CHAR, LOGI, MESS
|
||||
};
|
||||
|
||||
const unsigned int true_value = 0xffffffff;
|
||||
const unsigned int false_value = 0x00000000;
|
||||
|
||||
const int sizeOfInte = 4; // number of bytes pr integer (inte) element
|
||||
const int sizeOfReal = 4; // number of bytes pr float (real) element
|
||||
const int sizeOfDoub = 8; // number of bytes pr double (doub) element
|
||||
const int sizeOfLogi = 4; // number of bytes pr bool (logi) element
|
||||
const int sizeOfChar = 8; // number of bytes pr string (char) element
|
||||
|
||||
const int MaxBlockSizeInte = 4000; // Maximum block size for INTE arrays in binary files
|
||||
const int MaxBlockSizeReal = 4000; // Maximum block size for REAL arrays in binary files
|
||||
const int MaxBlockSizeDoub = 8000; // Maximum block size for DOUB arrays in binary files
|
||||
const int MaxBlockSizeLogi = 4000; // Maximum block size for LOGI arrays in binary files
|
||||
const int MaxBlockSizeChar = 840; // Maximum block size for CHAR arrays in binary files
|
||||
|
||||
} // ecl
|
||||
} // Opm
|
||||
|
||||
#endif // OPM_ECLIO_DATA_HPP
|
||||
@@ -16,18 +16,20 @@
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <opm/test_util/summaryComparator.hpp>
|
||||
#include <ert/ecl/ecl_sum.h>
|
||||
#include <ert/util/stringlist.h>
|
||||
#include <ert/util/int_vector.h>
|
||||
#include <ert/util/bool_vector.h>
|
||||
#include "summaryComparator.hpp"
|
||||
#include <ert/ecl/ecl_sum.hpp>
|
||||
#include <ert/util/stringlist.hpp>
|
||||
#include <ert/util/int_vector.hpp>
|
||||
#include <ert/util/bool_vector.hpp>
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <cmath>
|
||||
#include <numeric>
|
||||
|
||||
SummaryComparator::SummaryComparator(const char* basename1, const char* basename2, double absoluteTol, double relativeTol){
|
||||
ecl_sum1 = ecl_sum_fread_alloc_case(basename1, ":");
|
||||
ecl_sum2 = ecl_sum_fread_alloc_case(basename2, ":");
|
||||
SummaryComparator::SummaryComparator(const std::string& basename1,
|
||||
const std::string& basename2,
|
||||
double absoluteTol, double relativeTol){
|
||||
ecl_sum1 = ecl_sum_fread_alloc_case(basename1.c_str(), ":");
|
||||
ecl_sum2 = ecl_sum_fread_alloc_case(basename2.c_str(), ":");
|
||||
if (ecl_sum1 == nullptr || ecl_sum2 == nullptr) {
|
||||
OPM_THROW(std::runtime_error, "Not able to open files");
|
||||
}
|
||||
@@ -20,8 +20,10 @@
|
||||
#ifndef SUMMARYCOMPARATOR_HPP
|
||||
#define SUMMARYCOMPARATOR_HPP
|
||||
|
||||
#include "Deviation.hpp"
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
@@ -46,13 +48,6 @@ struct ecl_sum_struct;
|
||||
typedef struct ecl_sum_struct ecl_sum_type;
|
||||
|
||||
|
||||
//! \brief Struct for storing the deviation between two values.
|
||||
struct Deviation {
|
||||
double abs = 0;//!< The absolute deviation
|
||||
double rel = 0; //!< The relative deviation
|
||||
};
|
||||
|
||||
|
||||
class SummaryComparator {
|
||||
private:
|
||||
double absoluteTolerance = 0; //!< The maximum absolute deviation that is allowed between two values.
|
||||
@@ -73,6 +68,8 @@ class SummaryComparator {
|
||||
bool printKeyword = false; //!< Boolean value for choosing whether to print the keywords or not
|
||||
bool printSpecificKeyword = false; //!< Boolean value for choosing whether to print the vectors of a keyword or not
|
||||
bool throwOnError = true; //!< Throw on first error
|
||||
bool analysis = false; //!< Perform error analysis
|
||||
std::map<std::string, std::vector<Deviation>> deviations;
|
||||
|
||||
//! \brief Calculate deviation between two data values and stores it in a Deviation struct.
|
||||
//! \param[in] refIndex Index in reference data
|
||||
@@ -142,7 +139,9 @@ class SummaryComparator {
|
||||
//! \param[in] absoluteTolerance The absolute tolerance which is to be used in the test.
|
||||
//! \param[in] relativeTolerance The relative tolerance which is to be used in the test.
|
||||
//! \details The constructor creates an object of the class, and openes the files, an exception is thrown if the opening of the files fails. \n It creates stringlists, in which keywords are to be stored, and figures out which keylist that contains the more/less keywords. \n Also the private member variables aboluteTolerance and relativeTolerance are set.
|
||||
SummaryComparator(const char* basename1, const char* basename2, double absoluteTolerance, double relativeTolerance);
|
||||
SummaryComparator(const std::string& basename1,
|
||||
const std::string& basename2,
|
||||
double absoluteTolerance, double relativeTolerance);
|
||||
|
||||
//! \brief Destructor
|
||||
//! \details The destructor takes care of the allocated memory in which data has been stored.
|
||||
@@ -175,6 +174,9 @@ class SummaryComparator {
|
||||
|
||||
//! \brief Set whether to throw on errors or not.
|
||||
void throwOnErrors(bool dothrow) { throwOnError = dothrow; }
|
||||
|
||||
//! \brief Set whether or not to perform error analysis.
|
||||
void doAnalysis(bool analyse) { analysis = analyse; }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -17,14 +17,14 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <opm/test_util/summaryIntegrationTest.hpp>
|
||||
#include "summaryIntegrationTest.hpp"
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <ert/ecl/ecl_sum.h>
|
||||
#include <ert/util/stringlist.h>
|
||||
#include <ert/ecl/ecl_sum.hpp>
|
||||
#include <ert/util/stringlist.hpp>
|
||||
#include <cmath>
|
||||
|
||||
|
||||
void IntegrationTest::getIntegrationTest(){
|
||||
void SummaryIntegrationTest::getIntegrationTest(){
|
||||
std::vector<double> timeVec1, timeVec2;
|
||||
setTimeVecs(timeVec1, timeVec2); // Sets the time vectors, they are equal for all keywords (WPOR:PROD01 etc)
|
||||
setDataSets(timeVec1, timeVec2);
|
||||
@@ -89,7 +89,7 @@ void IntegrationTest::getIntegrationTest(){
|
||||
}
|
||||
|
||||
|
||||
void IntegrationTest::getIntegrationTest(const char* keyword){
|
||||
void SummaryIntegrationTest::getIntegrationTest(const char* keyword){
|
||||
if(stringlist_contains(keysShort,keyword) && stringlist_contains(keysLong, keyword)){
|
||||
std::vector<double> timeVec1, timeVec2;
|
||||
setTimeVecs(timeVec1, timeVec2); // Sets the time vectors, they are equal for all keywords (WPOR:PROD01 etc)
|
||||
@@ -115,9 +115,9 @@ void IntegrationTest::getIntegrationTest(const char* keyword){
|
||||
}
|
||||
|
||||
|
||||
void IntegrationTest::checkForKeyword(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const char* keyword){
|
||||
void SummaryIntegrationTest::checkForKeyword(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const char* keyword){
|
||||
std::vector<double> dataVec1, dataVec2;
|
||||
getDataVecs(dataVec1,dataVec2,keyword);
|
||||
chooseReference(timeVec1, timeVec2,dataVec1,dataVec2);
|
||||
@@ -130,7 +130,7 @@ void IntegrationTest::checkForKeyword(const std::vector<double>& timeVec1,
|
||||
}
|
||||
|
||||
|
||||
int IntegrationTest::checkDeviation(const Deviation& deviation){
|
||||
int SummaryIntegrationTest::checkDeviation(const Deviation& deviation){
|
||||
double absTol = getAbsTolerance();
|
||||
double relTol = getRelTolerance();
|
||||
if (deviation.rel> relTol && deviation.abs > absTol){
|
||||
@@ -140,10 +140,10 @@ int IntegrationTest::checkDeviation(const Deviation& deviation){
|
||||
}
|
||||
|
||||
|
||||
void IntegrationTest::findGreatestErrorRatio(const WellProductionVolume& volume,
|
||||
double &greatestRatio,
|
||||
const char* currentKeyword,
|
||||
std::string &greatestErrorRatio){
|
||||
void SummaryIntegrationTest::findGreatestErrorRatio(const WellProductionVolume& volume,
|
||||
double &greatestRatio,
|
||||
const char* currentKeyword,
|
||||
std::string &greatestErrorRatio){
|
||||
if (volume.total != 0 && (volume.total - volume.error > getAbsTolerance()) ){
|
||||
if(volume.error/volume.total > greatestRatio){
|
||||
greatestRatio = volume.error/volume.total;
|
||||
@@ -154,14 +154,11 @@ void IntegrationTest::findGreatestErrorRatio(const WellProductionVolume& volume,
|
||||
}
|
||||
|
||||
|
||||
void IntegrationTest::volumeErrorCheck(const char* keyword){
|
||||
const smspec_node_type * node = ecl_sum_get_general_var_node (ecl_sum_fileShort ,keyword);//doesn't matter which ecl_sum_file one uses, the kewyord SHOULD be equal in terms of smspec data.
|
||||
bool hist = smspec_node_is_historical(node);
|
||||
/* returns true if the keyword corresponds to a summary vector "history".
|
||||
E.g. WOPRH, where the last character, 'H', indicates that it is a HISTORY vector.*/
|
||||
if(hist){
|
||||
return;//To make sure we do not include history vectors.
|
||||
}
|
||||
void SummaryIntegrationTest::volumeErrorCheck(const char* keyword){
|
||||
const ecl::smspec_node * node = ecl_sum_get_general_var_node (ecl_sum_fileShort ,keyword);//doesn't matter which ecl_sum_file one uses, the kewyord SHOULD be equal in terms of smspec data.
|
||||
if (node->is_historical())
|
||||
return;
|
||||
|
||||
if (!mainVariable.empty()){
|
||||
std::string keywordString(keyword);
|
||||
std::string firstFour = keywordString.substr(0,4);
|
||||
@@ -199,7 +196,7 @@ void IntegrationTest::volumeErrorCheck(const char* keyword){
|
||||
}
|
||||
|
||||
|
||||
void IntegrationTest::updateVolumeError(const char* keyword){
|
||||
void SummaryIntegrationTest::updateVolumeError(const char* keyword){
|
||||
std::string keywordString(keyword);
|
||||
std::string firstFour = keywordString.substr(0,4);
|
||||
|
||||
@@ -223,7 +220,7 @@ void IntegrationTest::updateVolumeError(const char* keyword){
|
||||
}
|
||||
|
||||
|
||||
WellProductionVolume IntegrationTest::getWellProductionVolume(const char * keyword){
|
||||
WellProductionVolume SummaryIntegrationTest::getWellProductionVolume(const char * keyword){
|
||||
double total = integrate(*referenceVec, *referenceDataVec);
|
||||
double error = integrateError(*referenceVec, *referenceDataVec,
|
||||
*checkVec, *checkDataVec);
|
||||
@@ -239,7 +236,7 @@ WellProductionVolume IntegrationTest::getWellProductionVolume(const char * keywo
|
||||
}
|
||||
|
||||
|
||||
void IntegrationTest::evaluateWellProductionVolume(){
|
||||
void SummaryIntegrationTest::evaluateWellProductionVolume(){
|
||||
if(mainVariable.empty()){
|
||||
double ratioWOP, ratioWWP, ratioWGP, ratioWBHP;
|
||||
ratioWOP = WOP.error/WOP.total;
|
||||
@@ -266,7 +263,7 @@ void IntegrationTest::evaluateWellProductionVolume(){
|
||||
}
|
||||
|
||||
|
||||
void IntegrationTest::checkWithSpikes(const char* keyword){
|
||||
void SummaryIntegrationTest::checkWithSpikes(const char* keyword){
|
||||
int errorOccurrences = 0;
|
||||
size_t jvar = 0 ;
|
||||
bool spikeCurrent = false;
|
||||
@@ -295,9 +292,9 @@ void IntegrationTest::checkWithSpikes(const char* keyword){
|
||||
|
||||
|
||||
WellProductionVolume
|
||||
IntegrationTest::getSpecificWellVolume(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const char* keyword){
|
||||
SummaryIntegrationTest::getSpecificWellVolume(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const char* keyword){
|
||||
std::vector<double> dataVec1, dataVec2;
|
||||
getDataVecs(dataVec1,dataVec2,keyword);
|
||||
chooseReference(timeVec1, timeVec2,dataVec1,dataVec2);
|
||||
@@ -305,20 +302,8 @@ IntegrationTest::getSpecificWellVolume(const std::vector<double>& timeVec1,
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
bool IntegrationTest::checkUnits(const char * keyword){
|
||||
const smspec_node_type * node1 = ecl_sum_get_general_var_node (ecl_sum_fileShort ,keyword);
|
||||
const smspec_node_type * node2 = ecl_sum_get_general_var_node (ecl_sum_fileLong ,keyword);
|
||||
if(strcmp(smspec_node_get_unit(node1),smspec_node_get_unit(node2)) == 0){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
double IntegrationTest::integrate(const std::vector<double>& timeVec,
|
||||
const std::vector<double>& dataVec){
|
||||
double SummaryIntegrationTest::integrate(const std::vector<double>& timeVec,
|
||||
const std::vector<double>& dataVec){
|
||||
double totalSum = 0;
|
||||
if(timeVec.size() != dataVec.size()){
|
||||
OPM_THROW(std::runtime_error, "The size of the time vector does not match the size of the data vector.");
|
||||
@@ -332,10 +317,10 @@ double IntegrationTest::integrate(const std::vector<double>& timeVec,
|
||||
}
|
||||
|
||||
|
||||
double IntegrationTest::integrateError(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& dataVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const std::vector<double>& dataVec2){
|
||||
double SummaryIntegrationTest::integrateError(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& dataVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const std::vector<double>& dataVec2){
|
||||
// When the data corresponds to a rate the integration will become a Riemann
|
||||
// sum. This function calculates the Riemann sum of the error. The reason why
|
||||
// a Riemann sum is used is because of the way the data is written to file.
|
||||
@@ -17,7 +17,7 @@
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <opm/test_util/summaryComparator.hpp>
|
||||
#include "summaryComparator.hpp"
|
||||
|
||||
//! \brief Struct for storing the total area under a graph.
|
||||
//! \details Used when plotting summary vector against time. In most cases this represents a volume.
|
||||
@@ -35,7 +35,7 @@ struct WellProductionVolume{
|
||||
};
|
||||
|
||||
//! \details The class inherits from the SummaryComparator class, which takes care of all file reading. \n The IntegrationTest class compares values from the two different files and throws exceptions when the deviation is unsatisfying.
|
||||
class IntegrationTest: public SummaryComparator {
|
||||
class SummaryIntegrationTest: public SummaryComparator {
|
||||
private:
|
||||
bool allowSpikes = false; //!< Boolean value, when true checkForSpikes is included as a sub test in the integration test. By default: false.
|
||||
bool findVolumeError = false; //!< Boolean value, when true volumeErrorCheck() is included as a sub test in the integration test. By default: false.
|
||||
@@ -124,8 +124,9 @@ class IntegrationTest: public SummaryComparator {
|
||||
//! \param[in] atol The absolute tolerance which is to be used in the test.
|
||||
//! \param[in] rtol The relative tolerance which is to be used in the test.
|
||||
//! \details The constructor calls the constructor of the super class.
|
||||
IntegrationTest(const char* basename1, const char* basename2,
|
||||
double atol, double rtol) :
|
||||
SummaryIntegrationTest(const std::string& basename1,
|
||||
const std::string& basename2,
|
||||
double atol, double rtol) :
|
||||
SummaryComparator(basename1, basename2, atol, rtol) {}
|
||||
|
||||
//! \brief This function sets the private member variable allowSpikes.
|
||||
@@ -16,19 +16,21 @@
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <opm/test_util/summaryRegressionTest.hpp>
|
||||
#include "summaryRegressionTest.hpp"
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <ert/ecl/ecl_sum.h>
|
||||
#include <ert/ecl/ecl_sum.hpp>
|
||||
#include <ert/util/stringlist.h>
|
||||
#include <string>
|
||||
|
||||
void RegressionTest::getRegressionTest(){
|
||||
void SummaryRegressionTest::getRegressionTest(){
|
||||
std::vector<double> timeVec1, timeVec2;
|
||||
setTimeVecs(timeVec1, timeVec2); // Sets the time vectors, they are equal for all keywords (WPOR:PROD01 etc)
|
||||
setDataSets(timeVec1, timeVec2); //Figures which dataset that contains more/less values pr keyword vector.
|
||||
std::cout << "Comparing " << timeVec1.size() << " steps." << std::endl;
|
||||
int ivar = 0;
|
||||
if(stringlist_get_size(keysShort) != stringlist_get_size(keysLong)){
|
||||
if((! this->allowDifferentNumberOfKeywords) &&
|
||||
(stringlist_get_size(keysShort) != stringlist_get_size(keysLong)))
|
||||
{
|
||||
int missing_count = 0;
|
||||
std::cout << "Keywords missing from one case: " << std::endl;
|
||||
|
||||
@@ -72,15 +74,39 @@ void RegressionTest::getRegressionTest(){
|
||||
}
|
||||
ivar++;
|
||||
}
|
||||
if (analysis) {
|
||||
std::cout << deviations.size() << " summary keyword"
|
||||
<< (deviations.size() > 1 ? "s":"") << " exhibit failures" << std::endl;
|
||||
size_t len = ecl_sum_get_data_length(ecl_sum1);
|
||||
for (const auto& iter : deviations) {
|
||||
std::cout << "\t" << iter.first << std::endl;
|
||||
std::cout << "\t\tFails for " << iter.second.size() << " / " << len << " steps." << std::endl;
|
||||
std::cout.precision(7);
|
||||
double absErr = std::max_element(iter.second.begin(), iter.second.end(),
|
||||
[](const Deviation& a, const Deviation& b)
|
||||
{
|
||||
return a.abs < b.abs;
|
||||
})->abs;
|
||||
double relErr = std::max_element(iter.second.begin(), iter.second.end(),
|
||||
[](const Deviation& a, const Deviation& b)
|
||||
{
|
||||
return a.rel < b.rel;
|
||||
})->rel;
|
||||
std::cout << "\t\tLargest absolute error: "
|
||||
<< std::scientific << absErr << std::endl;
|
||||
std::cout << "\t\tLargest relative error: "
|
||||
<< std::scientific << relErr << std::endl;
|
||||
}
|
||||
}
|
||||
if (throwAtEnd)
|
||||
OPM_THROW(std::runtime_error, "Regression test failed.");
|
||||
else
|
||||
else if (deviations.empty())
|
||||
std::cout << "Regression test succeeded." << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RegressionTest::getRegressionTest(const char* keyword){
|
||||
void SummaryRegressionTest::getRegressionTest(const char* keyword){
|
||||
std::vector<double> timeVec1, timeVec2;
|
||||
setTimeVecs(timeVec1, timeVec2); // Sets the time vectors, they are equal for all keywords (WPOR:PROD01 etc)
|
||||
setDataSets(timeVec1, timeVec2); //Figures which dataset that contains more/less values pr keyword vector.
|
||||
@@ -102,18 +128,22 @@ void RegressionTest::getRegressionTest(const char* keyword){
|
||||
|
||||
|
||||
|
||||
bool RegressionTest::checkDeviation(Deviation deviation, const char* keyword, int refIndex, int checkIndex){
|
||||
bool SummaryRegressionTest::checkDeviation(Deviation deviation, const char* keyword, int refIndex, int checkIndex){
|
||||
double absTol = getAbsTolerance();
|
||||
double relTol = getRelTolerance();
|
||||
|
||||
if (deviation.rel > relTol && deviation.abs > absTol){
|
||||
std::cout << "For keyword " << keyword << std::endl;
|
||||
std::cout << "(days, reference value) and (days, check value) = (" << (*referenceVec)[refIndex] << ", " << (*referenceDataVec)[refIndex]
|
||||
<< ") and (" << (*checkVec)[checkIndex-1] << ", " << (*checkDataVec)[checkIndex-1] << ")\n";
|
||||
// -1 in [checkIndex -1] because checkIndex is updated after leaving getDeviation function
|
||||
std::cout << "The absolute deviation is " << deviation.abs << ". The tolerance limit is " << absTol << std::endl;
|
||||
std::cout << "The relative deviation is " << deviation.rel << ". The tolerance limit is " << relTol << std::endl;
|
||||
HANDLE_ERROR(std::runtime_error, "Deviation exceed the limit.");
|
||||
if (analysis) {
|
||||
deviations[keyword].push_back(deviation);
|
||||
} else {
|
||||
std::cout << "For keyword " << keyword << std::endl;
|
||||
std::cout << "(days, reference value) and (days, check value) = (" << (*referenceVec)[refIndex] << ", " << (*referenceDataVec)[refIndex]
|
||||
<< ") and (" << (*checkVec)[checkIndex-1] << ", " << (*checkDataVec)[checkIndex-1] << ")\n";
|
||||
// -1 in [checkIndex -1] because checkIndex is updated after leaving getDeviation function
|
||||
std::cout << "The absolute deviation is " << deviation.abs << ". The tolerance limit is " << absTol << std::endl;
|
||||
std::cout << "The relative deviation is " << deviation.rel << ". The tolerance limit is " << relTol << std::endl;
|
||||
HANDLE_ERROR(std::runtime_error, "Deviation exceed the limit.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -121,7 +151,7 @@ bool RegressionTest::checkDeviation(Deviation deviation, const char* keyword, in
|
||||
|
||||
|
||||
|
||||
bool RegressionTest::checkForKeyword(std::vector<double>& timeVec1, std::vector<double>& timeVec2, const char* keyword){
|
||||
bool SummaryRegressionTest::checkForKeyword(std::vector<double>& timeVec1, std::vector<double>& timeVec2, const char* keyword){
|
||||
std::vector<double> dataVec1, dataVec2;
|
||||
getDataVecs(dataVec1,dataVec2,keyword);
|
||||
chooseReference(timeVec1, timeVec2,dataVec1,dataVec2);
|
||||
@@ -130,7 +160,7 @@ bool RegressionTest::checkForKeyword(std::vector<double>& timeVec1, std::vector<
|
||||
|
||||
|
||||
|
||||
bool RegressionTest::startTest(const char* keyword){
|
||||
bool SummaryRegressionTest::startTest(const char* keyword){
|
||||
size_t jvar = 0;
|
||||
Deviation deviation;
|
||||
bool result = true;
|
||||
@@ -141,3 +171,8 @@ bool RegressionTest::startTest(const char* keyword){
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void SummaryRegressionTest::setAllowDifferentNumberOfKeywords(const bool allow)
|
||||
{
|
||||
this->allowDifferentNumberOfKeywords = allow;
|
||||
}
|
||||
@@ -20,10 +20,10 @@
|
||||
#ifndef SUMMARYREGRESSIONTEST_HPP
|
||||
#define SUMMARYREGRESSIONTEST_HPP
|
||||
|
||||
#include <opm/test_util/summaryComparator.hpp>
|
||||
#include "summaryComparator.hpp"
|
||||
|
||||
//! \details The class inherits from the SummaryComparator class, which takes care of all file reading. \n The RegressionTest class compares the values from the two different files and throws exceptions when the deviation is unsatisfying.
|
||||
class RegressionTest: public SummaryComparator {
|
||||
class SummaryRegressionTest: public SummaryComparator {
|
||||
private:
|
||||
//! \brief Gathers the correct data for comparison for a specific keyword
|
||||
//! \param[in] timeVec1 The time steps of file 1.
|
||||
@@ -48,6 +48,12 @@ class RegressionTest: public SummaryComparator {
|
||||
bool checkDeviation(Deviation deviation, const char* keyword, int refIndex, int checkIndex);
|
||||
|
||||
bool isRestartFile = false; //!< Private member variable, when true the files that are being compared is a restart file vs a normal file
|
||||
|
||||
/// Whether or not to require that the two files have the same
|
||||
/// number of keywords. Throw exception if not.
|
||||
/// Default value: false (don't allow different number of keywords).
|
||||
bool allowDifferentNumberOfKeywords = false;
|
||||
|
||||
public:
|
||||
//! \brief Constructor, creates an object of RefressionTest class.
|
||||
//! \param[in] basename1 Path to file1 without extension.
|
||||
@@ -55,7 +61,9 @@ class RegressionTest: public SummaryComparator {
|
||||
//! \param[in] relativeTol The relative tolerance which is to be used in the test.
|
||||
//! \param[in] absoluteTol The absolute tolerance which is to be used in the test.
|
||||
//! \details The constructor calls the constructor of the super class.
|
||||
RegressionTest(const char* basename1, const char* basename2, double relativeTol, double absoluteTol):
|
||||
SummaryRegressionTest(const std::string& basename1,
|
||||
const std::string& basename2,
|
||||
double relativeTol, double absoluteTol) :
|
||||
SummaryComparator(basename1, basename2, relativeTol, absoluteTol) {}
|
||||
|
||||
//! \details The function executes a regression test for all the keywords. If the two files do not match in amount of keywords, an exception is thrown.
|
||||
@@ -67,6 +75,13 @@ class RegressionTest: public SummaryComparator {
|
||||
//! \brief This function sets the private member variable isRestartFiles
|
||||
//! \param[in] boolean Boolean value
|
||||
void setIsRestartFile(bool boolean){this->isRestartFile = boolean;}
|
||||
|
||||
/// \brief Dynamically control whether or not to require equal
|
||||
/// number of keywords (vectors) in the two result sets.
|
||||
///
|
||||
/// \param[in] allow Whether or not to allow different number of
|
||||
/// summary keywords in the two result sets.
|
||||
void setAllowDifferentNumberOfKeywords(const bool allow);
|
||||
};
|
||||
|
||||
#endif
|
||||
4
external/cjson/README.opm
vendored
4
external/cjson/README.opm
vendored
@@ -1,4 +1,2 @@
|
||||
This directory contains the cJSON package downloaded unchanged from:
|
||||
http://sourceforge.net/projects/cjson/. The cJSON package is plain C,
|
||||
the JsonObject class provides a minimal C++ wrapping of this.
|
||||
This directory contains the the 1.7.10 version of the cJSON package from https://github.com/DaveGamble/cJSON
|
||||
|
||||
|
||||
3177
external/cjson/cJSON.c
vendored
3177
external/cjson/cJSON.c
vendored
File diff suppressed because it is too large
Load Diff
290
external/cjson/cJSON.h
vendored
290
external/cjson/cJSON.h
vendored
@@ -1,16 +1,16 @@
|
||||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
@@ -23,118 +23,260 @@
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
|
||||
#define __WINDOWS__
|
||||
#endif
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
|
||||
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
|
||||
|
||||
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
|
||||
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
|
||||
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
||||
|
||||
For *nix builds that support visibility attribute, you can define similar behavior by
|
||||
|
||||
setting default visibility to hidden by adding
|
||||
-fvisibility=hidden (for gcc)
|
||||
or
|
||||
-xldscope=hidden (for sun cc)
|
||||
to CFLAGS
|
||||
|
||||
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
|
||||
|
||||
*/
|
||||
|
||||
#define CJSON_CDECL __cdecl
|
||||
#define CJSON_STDCALL __stdcall
|
||||
|
||||
/* export symbols by default, this is necessary for copy pasting the C and header file */
|
||||
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_EXPORT_SYMBOLS
|
||||
#endif
|
||||
|
||||
#if defined(CJSON_HIDE_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) type CJSON_STDCALL
|
||||
#elif defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
|
||||
#elif defined(CJSON_IMPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
|
||||
#endif
|
||||
#else /* !__WINDOWS__ */
|
||||
#define CJSON_CDECL
|
||||
#define CJSON_STDCALL
|
||||
|
||||
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
|
||||
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
|
||||
#else
|
||||
#define CJSON_PUBLIC(type) type
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* project version */
|
||||
#define CJSON_VERSION_MAJOR 1
|
||||
#define CJSON_VERSION_MINOR 7
|
||||
#define CJSON_VERSION_PATCH 10
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_False 0
|
||||
#define cJSON_True 1
|
||||
#define cJSON_NULL 2
|
||||
#define cJSON_Number 3
|
||||
#define cJSON_String 4
|
||||
#define cJSON_Array 5
|
||||
#define cJSON_Object 6
|
||||
|
||||
#define cJSON_Invalid (0)
|
||||
#define cJSON_False (1 << 0)
|
||||
#define cJSON_True (1 << 1)
|
||||
#define cJSON_NULL (1 << 2)
|
||||
#define cJSON_Number (1 << 3)
|
||||
#define cJSON_String (1 << 4)
|
||||
#define cJSON_Array (1 << 5)
|
||||
#define cJSON_Object (1 << 6)
|
||||
#define cJSON_Raw (1 << 7) /* raw json */
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
#define cJSON_StringIsConst 512
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON {
|
||||
struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
typedef struct cJSON
|
||||
{
|
||||
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *next;
|
||||
struct cJSON *prev;
|
||||
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
struct cJSON *child;
|
||||
|
||||
int type; /* The type of the item, as above. */
|
||||
/* The type of the item, as above. */
|
||||
int type;
|
||||
|
||||
char *valuestring; /* The item's string, if type==cJSON_String */
|
||||
int valueint; /* The item's number, if type==cJSON_Number */
|
||||
double valuedouble; /* The item's number, if type==cJSON_Number */
|
||||
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
||||
char *valuestring;
|
||||
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
||||
int valueint;
|
||||
/* The item's number, if type==cJSON_Number */
|
||||
double valuedouble;
|
||||
|
||||
char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
char *string;
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks {
|
||||
void *(*malloc_fn)(size_t sz);
|
||||
void (*free_fn)(void *ptr);
|
||||
typedef struct cJSON_Hooks
|
||||
{
|
||||
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
|
||||
void *(CJSON_CDECL *malloc_fn)(size_t sz);
|
||||
void (CJSON_CDECL *free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
typedef int cJSON_bool;
|
||||
|
||||
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
|
||||
* This is to prevent stack overflows. */
|
||||
#ifndef CJSON_NESTING_LIMIT
|
||||
#define CJSON_NESTING_LIMIT 1000
|
||||
#endif
|
||||
|
||||
/* returns the version of cJSON as a string */
|
||||
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
extern void cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
|
||||
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
|
||||
extern cJSON *cJSON_Parse(const char *value);
|
||||
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
|
||||
extern char *cJSON_Print(cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
|
||||
extern char *cJSON_PrintUnformatted(cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage. */
|
||||
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
||||
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
|
||||
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
|
||||
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
extern void cJSON_Delete(cJSON *c);
|
||||
CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
extern int cJSON_GetArraySize(cJSON *array);
|
||||
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
|
||||
extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
|
||||
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
||||
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
|
||||
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
extern const char *cJSON_GetErrorPtr(void);
|
||||
|
||||
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
||||
|
||||
/* Check if the item is a string and return its valuestring */
|
||||
CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item);
|
||||
|
||||
/* These functions check the type of an item */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
extern cJSON *cJSON_CreateNull(void);
|
||||
extern cJSON *cJSON_CreateTrue(void);
|
||||
extern cJSON *cJSON_CreateFalse(void);
|
||||
extern cJSON *cJSON_CreateBool(int b);
|
||||
extern cJSON *cJSON_CreateNumber(double num);
|
||||
extern cJSON *cJSON_CreateString(const char *string);
|
||||
extern cJSON *cJSON_CreateArray(void);
|
||||
extern cJSON *cJSON_CreateObject(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||
/* raw json */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
||||
|
||||
/* Create a string where valuestring references a string so
|
||||
* it will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
||||
/* Create an object/arrray that only references it's elements so
|
||||
* they will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
||||
|
||||
/* These utilities create an Array of count items. */
|
||||
extern cJSON *cJSON_CreateIntArray(int *numbers,int count);
|
||||
extern cJSON *cJSON_CreateFloatArray(float *numbers,int count);
|
||||
extern cJSON *cJSON_CreateDoubleArray(double *numbers,int count);
|
||||
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
|
||||
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
|
||||
* writing to `item->string` */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
|
||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||
|
||||
/* Remove/Detatch items from Arrays/Objects. */
|
||||
extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
|
||||
extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
|
||||
extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
|
||||
extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
|
||||
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
|
||||
extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
||||
|
||||
/* Duplicate a cJSON item */
|
||||
extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||
need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||
The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
|
||||
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
|
||||
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);
|
||||
|
||||
/* Macros for creating things quickly. */
|
||||
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
|
||||
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
|
||||
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
|
||||
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
|
||||
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
|
||||
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
|
||||
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
||||
|
||||
/* Helper functions for creating and adding items to an object at the same time.
|
||||
* They return the added item or NULL on failure. */
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
||||
|
||||
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||
#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))
|
||||
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
|
||||
/* helper for the cJSON_SetNumberValue macro */
|
||||
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
||||
|
||||
/* Macro for iterating over an array or object */
|
||||
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
||||
|
||||
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
|
||||
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
||||
CJSON_PUBLIC(void) cJSON_free(void *object);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
declare -A configurations
|
||||
|
||||
declare -A EXTRA_MODULE_FLAGS
|
||||
EXTRA_MODULE_FLAGS[opm-common]="-DENABLE_WELL_TEST=ON"
|
||||
EXTRA_MODULE_FLAGS[opm-simulators]="-DBUILD_EBOS_EXTENSIONS=ON -DBUILD_EBOS_DEBUG_EXTENSIONS=ON"
|
||||
|
||||
# Parse revisions from trigger comment and setup arrays
|
||||
# Depends on: 'upstreams', upstreamRev',
|
||||
# 'downstreams', 'downstreamRev',
|
||||
@@ -79,10 +83,26 @@ function printHeader {
|
||||
# $2 = 0 to build and install module, 1 to build and test module
|
||||
# $3 = Source root of module to build
|
||||
function build_module {
|
||||
cmake $3 -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=$2 -DCMAKE_TOOLCHAIN_FILE=${configurations[$configuration]} $1
|
||||
CMAKE_PARAMS="$1"
|
||||
DO_TEST_FLAG="$2"
|
||||
MOD_SRC_DIR="$3"
|
||||
cmake "$MOD_SRC_DIR" -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=$DO_TEST_FLAG -DCMAKE_TOOLCHAIN_FILE=${configurations[$configuration]} $CMAKE_PARAMS
|
||||
test $? -eq 0 || exit 1
|
||||
if test $2 -eq 1
|
||||
if test $DO_TEST_FLAG -eq 1
|
||||
then
|
||||
|
||||
pushd "$CWD"
|
||||
cd "$MOD_SRC_DIR"
|
||||
if test -x "./jenkins/pre-build.sh"; then
|
||||
echo "Running pre-build script"
|
||||
if ! "./jenkins/pre-build.sh"; then
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "No pre-build script detected"
|
||||
fi
|
||||
popd
|
||||
|
||||
if [ ! -z $BUILDTHREADS ]
|
||||
then
|
||||
cmake --build . -- -j$BUILDTHREADS
|
||||
@@ -112,6 +132,7 @@ function build_module {
|
||||
else
|
||||
cmake --build . --target install
|
||||
fi
|
||||
test $? -eq 0 || exit 3
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -163,7 +184,7 @@ function build_upstreams {
|
||||
do
|
||||
echo "Building upstream $upstream=${upstreamRev[$upstream]} configuration=$configuration"
|
||||
# Build upstream and execute installation
|
||||
clone_and_build_module $upstream "-DCMAKE_PREFIX_PATH=$WORKSPACE/$configuration/install -DCMAKE_INSTALL_PREFIX=$WORKSPACE/$configuration/install" ${upstreamRev[$upstream]} $WORKSPACE/$configuration
|
||||
clone_and_build_module $upstream "-DCMAKE_PREFIX_PATH=$WORKSPACE/$configuration/install -DCMAKE_INSTALL_PREFIX=$WORKSPACE/$configuration/install ${EXTRA_MODULE_FLAGS[$upstream]}" ${upstreamRev[$upstream]} $WORKSPACE/$configuration
|
||||
test $? -eq 0 || exit 1
|
||||
done
|
||||
test $? -eq 0 || exit 1
|
||||
@@ -178,7 +199,7 @@ function build_downstreams {
|
||||
do
|
||||
echo "Building downstream $downstream=${downstreamRev[$downstream]} configuration=$configuration"
|
||||
# Build downstream and execute installation
|
||||
clone_and_build_module $downstream "-DCMAKE_PREFIX_PATH=$WORKSPACE/$configuration/install -DCMAKE_INSTALL_PREFIX=$WORKSPACE/$configuration/install -DOPM_TESTS_ROOT=$OPM_TESTS_ROOT" ${downstreamRev[$downstream]} $WORKSPACE/$configuration 1
|
||||
clone_and_build_module $downstream "-DCMAKE_PREFIX_PATH=$WORKSPACE/$configuration/install -DCMAKE_INSTALL_PREFIX=$WORKSPACE/$configuration/install -DOPM_TESTS_ROOT=$OPM_TESTS_ROOT ${EXTRA_MODULE_FLAGS[$downstream]}" ${downstreamRev[$downstream]} $WORKSPACE/$configuration 1
|
||||
test $? -eq 0 || exit 1
|
||||
|
||||
# Installation for downstream
|
||||
@@ -215,7 +236,7 @@ function build_module_full {
|
||||
mkdir -p $configuration/build-$1
|
||||
cd $configuration/build-$1
|
||||
echo "Building main module $1=$sha1 configuration=$configuration"
|
||||
build_module "-DCMAKE_INSTALL_PREFIX=$WORKSPACE/$configuration/install -DOPM_TESTS_ROOT=$OPM_TESTS_ROOT" 1 $WORKSPACE
|
||||
build_module "-DCMAKE_INSTALL_PREFIX=$WORKSPACE/$configuration/install -DOPM_TESTS_ROOT=$OPM_TESTS_ROOT ${EXTRA_MODULE_FLAGS[$1]}" 1 $WORKSPACE
|
||||
test $? -eq 0 || exit 1
|
||||
cmake --build . --target install
|
||||
test $? -eq 0 || exit 1
|
||||
|
||||
@@ -16,9 +16,14 @@ then
|
||||
cp $OPM_TESTS_ROOT_PREDEFINED $WORKSPACE/deps/opm-tests -R
|
||||
fi
|
||||
else
|
||||
# Specified in trigger, download it
|
||||
source $WORKSPACE/deps/opm-common/jenkins/build-opm-module.sh
|
||||
clone_module opm-tests $OPM_TESTS_REVISION
|
||||
# We need a full repo checkout
|
||||
cp $OPM_TESTS_ROOT_PREDEFINED $WORKSPACE/deps/opm-tests -R
|
||||
pushd $WORKSPACE/deps/opm-tests
|
||||
# Then we fetch the PR branch
|
||||
git remote add PR https://github.com/OPM/opm-tests
|
||||
git fetch --depth 1 PR $OPM_TESTS_REVISION:branch_to_build
|
||||
git checkout branch_to_build
|
||||
popd
|
||||
fi
|
||||
else
|
||||
if ! test -d $WORKSPACE/deps/opm-tests
|
||||
|
||||
@@ -81,7 +81,7 @@ then
|
||||
PRNUMBER=${rev//[!0-9]/}
|
||||
DATA_PR=`curl -X GET https://api.github.com/repos/OPM/opm-tests/pulls?head=jenkins4opm:$BRANCH_NAME | grep '"number":' | awk -F ':' '{print $2}' | sed -e 's/,//' -e 's/ //'`
|
||||
git push -u jenkins4opm $BRANCH_NAME -f
|
||||
curl -d "{ \"body\": \"Existing PR https://github.com/OPM/opm-data/pull/$DATA_PR was updated\" }" -X POST https://api.github.com/repos/OPM/$MAIN_REPO/issues/$PRNUMBER/comments?access_token=$GH_TOKEN
|
||||
curl -d "{ \"body\": \"Existing PR https://github.com/OPM/opm-tests/pull/$DATA_PR was updated\" }" -X POST https://api.github.com/repos/OPM/$MAIN_REPO/issues/$PRNUMBER/comments?access_token=$GH_TOKEN
|
||||
else
|
||||
git-open-pull -u jenkins4opm --base-account OPM --base-repo opm-tests -r /tmp/cmsg $BRANCH_NAME
|
||||
fi
|
||||
|
||||
52
msim/include/opm/msim/msim.hpp
Normal file
52
msim/include/opm/msim/msim.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef ISIM_MAIN_HPP
|
||||
#define ISIM_MAIN_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
|
||||
#include <opm/output/data/Solution.hpp>
|
||||
#include <opm/output/data/Wells.hpp>
|
||||
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class EclipseIO;
|
||||
class ParseContext;
|
||||
class Parser;
|
||||
|
||||
class msim {
|
||||
|
||||
public:
|
||||
using well_rate_function = double(const EclipseState&, const Schedule&, const data::Solution&, size_t report_step, double seconds_elapsed);
|
||||
using solution_function = void(const EclipseState&, const Schedule&, data::Solution&, size_t report_step, double seconds_elapsed);
|
||||
|
||||
msim(const EclipseState& state);
|
||||
|
||||
void well_rate(const std::string& well, data::Rates::opt rate, std::function<well_rate_function> func);
|
||||
void solution(const std::string& field, std::function<solution_function> func);
|
||||
void run(Schedule& schedule, EclipseIO& io);
|
||||
void post_step(Schedule& schedule, data::Solution& sol, data::Wells& well_data, size_t report_step, EclipseIO& io) const;
|
||||
private:
|
||||
|
||||
void run_step(const Schedule& schedule, data::Solution& sol, data::Wells& well_data, size_t report_step, EclipseIO& io) const;
|
||||
void run_step(const Schedule& schedule, data::Solution& sol, data::Wells& well_data, size_t report_step, double dt, EclipseIO& io) const;
|
||||
void output(size_t report_step, bool substep, double seconds_elapsed, const data::Solution& sol, const data::Wells& well_data, EclipseIO& io) const;
|
||||
void simulate(const Schedule& schedule, data::Solution& sol, data::Wells& well_data, size_t report_step, double seconds_elapsed, double time_step) const;
|
||||
|
||||
EclipseState state;
|
||||
|
||||
std::map<std::string, std::map<data::Rates::opt, std::function<well_rate_function>>> well_rates;
|
||||
std::map<std::string, std::function<solution_function>> solutions;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
148
msim/src/msim.cpp
Normal file
148
msim/src/msim.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
Copyright 2018 Equinor ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <opm/output/eclipse/EclipseIO.hpp>
|
||||
#include <opm/output/eclipse/RestartValue.hpp>
|
||||
#include <opm/output/data/Solution.hpp>
|
||||
#include <opm/output/data/Wells.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionContext.hpp>
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
|
||||
#include <opm/msim/msim.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
msim::msim(const EclipseState& state) :
|
||||
state(state)
|
||||
{}
|
||||
|
||||
void msim::run(Schedule& schedule, EclipseIO& io) {
|
||||
const double week = 7 * 86400;
|
||||
data::Solution sol;
|
||||
data::Wells well_data;
|
||||
|
||||
io.writeInitial();
|
||||
for (size_t report_step = 1; report_step < schedule.size(); report_step++) {
|
||||
double time_step = std::min(week, 0.5*schedule.stepLength(report_step - 1));
|
||||
run_step(schedule, sol, well_data, report_step, time_step, io);
|
||||
post_step(schedule, sol, well_data, report_step, io);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msim::post_step(Schedule& schedule, data::Solution& /* sol */, data::Wells& /* well_data */, size_t report_step, EclipseIO& io) const {
|
||||
const auto& actions = schedule.actions();
|
||||
if (actions.empty())
|
||||
return;
|
||||
|
||||
const SummaryState& summary_state = io.summaryState();
|
||||
ActionContext context( summary_state );
|
||||
std::vector<std::string> matching_wells;
|
||||
|
||||
auto sim_time = schedule.simTime(report_step);
|
||||
for (const auto& action : actions.pending(sim_time)) {
|
||||
if (action->eval(sim_time, context, matching_wells))
|
||||
schedule.applyAction(report_step, *action, matching_wells);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void msim::run_step(const Schedule& schedule, data::Solution& sol, data::Wells& well_data, size_t report_step, EclipseIO& io) const {
|
||||
this->run_step(schedule, sol, well_data, report_step, schedule.stepLength(report_step - 1), io);
|
||||
}
|
||||
|
||||
|
||||
void msim::run_step(const Schedule& schedule, data::Solution& sol, data::Wells& well_data, size_t report_step, double dt, EclipseIO& io) const {
|
||||
double start_time = schedule.seconds(report_step - 1);
|
||||
double end_time = schedule.seconds(report_step);
|
||||
double seconds_elapsed = start_time;
|
||||
|
||||
while (seconds_elapsed < end_time) {
|
||||
double time_step = dt;
|
||||
if ((seconds_elapsed + time_step) > end_time)
|
||||
time_step = end_time - seconds_elapsed;
|
||||
|
||||
this->simulate(schedule, sol, well_data, report_step, seconds_elapsed, time_step);
|
||||
|
||||
seconds_elapsed += time_step;
|
||||
this->output(report_step,
|
||||
(seconds_elapsed < end_time),
|
||||
seconds_elapsed,
|
||||
sol,
|
||||
well_data,
|
||||
io);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void msim::output(size_t report_step, bool /* substep */, double seconds_elapsed, const data::Solution& sol, const data::Wells& well_data, EclipseIO& io) const {
|
||||
RestartValue value(sol, well_data);
|
||||
io.writeTimeStep(report_step,
|
||||
false,
|
||||
seconds_elapsed,
|
||||
value,
|
||||
{},
|
||||
{},
|
||||
{});
|
||||
}
|
||||
|
||||
|
||||
void msim::simulate(const Schedule& schedule, data::Solution& sol, data::Wells& well_data, size_t report_step, double seconds_elapsed, double time_step) const {
|
||||
for (const auto& sol_pair : this->solutions) {
|
||||
auto func = sol_pair.second;
|
||||
func(this->state, schedule, sol, report_step, seconds_elapsed + time_step);
|
||||
}
|
||||
|
||||
for (const auto& well_pair : this->well_rates) {
|
||||
const std::string& well_name = well_pair.first;
|
||||
data::Well& well = well_data[well_name];
|
||||
for (const auto& rate_pair : well_pair.second) {
|
||||
auto rate = rate_pair.first;
|
||||
auto func = rate_pair.second;
|
||||
|
||||
well.rates.set(rate, func(this->state, schedule, sol, report_step, seconds_elapsed + time_step));
|
||||
}
|
||||
|
||||
// This is complete bogus; a temporary fix to pass an assert() in the
|
||||
// the restart output.
|
||||
well.connections.resize(100);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msim::well_rate(const std::string& well, data::Rates::opt rate, std::function<well_rate_function> func) {
|
||||
this->well_rates[well][rate] = func;
|
||||
}
|
||||
|
||||
|
||||
void msim::solution(const std::string& field, std::function<solution_function> func) {
|
||||
this->solutions[field] = func;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -25,3 +25,7 @@ else()
|
||||
"Boost 1.44.0
|
||||
COMPONENTS system unit_test_framework REQUIRED")
|
||||
endif()
|
||||
# We need a defined target for libecl when linking.
|
||||
# The definition of the target is done implicitly below when
|
||||
# libecl is searched for.
|
||||
find_package_deps(opm-common)
|
||||
|
||||
@@ -20,12 +20,14 @@
|
||||
#ifndef OPM_OUTPUT_WELLS_HPP
|
||||
#define OPM_OUTPUT_WELLS_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <initializer_list>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm {
|
||||
@@ -56,6 +58,12 @@ namespace Opm {
|
||||
reservoir_water = (1 << 8),
|
||||
reservoir_oil = (1 << 9),
|
||||
reservoir_gas = (1 << 10),
|
||||
productivity_index_water = (1 << 11),
|
||||
productivity_index_oil = (1 << 12),
|
||||
productivity_index_gas = (1 << 13),
|
||||
well_potential_water = (1 << 14),
|
||||
well_potential_oil = (1 << 15),
|
||||
well_potential_gas = (1 << 16),
|
||||
};
|
||||
|
||||
using enum_size = std::underlying_type< opt >::type;
|
||||
@@ -99,9 +107,15 @@ namespace Opm {
|
||||
double reservoir_water = 0.0;
|
||||
double reservoir_oil = 0.0;
|
||||
double reservoir_gas = 0.0;
|
||||
double productivity_index_water = 0.0;
|
||||
double productivity_index_oil = 0.0;
|
||||
double productivity_index_gas = 0.0;
|
||||
double well_potential_water = 0.0;
|
||||
double well_potential_oil = 0.0;
|
||||
double well_potential_gas = 0.0;
|
||||
};
|
||||
|
||||
struct Completion {
|
||||
struct Connection {
|
||||
using global_index = size_t;
|
||||
static const constexpr int restart_size = 2;
|
||||
|
||||
@@ -112,6 +126,7 @@ namespace Opm {
|
||||
double cell_pressure;
|
||||
double cell_saturation_water;
|
||||
double cell_saturation_gas;
|
||||
double effective_Kh;
|
||||
|
||||
template <class MessageBufferType>
|
||||
void write(MessageBufferType& buffer) const;
|
||||
@@ -119,14 +134,26 @@ namespace Opm {
|
||||
void read(MessageBufferType& buffer);
|
||||
};
|
||||
|
||||
struct Segment {
|
||||
Rates rates;
|
||||
double pressure;
|
||||
std::size_t segNumber;
|
||||
|
||||
template <class MessageBufferType>
|
||||
void write(MessageBufferType& buffer) const;
|
||||
|
||||
template <class MessageBufferType>
|
||||
void read(MessageBufferType& buffer);
|
||||
};
|
||||
|
||||
struct Well {
|
||||
Rates rates;
|
||||
double bhp;
|
||||
double thp;
|
||||
double temperature;
|
||||
int control;
|
||||
std::vector< Completion > completions;
|
||||
|
||||
std::vector< Connection > connections;
|
||||
std::unordered_map<std::size_t, Segment> segments;
|
||||
inline bool flowing() const noexcept;
|
||||
template <class MessageBufferType>
|
||||
void write(MessageBufferType& buffer) const;
|
||||
@@ -146,20 +173,20 @@ namespace Opm {
|
||||
}
|
||||
|
||||
|
||||
double get(const std::string& well_name , Completion::global_index completion_grid_index, Rates::opt m) const {
|
||||
double get(const std::string& well_name , Connection::global_index connection_grid_index, Rates::opt m) const {
|
||||
const auto& witr = this->find( well_name );
|
||||
if( witr == this->end() ) return 0.0;
|
||||
|
||||
const auto& well = witr->second;
|
||||
const auto& completion = std::find_if( well.completions.begin() ,
|
||||
well.completions.end() ,
|
||||
[=]( const Completion& c ) {
|
||||
return c.index == completion_grid_index; });
|
||||
const auto& connection = std::find_if( well.connections.begin() ,
|
||||
well.connections.end() ,
|
||||
[=]( const Connection& c ) {
|
||||
return c.index == connection_grid_index; });
|
||||
|
||||
if( completion == well.completions.end() )
|
||||
if( connection == well.connections.end() )
|
||||
return 0.0;
|
||||
|
||||
return completion->rates.get( m, 0.0 );
|
||||
return connection->rates.get( m, 0.0 );
|
||||
}
|
||||
|
||||
template <class MessageBufferType>
|
||||
@@ -248,6 +275,12 @@ namespace Opm {
|
||||
case opt::reservoir_water: return this->reservoir_water;
|
||||
case opt::reservoir_oil: return this->reservoir_oil;
|
||||
case opt::reservoir_gas: return this->reservoir_gas;
|
||||
case opt::productivity_index_water: return this->productivity_index_water;
|
||||
case opt::productivity_index_oil: return this->productivity_index_oil;
|
||||
case opt::productivity_index_gas: return this->productivity_index_gas;
|
||||
case opt::well_potential_water: return this->well_potential_water;
|
||||
case opt::well_potential_oil: return this->well_potential_oil;
|
||||
case opt::well_potential_gas: return this->well_potential_gas;
|
||||
}
|
||||
|
||||
throw std::invalid_argument(
|
||||
@@ -285,10 +318,16 @@ namespace Opm {
|
||||
buffer.write(this->reservoir_water);
|
||||
buffer.write(this->reservoir_oil);
|
||||
buffer.write(this->reservoir_gas);
|
||||
buffer.write(this->productivity_index_water);
|
||||
buffer.write(this->productivity_index_oil);
|
||||
buffer.write(this->productivity_index_gas);
|
||||
buffer.write(this->well_potential_water);
|
||||
buffer.write(this->well_potential_oil);
|
||||
buffer.write(this->well_potential_gas);
|
||||
}
|
||||
|
||||
template <class MessageBufferType>
|
||||
void Completion::write(MessageBufferType& buffer) const {
|
||||
void Connection::write(MessageBufferType& buffer) const {
|
||||
buffer.write(this->index);
|
||||
this->rates.write(buffer);
|
||||
buffer.write(this->pressure);
|
||||
@@ -296,6 +335,14 @@ namespace Opm {
|
||||
buffer.write(this->cell_pressure);
|
||||
buffer.write(this->cell_saturation_water);
|
||||
buffer.write(this->cell_saturation_gas);
|
||||
buffer.write(this->effective_Kh);
|
||||
}
|
||||
|
||||
template <class MessageBufferType>
|
||||
void Segment::write(MessageBufferType& buffer) const {
|
||||
buffer.write(this->segNumber);
|
||||
this->rates.write(buffer);
|
||||
buffer.write(this->pressure);
|
||||
}
|
||||
|
||||
template <class MessageBufferType>
|
||||
@@ -305,10 +352,20 @@ namespace Opm {
|
||||
buffer.write(this->thp);
|
||||
buffer.write(this->temperature);
|
||||
buffer.write(this->control);
|
||||
unsigned int size = this->completions.size();
|
||||
unsigned int size = this->connections.size();
|
||||
buffer.write(size);
|
||||
for (const Completion& comp : this->completions)
|
||||
for (const Connection& comp : this->connections)
|
||||
comp.write(buffer);
|
||||
|
||||
{
|
||||
const auto nSeg =
|
||||
static_cast<unsigned int>(this->segments.size());
|
||||
buffer.write(nSeg);
|
||||
|
||||
for (const auto& seg : this->segments) {
|
||||
seg.second.write(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class MessageBufferType>
|
||||
@@ -325,10 +382,16 @@ namespace Opm {
|
||||
buffer.read(this->reservoir_water);
|
||||
buffer.read(this->reservoir_oil);
|
||||
buffer.read(this->reservoir_gas);
|
||||
buffer.read(this->productivity_index_water);
|
||||
buffer.read(this->productivity_index_oil);
|
||||
buffer.read(this->productivity_index_gas);
|
||||
buffer.read(this->well_potential_water);
|
||||
buffer.read(this->well_potential_oil);
|
||||
buffer.read(this->well_potential_gas);
|
||||
}
|
||||
|
||||
template <class MessageBufferType>
|
||||
void Completion::read(MessageBufferType& buffer) {
|
||||
void Connection::read(MessageBufferType& buffer) {
|
||||
buffer.read(this->index);
|
||||
this->rates.read(buffer);
|
||||
buffer.read(this->pressure);
|
||||
@@ -336,8 +399,16 @@ namespace Opm {
|
||||
buffer.read(this->cell_pressure);
|
||||
buffer.read(this->cell_saturation_water);
|
||||
buffer.read(this->cell_saturation_gas);
|
||||
buffer.read(this->effective_Kh);
|
||||
}
|
||||
|
||||
template <class MessageBufferType>
|
||||
void Segment::read(MessageBufferType& buffer) {
|
||||
buffer.read(this->segNumber);
|
||||
this->rates.read(buffer);
|
||||
buffer.read(this->pressure);
|
||||
}
|
||||
|
||||
template <class MessageBufferType>
|
||||
void Well::read(MessageBufferType& buffer) {
|
||||
this->rates.read(buffer);
|
||||
@@ -345,17 +416,35 @@ namespace Opm {
|
||||
buffer.read(this->thp);
|
||||
buffer.read(this->temperature);
|
||||
buffer.read(this->control);
|
||||
unsigned int size = 0.0; //this->completions.size();
|
||||
|
||||
// Connection information
|
||||
unsigned int size = 0.0; //this->connections.size();
|
||||
buffer.read(size);
|
||||
this->completions.resize(size);
|
||||
this->connections.resize(size);
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
auto& comp = this->completions[ i ];
|
||||
auto& comp = this->connections[ i ];
|
||||
comp.read(buffer);
|
||||
}
|
||||
|
||||
// Segment information (if applicable)
|
||||
const auto nSeg = [&buffer]() -> unsigned int
|
||||
{
|
||||
auto n = 0u;
|
||||
buffer.read(n);
|
||||
|
||||
return n;
|
||||
}();
|
||||
|
||||
for (auto segID = 0*nSeg; segID < nSeg; ++segID) {
|
||||
auto seg = Segment{};
|
||||
seg.read(buffer);
|
||||
|
||||
const auto segNumber = seg.segNumber;
|
||||
this->segments.emplace(segNumber, std::move(seg));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}} // Opm::data
|
||||
|
||||
#endif //OPM_OUTPUT_WELLS_HPP
|
||||
|
||||
75
opm/output/eclipse/AggregateConnectionData.hpp
Executable file
75
opm/output/eclipse/AggregateConnectionData.hpp
Executable file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright (c) 2018 Equinor ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_AGGREGATE_CONNECTION_DATA_HPP
|
||||
#define OPM_AGGREGATE_CONNECTION_DATA_HPP
|
||||
|
||||
#include <opm/output/eclipse/WindowedArray.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm {
|
||||
class EclipseGrid;
|
||||
class Schedule;
|
||||
class UnitSystem;
|
||||
} // Opm
|
||||
|
||||
namespace Opm { namespace data {
|
||||
class WellRates;
|
||||
}}
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
|
||||
class AggregateConnectionData
|
||||
{
|
||||
public:
|
||||
explicit AggregateConnectionData(const std::vector<int>& inteHead);
|
||||
|
||||
void captureDeclaredConnData(const Opm::Schedule& sched,
|
||||
const Opm::EclipseGrid& grid,
|
||||
const Opm::UnitSystem& units,
|
||||
const Opm::data::WellRates& xw,
|
||||
const std::size_t sim_step);
|
||||
|
||||
const std::vector<int>& getIConn() const
|
||||
{
|
||||
return this->iConn_.data();
|
||||
}
|
||||
|
||||
const std::vector<float>& getSConn() const
|
||||
{
|
||||
return this->sConn_.data();
|
||||
}
|
||||
|
||||
const std::vector<double>& getXConn() const
|
||||
{
|
||||
return this->xConn_.data();
|
||||
}
|
||||
|
||||
private:
|
||||
WindowedMatrix<int> iConn_;
|
||||
WindowedMatrix<float> sConn_;
|
||||
WindowedMatrix<double> xConn_;
|
||||
};
|
||||
|
||||
}}} // Opm::RestartIO::Helpers
|
||||
|
||||
#endif // OPM_AGGREGATE_CONNECTION_DATA_HPP
|
||||
173
opm/output/eclipse/AggregateGroupData.hpp
Normal file
173
opm/output/eclipse/AggregateGroupData.hpp
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
Copyright (c) 2018 Statoil ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_AGGREGATE_GROUP_DATA_HPP
|
||||
#define OPM_AGGREGATE_GROUP_DATA_HPP
|
||||
|
||||
#include <opm/output/eclipse/CharArrayNullTerm.hpp>
|
||||
#include <opm/output/eclipse/WindowedArray.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace Opm {
|
||||
class Schedule;
|
||||
class SummaryState;
|
||||
class Group;
|
||||
} // Opm
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
|
||||
class groupMaps {
|
||||
public:
|
||||
const std::map <size_t, const Opm::Group*>& indexGroupMap() const;
|
||||
const std::map <const std::string, size_t>& groupNameIndexMap() const;
|
||||
|
||||
void currentGrpTreeNameSeqIndMap(const Opm::Schedule& sched,
|
||||
const size_t simStep,
|
||||
const std::map<const std::string , size_t>& GnIMap,
|
||||
const std::map<size_t, const Opm::Group*>& IGMap);
|
||||
|
||||
private:
|
||||
std::map <size_t, const Opm::Group*> m_indexGroupMap;
|
||||
std::map <const std::string, size_t> m_groupNameIndexMap;
|
||||
};
|
||||
|
||||
class AggregateGroupData
|
||||
{
|
||||
public:
|
||||
explicit AggregateGroupData(const std::vector<int>& inteHead);
|
||||
|
||||
void captureDeclaredGroupData(const Opm::Schedule& sched,
|
||||
const std::vector<std::string>& restart_group_keys,
|
||||
const std::vector<std::string>& restart_field_keys,
|
||||
const std::map<std::string, size_t>& groupKeyToIndex,
|
||||
const std::map<std::string, size_t>& fieldKeyToIndex,
|
||||
const bool ecl_compatible_rst,
|
||||
const std::size_t simStep,
|
||||
const Opm::SummaryState& sumState,
|
||||
const std::vector<int>& inteHead);
|
||||
|
||||
const std::vector<int>& getIGroup() const
|
||||
{
|
||||
return this->iGroup_.data();
|
||||
}
|
||||
|
||||
const std::vector<float>& getSGroup() const
|
||||
{
|
||||
return this->sGroup_.data();
|
||||
}
|
||||
|
||||
const std::vector<double>& getXGroup() const
|
||||
{
|
||||
return this->xGroup_.data();
|
||||
}
|
||||
|
||||
const std::vector<CharArrayNullTerm<8>>& getZGroup() const
|
||||
{
|
||||
return this->zGroup_.data();
|
||||
}
|
||||
|
||||
const std::vector<std::string> restart_group_keys = {"GOPP", "GWPP", "GOPR", "GWPR", "GGPR",
|
||||
"GVPR", "GWIR", "GGIR", "GWCT", "GGOR",
|
||||
"GOPT", "GWPT", "GGPT", "GVPT", "GWIT",
|
||||
"GGIT",
|
||||
"GOPTH", "GWPTH", "GGPTH",
|
||||
"GWITH", "GGITH"};
|
||||
|
||||
const std::vector<std::string> restart_field_keys = {"FOPP", "FWPP", "FOPR", "FWPR", "FGPR",
|
||||
"FVPR", "FWIR", "FGIR", "FWCT", "FGOR",
|
||||
"FOPT", "FWPT", "FGPT", "FVPT", "FWIT",
|
||||
"FGIT",
|
||||
"FOPTH", "FWPTH", "FGPTH",
|
||||
"FWITH", "FGITH"};
|
||||
|
||||
const std::map<std::string, size_t> groupKeyToIndex = {
|
||||
{"GOPR", 0},
|
||||
{"GWPR", 1},
|
||||
{"GGPR", 2},
|
||||
{"GVPR", 3},
|
||||
{"GWIR", 5},
|
||||
{"GGIR", 6},
|
||||
{"GWCT", 8},
|
||||
{"GGOR", 9},
|
||||
{"GOPT", 10},
|
||||
{"GWPT", 11},
|
||||
{"GGPT", 12},
|
||||
{"GVPT", 13},
|
||||
{"GWIT", 15},
|
||||
{"GGIT", 16},
|
||||
{"GOPP", 22},
|
||||
{"GWPP", 23},
|
||||
{"GOPTH", 135},
|
||||
{"GWPTH", 139},
|
||||
{"GWITH", 140},
|
||||
{"GGPTH", 143},
|
||||
{"GGITH", 144},
|
||||
};
|
||||
|
||||
const std::map<std::string, size_t> fieldKeyToIndex = {
|
||||
{"FOPR", 0},
|
||||
{"FWPR", 1},
|
||||
{"FGPR", 2},
|
||||
{"FVPR", 3},
|
||||
{"FWIR", 5},
|
||||
{"FGIR", 6},
|
||||
{"FWCT", 8},
|
||||
{"FGOR", 9},
|
||||
{"FOPT", 10},
|
||||
{"FWPT", 11},
|
||||
{"FGPT", 12},
|
||||
{"FVPT", 13},
|
||||
{"FWIT", 15},
|
||||
{"FGIT", 16},
|
||||
{"FOPP", 22},
|
||||
{"FWPP", 23},
|
||||
{"FOPTH", 135},
|
||||
{"FWPTH", 139},
|
||||
{"FWITH", 140},
|
||||
{"FGPTH", 143},
|
||||
{"FGITH", 144},
|
||||
};
|
||||
|
||||
private:
|
||||
/// Aggregate 'IWEL' array (Integer) for all wells.
|
||||
WindowedArray<int> iGroup_;
|
||||
|
||||
/// Aggregate 'SWEL' array (Real) for all wells.
|
||||
WindowedArray<float> sGroup_;
|
||||
|
||||
/// Aggregate 'XWEL' array (Double Precision) for all wells.
|
||||
WindowedArray<double> xGroup_;
|
||||
|
||||
/// Aggregate 'ZWEL' array (Character) for all wells.
|
||||
WindowedArray<CharArrayNullTerm<8>> zGroup_;
|
||||
|
||||
/// Maximum number of wells in a group.
|
||||
int nWGMax_;
|
||||
|
||||
/// Maximum number of groups
|
||||
int nGMaxz_;
|
||||
};
|
||||
|
||||
}}} // Opm::RestartIO::Helpers
|
||||
|
||||
#endif // OPM_AGGREGATE_WELL_DATA_HPP
|
||||
116
opm/output/eclipse/AggregateMSWData.hpp
Normal file
116
opm/output/eclipse/AggregateMSWData.hpp
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
Copyright (c) 2018 Statoil ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_AGGREGATE_MSW_DATA_HPP
|
||||
#define OPM_AGGREGATE_MSW_DATA_HPP
|
||||
|
||||
#include <opm/output/data/Wells.hpp>
|
||||
#include <opm/output/eclipse/CharArrayNullTerm.hpp>
|
||||
#include <opm/output/eclipse/WindowedArray.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm {
|
||||
class Phases;
|
||||
class Schedule;
|
||||
class EclipseGrid;
|
||||
class UnitSystem;
|
||||
class SummaryState;
|
||||
} // Opm
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
|
||||
struct BranchSegmentPar {
|
||||
int outletS;
|
||||
int noSegInBranch;
|
||||
int firstSeg;
|
||||
int lastSeg;
|
||||
int branch;
|
||||
};
|
||||
|
||||
struct SegmentSetSourceSinkTerms {
|
||||
std::vector<double> qosc;
|
||||
std::vector<double> qwsc;
|
||||
std::vector<double> qgsc;
|
||||
};
|
||||
|
||||
struct SegmentSetFlowRates {
|
||||
std::vector<double> sofr;
|
||||
std::vector<double> swfr;
|
||||
std::vector<double> sgfr;
|
||||
};
|
||||
|
||||
class AggregateMSWData
|
||||
{
|
||||
public:
|
||||
explicit AggregateMSWData(const std::vector<int>& inteHead);
|
||||
|
||||
void captureDeclaredMSWData(const Opm::Schedule& sched,
|
||||
const std::size_t rptStep,
|
||||
const Opm::UnitSystem& units,
|
||||
const std::vector<int>& inteHead,
|
||||
const Opm::EclipseGrid& grid,
|
||||
const Opm::SummaryState& smry,
|
||||
const Opm::data::WellRates& wr
|
||||
);
|
||||
|
||||
/// Retrieve Integer Multisegment well data Array.
|
||||
const std::vector<int>& getISeg() const
|
||||
{
|
||||
return this->iSeg_.data();
|
||||
}
|
||||
|
||||
/// Retrieve Double precision segment data Array.
|
||||
const std::vector<double>& getRSeg() const
|
||||
{
|
||||
return this->rSeg_.data();
|
||||
}
|
||||
|
||||
/// Retrieve Integer multisegment well data Array for lateral branches (ILBS)
|
||||
const std::vector<int>& getILBs() const
|
||||
{
|
||||
return this->iLBS_.data();
|
||||
}
|
||||
|
||||
/// Retrieve Integer multisegment well data Array for lateral branches (ILBR)
|
||||
const std::vector<int>& getILBr() const
|
||||
{
|
||||
return this->iLBR_.data();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
/// Aggregate 'ISEG' array (Integer) for all multisegment wells
|
||||
WindowedArray<int> iSeg_;
|
||||
|
||||
/// Aggregate 'RSEG' array (Double) for all multisegment wells
|
||||
WindowedArray<double> rSeg_;
|
||||
|
||||
/// Aggregate 'ILBS' array (Integer) for all multisegment wells
|
||||
WindowedArray<int> iLBS_;
|
||||
|
||||
/// Aggregate 'ILBR' array (Integer) for all multisegment wells
|
||||
WindowedArray<int> iLBR_;
|
||||
|
||||
};
|
||||
|
||||
}}} // Opm::RestartIO::Helpers
|
||||
|
||||
#endif // OPM_AGGREGATE_WELL_DATA_HPP
|
||||
104
opm/output/eclipse/AggregateWellData.hpp
Normal file
104
opm/output/eclipse/AggregateWellData.hpp
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
Copyright (c) 2018 Statoil ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_AGGREGATE_WELL_DATA_HPP
|
||||
#define OPM_AGGREGATE_WELL_DATA_HPP
|
||||
|
||||
#include <opm/output/eclipse/CharArrayNullTerm.hpp>
|
||||
#include <opm/output/eclipse/WindowedArray.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm {
|
||||
class Schedule;
|
||||
class SummaryState;
|
||||
class UnitSystem;
|
||||
} // Opm
|
||||
|
||||
namespace Opm { namespace data {
|
||||
class WellRates;
|
||||
}} // Opm::data
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
|
||||
class AggregateWellData
|
||||
{
|
||||
public:
|
||||
explicit AggregateWellData(const std::vector<int>& inteHead);
|
||||
|
||||
void captureDeclaredWellData(const Schedule& sched,
|
||||
const UnitSystem& units,
|
||||
const std::size_t sim_step,
|
||||
const ::Opm::SummaryState& smry,
|
||||
const std::vector<int>& inteHead);
|
||||
|
||||
void captureDynamicWellData(const Opm::Schedule& sched,
|
||||
const std::size_t sim_step,
|
||||
const bool ecl_compatible_rst,
|
||||
const Opm::data::WellRates& xw,
|
||||
const Opm::SummaryState& smry);
|
||||
|
||||
/// Retrieve Integer Well Data Array.
|
||||
const std::vector<int>& getIWell() const
|
||||
{
|
||||
return this->iWell_.data();
|
||||
}
|
||||
|
||||
/// Retrieve Floating-Point (Real) Well Data Array.
|
||||
const std::vector<float>& getSWell() const
|
||||
{
|
||||
return this->sWell_.data();
|
||||
}
|
||||
|
||||
/// Retrieve Floating-Point (Double Precision) Well Data Array.
|
||||
const std::vector<double>& getXWell() const
|
||||
{
|
||||
return this->xWell_.data();
|
||||
}
|
||||
|
||||
/// Retrieve Character Well Data Array.
|
||||
const std::vector<CharArrayNullTerm<8>>& getZWell() const
|
||||
{
|
||||
return this->zWell_.data();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
/// Aggregate 'IWEL' array (Integer) for all wells.
|
||||
WindowedArray<int> iWell_;
|
||||
|
||||
/// Aggregate 'SWEL' array (Real) for all wells.
|
||||
WindowedArray<float> sWell_;
|
||||
|
||||
/// Aggregate 'XWEL' array (Double Precision) for all wells.
|
||||
WindowedArray<double> xWell_;
|
||||
|
||||
/// Aggregate 'ZWEL' array (Character) for all wells.
|
||||
WindowedArray<CharArrayNullTerm<8>> zWell_;
|
||||
|
||||
/// Maximum number of groups in model.
|
||||
int nWGMax_;
|
||||
};
|
||||
|
||||
}}} // Opm::RestartIO::Helpers
|
||||
|
||||
#endif // OPM_AGGREGATE_WELL_DATA_HPP
|
||||
103
opm/output/eclipse/CharArrayNullTerm.hpp
Normal file
103
opm/output/eclipse/CharArrayNullTerm.hpp
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
Copyright (c) 2018 Statoil ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_CHARARRAY_HEADER_HPP
|
||||
#define OPM_CHARARRAY_HEADER_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
|
||||
/// Null-terminated, left adjusted, space padded array of N characters.
|
||||
///
|
||||
/// Simple container of character data. Exists solely for purpose of
|
||||
/// outputting std::string (or types convertible to std::string) as
|
||||
/// Fortran-style \code character (len=N) \endcode values.
|
||||
///
|
||||
/// \tparam N Number of characters.
|
||||
template <std::size_t N>
|
||||
class CharArrayNullTerm
|
||||
{
|
||||
public:
|
||||
CharArrayNullTerm()
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
explicit CharArrayNullTerm(const std::string& s)
|
||||
: CharArrayNullTerm()
|
||||
{
|
||||
this->copy_in(s.c_str(), s.size());
|
||||
}
|
||||
|
||||
~CharArrayNullTerm() = default;
|
||||
|
||||
CharArrayNullTerm(const CharArrayNullTerm& rhs) = default;
|
||||
CharArrayNullTerm(CharArrayNullTerm&& rhs) = default;
|
||||
|
||||
CharArrayNullTerm& operator=(const CharArrayNullTerm& rhs) = default;
|
||||
CharArrayNullTerm& operator=(CharArrayNullTerm&& rhs) = default;
|
||||
|
||||
/// Assign from \code std::string \endcode.
|
||||
CharArrayNullTerm& operator=(const std::string& s)
|
||||
{
|
||||
this->clear();
|
||||
this->copy_in(s.data(), s.size());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
const char* c_str() const
|
||||
{
|
||||
return this->s_.data();
|
||||
}
|
||||
|
||||
private:
|
||||
enum : typename std::array<char, N + 1>::size_type { NChar = N };
|
||||
|
||||
std::array<char, NChar + 1> s_;
|
||||
|
||||
/// Clear contents of internal array (fill with ' ').
|
||||
void clear()
|
||||
{
|
||||
this->s_.fill(' ');
|
||||
this->s_[NChar] = '\0';
|
||||
}
|
||||
|
||||
/// Assign new value to internal array (left adjusted, space padded
|
||||
/// and null-terminated).
|
||||
void copy_in(const char* s,
|
||||
const typename std::array<char, NChar + 1>::size_type len)
|
||||
{
|
||||
const auto ncpy = std::min(len, static_cast<decltype(len)>(NChar));
|
||||
|
||||
// Note: Not strcpy() or strncpy() here. The former has no bounds
|
||||
// checking, the latter writes a null-terminator at position 'ncpy'
|
||||
// (s_[ncpy]) which violates the post condition if ncpy < NChar.
|
||||
std::memcpy(this->s_.data(), s,
|
||||
ncpy * sizeof *this->s_.data());
|
||||
}
|
||||
};
|
||||
|
||||
}}} // Opm::RestartIO::Helpers
|
||||
#endif // CHARARRAY_HEADER
|
||||
73
opm/output/eclipse/DoubHEAD.hpp
Executable file
73
opm/output/eclipse/DoubHEAD.hpp
Executable file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
Copyright 2018 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media Project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_DOUBHEAD_HEADER_INCLUDED
|
||||
#define OPM_DOUBHEAD_HEADER_INCLUDED
|
||||
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm {
|
||||
class Tuning;
|
||||
class Schedule;
|
||||
}
|
||||
|
||||
namespace Opm { namespace RestartIO {
|
||||
|
||||
class DoubHEAD
|
||||
{
|
||||
public:
|
||||
struct TimeStamp {
|
||||
std::chrono::time_point<std::chrono::system_clock> start;
|
||||
std::chrono::duration<double, std::chrono::seconds::period> elapsed;
|
||||
};
|
||||
|
||||
DoubHEAD();
|
||||
|
||||
~DoubHEAD() = default;
|
||||
DoubHEAD(const DoubHEAD& rhs) = default;
|
||||
DoubHEAD(DoubHEAD&& rhs) = default;
|
||||
|
||||
DoubHEAD& operator=(const DoubHEAD& rhs) = default;
|
||||
DoubHEAD& operator=(DoubHEAD&& rhs) = default;
|
||||
|
||||
DoubHEAD& tuningParameters(const Tuning& tuning,
|
||||
const std::size_t lookup_step,
|
||||
const double cnvT);
|
||||
|
||||
DoubHEAD& timeStamp(const TimeStamp& ts);
|
||||
DoubHEAD& nextStep(const double nextTimeStep);
|
||||
|
||||
DoubHEAD& drsdt(const Schedule& sched,
|
||||
const std::size_t lookup_step,
|
||||
const double cnvT);
|
||||
|
||||
const std::vector<double>& data() const
|
||||
{
|
||||
return this->data_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<double> data_;
|
||||
};
|
||||
|
||||
}} // Opm::RestartIO
|
||||
|
||||
#endif // OPM_DOUBHEAD_HEADER_INCLUDED
|
||||
@@ -41,6 +41,7 @@ namespace Opm {
|
||||
class EclipseState;
|
||||
class SummaryConfig;
|
||||
class Schedule;
|
||||
class SummaryState;
|
||||
|
||||
/*!
|
||||
* \brief A class to write the reservoir state and the well state of a
|
||||
@@ -173,13 +174,11 @@ public:
|
||||
void writeTimeStep( int report_step,
|
||||
bool isSubstep,
|
||||
double seconds_elapsed,
|
||||
data::Solution,
|
||||
data::Wells,
|
||||
RestartValue value,
|
||||
const std::map<std::string, double>& single_summary_values,
|
||||
const std::map<std::string, std::vector<double>>& region_summary_values,
|
||||
const std::map<std::pair<std::string, int>, double>& block_summary_values,
|
||||
const std::map<std::string, std::vector<double>>& extra_restart = {},
|
||||
bool write_double = false);
|
||||
const bool write_double = false);
|
||||
|
||||
|
||||
/*
|
||||
@@ -220,12 +219,14 @@ public:
|
||||
missing, if the bool is false missing keywords will be ignored
|
||||
(there will *not* be an empty vector in the return value).
|
||||
*/
|
||||
RestartValue loadRestart(const std::map<std::string, RestartKey>& keys, const std::map<std::string, bool>& extra_keys = {}) const;
|
||||
RestartValue loadRestart(const std::vector<RestartKey>& solution_keys, const std::vector<RestartKey>& extra_keys = {}) const;
|
||||
|
||||
|
||||
EclipseIO( const EclipseIO& ) = delete;
|
||||
~EclipseIO();
|
||||
|
||||
const SummaryState& summaryState() const;
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr< Impl > impl;
|
||||
|
||||
137
opm/output/eclipse/InteHEAD.hpp
Executable file
137
opm/output/eclipse/InteHEAD.hpp
Executable file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
Copyright 2016, 2017, 2018 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media Project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_INTEHEAD_HEADER_INCLUDED
|
||||
#define OPM_INTEHEAD_HEADER_INCLUDED
|
||||
|
||||
#include <array>
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm { namespace RestartIO {
|
||||
|
||||
class InteHEAD
|
||||
{
|
||||
public:
|
||||
enum class UnitSystem {
|
||||
Metric, Field, Lab, PVT_M
|
||||
};
|
||||
|
||||
struct WellTableDim {
|
||||
int numWells;
|
||||
int maxPerf;
|
||||
int maxWellInGroup;
|
||||
int maxGroupInField;
|
||||
};
|
||||
|
||||
struct WellSegDims {
|
||||
int nsegwl;
|
||||
int nswlmx;
|
||||
int nsegmx;
|
||||
int nlbrmx;
|
||||
int nisegz;
|
||||
int nrsegz;
|
||||
int nilbrz;
|
||||
};
|
||||
|
||||
struct RegDims {
|
||||
int ntfip;
|
||||
int nmfipr;
|
||||
int nrfreg;
|
||||
int ntfreg;
|
||||
int nplmix;
|
||||
};
|
||||
|
||||
struct TimePoint {
|
||||
int year;
|
||||
int month; // 1..12
|
||||
int day; // 1..31
|
||||
|
||||
int hour; // 0..23
|
||||
int minute; // 0..59
|
||||
int second; // 0..59
|
||||
|
||||
int microseconds; // 0..999999
|
||||
};
|
||||
|
||||
struct Phases {
|
||||
int oil;
|
||||
int water;
|
||||
int gas;
|
||||
};
|
||||
|
||||
struct TuningPar {
|
||||
int newtmx;
|
||||
int newtmn;
|
||||
int litmax;
|
||||
int litmin;
|
||||
int mxwsit;
|
||||
int mxwpit;
|
||||
};
|
||||
|
||||
struct Group {
|
||||
int ngroups;
|
||||
};
|
||||
|
||||
InteHEAD();
|
||||
~InteHEAD() = default;
|
||||
|
||||
InteHEAD(const InteHEAD& rhs) = default;
|
||||
InteHEAD(InteHEAD&& rhs) = default;
|
||||
|
||||
InteHEAD& operator=(const InteHEAD& rhs) = default;
|
||||
InteHEAD& operator=(InteHEAD&& rhs) = default;
|
||||
|
||||
InteHEAD& dimensions(const int nx, const int ny, const int nz);
|
||||
InteHEAD& dimensions(const std::array<int,3>& cartDims);
|
||||
InteHEAD& numActive(const int nactive);
|
||||
|
||||
InteHEAD& unitConventions(const UnitSystem& usys);
|
||||
InteHEAD& wellTableDimensions(const WellTableDim& wtdim);
|
||||
InteHEAD& calendarDate(const TimePoint& date);
|
||||
InteHEAD& activePhases(const Phases& phases);
|
||||
InteHEAD& params_NWELZ(const int niwelz, const int nswelz, const int nxwelz, const int nzwelz);
|
||||
InteHEAD& params_NCON(const int niconz, const int nsconz, const int nxconz);
|
||||
InteHEAD& params_GRPZ(const std::array<int, 4>& grpz);
|
||||
InteHEAD& params_NAAQZ(const int ncamax, const int niaaqz, const int nsaaqz, const int nxaaqz, const int nicaqz, const int nscaqz, const int nacaqz);
|
||||
InteHEAD& stepParam(const int tstep, const int report_step);
|
||||
InteHEAD& tuningParam(const TuningPar& tunpar);
|
||||
InteHEAD& variousParam(const int version, const int iprog);
|
||||
InteHEAD& wellSegDimensions(const WellSegDims& wsdim);
|
||||
InteHEAD& regionDimensions(const RegDims& rdim);
|
||||
InteHEAD& ngroups(const Group& gr);
|
||||
|
||||
const std::vector<int>& data() const
|
||||
{
|
||||
return this->data_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<int> data_;
|
||||
};
|
||||
|
||||
std::time_t makeUTCTime(const std::tm& timePoint);
|
||||
|
||||
InteHEAD::TimePoint
|
||||
getSimulationTimePoint(const std::time_t start,
|
||||
const double elapsed);
|
||||
}} // Opm::RestartIO
|
||||
|
||||
#endif // OPM_INTEHEAD_HEADER_INCLUDED
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
Copyright 2019 Equinor.
|
||||
Copyright 2017 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
@@ -35,6 +36,8 @@ namespace Opm {
|
||||
public:
|
||||
/// Constructor.
|
||||
///
|
||||
/// Padded table entries set to +1.0e+20.
|
||||
///
|
||||
/// \param[in] numTables Number of tables managed by internal
|
||||
/// buffer. Typically corresponds to maximum value of a region
|
||||
/// ID vector such as SATNUM, IMBNUM, or PVTNUM.
|
||||
@@ -57,6 +60,33 @@ namespace Opm {
|
||||
const std::size_t numRows,
|
||||
const std::size_t numCols);
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// \param[in] numTables Number of tables managed by internal
|
||||
/// buffer. Typically corresponds to maximum value of a region
|
||||
/// ID vector such as SATNUM, IMBNUM, or PVTNUM.
|
||||
///
|
||||
/// \param[in] numPrimary Number of primary look-up keys for the
|
||||
/// tabular data managed by the internal buffer. Mostly relevant
|
||||
/// (i.e., greater than one) for miscible oil ("PVTO") or
|
||||
/// miscible gas ("PVTG") tables and typically corresponds to the
|
||||
/// number of Rs/Rv entries from the TABDIMS keyword.
|
||||
///
|
||||
/// \param[in] numRows Number of rows in each sub-table
|
||||
/// corresponding to a single primary look-up key. Typically the
|
||||
/// number of nodes (e.g., NSSFUN or NPPVT) of the corresponding
|
||||
/// input keyword.
|
||||
///
|
||||
/// \param[in] numCols Number of columns in each sub-table (and main
|
||||
/// table). Typically 5.
|
||||
///
|
||||
/// \param[in] fillValue Data element value for padded table entries.
|
||||
LinearisedOutputTable(const std::size_t numTables,
|
||||
const std::size_t numPrimary,
|
||||
const std::size_t numRows,
|
||||
const std::size_t numCols,
|
||||
const double fillValue);
|
||||
|
||||
/// Retrieve iterator to start of \c numRows (contiguous) column
|
||||
/// elements of a particular sub-table of a particular main table.
|
||||
///
|
||||
|
||||
56
opm/output/eclipse/LogiHEAD.hpp
Normal file
56
opm/output/eclipse/LogiHEAD.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
Copyright 2016, 2017 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media Project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_LOGIHEAD_HEADER_INCLUDED
|
||||
#define OPM_LOGIHEAD_HEADER_INCLUDED
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Opm { namespace RestartIO {
|
||||
|
||||
class LogiHEAD
|
||||
{
|
||||
public:
|
||||
LogiHEAD();
|
||||
~LogiHEAD() = default;
|
||||
|
||||
LogiHEAD(const LogiHEAD& rhs) = default;
|
||||
LogiHEAD(LogiHEAD&& rhs) = default;
|
||||
|
||||
LogiHEAD& operator=(const LogiHEAD& rhs) = default;
|
||||
LogiHEAD& operator=(LogiHEAD&& rhs) = default;
|
||||
|
||||
LogiHEAD& variousParam(const bool e300_radial,
|
||||
const bool e100_radial,
|
||||
const int nswlmx,
|
||||
const bool enableHyster
|
||||
);
|
||||
|
||||
const std::vector<bool>& data() const
|
||||
{
|
||||
return this->data_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<bool> data_;
|
||||
};
|
||||
|
||||
}} // Opm::RestartIO
|
||||
|
||||
#endif // OPM_LOGIHEAD_HEADER_INCLUDED
|
||||
@@ -32,12 +32,12 @@ namespace out {
|
||||
public:
|
||||
RegionCache() = default;
|
||||
RegionCache(const Eclipse3DProperties& properties, const EclipseGrid& grid, const Schedule& schedule);
|
||||
const std::vector<std::pair<std::string,size_t>>& completions( int region_id ) const;
|
||||
const std::vector<std::pair<std::string,size_t>>& connections( int region_id ) const;
|
||||
|
||||
private:
|
||||
std::vector<std::pair<std::string,size_t>> completions_empty;
|
||||
std::vector<std::pair<std::string,size_t>> connections_empty;
|
||||
|
||||
std::map<int , std::vector<std::pair<std::string,size_t>>> completion_map;
|
||||
std::map<int , std::vector<std::pair<std::string,size_t>>> connection_map;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2018 Equinor ASA
|
||||
Copyright (c) 2016 Statoil ASA
|
||||
Copyright (c) 2013-2015 Andreas Lauser
|
||||
Copyright (c) 2013 SINTEF ICT, Applied Mathematics.
|
||||
@@ -23,35 +24,38 @@
|
||||
#ifndef RESTART_IO_HPP
|
||||
#define RESTART_IO_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
|
||||
|
||||
#include <opm/output/data/Cells.hpp>
|
||||
#include <opm/output/data/Solution.hpp>
|
||||
#include <opm/output/data/Wells.hpp>
|
||||
#include <opm/output/eclipse/RestartValue.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
||||
|
||||
#include <ert/ecl/EclKW.hpp>
|
||||
#include <ert/ecl/ecl_rsthead.h>
|
||||
#include <ert/ecl/ecl_rst_file.h>
|
||||
#include <ert/util/util.h>
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class EclipseGrid;
|
||||
class EclipseState;
|
||||
class Phases;
|
||||
class Schedule;
|
||||
class EclipseGrid;
|
||||
class EclipseState;
|
||||
class Phases;
|
||||
class Schedule;
|
||||
|
||||
namespace RestartIO {
|
||||
} // namespace Opm
|
||||
|
||||
|
||||
/*
|
||||
The two loose functions RestartIO::save() and RestartIO::load() can
|
||||
The two free functions RestartIO::save() and RestartIO::load() can
|
||||
be used to save and load reservoir and well state from restart
|
||||
files. Observe that these functions 'just do it', i.e. the checking
|
||||
of which report step to load from, if output is enabled at all and
|
||||
@@ -68,30 +72,30 @@ namespace RestartIO {
|
||||
load("CASE.X0010" , 99 , ...)
|
||||
save("CASE.X0010" , 99 , ...)
|
||||
|
||||
will read and write to the file "CASE.X0010" - completely ignoring
|
||||
will read from and write to the file "CASE.X0010" - completely ignoring
|
||||
the report step argument '99'.
|
||||
*/
|
||||
namespace Opm { namespace RestartIO {
|
||||
|
||||
void save(const std::string& filename,
|
||||
int report_step,
|
||||
double seconds_elapsed,
|
||||
data::Solution cells,
|
||||
data::Wells wells,
|
||||
const EclipseState& es,
|
||||
const EclipseGrid& grid,
|
||||
const Schedule& schedule,
|
||||
std::map<std::string, std::vector<double>> extra_data = {},
|
||||
bool write_double = false);
|
||||
void save(const std::string& filename,
|
||||
int report_step,
|
||||
double seconds_elapsed,
|
||||
RestartValue value,
|
||||
const EclipseState& es,
|
||||
const EclipseGrid& grid,
|
||||
const Schedule& schedule,
|
||||
const SummaryState& sumState,
|
||||
bool write_double = false);
|
||||
|
||||
std::pair<RestartValue, SummaryState>
|
||||
load(const std::string& filename,
|
||||
int report_step,
|
||||
const std::vector<RestartKey>& solution_keys,
|
||||
const EclipseState& es,
|
||||
const EclipseGrid& grid,
|
||||
const Schedule& schedule,
|
||||
const std::vector<RestartKey>& extra_keys = {});
|
||||
|
||||
RestartValue load( const std::string& filename,
|
||||
int report_step,
|
||||
const std::map<std::string, RestartKey>& keys,
|
||||
const EclipseState& es,
|
||||
const EclipseGrid& grid,
|
||||
const Schedule& schedule,
|
||||
const std::map<std::string, bool>& extra_keys = {});
|
||||
}} // namespace Opm::RestartIO
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // RESTART_IO_HPP
|
||||
|
||||
@@ -22,39 +22,30 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
|
||||
#include <opm/output/data/Solution.hpp>
|
||||
#include <opm/output/data/Wells.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
|
||||
/*
|
||||
Small convenience class used in the map passed to the
|
||||
RestartIO::load( ) function. A class instance can be constructed
|
||||
from a UnitSystem::measure value, which will default to a
|
||||
required key, but it can also be constructed from a
|
||||
two-parameter constructor, and then the required/not required
|
||||
can controlled explicitly:
|
||||
|
||||
|
||||
RestartIO::load(..., {{"PRESSURE" , UnitSystem::measure::pressure},
|
||||
{"MAX_SWAT" , {UnitSystem::measure::identity, false}} )
|
||||
|
||||
The RestartKey( ) for pressure is implicitly created from
|
||||
UnitSystem::measure::pressure and will be required, whereas the
|
||||
MAX_SWAT keyword is optional.
|
||||
|
||||
*/
|
||||
class RestartKey {
|
||||
public:
|
||||
|
||||
std::string key;
|
||||
UnitSystem::measure dim;
|
||||
bool required = true;
|
||||
bool required;
|
||||
|
||||
explicit RestartKey( UnitSystem::measure _dim)
|
||||
: dim(_dim)
|
||||
RestartKey( const std::string& _key, UnitSystem::measure _dim)
|
||||
: key(_key),
|
||||
dim(_dim),
|
||||
required(true)
|
||||
{}
|
||||
|
||||
|
||||
RestartKey( UnitSystem::measure _dim, bool _required)
|
||||
: dim(_dim),
|
||||
RestartKey( const std::string& _key, UnitSystem::measure _dim, bool _required)
|
||||
: key(_key),
|
||||
dim(_dim),
|
||||
required(_required)
|
||||
{}
|
||||
|
||||
@@ -62,32 +53,27 @@ namespace Opm {
|
||||
|
||||
|
||||
/*
|
||||
A simple struct - the only purpose is to facilitate return by value from the
|
||||
RestartIO::load( ) function.
|
||||
A simple class used to communicate values between the simulator and the
|
||||
RestartIO function.
|
||||
*/
|
||||
|
||||
|
||||
struct RestartValue {
|
||||
|
||||
class RestartValue {
|
||||
public:
|
||||
using ExtraVector = std::vector<std::pair<RestartKey, std::vector<double>>>;
|
||||
data::Solution solution;
|
||||
data::Wells wells;
|
||||
std::map<std::string,std::vector<double>> extra = {};
|
||||
ExtraVector extra;
|
||||
|
||||
RestartValue(data::Solution sol, data::Wells wells_arg);
|
||||
|
||||
RestartValue(data::Solution sol, data::Wells wells_arg, std::map<std::string, std::vector<double>> extra_arg) :
|
||||
solution(std::move(sol)),
|
||||
wells(std::move(wells_arg)),
|
||||
extra(std::move(extra_arg))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
RestartValue(data::Solution sol, data::Wells wells_arg) :
|
||||
solution(std::move(sol)),
|
||||
wells(std::move(wells_arg))
|
||||
{
|
||||
}
|
||||
bool hasExtra(const std::string& key) const;
|
||||
void addExtra(const std::string& key, UnitSystem::measure dimension, std::vector<double> data);
|
||||
void addExtra(const std::string& key, std::vector<double> data);
|
||||
const std::vector<double>& getExtra(const std::string& key) const;
|
||||
|
||||
void convertFromSI(const UnitSystem& units);
|
||||
void convertToSI(const UnitSystem& units);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
#ifndef OPM_OUTPUT_SUMMARY_HPP
|
||||
#define OPM_OUTPUT_SUMMARY_HPP
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <ert/ecl/ecl_sum.h>
|
||||
#include <ert/ecl/Smspec.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
||||
|
||||
#include <opm/output/data/Wells.hpp>
|
||||
#include <opm/output/eclipse/RegionCache.hpp>
|
||||
@@ -61,6 +61,10 @@ class Summary {
|
||||
|
||||
~Summary();
|
||||
|
||||
const SummaryState& get_restart_vectors() const;
|
||||
|
||||
void reset_cumulative_quantities(const SummaryState& rstrt);
|
||||
|
||||
private:
|
||||
class keyword_handlers;
|
||||
|
||||
@@ -68,8 +72,8 @@ class Summary {
|
||||
out::RegionCache regionCache;
|
||||
ERT::ert_unique_ptr< ecl_sum_type, ecl_sum_free > ecl_sum;
|
||||
std::unique_ptr< keyword_handlers > handlers;
|
||||
const ecl_sum_tstep_type* prev_tstep = nullptr;
|
||||
double prev_time_elapsed = 0;
|
||||
SummaryState prev_state;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/*
|
||||
Copyright 2019 Equinor.
|
||||
Copyright 2017 Statoil ASA.
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
@@ -42,6 +44,15 @@ namespace Opm {
|
||||
void addPVTW(const PvtwTable& pvtwTable);
|
||||
void addDensity(const DensityTable& density);
|
||||
|
||||
/// Add normalised PVT function tables to INIT file's TAB vector.
|
||||
///
|
||||
/// \param[in] es Valid \c EclipseState object with accurate RUNSPEC
|
||||
/// information on active phases and table dimensions ("TABDIMS").
|
||||
///
|
||||
/// \param[in] logihead Flag specifications identifying which tables
|
||||
/// to output.
|
||||
void addPVTTables(const EclipseState& es);
|
||||
|
||||
/// Add normalised saturation function tables to INIT file's TAB
|
||||
/// vector.
|
||||
///
|
||||
@@ -101,6 +112,30 @@ namespace Opm {
|
||||
const bool gas,
|
||||
const bool oil,
|
||||
const bool wat);
|
||||
|
||||
/// Add gas PVT tables (keywords PVDG and PVTG) to the tabular data
|
||||
/// (TABDIMS and TAB vectors).
|
||||
///
|
||||
/// \param[in] es Valid \c EclipseState object with accurate table
|
||||
/// dimensions ("TABDIMS" keyword) and an initialised \c
|
||||
/// TableManager sub-object.
|
||||
void addGasPVTTables(const EclipseState& es);
|
||||
|
||||
/// Add oil PVT tables (keywords PVCDO, PVDO and PVTO) to the
|
||||
/// tabular data (TABDIMS and TAB vectors).
|
||||
///
|
||||
/// \param[in] es Valid \c EclipseState object with accurate table
|
||||
/// dimensions ("TABDIMS" keyword) and an initialised \c
|
||||
/// TableManager sub-object.
|
||||
void addOilPVTTables(const EclipseState& es);
|
||||
|
||||
/// Add water PVT tables (keyword PVTW) to the tabular data (TABDIMS
|
||||
/// and TAB vectors).
|
||||
///
|
||||
/// \param[in] es Valid \c EclipseState object with accurate table
|
||||
/// dimensions ("TABDIMS" keyword) and an initialised \c
|
||||
/// TableManager sub-object.
|
||||
void addWaterPVTTables(const EclipseState& es);
|
||||
};
|
||||
|
||||
/// Emit normalised tabular information (TABDIMS and TAB vectors) to
|
||||
|
||||
76
opm/output/eclipse/VectorItems/connection.hpp
Normal file
76
opm/output/eclipse/VectorItems/connection.hpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Copyright (c) 2018 Equinor ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_OUTPUT_ECLIPSE_VECTOR_CONNECTION_HPP
|
||||
#define OPM_OUTPUT_ECLIPSE_VECTOR_CONNECTION_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems {
|
||||
namespace IConn {
|
||||
enum index : std::vector<int>::size_type {
|
||||
SeqIndex = 0, // Connection sequence index
|
||||
CellI = 1, // I-location (1-based cell index) of connection
|
||||
CellJ = 2, // J-location (1-based cell index) of connection
|
||||
CellK = 3, // K-location (1-based cell index) of connection
|
||||
ConnStat = 5, // Connection status.
|
||||
// > 0 => open, shut otherwise
|
||||
|
||||
Drainage = 6, // Saturation function (table ID) for drainage
|
||||
Imbibition = 9, // Saturation function (table ID) for imbibition
|
||||
|
||||
ComplNum = 12, // Completion ID (1-based)
|
||||
ConnDir = 13, // Penetration direction (1:X, 2:Y, 3:Z)
|
||||
Segment = 14, // Segment ID of connection
|
||||
// 0 for regular connections, > 0 for MSW.
|
||||
};
|
||||
} // IConn
|
||||
|
||||
namespace SConn {
|
||||
enum index : std::vector<float>::size_type {
|
||||
ConnTrans = 0, // Connection transmissibility factor
|
||||
Depth = 1, // Connection centre depth
|
||||
Diameter = 2, // Connection diameter
|
||||
|
||||
EffectiveKH = 3, // Effective Kh product of connection
|
||||
|
||||
item12 = 11, // Connection transmissibility factor
|
||||
|
||||
SegDistEnd = 20, // Distance to end of connection in segment
|
||||
SegDistStart = 21, // Distance to start of connection in segment
|
||||
|
||||
item30 = 29, // Unknown
|
||||
item31 = 30, // Unknown
|
||||
};
|
||||
} // SConn
|
||||
|
||||
namespace XConn {
|
||||
enum index : std::vector<double>::size_type {
|
||||
OilRate = 0, // Surface flow rate (oil)
|
||||
WaterRate = 1, // Surface flow rate (water)
|
||||
GasRate = 2, // Surface Flow rate (gas)
|
||||
|
||||
Pressure = 34, // Connection pressure value
|
||||
|
||||
ResVRate = 49, // Reservoir voidage rate
|
||||
};
|
||||
} // XConn
|
||||
}}}} // Opm::RestartIO::Helpers::VectorItems
|
||||
|
||||
#endif // OPM_OUTPUT_ECLIPSE_VECTOR_CONNECTION_HPP
|
||||
37
opm/output/eclipse/VectorItems/doubhead.hpp
Normal file
37
opm/output/eclipse/VectorItems/doubhead.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright (c) 2018 Equinor ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_OUTPUT_ECLIPSE_VECTOR_DOUBHEAD_HPP
|
||||
#define OPM_OUTPUT_ECLIPSE_VECTOR_DOUBHEAD_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems {
|
||||
|
||||
// This is a subset of the items in src/opm/output/eclipse/DoubHEAD.cpp .
|
||||
// Promote items from that list to this in order to make them public.
|
||||
enum doubhead : std::vector<double>::size_type {
|
||||
TsInit = 1, // Maximum Length of Next Timestep
|
||||
TsMaxz = 2, // Maximum Length of Timestep After Next
|
||||
TsMinz = 3, // Minumum Length of All Timesteps
|
||||
};
|
||||
|
||||
}}}} // Opm::RestartIO::Helpers::VectorItems
|
||||
|
||||
#endif // OPM_OUTPUT_ECLIPSE_VECTOR_DOUBHEAD_HPP
|
||||
67
opm/output/eclipse/VectorItems/group.hpp
Normal file
67
opm/output/eclipse/VectorItems/group.hpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
Copyright (c) 2018 Equinor ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_OUTPUT_ECLIPSE_VECTOR_GROUP_HPP
|
||||
#define OPM_OUTPUT_ECLIPSE_VECTOR_GROUP_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems {
|
||||
|
||||
namespace XGroup {
|
||||
enum index : std::vector<double>::size_type {
|
||||
OilPrRate = 0, // Group's oil production rate
|
||||
WatPrRate = 1, // Group's water production rate
|
||||
GasPrRate = 2, // Group's gas production rate
|
||||
LiqPrRate = 3, // Group's liquid production rate
|
||||
|
||||
WatInjRate = 5, // Group's water injection rate
|
||||
GasInjRate = 6, // Group's gas injection rate
|
||||
|
||||
WatCut = 8, // Group's producing water cut
|
||||
GORatio = 9, // Group's producing gas/oil ratio
|
||||
|
||||
OilPrTotal = 10, // Group's total cumulative oil production
|
||||
WatPrTotal = 11, // Group's total cumulative water production
|
||||
GasPrTotal = 12, // Group's total cumulative gas production
|
||||
VoidPrTotal = 13, // Group's total cumulative reservoir
|
||||
// voidage production
|
||||
|
||||
WatInjTotal = 15, // Group's total cumulative water injection
|
||||
GasInjTotal = 16, // Group's total cumulative gas injection
|
||||
|
||||
OilPrPot = 22, // Group's oil production potential
|
||||
WatPrPot = 23, // Group's water production potential
|
||||
|
||||
HistOilPrTotal = 135, // Group's total cumulative oil
|
||||
// production (observed/historical rates)
|
||||
HistWatPrTotal = 139, // Group's total cumulative water
|
||||
// production (observed/historical rates)
|
||||
HistWatInjTotal = 140, // Group's total cumulative water
|
||||
// injection (observed/historical rates)
|
||||
HistGasPrTotal = 143, // Group's total cumulative gas
|
||||
// production (observed/historical rates)
|
||||
HistGasInjTotal = 144, // Group's total cumulative gas injection
|
||||
// (observed/historical rates)
|
||||
};
|
||||
} // XGroup
|
||||
|
||||
}}}} // Opm::RestartIO::Helpers::VectorItems
|
||||
|
||||
#endif // OPM_OUTPUT_ECLIPSE_VECTOR_GROUP_HPP
|
||||
90
opm/output/eclipse/VectorItems/intehead.hpp
Normal file
90
opm/output/eclipse/VectorItems/intehead.hpp
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright (c) 2018 Equinor ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_OUTPUT_ECLIPSE_VECTOR_INTEHEAD_HPP
|
||||
#define OPM_OUTPUT_ECLIPSE_VECTOR_INTEHEAD_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems {
|
||||
|
||||
// This is a subset of the items in src/opm/output/eclipse/InteHEAD.cpp .
|
||||
// Promote items from that list to this in order to make them public.
|
||||
enum intehead : std::vector<int>::size_type {
|
||||
ISNUM = 0, // An encoded integer corresponding to the
|
||||
// time the file was created. For files not
|
||||
// originating from ECLIPSE, this value may
|
||||
// be set to zero.
|
||||
|
||||
VERSION = 1, // Simulator version
|
||||
UNIT = 2, // Units convention
|
||||
// 1: METRIC, 2: FIELD, 3: LAB, 4: PVT-M
|
||||
|
||||
NX = 8, // #cells in X direction (Cartesian)
|
||||
NY = 9, // #cells in Y direction (Cartesian)
|
||||
NZ = 10, // #cells in Z direction (Cartesian)
|
||||
NACTIV = 11, // Number of active cells
|
||||
|
||||
PHASE = 14, // Phase indicator:
|
||||
// 1: oil, 2: water, 3: O/W, 4: gas,
|
||||
// 5: G/O, 6: G/W, 7: O/G/W
|
||||
|
||||
NWELLS = 16, // Number of wells
|
||||
NCWMAX = 17, // Maximum number of completions per well
|
||||
NWGMAX = 19, // Maximum number of wells in any well group
|
||||
NGMAXZ = 20, // Maximum number of groups in field
|
||||
|
||||
NIWELZ = 24, // Number of data elements per well in IWEL array
|
||||
// (default 97 for ECLIPSE, 94 for ECLIPSE 300).
|
||||
NSWELZ = 25, // Number of data elements per well in SWEL array
|
||||
NXWELZ = 26, // Number of delements per well in XWEL array
|
||||
NZWELZ = 27, // Number of 8-character words per well in ZWEL array
|
||||
|
||||
NICONZ = 32, // Number of data elements per completion
|
||||
// in ICON array (default 19)
|
||||
NSCONZ = 33, // Number of data elements per completion in SCON array
|
||||
NXCONZ = 34, // Number of data elements per completion in XCON array
|
||||
|
||||
NIGRPZ = 36, // Number of data elements per group in IGRP array
|
||||
NSGRPZ = 37, // Number of data elements per group in SGRP array
|
||||
NXGRPZ = 38, // Number of data elements per group in XGRP array
|
||||
NZGRPZ = 39, // Number of data elements per group in ZGRP array
|
||||
|
||||
NCAMAX = 41, // Maximum number of analytic aquifer connections
|
||||
|
||||
NIAAQZ = 42, // Number of data elements per aquifer in IAAQ array
|
||||
NSAAQZ = 43, // Number of data elements per aquifer in SAAQ array
|
||||
NXAAQZ = 44, // Number of data elements per aquifer in XAAQ array
|
||||
|
||||
NICAQZ = 45, // Number of data elements per aquifer connection in ICAQ array
|
||||
NSCAQZ = 46, // Number of data elements per aquifer connection in SCAQ array
|
||||
NACAQZ = 47, // Number of data elements per aquifer connection in ACAQ array
|
||||
|
||||
NSEGWL = 174, // Number of multisegment wells defined with WELSEG
|
||||
NSWLMX = 175, // Maximum number of segmented wells (item 1 ofWSEGDIMS)
|
||||
NSEGMX = 176, // Maximum number of segments per well (item 2 of WSEGDIMS)
|
||||
NLBRMX = 177, // Maximum number of lateral branches (item 3 of WSEGDIMS)
|
||||
|
||||
NISEGZ = 178, // Number of entries per segment in ISEG array
|
||||
NRSEGZ = 179, // Number of entries per segment in RSEG array
|
||||
NILBRZ = 180, // Number of entries per segment in ILBR array
|
||||
};
|
||||
}}}} // Opm::RestartIO::Helpers::VectorItems
|
||||
|
||||
#endif // OPM_OUTPUT_ECLIPSE_VECTOR_INTEHEAD_HPP
|
||||
64
opm/output/eclipse/VectorItems/msw.hpp
Normal file
64
opm/output/eclipse/VectorItems/msw.hpp
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright (c) 2018 Equinor ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_OUTPUT_ECLIPSE_VECTOR_MSW_HPP
|
||||
#define OPM_OUTPUT_ECLIPSE_VECTOR_MSW_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems {
|
||||
|
||||
namespace ISeg {
|
||||
enum index : std::vector<int>::size_type {
|
||||
SegNo = 0, // Segment number (one-based)
|
||||
OutSeg = 1, // Outlet segment (one-based)
|
||||
InSegCurBranch = 2, // Inflow segment current branch (one-based)
|
||||
BranchNo = 3, // Branch number (one-based)
|
||||
};
|
||||
} // ISeg
|
||||
|
||||
namespace RSeg {
|
||||
enum index : std::vector<double>::size_type {
|
||||
DistOutlet = 0, // Segment's distance to outlet
|
||||
OutletDepthDiff = 1, // Segment's depth differential to outlet
|
||||
SegDiam = 2, // Internal diameter of segment
|
||||
SegRough = 3, // Roughness parameter of segment
|
||||
SegArea = 4, // Cross-sectional area of segment
|
||||
SegVolume = 5, // Physical volume of segment
|
||||
DistBHPRef = 6, // Segment's distance to BHP reference node
|
||||
DepthBHPRef = 7, // Segment's depth differential to BHP ref. node
|
||||
|
||||
TotFlowRate = 8, // Normalised total segment flow rate
|
||||
WatFlowFract = 9, // Normalised Water flow rate fraction
|
||||
GasFlowFract = 10, // Normalised Gas flow rate fraction
|
||||
Pressure = 11, // Segment pressure
|
||||
|
||||
item40 = 39, // Unknown
|
||||
item106 = 105, // Unknown
|
||||
item107 = 106, // Unknown
|
||||
item108 = 107, // Unknown
|
||||
item109 = 108, // Unknown
|
||||
item110 = 109, // Unknown
|
||||
item111 = 110, // Unknown
|
||||
};
|
||||
} // RSeg
|
||||
|
||||
}}}} // Opm::RestartIO::Helpers::VectorItems
|
||||
|
||||
#endif // OPM_OUTPUT_ECLIPSE_VECTOR_MSW_HPP
|
||||
187
opm/output/eclipse/VectorItems/well.hpp
Normal file
187
opm/output/eclipse/VectorItems/well.hpp
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
Copyright (c) 2018 Equinor ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_OUTPUT_ECLIPSE_VECTOR_WELL_HPP
|
||||
#define OPM_OUTPUT_ECLIPSE_VECTOR_WELL_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems {
|
||||
|
||||
namespace IWell {
|
||||
enum index : std::vector<int>::size_type {
|
||||
IHead = 0, // I-location (one-based) of well head
|
||||
JHead = 1, // J-location (one-based) of well head
|
||||
FirstK = 2, // Layer ID (one-based) of top/first connection
|
||||
LastK = 3, // Layer ID (one-based) of bottom/last connection
|
||||
NConn = 4, // Number of active cells connected to well
|
||||
Group = 5, // Index (one-based) of well's current group
|
||||
WType = 6, // Well type (producer vs. injector)
|
||||
ActWCtrl = 7, // Well's active target control mode (constraint).
|
||||
|
||||
item9 = 8, // Unknown
|
||||
item11 = 10, // Unknown
|
||||
VFPTab = 11, // ID (one-based) of well's current VFP table.
|
||||
|
||||
PredReqWCtrl = 15, // Well's requested control mode from
|
||||
// simulation deck (WCONINJE, WCONPROD).
|
||||
|
||||
item18 = 17, // Unknown
|
||||
XFlow = 22,
|
||||
item25 = 24, // Unknown
|
||||
item32 = 31, // Unknown
|
||||
item48 = 47, // Unknown
|
||||
|
||||
HistReqWCtrl = 49, // Well's requested control mode from
|
||||
// simulation deck (WCONHIST, WCONINJH)
|
||||
|
||||
MsWID = 70, // Multisegment well ID
|
||||
// Value 0 for regular wells
|
||||
// Value 1..#MS wells for MS wells
|
||||
NWseg = 71, // Number of well segments
|
||||
// Value 0 for regular wells
|
||||
// Value #segments for MS wells
|
||||
|
||||
CompOrd = 98, // Well's completion ordering scheme.
|
||||
};
|
||||
|
||||
namespace Value {
|
||||
enum WellType : int {
|
||||
WTUnk = 0, // Unknown well type (OPM only)
|
||||
Producer = 1, // Well is producer
|
||||
OilInj = 2, // Well is oil injector
|
||||
WatInj = 3, // Well is water injector
|
||||
GasInj = 4, // Well is gas injector
|
||||
};
|
||||
|
||||
enum WellCtrlMode : int {
|
||||
WMCtlUnk = -10, // Unknown well control mode (OPM only)
|
||||
Group = - 1, // Well under group control
|
||||
Shut = 0, // Well is shut
|
||||
OilRate = 1, // Well controlled by oil rate
|
||||
WatRate = 2, // Well controlled by water rate
|
||||
GasRate = 3, // Well controlled by gas rate
|
||||
LiqRate = 4, // Well controlled by liquid rate
|
||||
|
||||
ResVRate = 5, // Well controlled by
|
||||
// reservoir voidage rate
|
||||
|
||||
THP = 6, // Well controlled by
|
||||
// tubing head pressure target
|
||||
|
||||
BHP = 7, // Well controlled by
|
||||
// bottom-hole pressure target
|
||||
|
||||
CombRate = 9, // Well controlled by linearly
|
||||
// combined rate target
|
||||
};
|
||||
|
||||
enum CompOrder : int {
|
||||
Track = 0, // Connections ordered along
|
||||
// well track (increasing MD)
|
||||
|
||||
Depth = 1, // Connections ordered by inceasing
|
||||
// true vertical depth. Not really
|
||||
// supported in OPM Flow.
|
||||
|
||||
Input = 2, // Connections listed in order of
|
||||
// appearance in simulation model's
|
||||
// COMPDAT keyword.
|
||||
};
|
||||
} // Value
|
||||
} // IWell
|
||||
|
||||
namespace SWell {
|
||||
enum index : std::vector<float>::size_type {
|
||||
OilRateTarget = 0, // Well's current oil rate production target
|
||||
WatRateTarget = 1, // Well's current water rate production target
|
||||
GasRateTarget = 2, // Well's current gas rate production target
|
||||
LiqRateTarget = 3, // Well's current liquid rate production target
|
||||
ResVRateTarget = 4, // Well's current reservoir voidate rate
|
||||
// production target
|
||||
|
||||
THPTarget = 5, // Well's tubing head pressure target
|
||||
BHPTarget = 6, // Well's bottom hole pressure target
|
||||
|
||||
DatumDepth = 9, // Well's reference depth for BHP
|
||||
|
||||
HistLiqRateTarget = 33, // Well's historical/observed liquid
|
||||
// rate target/limit
|
||||
|
||||
HistGasRateTarget = 54, // Well's historical/observed gas rate
|
||||
// target/limit
|
||||
|
||||
HistBHPTarget = 55, // Well's historical/observed bottom
|
||||
// hole pressure target/limit
|
||||
};
|
||||
} // SWell
|
||||
|
||||
namespace XWell {
|
||||
enum index : std::vector<double>::size_type {
|
||||
OilPrRate = 0, // Well's oil production rate
|
||||
WatPrRate = 1, // Well's water production rate
|
||||
GasPrRate = 2, // Well's gas production rate
|
||||
LiqPrRate = 3, // Well's liquid production rate
|
||||
VoidPrRate = 4, // Well's reservoir voidage production rate
|
||||
|
||||
FlowBHP = 6, // Well's flowing/producing bottom hole pressure
|
||||
WatCut = 7, // Well's producing water cut
|
||||
GORatio = 8, // Well's producing gas/oil ratio
|
||||
|
||||
OilPrTotal = 18, // Well's total cumulative oil production
|
||||
WatPrTotal = 19, // Well's total cumulative water production
|
||||
GasPrTotal = 20, // Well's total cumulative gas production
|
||||
VoidPrTotal = 21, // Well's total cumulative reservoir
|
||||
// voidage production
|
||||
|
||||
WatInjTotal = 23, // Well's total cumulative water injection
|
||||
GasInjTotal = 24, // Well's total cumulative gas injection
|
||||
|
||||
GasFVF = 34, // Well's producing gas formation volume factor.
|
||||
|
||||
item37 = 36, // Unknown
|
||||
item38 = 37, // Unknown
|
||||
|
||||
BHPTarget = 41, // Well's current BHP Target/Limit
|
||||
|
||||
HistOilPrTotal = 75, // Well's total cumulative oil production
|
||||
// (observed/historical rates)
|
||||
HistWatPrTotal = 76, // Well's total cumulative water
|
||||
// production (observed/historical rates)
|
||||
HistGasPrTotal = 77, // Well's total cumulative gas production
|
||||
// (observed(historical rates)
|
||||
|
||||
HistWatInjTotal = 81, // Well's total cumulative water injection
|
||||
// (observed/historical rates)
|
||||
HistGasInjTotal = 82, // Well's total cumulative gas injection
|
||||
// (observed/historical rates)
|
||||
|
||||
WatVoidPrRate = 122, // Well's voidage production rate
|
||||
GasVoidPrRate = 123, // Well's voidage production rate
|
||||
};
|
||||
} // XWell
|
||||
|
||||
namespace ZWell {
|
||||
enum index : std::vector<const char*>::size_type {
|
||||
WellName = 0, // Well name
|
||||
};
|
||||
} // ZWell
|
||||
}}}} // Opm::RestartIO::Helpers::VectorItems
|
||||
|
||||
#endif // OPM_OUTPUT_ECLIPSE_VECTOR_WELL_HPP
|
||||
262
opm/output/eclipse/WindowedArray.hpp
Normal file
262
opm/output/eclipse/WindowedArray.hpp
Normal file
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
Copyright (c) 2018 Statoil ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_WINDOWED_ARRAY_HPP
|
||||
#define OPM_WINDOWED_ARRAY_HPP
|
||||
|
||||
#include <cassert>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
|
||||
/// \file
|
||||
///
|
||||
/// Provide facilities to simplify constructing restart vectors
|
||||
/// such as IWEL or RSEG.
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
|
||||
/// Provide read-only and read/write access to constantly sized
|
||||
/// portions/windows of a linearised buffer with an implied
|
||||
/// 1D array structure.
|
||||
///
|
||||
/// Intended as backing store for vectors that have a constant
|
||||
/// number of items per entity (e.g., N integer data items for
|
||||
/// each active group at a report step).
|
||||
///
|
||||
/// \tparam T Element type for underlying data items.
|
||||
template <typename T>
|
||||
class WindowedArray
|
||||
{
|
||||
public:
|
||||
/// Read/write access.
|
||||
using WriteWindow = boost::iterator_range<
|
||||
typename std::vector<T>::iterator>;
|
||||
|
||||
/// Read-only access.
|
||||
using ReadWindow = boost::iterator_range<
|
||||
typename std::vector<T>::const_iterator>;
|
||||
|
||||
using Idx = typename std::vector<T>::size_type;
|
||||
|
||||
/// Distinct compile-time type for number of windows in
|
||||
/// underlying storage.
|
||||
struct NumWindows { Idx value; };
|
||||
|
||||
/// Distinct compile-time type for size of windows
|
||||
/// (number of data items per window.)
|
||||
struct WindowSize { Idx value; };
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// \param[in] n Number of windows.
|
||||
/// \param[in] sz Number of data items per window.
|
||||
explicit WindowedArray(const NumWindows n, const WindowSize sz)
|
||||
: x_ (n.value * sz.value)
|
||||
, windowSize_(sz.value)
|
||||
{}
|
||||
|
||||
/// Retrieve number of windows allocated for this array.
|
||||
Idx numWindows() const
|
||||
{
|
||||
return this->x_.size() / this->windowSize_;
|
||||
}
|
||||
|
||||
/// Retrieve number of data items per windows.
|
||||
Idx windowSize() const
|
||||
{
|
||||
return this->windowSize_;
|
||||
}
|
||||
|
||||
/// Request read/write access to individual window.
|
||||
///
|
||||
/// \param[in] window Numeric ID of particular read/write window.
|
||||
/// Must be in range \code [0 .. numWindows()-1] \endcode.
|
||||
WriteWindow operator[](const Idx window)
|
||||
{
|
||||
assert ((window < this->numWindows()) &&
|
||||
"Window ID Out of Bounds");
|
||||
|
||||
auto b = std::begin(this->x_) + window*this->windowSize_;
|
||||
auto e = b + this->windowSize_;
|
||||
|
||||
return { b, e };
|
||||
}
|
||||
|
||||
/// Request read-only access to individual window.
|
||||
///
|
||||
/// \param[in] window Numeric ID of particular read-only window.
|
||||
/// Must be in range \code [0 .. numWindows()-1] \endcode.
|
||||
ReadWindow operator[](const Idx window) const
|
||||
{
|
||||
assert ((window < this->numWindows()) &&
|
||||
"Window ID Out of Bounds");
|
||||
|
||||
auto b = std::begin(this->x_) + window*this->windowSize_;
|
||||
auto e = b + this->windowSize_;
|
||||
|
||||
return { b, e };
|
||||
}
|
||||
|
||||
/// Get read-only access to full, linearised data items for
|
||||
/// all windows.
|
||||
const std::vector<T>& data() const
|
||||
{
|
||||
return this->x_;
|
||||
}
|
||||
|
||||
/// Extract full, linearised data items for all windows.
|
||||
///
|
||||
/// Destroys the internal state of the \c WindowedArray.
|
||||
std::vector<T> getDataDestructively()
|
||||
{
|
||||
return std::move(this->x_);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<T> x_;
|
||||
|
||||
Idx windowSize_;
|
||||
};
|
||||
|
||||
|
||||
/// Provide read-only and read/write access to constantly sized
|
||||
/// portions/windows of a linearised buffer with an implied
|
||||
/// row/column matrix (2D array) structure.
|
||||
///
|
||||
/// Intended as backing store for vectors that have a constant
|
||||
/// number of items per sub-entity of a fixed number of containing
|
||||
/// entities (e.g., K double precision data items for each of N
|
||||
/// maximum well connections for each of M maximum active wells at
|
||||
/// a particular report step).
|
||||
///
|
||||
/// \tparam T Element type for underlying data items.
|
||||
template <typename T>
|
||||
class WindowedMatrix
|
||||
{
|
||||
private:
|
||||
using NumWindows = typename WindowedArray<T>::NumWindows;
|
||||
|
||||
public:
|
||||
using WriteWindow = typename WindowedArray<T>::WriteWindow;
|
||||
using ReadWindow = typename WindowedArray<T>::ReadWindow;
|
||||
using WindowSize = typename WindowedArray<T>::WindowSize;
|
||||
using Idx = typename WindowedArray<T>::Idx;
|
||||
|
||||
/// Distinct compile-time type for number of matrix rows
|
||||
/// in underlying storage.
|
||||
struct NumRows { Idx value; };
|
||||
|
||||
/// Distinct compile-time type for number of matrix columns
|
||||
/// in underlying storage.
|
||||
struct NumCols { Idx value; };
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// \param[in] nRows Number of rows.
|
||||
/// \param[in] nCols Number of columns.
|
||||
/// \param[in] sz Number of data items per (row,column) window.
|
||||
explicit WindowedMatrix(const NumRows& nRows,
|
||||
const NumCols& nCols,
|
||||
const WindowSize& sz)
|
||||
: data_ (NumWindows{ nRows.value * nCols.value }, sz)
|
||||
, numCols_(nCols.value)
|
||||
{}
|
||||
|
||||
/// Retrieve number of columns allocated for this matrix.
|
||||
Idx numCols() const
|
||||
{
|
||||
return this->numCols_;
|
||||
}
|
||||
|
||||
/// Retrieve number of rows allocated for this matrix.
|
||||
Idx numRows() const
|
||||
{
|
||||
return this->data_.numWindows() / this->numCols();
|
||||
}
|
||||
|
||||
/// Retrieve number of data items per windows.
|
||||
Idx windowSize() const
|
||||
{
|
||||
return this->data_.windowSize();
|
||||
}
|
||||
|
||||
/// Request read/write access to individual window.
|
||||
///
|
||||
/// \param[in] row Numeric ID of particular row in matrix.
|
||||
/// Must be in range \code [0 .. numRows()-1] \endcode.
|
||||
///
|
||||
/// \param[in] col Numeric ID of particular column in matrix.
|
||||
/// Must be in range \code [0 .. numCols()-1] \endcode.
|
||||
///
|
||||
/// \return Read/write window at position \code (row,col) \endcode.
|
||||
WriteWindow operator()(const Idx row, const Idx col)
|
||||
{
|
||||
return this->data_[ this->i(row, col) ];
|
||||
}
|
||||
|
||||
/// Request read-only access to individual window.
|
||||
///
|
||||
/// \param[in] row Numeric ID of particular row in matrix.
|
||||
/// Must be in range \code [0 .. numRows()-1] \endcode.
|
||||
///
|
||||
/// \param[in] col Numeric ID of particular column in matrix.
|
||||
/// Must be in range \code [0 .. numCols()-1] \endcode.
|
||||
///
|
||||
/// \return Read-only window at position \code (row,col) \endcode.
|
||||
ReadWindow operator()(const Idx row, const Idx col) const
|
||||
{
|
||||
return this->data_[ this->i(row, col) ];
|
||||
}
|
||||
|
||||
/// Get read-only access to full, linearised data items for
|
||||
/// all windows.
|
||||
auto data() const
|
||||
-> decltype(std::declval<const WindowedArray<T>>().data())
|
||||
{
|
||||
return this->data_.data();
|
||||
}
|
||||
|
||||
/// Extract full, linearised data items for all windows.
|
||||
///
|
||||
/// Destroys the internal state of the \c WindowedMatrix.
|
||||
auto getDataDestructively()
|
||||
-> decltype(std::declval<WindowedArray<T>>()
|
||||
.getDataDestructively())
|
||||
{
|
||||
return this->data_.getDataDestructively();
|
||||
}
|
||||
|
||||
private:
|
||||
WindowedArray<T> data_;
|
||||
|
||||
Idx numCols_;
|
||||
|
||||
/// Row major (C) order.
|
||||
Idx i(const Idx row, const Idx col) const
|
||||
{
|
||||
return row*this->numCols() + col;
|
||||
}
|
||||
};
|
||||
|
||||
}}} // Opm::RestartIO::Helpers
|
||||
|
||||
#endif // OPM_WINDOW_ARRAY_HPP
|
||||
80
opm/output/eclipse/WriteRestartHelpers.hpp
Executable file
80
opm/output/eclipse/WriteRestartHelpers.hpp
Executable file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
Copyright (c) 2018 Statoil ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_WRITE_RESTART_HELPERS_HPP
|
||||
#define OPM_WRITE_RESTART_HELPERS_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
// Missing definitions (really belong in ert/ecl_well/well_const.h, but not
|
||||
// defined there)
|
||||
#define SCON_KH_INDEX 3
|
||||
|
||||
|
||||
// Forward declarations
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class EclipseGrid;
|
||||
class EclipseState;
|
||||
class Schedule;
|
||||
class Well;
|
||||
class UnitSystem;
|
||||
|
||||
} // Opm
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
|
||||
const double UNIMPLEMENTED_VALUE = 1e-100; // placeholder for values not yet available
|
||||
|
||||
std::vector<double>
|
||||
createDoubHead(const EclipseState& es,
|
||||
const Schedule& sched,
|
||||
const std::size_t lookup_step,
|
||||
const double simTime,
|
||||
const double nextTimeStep);
|
||||
|
||||
|
||||
|
||||
std::vector<int>
|
||||
createInteHead(const EclipseState& es,
|
||||
const EclipseGrid& grid,
|
||||
const Schedule& sched,
|
||||
const double simTime,
|
||||
const int num_solver_steps,
|
||||
const int lookup_step); // The integer index used to look up dynamic properties, e.g. the number of well.
|
||||
|
||||
std::vector<bool>
|
||||
createLogiHead(const EclipseState& es);
|
||||
|
||||
|
||||
std::vector<int> serialize_ICON(int lookup_step, // The integer index used to look up dynamic properties, e.g. the number of well.
|
||||
int ncwmax, // Max number of completions per well, should be entry 17 from createInteHead.
|
||||
int niconz, // Number of elements per completion in ICON, should be entry 32 from createInteHead.
|
||||
const std::vector<const Well*>& sched_wells);
|
||||
|
||||
std::vector<double> serialize_SCON(int lookup_step, // The integer index used to look up dynamic properties, e.g. the number of well.
|
||||
int ncwmax, // Max number of completions per well, should be entry 17 from createInteHead.
|
||||
int nsconz, // Number of elements per completion in SCON, should be entry 33 from createInteHead.
|
||||
const std::vector<const Well*>& sched_wells,
|
||||
const UnitSystem& units);
|
||||
|
||||
}}} // Opm::RestartIO::Helpers
|
||||
|
||||
#endif // OPM_WRITE_RESTART_HELPERS_HPP
|
||||
1100
opm/output/eclipse/libECLRestart.hpp
Executable file
1100
opm/output/eclipse/libECLRestart.hpp
Executable file
File diff suppressed because it is too large
Load Diff
@@ -131,6 +131,9 @@ namespace Opm {
|
||||
|
||||
Deck( const Deck& );
|
||||
|
||||
//! \brief Deleted assignment operator.
|
||||
Deck& operator=(const Deck& rhs) = delete;
|
||||
|
||||
void addKeyword( DeckKeyword&& keyword );
|
||||
void addKeyword( const DeckKeyword& keyword );
|
||||
|
||||
@@ -141,8 +144,10 @@ namespace Opm {
|
||||
UnitSystem& getActiveUnitSystem();
|
||||
UnitSystem& getDefaultUnitSystem();
|
||||
|
||||
const std::string getDataFile() const;
|
||||
const std::string& getInputPath() const;
|
||||
const std::string& getDataFile() const;
|
||||
void setDataFile(const std::string& dataFile);
|
||||
std::string makeDeckPath(const std::string& path) const;
|
||||
|
||||
iterator begin();
|
||||
iterator end();
|
||||
@@ -156,6 +161,7 @@ namespace Opm {
|
||||
UnitSystem activeUnits;
|
||||
|
||||
std::string m_dataFile;
|
||||
std::string input_path;
|
||||
};
|
||||
}
|
||||
#endif /* DECK_HPP */
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace Opm {
|
||||
*/
|
||||
bool operator==(const DeckItem& other) const;
|
||||
bool operator!=(const DeckItem& other) const;
|
||||
|
||||
static bool to_bool(std::string string_value);
|
||||
private:
|
||||
std::vector< double > dval;
|
||||
std::vector< int > ival;
|
||||
|
||||
@@ -28,7 +28,8 @@ namespace Opm {
|
||||
|
||||
class DeckOutput {
|
||||
public:
|
||||
explicit DeckOutput(std::ostream& s);
|
||||
explicit DeckOutput(std::ostream& s, int precision = 10);
|
||||
~DeckOutput();
|
||||
void stash_default( );
|
||||
|
||||
void start_record( );
|
||||
@@ -51,9 +52,11 @@ namespace Opm {
|
||||
size_t default_count;
|
||||
size_t row_count;
|
||||
bool record_on;
|
||||
int org_precision;
|
||||
|
||||
template <typename T> void write_value(const T& value);
|
||||
void write_sep( );
|
||||
void set_precision(int precision);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -44,21 +44,22 @@ namespace Opm {
|
||||
struct AquanconOutput{
|
||||
int aquiferID;
|
||||
std::vector<size_t> global_index;
|
||||
std::vector<double> influx_coeff; // Size = size(global_index)
|
||||
std::vector<std::shared_ptr<double>> influx_coeff; // Size = size(global_index)
|
||||
std::vector<double> influx_multiplier; // Size = size(global_index)
|
||||
std::vector<int> reservoir_face_dir; // Size = size(global_index)
|
||||
std::vector<int> record_index;
|
||||
};
|
||||
|
||||
Aquancon(const EclipseGrid& grid, const Deck& deck);
|
||||
|
||||
const std::vector<Aquancon::AquanconOutput>& getAquOutput() const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void logic_application(std::vector<Aquancon::AquanconOutput>& output_vector);
|
||||
std::vector<Aquancon::AquanconOutput> logic_application(const std::vector<Aquancon::AquanconOutput>& original_vector);
|
||||
|
||||
void collate_function(std::vector<Aquancon::AquanconOutput>& output_vector,
|
||||
std::vector<Opm::AquanconRecord>& m_aqurecord,
|
||||
void collate_function(std::vector<Aquancon::AquanconOutput>& output_vector,
|
||||
std::vector<Opm::AquanconRecord>& m_aqurecord,
|
||||
std::vector<int> m_aquiferID_per_record, int m_maxAquID);
|
||||
|
||||
void convert_record_id_to_aquifer_id(std::vector<int>& record_indices_matching_id, int i,
|
||||
|
||||
@@ -25,20 +25,22 @@
|
||||
This includes the logic for parsing as well as the associated tables. It is meant to be used by opm-grid and opm-simulators in order to
|
||||
implement the Carter Tracy analytical aquifer model in OPM Flow.
|
||||
*/
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/A.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
|
||||
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/Aqudims.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/TableContainer.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/AqutabTable.hpp>
|
||||
#include <boost/concept_check.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class EclipseState;
|
||||
|
||||
class AquiferCT {
|
||||
public:
|
||||
|
||||
@@ -60,6 +62,7 @@ namespace Opm {
|
||||
theta , //angle subtended by the aquifer boundary
|
||||
c2 ; //6.283 (METRIC, PVT-M); 1.1191 (FIELD); 6.283 (LAB).
|
||||
|
||||
std::shared_ptr<double> p0; //Initial aquifer pressure at datum depth, d0
|
||||
std::vector<double> td, pi;
|
||||
};
|
||||
|
||||
@@ -68,23 +71,23 @@ namespace Opm {
|
||||
const std::vector<AquiferCT::AQUCT_data>& getAquifers() const;
|
||||
int getAqInflTabID(size_t aquiferIndex);
|
||||
int getAqPvtTabID(size_t aquiferIndex);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
std::vector<AquiferCT::AQUCT_data> m_aquct;
|
||||
|
||||
//Set the default Pd v/s Td tables (constant terminal rate case for an infinite aquifer) as described in
|
||||
//Van Everdingen, A. & Hurst, W., December, 1949.The Application of the Laplace Transformation to Flow Problems in Reservoirs.
|
||||
|
||||
//Set the default Pd v/s Td tables (constant terminal rate case for an infinite aquifer) as described in
|
||||
//Van Everdingen, A. & Hurst, W., December, 1949.The Application of the Laplace Transformation to Flow Problems in Reservoirs.
|
||||
//Petroleum Transactions, AIME.
|
||||
inline void set_default_tables(std::vector<double>& td, std::vector<double>& pi)
|
||||
{
|
||||
std::vector<double> default_pressure_ = { 0.112, 0.229, 0.315, 0.376, 0.424, 0.469, 0.503, 0.564, 0.616, 0.659, 0.702, 0.735,
|
||||
0.772, 0.802, 0.927, 1.02, 1.101, 1.169, 1.275, 1.362, 1.436, 1.5, 1.556, 1.604,
|
||||
1.651, 1.829, 1.96, 2.067, 2.147, 2.282, 2.388, 2.476, 2.55, 2.615, 2.672, 2.723,
|
||||
{
|
||||
std::vector<double> default_pressure_ = { 0.112, 0.229, 0.315, 0.376, 0.424, 0.469, 0.503, 0.564, 0.616, 0.659, 0.702, 0.735,
|
||||
0.772, 0.802, 0.927, 1.02, 1.101, 1.169, 1.275, 1.362, 1.436, 1.5, 1.556, 1.604,
|
||||
1.651, 1.829, 1.96, 2.067, 2.147, 2.282, 2.388, 2.476, 2.55, 2.615, 2.672, 2.723,
|
||||
2.921, 3.064, 3.173, 3.263, 3.406, 3.516, 3.608, 3.684, 3.75, 3.809, 3.86 };
|
||||
|
||||
std::vector<double> default_time_ = { 0.01, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1,
|
||||
1.5, 2, 2.5, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 40, 50, 60, 70,
|
||||
std::vector<double> default_time_ = { 0.01, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1,
|
||||
1.5, 2, 2.5, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 40, 50, 60, 70,
|
||||
80, 90, 100, 150, 200, 250, 300, 400, 500, 600, 700, 800, 900, 1000 };
|
||||
|
||||
td = default_time_;
|
||||
|
||||
74
opm/parser/eclipse/EclipseState/Aquifetp.hpp
Executable file
74
opm/parser/eclipse/EclipseState/Aquifetp.hpp
Executable file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
Copyright (C) 2017 TNO
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_AQUIFERFETP_HPP
|
||||
#define OPM_AQUIFERFETP_HPP
|
||||
|
||||
/*
|
||||
The Aquiferfetp which stands for AquiferFetkovich is a data container object meant to hold the data for the fetkovich aquifer model.
|
||||
This includes the logic for parsing as well as the associated tables. It is meant to be used by opm-grid and opm-simulators in order to
|
||||
implement the Fetkovich analytical aquifer model in OPM Flow.
|
||||
*/
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/A.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/Aqudims.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/TableContainer.hpp>
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class Aquifetp {
|
||||
public:
|
||||
|
||||
struct AQUFETP_data{
|
||||
|
||||
// Aquifer ID
|
||||
int aquiferID;
|
||||
// Table IDs
|
||||
int inftableID, pvttableID;
|
||||
std::vector<int> cell_id;
|
||||
// Variables constants
|
||||
double J, // Specified Productivity Index
|
||||
rho, // water density in the aquifer
|
||||
C_t, // total rock compressibility
|
||||
V0, // initial volume of water in aquifer
|
||||
d0; // aquifer datum depth
|
||||
std::shared_ptr<double> p0; //Initial aquifer pressure at datum depth d0 - nullptr if the pressure has been defaulted.
|
||||
};
|
||||
|
||||
Aquifetp(const Deck& deck);
|
||||
|
||||
const std::vector<Aquifetp::AQUFETP_data>& getAquifers() const;
|
||||
int getAqPvtTabID(size_t aquiferIndex);
|
||||
|
||||
private:
|
||||
|
||||
std::vector<Aquifetp::AQUFETP_data> m_aqufetp;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -49,10 +49,14 @@ namespace Opm {
|
||||
public:
|
||||
|
||||
Eclipse3DProperties() = default;
|
||||
|
||||
Eclipse3DProperties(const Deck& deck,
|
||||
const TableManager& tableManager,
|
||||
const EclipseGrid& eclipseGrid);
|
||||
|
||||
Eclipse3DProperties( UnitSystem unit_system,
|
||||
const TableManager& tableManager,
|
||||
const EclipseGrid& eclipseGrid);
|
||||
|
||||
std::vector< int > getRegions( const std::string& keyword ) const;
|
||||
std::string getDefaultRegionKeyword() const;
|
||||
@@ -89,6 +93,7 @@ namespace Opm {
|
||||
void handleEQUALREGKeyword(const DeckKeyword& deckKeyword );
|
||||
void handleMULTIREGKeyword(const DeckKeyword& deckKeyword );
|
||||
void handleOPERATEKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager);
|
||||
void handleOPERATERKeyword( const DeckKeyword& deckKeyword);
|
||||
|
||||
void loadGridPropertyFromDeckKeyword(const Box& inputBox,
|
||||
const DeckKeyword& deckKeyword);
|
||||
|
||||
@@ -29,11 +29,13 @@
|
||||
namespace Opm {
|
||||
|
||||
class Deck;
|
||||
class ParseContext;
|
||||
class ErrorGuard;
|
||||
|
||||
class EclipseConfig
|
||||
{
|
||||
public:
|
||||
EclipseConfig(const Deck& deck);
|
||||
EclipseConfig(const Deck& deck, const ParseContext& parseContext, ErrorGuard& errors);
|
||||
|
||||
const InitConfig& init() const;
|
||||
const IOConfig& io() const;
|
||||
|
||||
@@ -23,15 +23,17 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Edit/EDITNNC.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/FaultCollection.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/NNC.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/TransMult.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/SimulationConfig/SimulationConfig.hpp>
|
||||
|
||||
namespace Opm {
|
||||
@@ -64,9 +66,11 @@ namespace Opm {
|
||||
AllProperties = IntProperties | DoubleProperties
|
||||
};
|
||||
|
||||
EclipseState(const Deck& deck , ParseContext parseContext = ParseContext());
|
||||
template<typename T>
|
||||
EclipseState(const Deck& deck , const ParseContext& parseContext, T&& errors);
|
||||
EclipseState(const Deck& deck , const ParseContext& parseContext, ErrorGuard& errors);
|
||||
EclipseState(const Deck& deck);
|
||||
|
||||
const ParseContext& getParseContext() const;
|
||||
const IOConfig& getIOConfig() const;
|
||||
IOConfig& getIOConfig();
|
||||
|
||||
@@ -85,6 +89,11 @@ namespace Opm {
|
||||
const NNC& getInputNNC() const;
|
||||
bool hasInputNNC() const;
|
||||
|
||||
/// editing non-neighboring connections
|
||||
/// the non-standard adjacencies as specified in input deck
|
||||
const EDITNNC& getInputEDITNNC() const;
|
||||
bool hasInputEDITNNC() const;
|
||||
|
||||
const Eclipse3DProperties& get3DProperties() const;
|
||||
const TableManager& getTableManager() const;
|
||||
const EclipseConfig& getEclipseConfig() const;
|
||||
@@ -112,12 +121,12 @@ namespace Opm {
|
||||
void complainAboutAmbiguousKeyword(const Deck& deck,
|
||||
const std::string& keywordName);
|
||||
|
||||
ParseContext m_parseContext;
|
||||
const TableManager m_tables;
|
||||
Runspec m_runspec;
|
||||
EclipseConfig m_eclipseConfig;
|
||||
UnitSystem m_deckUnitSystem;
|
||||
NNC m_inputNnc;
|
||||
EDITNNC m_inputEditNnc;
|
||||
EclipseGrid m_inputGrid;
|
||||
Eclipse3DProperties m_eclipseProperties;
|
||||
const SimulationConfig m_simulationConfig;
|
||||
|
||||
48
opm/parser/eclipse/EclipseState/Edit/EDITNNC.hpp
Normal file
48
opm/parser/eclipse/EclipseState/Edit/EDITNNC.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
Copyright 2018 Equinor AS
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef OPM_COMMON_EDITNNC_HPP
|
||||
#define OPM_COMMON_EDITNNC_HPP
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/NNC.hpp>
|
||||
namespace Opm
|
||||
{
|
||||
|
||||
/// Represents edit information for non-neighboring connections (NNCs, faults, etc.)
|
||||
class EDITNNC
|
||||
{
|
||||
public:
|
||||
EDITNNC() = default;
|
||||
|
||||
/// Construct from input deck
|
||||
explicit EDITNNC(const Deck& deck);
|
||||
/// \brief Get an ordered set of EDITNNC
|
||||
const std::vector<NNCdata>& data() const
|
||||
{
|
||||
return m_editnnc;
|
||||
}
|
||||
/// \brief Get the number of entries
|
||||
size_t size() const;
|
||||
/// \brief Whether EDITNNC was empty.
|
||||
bool empty() const;
|
||||
|
||||
private:
|
||||
std::vector<NNCdata> m_editnnc;
|
||||
};
|
||||
}
|
||||
#endif // OPM_COMMON_EDITNNC_HPP
|
||||
@@ -38,6 +38,7 @@ namespace Opm {
|
||||
|
||||
class Deck;
|
||||
class ZcornMapper;
|
||||
class NNC;
|
||||
|
||||
/**
|
||||
About cell information and dimension: The actual grid
|
||||
@@ -76,6 +77,8 @@ namespace Opm {
|
||||
/// explicitly. If a null pointer is passed, every cell is active.
|
||||
EclipseGrid(const Deck& deck, const int * actnum = nullptr);
|
||||
|
||||
|
||||
static bool hasGDFILE(const Deck& deck);
|
||||
static bool hasCylindricalKeywords(const Deck& deck);
|
||||
static bool hasCornerPointKeywords(const Deck&);
|
||||
static bool hasCartesianKeywords(const Deck&);
|
||||
@@ -85,6 +88,8 @@ namespace Opm {
|
||||
size_t activeIndex(size_t i, size_t j, size_t k) const;
|
||||
size_t activeIndex(size_t globalIndex) const;
|
||||
|
||||
void save(const std::string& filename, UnitSystem::UnitType output_units) const;
|
||||
void addNNC(const NNC& nnc);
|
||||
/*
|
||||
Observe that the there is a getGlobalIndex(i,j,k)
|
||||
implementation in the base class. This method - translating
|
||||
@@ -107,7 +112,7 @@ namespace Opm {
|
||||
PinchMode::ModeEnum getMultzOption( ) const;
|
||||
|
||||
MinpvMode::ModeEnum getMinpvMode() const;
|
||||
double getMinpvValue( ) const;
|
||||
const std::vector<double>& getMinpvVector( ) const;
|
||||
|
||||
|
||||
/*
|
||||
@@ -176,14 +181,14 @@ namespace Opm {
|
||||
const ecl_grid_type * c_ptr() const;
|
||||
|
||||
private:
|
||||
double m_minpvValue;
|
||||
std::vector<double> m_minpvVector;
|
||||
MinpvMode::ModeEnum m_minpvMode;
|
||||
Value<double> m_pinch;
|
||||
PinchMode::ModeEnum m_pinchoutMode;
|
||||
PinchMode::ModeEnum m_multzMode;
|
||||
mutable std::vector<double> volume_cache;
|
||||
mutable std::vector< int > activeMap;
|
||||
bool m_circle = false;
|
||||
|
||||
/*
|
||||
The internal class grid_ptr is a a std::unique_ptr with
|
||||
special copy semantics. The purpose of implementing this is
|
||||
@@ -200,6 +205,7 @@ namespace Opm {
|
||||
ert_ptr( ecl_grid_alloc_copy( src.get() ) ) {}
|
||||
};
|
||||
grid_ptr m_grid;
|
||||
void initBinaryGrid(const Deck& deck);
|
||||
|
||||
void initCornerPointGrid(const std::array<int,3>& dims ,
|
||||
const std::vector<double>& coord ,
|
||||
|
||||
@@ -52,7 +52,7 @@ private:
|
||||
void addFaultFaces(const GridDims& grid,
|
||||
const DeckRecord& faultRecord,
|
||||
const std::string& faultName);
|
||||
OrderedMap<Fault> m_faults;
|
||||
OrderedMap<std::string, Fault> m_faults;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace Opm {
|
||||
|
||||
size_t getNY() const;
|
||||
size_t getNZ() const;
|
||||
size_t operator[](int dim) const;
|
||||
|
||||
const std::array<int, 3> getNXYZ() const;
|
||||
|
||||
@@ -64,6 +65,7 @@ namespace Opm {
|
||||
|
||||
private:
|
||||
void init(const DeckKeyword& keyword);
|
||||
void binary_init(const Deck& deck);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -141,12 +141,13 @@ namespace Opm {
|
||||
void handleMULTIPLYRecord( const DeckRecord& record, BoxManager& boxManager);
|
||||
void handleCOPYRecord( const DeckRecord& record, BoxManager& boxManager);
|
||||
void handleEQUALSRecord( const DeckRecord& record, BoxManager& boxManager);
|
||||
void handleOPERATERecord( const DeckRecord& record , BoxManager& boxManager);
|
||||
|
||||
void handleEQUALREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty );
|
||||
void handleADDREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty );
|
||||
void handleMULTIREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty );
|
||||
void handleCOPYREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty );
|
||||
void handleOPERATERecord( const DeckRecord& record , BoxManager& boxManager);
|
||||
void handleOPERATERRecord( const DeckRecord& record , const GridProperty<int>& regionProperty );
|
||||
/*
|
||||
Iterators over initialized properties. The overloaded
|
||||
operator*() opens the pair which comes natively from the
|
||||
@@ -184,6 +185,11 @@ namespace Opm {
|
||||
const std::string& dimString,
|
||||
const bool defaultInitializable );
|
||||
|
||||
void postAddKeyword(const std::string& name,
|
||||
std::function< std::vector< T >(size_t) > initProcessor,
|
||||
const std::string& dimString);
|
||||
|
||||
|
||||
GridProperty<T>& getKeyword(const std::string& keyword);
|
||||
bool addAutoGeneratedKeyword_(const std::string& keywordName) const;
|
||||
void insertKeyword(const SupportedKeywordInfo& supportedKeyword) const;
|
||||
|
||||
@@ -177,13 +177,91 @@ public:
|
||||
grid and call the cellsEqual( T , std::vector<int>&) overload,
|
||||
otherwise it will return indexEqual( value );
|
||||
*/
|
||||
std::vector<size_t> cellsEqual(T value, const EclipseGrid& grid, bool active = true) const;
|
||||
|
||||
std::vector<size_t> cellsEqual(T value, const EclipseGrid& grid, bool active = true) const;
|
||||
/*
|
||||
Will return a std::vector<T> of the data in the active cells.
|
||||
*/
|
||||
std::vector<T> compressedCopy( const EclipseGrid& grid) const;
|
||||
|
||||
|
||||
/*
|
||||
The grid properties like PORO and SATNUM can be created in essentially two
|
||||
ways; either they can be explicitly assigned in the deck as:
|
||||
|
||||
PORO
|
||||
1000*0.15 /
|
||||
|
||||
or they can be created indirectly through various mathematical operations
|
||||
like:
|
||||
|
||||
MULTIPLY
|
||||
TRANX 0.20 /
|
||||
/
|
||||
|
||||
The deckAssigned() property is used so that we can differentiate between
|
||||
properties which have been explicitly assigned/loaded from the deck, and
|
||||
those where the default construction has been invoked. This functionality
|
||||
is implemented purely to support the TRAN? keywords. The transmissibility
|
||||
is be default calculated by the simulator code, but the TRAN keywords can
|
||||
be used in the deck to manipulate this calculation in two different ways:
|
||||
|
||||
1. TRAN explicitly assigned in GRID section
|
||||
===========================================
|
||||
...
|
||||
TRANX
|
||||
1000*0.026 /
|
||||
|
||||
COPY
|
||||
'TRANX' 'TRANY' /
|
||||
/
|
||||
|
||||
In this case the simulator should detect that the input deck has TRANX
|
||||
specified and just use the input values from the deck. This is the
|
||||
normal handling of keywords, and agrees with e.g. PERMX and PORO. This
|
||||
also applies when the COPY keyword has been used, as in the case of
|
||||
'TRANY' above.
|
||||
|
||||
|
||||
2. TRAN modifier present in EDIT section
|
||||
========================================
|
||||
The scenario here is that there is no mention of TRANX in the GRID
|
||||
section, however the EDIT section contains modifiers like this:
|
||||
|
||||
MULTIPLY
|
||||
TRANX 0.25 /
|
||||
|
||||
I.e. we request the TRANX values to be reduced with a factor of 0.25. In
|
||||
this case the simulator should still calculate transmissibility according
|
||||
to it's normal algorithm, and then subsequently scale that result with a
|
||||
factor of 0.25.
|
||||
|
||||
In this case the input layer needs to autocreate a TRANX keyword,
|
||||
defaulted to 1.0 and then scale that to 0.25.
|
||||
|
||||
|
||||
Now - the important point is that when doing transmissibility calculations
|
||||
the simulator must be able to distinguish between cases 1 and 2,
|
||||
specifically whether the TRANX keyword should be interpreted as absolute
|
||||
values(case 1) or as a multiplier(case 2). That is the purpose of the
|
||||
deckAssigned() property. Pseudo code for the transmissibility calculations
|
||||
in the simulator could be:
|
||||
|
||||
|
||||
const auto& input_tranx = properties.getKeyword("TRANX");
|
||||
if (input_tranx.deckAssigned()) {
|
||||
// set simulator internal transmissibilities to values from input_tranx
|
||||
tranx = input_tranx;
|
||||
} else {
|
||||
// Calculate transmissibilities according to normal simulator algorithm
|
||||
...
|
||||
...
|
||||
// Scale transmissibilities with scale factor from input_tranx
|
||||
tranx *= input_tranx;
|
||||
}
|
||||
|
||||
*/
|
||||
bool deckAssigned() const;
|
||||
|
||||
private:
|
||||
const DeckItem& getDeckItem( const DeckKeyword& );
|
||||
void setDataPoint(size_t sourceIdx, size_t targetIdx, const DeckItem& deckItem);
|
||||
@@ -192,6 +270,7 @@ private:
|
||||
SupportedKeywordInfo m_kwInfo;
|
||||
std::vector<T> m_data;
|
||||
bool m_hasRunPostProcessor = false;
|
||||
bool assigned = false;
|
||||
};
|
||||
|
||||
// initialize the TEMPI grid property using the temperature vs depth
|
||||
|
||||
@@ -50,16 +50,13 @@ namespace Opm {
|
||||
|
||||
|
||||
|
||||
class MULTREGTRecord {
|
||||
public:
|
||||
MULTREGTRecord(const DeckRecord& deckRecord , const std::string& defaultRegion);
|
||||
|
||||
Value<int> m_srcRegion;
|
||||
Value<int> m_targetRegion;
|
||||
double m_transMultiplier;
|
||||
int m_directions;
|
||||
MULTREGT::NNCBehaviourEnum m_nncBehaviour;
|
||||
Value<std::string> m_region;
|
||||
struct MULTREGTRecord {
|
||||
int src_value;
|
||||
int target_value;
|
||||
double trans_mult;
|
||||
int directions;
|
||||
MULTREGT::NNCBehaviourEnum nnc_behaviour;
|
||||
std::string region_name;
|
||||
};
|
||||
|
||||
typedef std::map< std::pair<int , int> , const MULTREGTRecord * > MULTREGTSearchMap;
|
||||
@@ -75,7 +72,7 @@ namespace Opm {
|
||||
double getRegionMultiplier(size_t globalCellIdx1, size_t globalCellIdx2, FaceDir::DirEnum faceDir) const;
|
||||
|
||||
private:
|
||||
void addKeyword( const DeckKeyword& deckKeyword, const std::string& defaultRegion);
|
||||
void addKeyword( const Eclipse3DProperties& props, const DeckKeyword& deckKeyword, const std::string& defaultRegion);
|
||||
void assertKeywordSupported(const DeckKeyword& deckKeyword, const std::string& defaultRegion);
|
||||
std::vector< MULTREGTRecord > m_records;
|
||||
std::map<std::string , MULTREGTSearchMap> m_searchMap;
|
||||
|
||||
@@ -28,6 +28,10 @@ namespace Opm
|
||||
{
|
||||
|
||||
struct NNCdata {
|
||||
NNCdata(size_t c1, size_t c2, double t)
|
||||
: cell1(c1), cell2(c2), trans(t)
|
||||
{}
|
||||
NNCdata() = default;
|
||||
size_t cell1;
|
||||
size_t cell2;
|
||||
double trans;
|
||||
|
||||
@@ -105,6 +105,41 @@ namespace Opm {
|
||||
------ Default ------
|
||||
If no keywords for config of writing restart files have been handled; no restart files are written.
|
||||
|
||||
|
||||
ECL compatible restart
|
||||
======================
|
||||
|
||||
Unfortunately flow & eclipse are not compatible across restarts. The
|
||||
RestartIO implementation can write restart files for flow -> flow restart
|
||||
or alternatively for flow -> eclipse restart. This is regulated by the
|
||||
boolean flag ecl_compatible_restart in the IOConfig class. The difference
|
||||
between the two are as follows:
|
||||
|
||||
ecl_compatible_restart = false:
|
||||
|
||||
1. The 'extra' fields in the RestartValue structure are actually
|
||||
written to disk.
|
||||
|
||||
2. You can optionally ask the RestartIO::save() function to save the
|
||||
solution in double precision.
|
||||
|
||||
3. The RestartIO::save() function will save opm specific vector OPM_IWEL
|
||||
and OPM_XWEL.
|
||||
|
||||
ecl_compatible_restart = true:
|
||||
|
||||
1. The 'extra' fields in the RestartValue are silently ignored.
|
||||
|
||||
2. If request double precision solution data that is silently ignored,
|
||||
it will be float.
|
||||
|
||||
3. The OPM_IWEL and OPM_XWEL vectors will not be written.
|
||||
|
||||
Observe that the solution data in the RestartValue is passed
|
||||
unconditionally to the solution section in the restart file, so if you
|
||||
pass a field in the solution section which Eclipse does not recognize you
|
||||
will end up with a restart file which Eclipse can not read, even if you
|
||||
have set ecl_compatible_restart to true.
|
||||
*/
|
||||
|
||||
|
||||
@@ -117,7 +152,8 @@ namespace Opm {
|
||||
explicit IOConfig( const Deck& );
|
||||
explicit IOConfig( const std::string& input_path );
|
||||
|
||||
|
||||
void setEclCompatibleRST(bool ecl_rst);
|
||||
bool getEclCompatibleRST() const;
|
||||
bool getWriteEGRIDFile() const;
|
||||
bool getWriteINITFile() const;
|
||||
bool getUNIFOUT() const;
|
||||
@@ -138,7 +174,7 @@ namespace Opm {
|
||||
void setOutputDir(const std::string& outputDir);
|
||||
|
||||
const std::string& getBaseName() const;
|
||||
void setBaseName(std::string baseName);
|
||||
void setBaseName(const std::string& baseName);
|
||||
|
||||
/// Return a string consisting of outputpath and basename;
|
||||
/// i.e. /path/to/sim/CASE
|
||||
@@ -163,8 +199,9 @@ namespace Opm {
|
||||
std::string m_deck_filename;
|
||||
bool m_output_enabled = true;
|
||||
std::string m_output_dir;
|
||||
std::string m_base_name;
|
||||
bool m_nosim;
|
||||
std::string m_base_name;
|
||||
bool ecl_compatible_rst = true;
|
||||
|
||||
IOConfig( const GRIDSection&,
|
||||
const RUNSPECSection&,
|
||||
|
||||
@@ -200,7 +200,8 @@ namespace Opm {
|
||||
class SOLUTIONSection;
|
||||
class TimeMap;
|
||||
class Schedule;
|
||||
|
||||
class ParseContext;
|
||||
class ErrorGuard;
|
||||
|
||||
/*The IOConfig class holds data about input / ouput configurations
|
||||
|
||||
@@ -317,19 +318,27 @@ namespace Opm {
|
||||
public:
|
||||
|
||||
RestartConfig();
|
||||
explicit RestartConfig( const Deck& );
|
||||
|
||||
template<typename T>
|
||||
RestartConfig( const Deck&, const ParseContext& parseContext, T&& errors );
|
||||
|
||||
RestartConfig( const Deck&, const ParseContext& parseContext, ErrorGuard& errors );
|
||||
RestartConfig( const Deck& );
|
||||
|
||||
RestartConfig( const SCHEDULESection& schedule,
|
||||
const SOLUTIONSection& solution,
|
||||
const ParseContext& parseContext,
|
||||
ErrorGuard& errors,
|
||||
TimeMap timemap );
|
||||
|
||||
|
||||
int getFirstRestartStep() const;
|
||||
bool getWriteRestartFile(size_t timestep) const;
|
||||
bool getWriteRestartFile(size_t timestep, bool log=true) const;
|
||||
const std::map< std::string, int >& getRestartKeywords( size_t timestep ) const;
|
||||
int getKeyword( const std::string& keyword, size_t timeStep) const;
|
||||
|
||||
void overrideRestartWriteInterval(size_t interval);
|
||||
void handleSolutionSection(const SOLUTIONSection& solutionSection);
|
||||
void handleSolutionSection(const SOLUTIONSection& solutionSection, const ParseContext& parseContext, ErrorGuard& errors);
|
||||
void setWriteInitialRestartFile(bool writeInitialRestartFile);
|
||||
|
||||
RestartSchedule getNode( size_t timestep ) const;
|
||||
@@ -356,12 +365,13 @@ namespace Opm {
|
||||
int m_first_restart_step;
|
||||
bool m_write_initial_RST_file = false;
|
||||
|
||||
void handleScheduleSection( const SCHEDULESection& schedule);
|
||||
void handleScheduleSection( const SCHEDULESection& schedule, const ParseContext& parseContext, ErrorGuard& errors);
|
||||
void update( size_t step, const RestartSchedule& rs);
|
||||
static RestartSchedule rptsched( const DeckKeyword& );
|
||||
|
||||
DynamicState< RestartSchedule > restart_schedule;
|
||||
DynamicState< std::map< std::string, int > > restart_keywords;
|
||||
std::vector< bool > save_keywords;
|
||||
};
|
||||
} //namespace Opm
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#ifndef OPM_INIT_CONFIG_HPP
|
||||
#define OPM_INIT_CONFIG_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/InitConfig/Equil.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/Tabdims.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EndpointScaling.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/UDQConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp>
|
||||
|
||||
namespace Opm {
|
||||
class Deck;
|
||||
@@ -75,7 +75,12 @@ public:
|
||||
return this->nGMax;
|
||||
}
|
||||
|
||||
int maxWellsInField() const
|
||||
{
|
||||
return this->nWMax;
|
||||
}
|
||||
private:
|
||||
int nWMax { 0 };
|
||||
int nCWMax { 0 };
|
||||
int nWGMax { 0 };
|
||||
int nGMax { 0 };
|
||||
@@ -107,27 +112,73 @@ private:
|
||||
int nLatBranchMax;
|
||||
};
|
||||
|
||||
class Runspec {
|
||||
public:
|
||||
explicit Runspec( const Deck& );
|
||||
class EclHysterConfig
|
||||
{
|
||||
public:
|
||||
explicit EclHysterConfig(const Deck& deck);
|
||||
|
||||
const UDQConfig& udqConfig() const noexcept;
|
||||
const Phases& phases() const noexcept;
|
||||
const Tabdims& tabdims() const noexcept;
|
||||
const EndpointScaling& endpointScaling() const noexcept;
|
||||
const Welldims& wellDimensions() const noexcept;
|
||||
const WellSegmentDims& wellSegmentDimensions() const noexcept;
|
||||
int eclPhaseMask( ) const noexcept;
|
||||
|
||||
private:
|
||||
Phases active_phases;
|
||||
Tabdims m_tabdims;
|
||||
EndpointScaling endscale;
|
||||
Welldims welldims;
|
||||
WellSegmentDims wsegdims;
|
||||
UDQConfig udq_config;
|
||||
/*!
|
||||
* \brief Specify whether hysteresis is enabled or not.
|
||||
*/
|
||||
//void setActive(bool yesno);
|
||||
|
||||
/*!
|
||||
* \brief Returns whether hysteresis is enabled (active).
|
||||
*/
|
||||
bool active() const;
|
||||
|
||||
/*!
|
||||
* \brief Return the type of the hysteresis model which is used for capillary pressure.
|
||||
*
|
||||
* -1: capillary pressure hysteresis is disabled
|
||||
* 0: use the Killough model for capillary pressure hysteresis
|
||||
*/
|
||||
int pcHysteresisModel() const;
|
||||
|
||||
/*!
|
||||
* \brief Return the type of the hysteresis model which is used for relative permeability.
|
||||
*
|
||||
* -1: relperm hysteresis is disabled
|
||||
* 0: use the Carlson model for relative permeability hysteresis
|
||||
*/
|
||||
int krHysteresisModel() const;
|
||||
|
||||
private:
|
||||
// enable hysteresis at all
|
||||
bool activeHyst { false };
|
||||
|
||||
// the capillary pressure and the relperm hysteresis models to be used
|
||||
int pcHystMod { 0 };
|
||||
int krHystMod { 0 };
|
||||
};
|
||||
|
||||
|
||||
|
||||
class Runspec {
|
||||
public:
|
||||
explicit Runspec( const Deck& );
|
||||
|
||||
const UDQParams& udqParams() const noexcept;
|
||||
const Phases& phases() const noexcept;
|
||||
const Tabdims& tabdims() const noexcept;
|
||||
const EndpointScaling& endpointScaling() const noexcept;
|
||||
const Welldims& wellDimensions() const noexcept;
|
||||
const WellSegmentDims& wellSegmentDimensions() const noexcept;
|
||||
int eclPhaseMask( ) const noexcept;
|
||||
const EclHysterConfig& hysterPar() const noexcept;
|
||||
|
||||
private:
|
||||
Phases active_phases;
|
||||
Tabdims m_tabdims;
|
||||
EndpointScaling endscale;
|
||||
Welldims welldims;
|
||||
WellSegmentDims wsegdims;
|
||||
UDQParams udq_params;
|
||||
EclHysterConfig hystpar;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif // OPM_RUNSPEC_HPP
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright 2018 Equinor ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ActionAST_HPP
|
||||
#define ActionAST_HPP
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class ActionContext;
|
||||
class ASTNode;
|
||||
|
||||
|
||||
|
||||
class ActionAST{
|
||||
public:
|
||||
ActionAST() = default;
|
||||
explicit ActionAST(const std::vector<std::string>& tokens);
|
||||
bool eval(const ActionContext& context, std::vector<std::string>& matching_wells) const;
|
||||
private:
|
||||
/*
|
||||
The use of a pointer here is to be able to create this class with only a
|
||||
forward declaration of the ASTNode class. Would have prefered to use a
|
||||
unique_ptr, but that requires writing custom destructors - the use of a
|
||||
shared_ptr does not imply any shared ownership.
|
||||
*/
|
||||
std::shared_ptr<ASTNode> condition;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright 2018 Equinor ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ActionContext_HPP
|
||||
#define ActionContext_HPP
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class ActionContext {
|
||||
public:
|
||||
/*
|
||||
Observe that the ActionContext takes a copy of the SummaryState object.
|
||||
*/
|
||||
explicit ActionContext(const SummaryState& summary_state);
|
||||
|
||||
/*
|
||||
The get methods will first check the internal storage in the 'values' map
|
||||
and then subsequently query the SummaryState member.
|
||||
*/
|
||||
double get(const std::string& func, const std::string& arg) const;
|
||||
void add(const std::string& func, const std::string& arg, double value);
|
||||
|
||||
double get(const std::string& func) const;
|
||||
void add(const std::string& func, double value);
|
||||
|
||||
std::vector<std::string> wells(const std::string& func) const;
|
||||
|
||||
private:
|
||||
SummaryState summary_state;
|
||||
std::map<std::string, double> values;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user