Compare commits
1543 Commits
testing/20
...
release/20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69a0a31309 | ||
|
|
3be35ec286 | ||
|
|
0469d28fa2 | ||
|
|
7cd7c7a158 | ||
|
|
7bc1fc8362 | ||
|
|
b573c28594 | ||
|
|
693c4607c8 | ||
|
|
1c17a5daed | ||
|
|
edee59df30 | ||
|
|
c5fcbf2084 | ||
|
|
8e860c4b7a | ||
|
|
ad9fbfe4ea | ||
|
|
53fff6bb3f | ||
|
|
8e23316eba | ||
|
|
d4e6c9ec44 | ||
|
|
ae9712232e | ||
|
|
d376ee9ed4 | ||
|
|
1067b66696 | ||
|
|
ac43482944 | ||
|
|
3ca39f2e62 | ||
|
|
aaaa22e279 | ||
|
|
646d263883 | ||
|
|
f1e0dcea81 | ||
|
|
7b3b26c452 | ||
|
|
5f9d67a6eb | ||
|
|
8e44ca1b2c | ||
|
|
89e2ebd5f9 | ||
|
|
06287e8631 | ||
|
|
4cd26c5f9a | ||
|
|
d4ce9fe909 | ||
|
|
7ee05a9ceb | ||
|
|
8a9814ad16 | ||
|
|
96b7bb65e2 | ||
|
|
4761fe724b | ||
|
|
8488efde1f | ||
|
|
3a89d05646 | ||
|
|
0d3037383a | ||
|
|
de67ce4083 | ||
|
|
0fadb026af | ||
|
|
fe275a55fd | ||
|
|
a44febc314 | ||
|
|
895c43dff0 | ||
|
|
e2ca798005 | ||
|
|
8fa07537fc | ||
|
|
7f9d250fd3 | ||
|
|
5eab9b003f | ||
|
|
14625b3279 | ||
|
|
3cb23e6857 | ||
|
|
f8f1efc0ac | ||
|
|
6d92c1f5de | ||
|
|
c68ec9c28b | ||
|
|
2dd6400d06 | ||
|
|
aa10ded01a | ||
|
|
edaa5ae561 | ||
|
|
aa56a40e8d | ||
|
|
2d7ba6a3c9 | ||
|
|
6c397ff2a8 | ||
|
|
c83feddb28 | ||
|
|
6d9deefb29 | ||
|
|
afaa99d3f4 | ||
|
|
c69a111e7a | ||
|
|
112e698d0a | ||
|
|
7dffd9f2e7 | ||
|
|
a3f2c115f1 | ||
|
|
32ac0034a7 | ||
|
|
17f246c1a7 | ||
|
|
d66f0a664c | ||
|
|
9af248f889 | ||
|
|
3c26314475 | ||
|
|
12e2c9c545 | ||
|
|
79d3f236c2 | ||
|
|
5c280ed72a | ||
|
|
73cc9cff3a | ||
|
|
c736e71e46 | ||
|
|
92f69d7648 | ||
|
|
bad1b1d3fb | ||
|
|
0e1339e648 | ||
|
|
3cc205ee93 | ||
|
|
ad564ad651 | ||
|
|
39c1056c87 | ||
|
|
9f1858265a | ||
|
|
5a9f5c0999 | ||
|
|
a5d943fd8f | ||
|
|
e598aa8cae | ||
|
|
359558536e | ||
|
|
e6e8b070d7 | ||
|
|
278f4ff3c9 | ||
|
|
2f6160ec17 | ||
|
|
a319d7be4f | ||
|
|
8101591277 | ||
|
|
223fe5e7df | ||
|
|
b6824af640 | ||
|
|
3bce48586a | ||
|
|
d1d651a70d | ||
|
|
4de3391fda | ||
|
|
90d0deeafb | ||
|
|
2fa017b29b | ||
|
|
e495207e9f | ||
|
|
5d9a9880ec | ||
|
|
390b6c6f5c | ||
|
|
b7543d4bc9 | ||
|
|
967954fc4b | ||
|
|
d99791d442 | ||
|
|
20523b46cc | ||
|
|
202651c34d | ||
|
|
16a8f4040c | ||
|
|
f2bc961bd4 | ||
|
|
7555c00ac3 | ||
|
|
68ff2f08a7 | ||
|
|
7bac89429e | ||
|
|
032de6c289 | ||
|
|
aa9471dff1 | ||
|
|
5a5a87d602 | ||
|
|
cefdd86f1b | ||
|
|
6865278ac5 | ||
|
|
204ea1a1a2 | ||
|
|
b4908c6fa0 | ||
|
|
2991ce0aea | ||
|
|
b9ded4433a | ||
|
|
7199e1ede4 | ||
|
|
3280f26f10 | ||
|
|
fbe1d211b2 | ||
|
|
9167359570 | ||
|
|
07a998f3c2 | ||
|
|
080225d8e5 | ||
|
|
37203833b3 | ||
|
|
c01dae67f9 | ||
|
|
b8cfa8be68 | ||
|
|
b28540c57f | ||
|
|
1aa4685b62 | ||
|
|
0d31e87072 | ||
|
|
c1cb489106 | ||
|
|
c60032e227 | ||
|
|
d9916d6e50 | ||
|
|
19d12e7ba2 | ||
|
|
ab14d99f0a | ||
|
|
3db106dd5c | ||
|
|
adebeba784 | ||
|
|
44ae1fd574 | ||
|
|
04eb33771c | ||
|
|
78820654c7 | ||
|
|
c51842d65b | ||
|
|
51b3d14851 | ||
|
|
650dd32274 | ||
|
|
809177af03 | ||
|
|
6c34aee00e | ||
|
|
25f8ec6641 | ||
|
|
c55c1799f6 | ||
|
|
6cdd4fd76f | ||
|
|
3f83f2ed56 | ||
|
|
f7b611afec | ||
|
|
a55f691581 | ||
|
|
e738712ad5 | ||
|
|
70daf0f2c8 | ||
|
|
dff62946dd | ||
|
|
0a6dda5d6d | ||
|
|
d2db04ec13 | ||
|
|
f799d7c6b9 | ||
|
|
ce95cd5721 | ||
|
|
4416721686 | ||
|
|
9c4ccd0ff6 | ||
|
|
4ca993400b | ||
|
|
1b63b8193b | ||
|
|
584f7ed5ca | ||
|
|
dc636e244c | ||
|
|
7af66a6eab | ||
|
|
7b2a7aa419 | ||
|
|
3d3f315b0a | ||
|
|
fe99293f33 | ||
|
|
c312c05732 | ||
|
|
b9fa2ec10d | ||
|
|
82a28a29bf | ||
|
|
41a350ad23 | ||
|
|
fd986cb397 | ||
|
|
af878ba229 | ||
|
|
8c5ef89bd3 | ||
|
|
0edd5c2207 | ||
|
|
3f8a8f9de8 | ||
|
|
11d1c7d634 | ||
|
|
3229c343f7 | ||
|
|
9c96588f36 | ||
|
|
69ddffc966 | ||
|
|
604c476554 | ||
|
|
060fb59c57 | ||
|
|
d4ab231124 | ||
|
|
c429a8a800 | ||
|
|
40570f1aba | ||
|
|
a5e897bdc7 | ||
|
|
6100a90e49 | ||
|
|
b41865d268 | ||
|
|
a4c9b05000 | ||
|
|
230c4494ed | ||
|
|
883fb1a337 | ||
|
|
ca744afa27 | ||
|
|
9eb0a01c7b | ||
|
|
17c6d7dbad | ||
|
|
622a093315 | ||
|
|
388d0e99c3 | ||
|
|
f3c065a899 | ||
|
|
dd4cce4e9a | ||
|
|
0bc150794d | ||
|
|
f7a434f274 | ||
|
|
34410cbe41 | ||
|
|
c3b0dab6e5 | ||
|
|
b5ba3405af | ||
|
|
882ce83e91 | ||
|
|
a91c755194 | ||
|
|
727abd0907 | ||
|
|
f214c2cf0f | ||
|
|
ff69737b99 | ||
|
|
ed5b8d0620 | ||
|
|
b1974db82c | ||
|
|
ae75aa3255 | ||
|
|
4f276b896c | ||
|
|
6c47cdb22f | ||
|
|
a281a3c6f4 | ||
|
|
4388c9d72f | ||
|
|
897edca773 | ||
|
|
7d32890d99 | ||
|
|
4bed60df0f | ||
|
|
93e4c2ffec | ||
|
|
6bbf1fcde2 | ||
|
|
93439cf41e | ||
|
|
8c874bf741 | ||
|
|
0e108311e3 | ||
|
|
d2aaff46e0 | ||
|
|
8a88d64bd1 | ||
|
|
d1fd6359af | ||
|
|
2b75ff1c19 | ||
|
|
b7459231d2 | ||
|
|
143d0d097a | ||
|
|
efe7a97b1d | ||
|
|
18ead60ccc | ||
|
|
f9a2c02c5e | ||
|
|
f375213d4b | ||
|
|
a1f35584a9 | ||
|
|
dd609e857a | ||
|
|
8664ce4af7 | ||
|
|
0c526b39f5 | ||
|
|
de7752b3e5 | ||
|
|
48aba21941 | ||
|
|
3070bf4a31 | ||
|
|
c8919ba088 | ||
|
|
4078451840 | ||
|
|
1a23df1e2f | ||
|
|
8efe3cf6a6 | ||
|
|
546cd46926 | ||
|
|
74291cc57f | ||
|
|
fd0cb01957 | ||
|
|
f3bd813f46 | ||
|
|
b957ca6a69 | ||
|
|
b68fe2e63a | ||
|
|
c826e24607 | ||
|
|
41a05a7a98 | ||
|
|
4504b8812f | ||
|
|
365fbd355b | ||
|
|
78ab86e2a3 | ||
|
|
0ae8c4b235 | ||
|
|
3ecb446c20 | ||
|
|
97728e9fda | ||
|
|
af096fddf9 | ||
|
|
0257528ea9 | ||
|
|
fcca1fa823 | ||
|
|
7fc7a8f0ba | ||
|
|
15d70c446f | ||
|
|
b97503d34d | ||
|
|
c01d3b0139 | ||
|
|
7811054029 | ||
|
|
e1bffe7b3d | ||
|
|
525dfdcd69 | ||
|
|
369a99a64a | ||
|
|
d5e0d72f0f | ||
|
|
6dee117f55 | ||
|
|
d2ff536cf3 | ||
|
|
f264c358e7 | ||
|
|
edf6440113 | ||
|
|
ab51fce599 | ||
|
|
f7d4ba037d | ||
|
|
77d6cb24ad | ||
|
|
4000b3226b | ||
|
|
1e10398b52 | ||
|
|
b07632ee50 | ||
|
|
bd18a82ae3 | ||
|
|
a0f05b380b | ||
|
|
b15b0bbec7 | ||
|
|
832a3222fb | ||
|
|
377513fec9 | ||
|
|
7ad764f92f | ||
|
|
6676eb9953 | ||
|
|
7dce180581 | ||
|
|
a88c1d0513 | ||
|
|
58bca59892 | ||
|
|
5267c07444 | ||
|
|
ad96affbbf | ||
|
|
c8e09ff751 | ||
|
|
16d38c3245 | ||
|
|
97ad4baa99 | ||
|
|
690cf8c43b | ||
|
|
15c2e69e9f | ||
|
|
058cefeafa | ||
|
|
e7639f77d0 | ||
|
|
ab2ea1acf3 | ||
|
|
1edf46ffd1 | ||
|
|
1c6e5f5099 | ||
|
|
5ad0c66f55 | ||
|
|
04239afc03 | ||
|
|
6683ac1be6 | ||
|
|
49d61cb4f6 | ||
|
|
318d396adc | ||
|
|
5455bc8425 | ||
|
|
ff79a404be | ||
|
|
1c988dc721 | ||
|
|
7577e6d851 | ||
|
|
7c2a2e574d | ||
|
|
752a9e2501 | ||
|
|
2c8d827945 | ||
|
|
cf9744ff1f | ||
|
|
132fc1ff1b | ||
|
|
6dfab9c621 | ||
|
|
dedc74f299 | ||
|
|
11eb0049da | ||
|
|
753d6dcb92 | ||
|
|
db6b5d2502 | ||
|
|
ad50a22ed7 | ||
|
|
e0ff18ee09 | ||
|
|
1588f3227e | ||
|
|
f813a04269 | ||
|
|
705be62be6 | ||
|
|
7a3b693471 | ||
|
|
08c5e342b2 | ||
|
|
7984d2a0f4 | ||
|
|
1d8f07fe62 | ||
|
|
723113b3b9 | ||
|
|
922afa26c4 | ||
|
|
41bd1eb449 | ||
|
|
17e6599749 | ||
|
|
c54639fc34 | ||
|
|
74baa18cd9 | ||
|
|
807fa9ecdb | ||
|
|
4073722771 | ||
|
|
8553bbf326 | ||
|
|
7bdd294ec5 | ||
|
|
ee26316f92 | ||
|
|
af72086db8 | ||
|
|
e026660c80 | ||
|
|
0296759ad0 | ||
|
|
9d442d3d4f | ||
|
|
5d5bcf6f24 | ||
|
|
9690588dd4 | ||
|
|
7021669758 | ||
|
|
3c22559849 | ||
|
|
5965b194df | ||
|
|
a449636dde | ||
|
|
9e6f8bd1c1 | ||
|
|
a2fc480e16 | ||
|
|
15e192876e | ||
|
|
dcf4347aee | ||
|
|
82accba45b | ||
|
|
22a9ffa7d9 | ||
|
|
a7c5483b0f | ||
|
|
be795af931 | ||
|
|
4cce5f5f1c | ||
|
|
3e1822770d | ||
|
|
f124fc692f | ||
|
|
dc26fd6364 | ||
|
|
80afcd852f | ||
|
|
17e5e3fec3 | ||
|
|
ab235a1eae | ||
|
|
974fef2c44 | ||
|
|
440049ab6c | ||
|
|
6cdae955d2 | ||
|
|
af2a09bde5 | ||
|
|
2aa10a0435 | ||
|
|
208c1a7143 | ||
|
|
12a8656647 | ||
|
|
de5246c701 | ||
|
|
c0c6f35099 | ||
|
|
8d858903f1 | ||
|
|
fa964b5820 | ||
|
|
dad13d2633 | ||
|
|
6b2aadaef7 | ||
|
|
ec36c227d7 | ||
|
|
d097660fcc | ||
|
|
09b445f69d | ||
|
|
8ef902bee5 | ||
|
|
38b6451c73 | ||
|
|
ec250f19f8 | ||
|
|
f0adb01941 | ||
|
|
a69b0bd06f | ||
|
|
07b2f47c7d | ||
|
|
a7956bcf31 | ||
|
|
aa9ed7a995 | ||
|
|
d06c0bfebb | ||
|
|
c516f868e4 | ||
|
|
a9cff8f7a1 | ||
|
|
8e8abee556 | ||
|
|
c0d95e01db | ||
|
|
b00615d21f | ||
|
|
16daa52fbc | ||
|
|
41f18d718c | ||
|
|
00661d6767 | ||
|
|
44bedf0f23 | ||
|
|
65f9fdec5c | ||
|
|
611dc0b565 | ||
|
|
eb30af2b11 | ||
|
|
31357cf40d | ||
|
|
3a15a16848 | ||
|
|
19ca93f227 | ||
|
|
ba34a9fed0 | ||
|
|
7f484b736d | ||
|
|
30b44ef233 | ||
|
|
c7497497f6 | ||
|
|
df4e94e351 | ||
|
|
f7b50a97f7 | ||
|
|
6f7d45750f | ||
|
|
e5013125f1 | ||
|
|
9a6065509b | ||
|
|
441b065b3d | ||
|
|
6d79ab4715 | ||
|
|
86b7d4406e | ||
|
|
7e775ecd17 | ||
|
|
6e93c5ee1f | ||
|
|
d6cbf47e38 | ||
|
|
079cb5fd0b | ||
|
|
6f7a6d47f2 | ||
|
|
a6eef07c76 | ||
|
|
a961f38c63 | ||
|
|
bc2e5f7d00 | ||
|
|
3846c8c7ab | ||
|
|
e186761f4a | ||
|
|
8efaa4dc66 | ||
|
|
bb6fb37ea1 | ||
|
|
97a73ea5a5 | ||
|
|
eee75da9ef | ||
|
|
cb165fb418 | ||
|
|
c9420d1883 | ||
|
|
01f0beb8ca | ||
|
|
7e62206481 | ||
|
|
3aefa3a953 | ||
|
|
e32853808f | ||
|
|
10142b482e | ||
|
|
522dee0a47 | ||
|
|
659fb45d04 | ||
|
|
cf6161ecfe | ||
|
|
03b81d116f | ||
|
|
554ceb87dd | ||
|
|
7e3ad77329 | ||
|
|
31bb6a0164 | ||
|
|
4eb9d5d46a | ||
|
|
4258bce6c5 | ||
|
|
1d5326f664 | ||
|
|
79a2c1bd4d | ||
|
|
e3ade4dff9 | ||
|
|
36338c8a71 | ||
|
|
c94ed2f643 | ||
|
|
5cd93cd702 | ||
|
|
6dc4804a57 | ||
|
|
d0634114c7 | ||
|
|
ee482b9a5f | ||
|
|
e25416c236 | ||
|
|
c40eed027b | ||
|
|
bef36f6c0d | ||
|
|
1ff60496c6 | ||
|
|
b0ad018a74 | ||
|
|
f898d33e65 | ||
|
|
e79b546544 | ||
|
|
1903b9517b | ||
|
|
d12426b9e8 | ||
|
|
d51c31634a | ||
|
|
cbf477e502 | ||
|
|
51517ec6a3 | ||
|
|
50902686b5 | ||
|
|
2002be13e2 | ||
|
|
5103e7b604 | ||
|
|
de107379a1 | ||
|
|
b70140dd4e | ||
|
|
ae27c8a9c6 | ||
|
|
1936f12356 | ||
|
|
de19aca322 | ||
|
|
f51420c6c6 | ||
|
|
27ffc41361 | ||
|
|
ca42ca5968 | ||
|
|
86b1a93b0e | ||
|
|
84116a7d70 | ||
|
|
7c15d79a93 | ||
|
|
eb1d00f9dc | ||
|
|
d20c58da07 | ||
|
|
a1edb0a1f7 | ||
|
|
ff956e7aff | ||
|
|
377294316e | ||
|
|
1715565920 | ||
|
|
f467d05035 | ||
|
|
02278912d6 | ||
|
|
3f773b956f | ||
|
|
4334256c5b | ||
|
|
a3f74c19c4 | ||
|
|
d6d1dbd38b | ||
|
|
1a02bb105a | ||
|
|
e3dc5e07d7 | ||
|
|
af811d2eaf | ||
|
|
083742c368 | ||
|
|
2bfad7ae37 | ||
|
|
c8cd730d5c | ||
|
|
4cde3e7e44 | ||
|
|
8416680368 | ||
|
|
44ddd382a3 | ||
|
|
79da1ba5eb | ||
|
|
a218a1c936 | ||
|
|
e00a32f75c | ||
|
|
29c3310671 | ||
|
|
e02fa5d04f | ||
|
|
9eda0ee1b8 | ||
|
|
0fb287b789 | ||
|
|
858e0b84cf | ||
|
|
39346c3b97 | ||
|
|
bcfc8b4966 | ||
|
|
98338e3326 | ||
|
|
fadcddbc92 | ||
|
|
1a79e811dd | ||
|
|
1caca2df4a | ||
|
|
5e751bb26c | ||
|
|
520df29bd8 | ||
|
|
354c20786d | ||
|
|
9e309375b6 | ||
|
|
74d0703dc2 | ||
|
|
5064519e83 | ||
|
|
1a62ceff7d | ||
|
|
4d1b747b42 | ||
|
|
28c2e7024c | ||
|
|
9ff301625b | ||
|
|
49d32a02fb | ||
|
|
9d9099a8fc | ||
|
|
ef91e18586 | ||
|
|
31176bacbb | ||
|
|
d1052d2034 | ||
|
|
cf9aa917dc | ||
|
|
de641d83d6 | ||
|
|
359955efc3 | ||
|
|
2747f20e24 | ||
|
|
27e1cc654a | ||
|
|
f0c5b914ad | ||
|
|
37b49cabf6 | ||
|
|
b0ad3a2b26 | ||
|
|
c208a59597 | ||
|
|
b55e073182 | ||
|
|
e013066040 | ||
|
|
f63c408ba4 | ||
|
|
bd28038327 | ||
|
|
02c43b7a09 | ||
|
|
3852c5224e | ||
|
|
692edfbf5c | ||
|
|
887a567869 | ||
|
|
8ff8d23146 | ||
|
|
0bfe490609 | ||
|
|
0f7062ef2a | ||
|
|
6016cd43b3 | ||
|
|
93b53df02a | ||
|
|
a06194ecae | ||
|
|
8a57e491c2 | ||
|
|
9516fdd3e6 | ||
|
|
7c856f681d | ||
|
|
9875d5fbd8 | ||
|
|
b9cdb9fb78 | ||
|
|
8c9674856a | ||
|
|
8633f07018 | ||
|
|
22ef5a4cd2 | ||
|
|
ed4bf054fa | ||
|
|
5bb56ff4a8 | ||
|
|
bab637ab67 | ||
|
|
658dc20f36 | ||
|
|
7d26cf44e1 | ||
|
|
7dfc20a4cc | ||
|
|
119cbc33f7 | ||
|
|
24393cc2ef | ||
|
|
9e6666357b | ||
|
|
2d66d15d96 | ||
|
|
dc4aa882be | ||
|
|
12294cb637 | ||
|
|
8a52da5851 | ||
|
|
b48f0affea | ||
|
|
cc14a83ecf | ||
|
|
ad9448c87d | ||
|
|
3655aeb579 | ||
|
|
57c27d603a | ||
|
|
d35a321214 | ||
|
|
c7532005b2 | ||
|
|
c24e220626 | ||
|
|
bb8cfc2e60 | ||
|
|
a304f560d5 | ||
|
|
1073ef3d55 | ||
|
|
787d9d3948 | ||
|
|
8873eb29e4 | ||
|
|
03b2a5c946 | ||
|
|
729948b712 | ||
|
|
d9fea19c5b | ||
|
|
7639dd7e5f | ||
|
|
43a5a153b1 | ||
|
|
a06a49b4d8 | ||
|
|
cd48199c1e | ||
|
|
5bcb80ba70 | ||
|
|
ccefe04230 | ||
|
|
65c4d91b19 | ||
|
|
f386404408 | ||
|
|
28e0b1cc3a | ||
|
|
5b1020151b | ||
|
|
3c77d66cd7 | ||
|
|
fd49cb7787 | ||
|
|
e14b938fde | ||
|
|
11fe1d6e03 | ||
|
|
2fb64e21d9 | ||
|
|
370ce5de1f | ||
|
|
5a39b0e249 | ||
|
|
2e1ef048df | ||
|
|
2ff8816bb7 | ||
|
|
eede6b05b5 | ||
|
|
a23c87be94 | ||
|
|
693395e78d | ||
|
|
6324d5d6c8 | ||
|
|
bc1403e1c6 | ||
|
|
f509c3e236 | ||
|
|
f2fe00b819 | ||
|
|
a886a2334b | ||
|
|
e79d1396df | ||
|
|
63c6eeb30e | ||
|
|
10890cc793 | ||
|
|
7494990611 | ||
|
|
9bb64df26e | ||
|
|
ceb9f01571 | ||
|
|
430cc9d7b2 | ||
|
|
ffba2b114b | ||
|
|
160f0f83e1 | ||
|
|
7559c31e43 | ||
|
|
6426644ce4 | ||
|
|
3d07072f08 | ||
|
|
2248a1133d | ||
|
|
2c8e4cb6b0 | ||
|
|
492fba07fc | ||
|
|
c87acf6571 | ||
|
|
c720dfe8a8 | ||
|
|
b860fdbccc | ||
|
|
4dbb33cce6 | ||
|
|
6a7191c376 | ||
|
|
6039cfa7ed | ||
|
|
3e078e76b1 | ||
|
|
43c504593f | ||
|
|
3e576b6332 | ||
|
|
748fd20e57 | ||
|
|
8d59054112 | ||
|
|
8d439e6260 | ||
|
|
085d7d23b6 | ||
|
|
83e2029af4 | ||
|
|
88afb50d09 | ||
|
|
f0215f1a3d | ||
|
|
2b41c40c58 | ||
|
|
1c777c5ba5 | ||
|
|
011666b3f9 | ||
|
|
6aabb6958d | ||
|
|
0694515c69 | ||
|
|
7f521652f4 | ||
|
|
8740a8dc1a | ||
|
|
3f5f4c1b40 | ||
|
|
54c8e107b7 | ||
|
|
c3dcedc392 | ||
|
|
e877de94bb | ||
|
|
5144456aa4 | ||
|
|
5f8d24c431 | ||
|
|
13bd564edf | ||
|
|
0aaf9823c1 | ||
|
|
a64745193d | ||
|
|
fe83324746 | ||
|
|
f48462841f | ||
|
|
89acca0fd7 | ||
|
|
c41ea17ba6 | ||
|
|
1cd6ebb403 | ||
|
|
522db6d093 | ||
|
|
a7aa78b7e9 | ||
|
|
33783b1e9f | ||
|
|
d61d9c920b | ||
|
|
17a2e5d334 | ||
|
|
8f7e6ccd94 | ||
|
|
51adb23728 | ||
|
|
7245598952 | ||
|
|
ba462d67cf | ||
|
|
62a3b7334d | ||
|
|
c314464ef3 | ||
|
|
57cc97af47 | ||
|
|
34d1918a2d | ||
|
|
39f8eb18c7 | ||
|
|
597bbde151 | ||
|
|
28ba27184a | ||
|
|
4baff64d63 | ||
|
|
0cf83567eb | ||
|
|
034488c902 | ||
|
|
fb8de64487 | ||
|
|
7c0b2df272 | ||
|
|
290123bc33 | ||
|
|
11bc26d28d | ||
|
|
a68db0a857 | ||
|
|
563c6317d4 | ||
|
|
8dbb8d70fc | ||
|
|
90ebc66c0b | ||
|
|
d32e0f6eaf | ||
|
|
dba43a4a5e | ||
|
|
82535a9136 | ||
|
|
ad9c818574 | ||
|
|
143c73cdd0 | ||
|
|
ef936afeaa | ||
|
|
5bed559f96 | ||
|
|
c26538f433 | ||
|
|
0d5cd70536 | ||
|
|
7475636610 | ||
|
|
cd43bb7a5f | ||
|
|
b116eda8bc | ||
|
|
29697a0906 | ||
|
|
28110584a3 | ||
|
|
c0c9d70dcf | ||
|
|
fbfdf5c244 | ||
|
|
c63e23c140 | ||
|
|
465ab091e0 | ||
|
|
189e84d40e | ||
|
|
b0d180b409 | ||
|
|
a8396de668 | ||
|
|
ae7ea2a286 | ||
|
|
694d17a228 | ||
|
|
a84771013b | ||
|
|
31415679f7 | ||
|
|
ecc653cce4 | ||
|
|
bb292365ff | ||
|
|
95070310f3 | ||
|
|
6efe981234 | ||
|
|
2fbf3c4fc9 | ||
|
|
ca7fe55934 | ||
|
|
a3d411279f | ||
|
|
4de0a7e9e3 | ||
|
|
ffecc035c0 | ||
|
|
763702fd0f | ||
|
|
6eea66a332 | ||
|
|
a4eeb57a58 | ||
|
|
4a08b57b23 | ||
|
|
65f8812e46 | ||
|
|
b14bd5acce | ||
|
|
677009317e | ||
|
|
e487dc1da5 | ||
|
|
281f701f27 | ||
|
|
fa37250446 | ||
|
|
323e9903b4 | ||
|
|
a4b9b0d460 | ||
|
|
cbc7394d60 | ||
|
|
9ed68a9f1f | ||
|
|
ab6ea86eac | ||
|
|
747a643288 | ||
|
|
41a74beb3e | ||
|
|
886e90c770 | ||
|
|
6bbfd66744 | ||
|
|
0f52c6a0ee | ||
|
|
fe6fdf4589 | ||
|
|
0631d4ad01 | ||
|
|
746a62b149 | ||
|
|
e4d030c891 | ||
|
|
bf6a0335b0 | ||
|
|
96b7797c4e | ||
|
|
f8aa13f6e8 | ||
|
|
ead8cfc1e9 | ||
|
|
98aafa4a9e | ||
|
|
260365870a | ||
|
|
df74ac102e | ||
|
|
2ecfa6e7b2 | ||
|
|
5604c4c3ba | ||
|
|
3d7bcb19ee | ||
|
|
63c802666d | ||
|
|
036951444c | ||
|
|
217e63b1fd | ||
|
|
c9ca9717bc | ||
|
|
4018e4b70b | ||
|
|
b72439387e | ||
|
|
5395add039 | ||
|
|
f71dec426a | ||
|
|
bf752c81a5 | ||
|
|
fcdca4a4d7 | ||
|
|
acfa281f77 | ||
|
|
1da4bd2ea4 | ||
|
|
729dc8dbd9 | ||
|
|
7a8d092c8b | ||
|
|
1c8d0bb0ab | ||
|
|
36651b803c | ||
|
|
e360b4b34e | ||
|
|
af2e3190a2 | ||
|
|
73839c43d2 | ||
|
|
3f2eefc638 | ||
|
|
da1fb0b744 | ||
|
|
7394a654bb | ||
|
|
7e5c9dee67 | ||
|
|
c638e5d1a0 | ||
|
|
2da74c7d80 | ||
|
|
5e88782e51 | ||
|
|
24f44c1c64 | ||
|
|
4161a1339a | ||
|
|
7d0b6f1bf6 | ||
|
|
212150e7b8 | ||
|
|
a1d4fe13af | ||
|
|
55f9c8c24f | ||
|
|
599ed7136f | ||
|
|
93256637af | ||
|
|
fc4fa45b69 | ||
|
|
faff634bab | ||
|
|
b259c807fd | ||
|
|
ef949aef7e | ||
|
|
52881467d6 | ||
|
|
d2f692ebae | ||
|
|
e6d299c726 | ||
|
|
a2817325fd | ||
|
|
ea208bbd56 | ||
|
|
79a5ba09e2 | ||
|
|
2c82787ee9 | ||
|
|
1bc47ca8a2 | ||
|
|
d73d0ccc99 | ||
|
|
5bc282d60e | ||
|
|
c09bc36c03 | ||
|
|
87d13c24f1 | ||
|
|
f01ed130af | ||
|
|
51b484d930 | ||
|
|
cc5b74fa94 | ||
|
|
53c1e07edf | ||
|
|
542353b118 | ||
|
|
2c5d0af37a | ||
|
|
51a779df67 | ||
|
|
7a1ed147f4 | ||
|
|
141aa41e30 | ||
|
|
5748d06914 | ||
|
|
8d2398612b | ||
|
|
327e6c3a5c | ||
|
|
d45731a205 | ||
|
|
772bd3cee5 | ||
|
|
83cb209ad8 | ||
|
|
49ac8e85d6 | ||
|
|
a19d253aa7 | ||
|
|
eb05c5b6aa | ||
|
|
9087323265 | ||
|
|
fac74432d4 | ||
|
|
6376e4dcc6 | ||
|
|
b630ecfb5b | ||
|
|
8cdc72549d | ||
|
|
6aea354ff4 | ||
|
|
66e8068494 | ||
|
|
193eeca5ff | ||
|
|
d1ec2e151c | ||
|
|
3d6ace0f97 | ||
|
|
71c046bef4 | ||
|
|
0a3d26e9be | ||
|
|
edbc9d2af7 | ||
|
|
44e21101bc | ||
|
|
f3abbf4981 | ||
|
|
ba2a12e876 | ||
|
|
1c14c0d921 | ||
|
|
3961f724db | ||
|
|
0c43f49f13 | ||
|
|
08305b6e30 | ||
|
|
51bd7a197d | ||
|
|
498a1bb677 | ||
|
|
bab231287e | ||
|
|
ebcac44715 | ||
|
|
edfacf2af8 | ||
|
|
40b556112f | ||
|
|
7413ce5a40 | ||
|
|
66fee23319 | ||
|
|
dff91dd742 | ||
|
|
82f88ce973 | ||
|
|
b1067dbc98 | ||
|
|
4cde0ac8a8 | ||
|
|
a3074d12b5 | ||
|
|
6af9b00bee | ||
|
|
ec20274fa3 | ||
|
|
8d65ba4e49 | ||
|
|
16e49a0223 | ||
|
|
c98bf7d4c8 | ||
|
|
725ac521ba | ||
|
|
82b0a2d82b | ||
|
|
cb106240bf | ||
|
|
89c8cb886b | ||
|
|
9aee2bee71 | ||
|
|
0757bd97cf | ||
|
|
add1a96d99 | ||
|
|
8eda3aaa15 | ||
|
|
32a1c3b5da | ||
|
|
7ec2ee9bff | ||
|
|
c9d1c50986 | ||
|
|
48c363dafa | ||
|
|
a2ec7d7f6d | ||
|
|
df1a011b78 | ||
|
|
992d3b0ce5 | ||
|
|
c71f57f635 | ||
|
|
2580a273f4 | ||
|
|
b9aeeab005 | ||
|
|
0dfe6ce7da | ||
|
|
2682eef9b3 | ||
|
|
8189dd8c9f | ||
|
|
5c65299c0a | ||
|
|
35a70310c6 | ||
|
|
54af290cc0 | ||
|
|
c8b0988191 | ||
|
|
e6b8e53d0a | ||
|
|
779a2b8d89 | ||
|
|
0c23aafc34 | ||
|
|
4439882402 | ||
|
|
8e87ffc7da | ||
|
|
418241137c | ||
|
|
01db100439 | ||
|
|
e3d9ef07eb | ||
|
|
51aee6e8cb | ||
|
|
73667596fc | ||
|
|
9dacc42c8a | ||
|
|
8fdb08b0ad | ||
|
|
0942e2dce1 | ||
|
|
01c0820d4c | ||
|
|
d11d26a2f1 | ||
|
|
584defebe0 | ||
|
|
43c5d3509a | ||
|
|
1caf9ecff0 | ||
|
|
51c805d280 | ||
|
|
eb24f72e5e | ||
|
|
e654915069 | ||
|
|
464bc4b795 | ||
|
|
94b160258e | ||
|
|
1d31de03c7 | ||
|
|
ad9cc20258 | ||
|
|
c0ccd06250 | ||
|
|
eb2c0b7441 | ||
|
|
c986c49113 | ||
|
|
5a31ae874b | ||
|
|
cd55d69ef7 | ||
|
|
76acb98c67 | ||
|
|
30a1a0b26e | ||
|
|
16dabd5dc4 | ||
|
|
272d0fc9a1 | ||
|
|
8231b84a11 | ||
|
|
c1f60b769c | ||
|
|
d42e86426f | ||
|
|
4010399f08 | ||
|
|
5f43a18050 | ||
|
|
cf970df48f | ||
|
|
c1f4c69c30 | ||
|
|
0c70d71df8 | ||
|
|
07b02ed151 | ||
|
|
2c7eb20726 | ||
|
|
255ffc5bba | ||
|
|
d7e41a5ac0 | ||
|
|
d554334316 | ||
|
|
4989c6cfec | ||
|
|
c92d74107f | ||
|
|
8126e8cb66 | ||
|
|
ba1c30fd4a | ||
|
|
25f25d15bf | ||
|
|
bd58468930 | ||
|
|
546517784e | ||
|
|
9e288a9d78 | ||
|
|
294c8aa2f7 | ||
|
|
de17c851bc | ||
|
|
50f907f608 | ||
|
|
38f483ae37 | ||
|
|
9b9fc2ef37 | ||
|
|
a8e7c03a4f | ||
|
|
1c82a8ad39 | ||
|
|
0ddf4d675e | ||
|
|
bce535c19f | ||
|
|
a265a99469 | ||
|
|
7835eeb142 | ||
|
|
4b8743d10f | ||
|
|
30733e4966 | ||
|
|
9fe4b23dcb | ||
|
|
eb30732444 | ||
|
|
77795b5005 | ||
|
|
e8dbf7d8ee | ||
|
|
0660ced877 | ||
|
|
ccd6a2b9da | ||
|
|
452742a6a2 | ||
|
|
0f3dabc3aa | ||
|
|
49cc815136 | ||
|
|
a3da1e23a2 | ||
|
|
7dba7a50cf | ||
|
|
8687a8a709 | ||
|
|
92caf4f010 | ||
|
|
894ad7a226 | ||
|
|
a9775f6945 | ||
|
|
559783d311 | ||
|
|
b7b9697fc5 | ||
|
|
35516f1b90 | ||
|
|
7a47f7cf2d | ||
|
|
0466effc93 | ||
|
|
bf6964522e | ||
|
|
d08760a922 | ||
|
|
b148769cc6 | ||
|
|
656878d649 | ||
|
|
8f7724409c | ||
|
|
de96af682a | ||
|
|
f4009fc6d8 | ||
|
|
9d8b08a8d8 | ||
|
|
605d7399a6 | ||
|
|
58a039c04a | ||
|
|
e954836774 | ||
|
|
2d69121b5a | ||
|
|
1cde5a4879 | ||
|
|
fffe259621 | ||
|
|
b955ecf6b4 | ||
|
|
5cfb91df24 | ||
|
|
a4bdba5841 | ||
|
|
dcdcc659b2 | ||
|
|
e833377bea | ||
|
|
fbece57167 | ||
|
|
54f45eaba7 | ||
|
|
7aa55f86a0 | ||
|
|
c3bd4b9e3a | ||
|
|
688edd6f63 | ||
|
|
c1af5a313f | ||
|
|
167a7a8c38 | ||
|
|
abc674d40f | ||
|
|
9c93a9349c | ||
|
|
44f8a5d94e | ||
|
|
7ef2d8b9a3 | ||
|
|
efb8375bac | ||
|
|
eff44e4fdc | ||
|
|
d5f240050a | ||
|
|
454a933b5a | ||
|
|
5e76f624ef | ||
|
|
14168f3ea6 | ||
|
|
b5dbc3d8e5 | ||
|
|
34dfbee01b | ||
|
|
027be42f70 | ||
|
|
eef4cad54f | ||
|
|
19ccc21786 | ||
|
|
521838dbdd | ||
|
|
393a543ed5 | ||
|
|
b562bef1af | ||
|
|
414b6820b4 | ||
|
|
5dbc22484e | ||
|
|
8b838264dd | ||
|
|
c533e1206f | ||
|
|
d87f9edf60 | ||
|
|
dbff25f79b | ||
|
|
4b657fc4cf | ||
|
|
a4e66a5484 | ||
|
|
226bfbe524 | ||
|
|
164ab30fa1 | ||
|
|
d5ce2b6a76 | ||
|
|
2997338eb2 | ||
|
|
ebedc9b0b6 | ||
|
|
ac58d8428c | ||
|
|
ba58cbc166 | ||
|
|
bd0c0f6356 | ||
|
|
135f2d491a | ||
|
|
fbfac1f797 | ||
|
|
4768f72400 | ||
|
|
db142f698b | ||
|
|
c54cb2195b | ||
|
|
24a8efb2e3 | ||
|
|
181eeffbdb | ||
|
|
46f2542487 | ||
|
|
6d1b2f3f4f | ||
|
|
188f78f2d6 | ||
|
|
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 | ||
|
|
2783737034 | ||
|
|
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 | ||
|
|
a6587b3f68 | ||
|
|
6ab8c9611c | ||
|
|
249cee7766 | ||
|
|
70ba4fbc81 | ||
|
|
93485e2aec | ||
|
|
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 | ||
|
|
25fbff2632 | ||
|
|
e3e67874dd | ||
|
|
b7fc40078b | ||
|
|
70cb7f0084 | ||
|
|
cf7c2ee537 | ||
|
|
c4b9378245 | ||
|
|
55eeb620ac | ||
|
|
dcb4528e71 | ||
|
|
0a378bd49d | ||
|
|
6d2a4b5daa | ||
|
|
e46f3bf48a | ||
|
|
f3f702e503 | ||
|
|
eed1309b7a | ||
|
|
d6147c386f | ||
|
|
514df9c289 | ||
|
|
b50da115b9 | ||
|
|
d22ba5b19a | ||
|
|
7ab73165be | ||
|
|
800a4221ec | ||
|
|
ef2384baf7 | ||
|
|
ca4400224f | ||
|
|
7dc82a43e3 | ||
|
|
9f802a30ee | ||
|
|
1f9de9be02 | ||
|
|
4591353f68 | ||
|
|
2252a7bd33 | ||
|
|
23153f32ab | ||
|
|
83428bd716 | ||
|
|
0ae305fc5d | ||
|
|
cc82c1241e | ||
|
|
86625ee014 | ||
|
|
d33a5a39b6 | ||
|
|
371f8fe59e | ||
|
|
60f1ac8c67 | ||
|
|
baa4524a56 | ||
|
|
66cf592e8d | ||
|
|
83f2714766 | ||
|
|
c61218c496 | ||
|
|
f22e884eb4 | ||
|
|
491c1461f2 | ||
|
|
4f26da6e20 | ||
|
|
ee0bbb70bb | ||
|
|
86215b69a1 | ||
|
|
c708381f52 | ||
|
|
5eed642924 | ||
|
|
67b30fe715 | ||
|
|
1566cd4e37 | ||
|
|
2318c7cea4 | ||
|
|
b5336fb128 | ||
|
|
54f66af2bd | ||
|
|
6f6cdbc1dc | ||
|
|
ffe2babdd9 | ||
|
|
5d13eddfc8 | ||
|
|
e2a66f2bfe | ||
|
|
524af0dcf0 | ||
|
|
69f74c858a | ||
|
|
d89412e238 | ||
|
|
c5fc5a0120 | ||
|
|
02f41b0524 | ||
|
|
2b9691e62c | ||
|
|
800a06c253 | ||
|
|
490a0ac15c | ||
|
|
2823c0672a | ||
|
|
a1424cc2fa | ||
|
|
b21d3e84c4 | ||
|
|
501235485f | ||
|
|
b15ab2dd01 | ||
|
|
eaee5429df | ||
|
|
2cfdfc8b98 | ||
|
|
56f326eec8 | ||
|
|
fc594faaa4 | ||
|
|
4be3d3ccd2 | ||
|
|
0ab722902d | ||
|
|
e1d860506a | ||
|
|
11fe32df4f | ||
|
|
9acb937361 | ||
|
|
8f89b598f4 | ||
|
|
79b9f66609 | ||
|
|
e92bd4bd36 | ||
|
|
4f2a8f8651 | ||
|
|
132ed34fa3 | ||
|
|
287834134c | ||
|
|
4982f0fd61 | ||
|
|
4607224642 | ||
|
|
163af49d18 | ||
|
|
d5efa529ab | ||
|
|
1959bce335 | ||
|
|
875c4efa8c | ||
|
|
1615417bd6 | ||
|
|
0e5fb1e0e0 | ||
|
|
836098e6a8 | ||
|
|
dd56505825 | ||
|
|
68a3df64c2 | ||
|
|
a4ff0e1114 | ||
|
|
c66cf7e159 | ||
|
|
e1f64e83e0 | ||
|
|
1ed4517d65 | ||
|
|
d966376562 | ||
|
|
7a6fff51ca | ||
|
|
0d8610ad04 | ||
|
|
a30de369f9 | ||
|
|
8e5d3149c0 | ||
|
|
e2485b0c22 | ||
|
|
af518e8908 | ||
|
|
7bdb0c7250 | ||
|
|
62de76c8f3 | ||
|
|
d52da78ecc | ||
|
|
42fc9b27d1 | ||
|
|
70a9ef173e | ||
|
|
38e483fa5f | ||
|
|
39fa96b02f | ||
|
|
afb28c00c2 | ||
|
|
cd75e134d5 | ||
|
|
c606a2cc6e | ||
|
|
1a419c88b6 | ||
|
|
4f89ed02af | ||
|
|
2d1b96d908 | ||
|
|
dc293f9ec6 | ||
|
|
bdb579b8db | ||
|
|
f6a6afa998 | ||
|
|
f26bc01f54 | ||
|
|
82e18c5147 | ||
|
|
2408611fb8 | ||
|
|
f70793129d | ||
|
|
2eab759227 | ||
|
|
a4d61d3493 | ||
|
|
435d0d3a2e | ||
|
|
8ac3570255 | ||
|
|
60f1c983c6 | ||
|
|
1903790bbe | ||
|
|
0edb093b41 | ||
|
|
15362a145e | ||
|
|
793f0b7be7 | ||
|
|
c2d4372a1e | ||
|
|
3876d67a96 | ||
|
|
a96a1317b0 | ||
|
|
c1bfade15f | ||
|
|
d3618225f0 | ||
|
|
b655f2d178 | ||
|
|
0f59ab1755 | ||
|
|
bd5fa1e335 | ||
|
|
b33190d30c | ||
|
|
6426407d9b | ||
|
|
9110164aa1 | ||
|
|
d669187eea | ||
|
|
bd3fae1b83 | ||
|
|
b2b5c471c1 | ||
|
|
f82990404f | ||
|
|
25bd997ffd | ||
|
|
19fcb1f6b8 | ||
|
|
b2748596ca | ||
|
|
a324a008fd | ||
|
|
96892ec07a | ||
|
|
463659047e | ||
|
|
fa7a3029d3 | ||
|
|
321ef1d194 | ||
|
|
25a3007a1e | ||
|
|
a9b537f5e8 | ||
|
|
c156eea300 | ||
|
|
ba06217321 | ||
|
|
79a61ac3c7 | ||
|
|
76ae686880 | ||
|
|
848978c155 | ||
|
|
c4c8eaf887 | ||
|
|
0186739c13 | ||
|
|
769a0eef8a | ||
|
|
823b4e4faf |
20
.clang-format
Normal file
20
.clang-format
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
BasedOnStyle: WebKit,
|
||||
AlignAfterOpenBracket: AlwaysBreak,
|
||||
AlignConsecutiveAssignments: false,
|
||||
AlignConsecutiveDeclarations: false,
|
||||
AlignAfterOpenBracket: Align,
|
||||
AllowShortBlocksOnASingleLine: false,
|
||||
AllowShortFunctionsOnASingleLine: None,
|
||||
AlwaysBreakAfterReturnType: TopLevelDefinitions,
|
||||
AlwaysBreakTemplateDeclarations: Yes,
|
||||
BinPackArguments: false,
|
||||
BinPackParameters: false,
|
||||
BreakBeforeBraces: Linux,
|
||||
BreakConstructorInitializers: BeforeComma,
|
||||
ColumnLimit: 120,
|
||||
Cpp11BracedListStyle: true,
|
||||
FixNamespaceComments: true,
|
||||
MaxEmptyLinesToKeep: 5,
|
||||
NamespaceIndentation: Inner,
|
||||
}
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -69,3 +69,7 @@ install
|
||||
|
||||
# emacs directory setting:
|
||||
.dir-locals.el
|
||||
|
||||
*.pyc
|
||||
*.eggs
|
||||
*.egg-info
|
||||
|
||||
0
.gitmodules
vendored
Normal file
0
.gitmodules
vendored
Normal file
176
CMakeLists.txt
176
CMakeLists.txt
@@ -7,7 +7,10 @@ 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" OFF)
|
||||
option(ENABLE_MOCKSIM "Build the mock simulator for io testing" ON)
|
||||
option(OPM_ENABLE_PYTHON "Enable python bindings?" OFF)
|
||||
option(OPM_ENABLE_EMBEDDED_PYTHON "Enable python bindings?" OFF)
|
||||
|
||||
|
||||
# Output implies input
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
@@ -109,6 +112,8 @@ macro (sources_hook)
|
||||
# Append generated sources
|
||||
list(APPEND opm-common_SOURCES ${PROJECT_BINARY_DIR}/ParserKeywords.cpp)
|
||||
endif()
|
||||
set_source_files_properties(src/opm/parser/eclipse/Python/Python.cpp
|
||||
PROPERTIES COMPILE_FLAGS -Wno-shadow)
|
||||
endmacro (sources_hook)
|
||||
|
||||
macro (fortran_hook)
|
||||
@@ -143,46 +148,64 @@ if (ENABLE_MOCKSIM)
|
||||
set(_libs mocksim opmcommon
|
||||
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
|
||||
|
||||
foreach( test test_msim)
|
||||
add_executable(${test} "tests/msim/${test}")
|
||||
target_link_libraries(${test} ${_libs})
|
||||
add_test(NAME ${test} COMMAND ${test})
|
||||
set_tests_properties(${test} PROPERTIES WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/tests)
|
||||
|
||||
if(HAVE_DYNAMIC_BOOST_TEST)
|
||||
set_target_properties(${test} PROPERTIES
|
||||
COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK)
|
||||
endif()
|
||||
foreach( test test_msim test_msim_ACTIONX )
|
||||
opm_add_test(${test} SOURCES tests/msim/${test}.cpp
|
||||
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_executable(compareECL
|
||||
test_util/EclFilesComparator.cpp
|
||||
test_util/EclRegressionTest.cpp
|
||||
test_util/compareECL.cpp
|
||||
)
|
||||
|
||||
add_executable(convertECL
|
||||
test_util/convertECL.cpp
|
||||
)
|
||||
|
||||
foreach(target compareECL convertECL)
|
||||
target_link_libraries(${target} opmcommon)
|
||||
install(TARGETS ${target} DESTINATION bin)
|
||||
endforeach()
|
||||
|
||||
# Add the tests
|
||||
set(_libs testutil opmcommon
|
||||
set(_libs opmcommon
|
||||
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
|
||||
opm_add_test(test_compareSummary CONDITION ENABLE_ECL_INPUT
|
||||
LIBRARIES ${_libs})
|
||||
opm_add_test(test_EclFilesComparator CONDITION ENABLE_ECL_INPUT
|
||||
LIBRARIES ${_libs})
|
||||
if(HAVE_DYNAMIC_BOOST_TEST)
|
||||
set_target_properties(test_compareSummary PROPERTIES
|
||||
COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK)
|
||||
set_target_properties(test_EclFilesComparator PROPERTIES
|
||||
COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK)
|
||||
endif()
|
||||
install(TARGETS compareECL DESTINATION bin)
|
||||
|
||||
opm_add_test(test_EclFilesComparator
|
||||
CONDITION
|
||||
ENABLE_ECL_INPUT
|
||||
SOURCES
|
||||
tests/test_EclFilesComparator.cpp
|
||||
test_util/EclFilesComparator.cpp
|
||||
LIBRARIES
|
||||
${_libs}
|
||||
WORKING_DIRECTORY
|
||||
${PROJECT_BINARY_DIR}/tests
|
||||
)
|
||||
|
||||
opm_add_test(test_EclRegressionTest
|
||||
CONDITION
|
||||
ENABLE_ECL_INPUT
|
||||
SOURCES
|
||||
tests/test_EclRegressionTest.cpp
|
||||
test_util/EclFilesComparator.cpp
|
||||
test_util/EclRegressionTest.cpp
|
||||
LIBRARIES
|
||||
${_libs}
|
||||
WORKING_DIRECTORY
|
||||
${PROJECT_BINARY_DIR}/tests
|
||||
)
|
||||
|
||||
foreach(test test_EclIO test_EGrid test_ERft test_ERst test_ESmry)
|
||||
opm_add_test(${test} CONDITION ENABLE_ECL_INPUT
|
||||
LIBRARIES ${_libs}
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/tests)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# Install build system files
|
||||
@@ -190,3 +213,90 @@ install(DIRECTORY cmake DESTINATION share/opm)
|
||||
|
||||
# Install tab completion skeleton
|
||||
install(FILES etc/opm_bash_completion.sh.in DESTINATION share/opm/etc)
|
||||
|
||||
if (OPM_ENABLE_PYTHON)
|
||||
# -------------------------------------------------------------------------
|
||||
# 1: Wrap C++ functionality in Python
|
||||
find_package(PythonInterp REQUIRED)
|
||||
include(FindPythonInterp)
|
||||
|
||||
make_directory(${CMAKE_BINARY_DIR}/python)
|
||||
set(PYTHON_PACKAGE_PATH "site-packages")
|
||||
set(PYTHON_INSTALL_PREFIX "lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/${PYTHON_PACKAGE_PATH}" CACHE STRING "Subdirectory to install Python modules in")
|
||||
|
||||
get_target_property(_opmcommon_include_dirs opmcommon INCLUDE_DIRECTORIES)
|
||||
list(APPEND _opmcommon_include_dirs ${_ecl_include_dirs})
|
||||
string(REPLACE ";" ":" _setup_include_dirs "${_opmcommon_include_dirs}")
|
||||
|
||||
set(_opmcommon_lib_dirs ${CMAKE_BINARY_DIR}/lib ${CMAKE_PREFIX_PATH}/lib)
|
||||
string(REPLACE ";" ":" _setup_lib_dirs "${_opmcommon_lib_dirs}")
|
||||
|
||||
add_custom_command(OUTPUT python/python/opm/libopmcommon_python.so
|
||||
DEPENDS
|
||||
python/cxx/connection.cpp
|
||||
python/cxx/converters.hpp
|
||||
python/cxx/deck.cpp
|
||||
python/cxx/deck_keyword.cpp
|
||||
python/cxx/eclipse_3d_properties.cpp
|
||||
python/cxx/eclipse_config.cpp
|
||||
python/cxx/eclipse_grid.cpp
|
||||
python/cxx/eclipse_state.cpp
|
||||
python/cxx/group.cpp
|
||||
python/cxx/log.cpp
|
||||
python/cxx/parsecontext.cpp
|
||||
python/cxx/parser.cpp
|
||||
python/cxx/schedule.cpp
|
||||
python/cxx/export.cpp
|
||||
python/cxx/export.hpp
|
||||
python/cxx/common_state.cpp
|
||||
python/cxx/common_state.hpp
|
||||
python/cxx/table_manager.cpp
|
||||
python/cxx/well.cpp
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/python/ ${CMAKE_BINARY_DIR}/python
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/python/setup.py
|
||||
build
|
||||
build_ext
|
||||
--build-lib=${CMAKE_BINARY_DIR}/python/python/opm
|
||||
--library-dirs=${_setup_lib_dirs}
|
||||
--include-dirs=${_setup_include_dirs}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/python
|
||||
COMMENT "Building python bindings")
|
||||
add_custom_target(opmcommon_python ALL DEPENDS python/python/opm/libopmcommon_python.so)
|
||||
add_dependencies(opmcommon_python opmcommon)
|
||||
|
||||
install( CODE "execute_process(COMMAND mkdir -p ${CMAKE_INSTALL_PREFIX}/${PYTHON_INSTALL_PREFIX} )" )
|
||||
install( CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} python/setup.py build_ext --dry-run install --prefix=${CMAKE_INSTALL_PREFIX} )" )
|
||||
|
||||
add_test(NAME python_tests
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/python
|
||||
COMMAND ${PYTHON_EXECUTABLE} setup.py build_ext --dry-run --build-lib ${CMAKE_BINARY_DIR}/python/python/opm test
|
||||
)
|
||||
|
||||
set_target_properties(opmcommon PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_BINARY_DIR}/python/python)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Let cmake configure some small shell scripts which can be used to simplify
|
||||
# building and testing of the Python extensions.
|
||||
configure_file(python/setup-build.sh.in tmp/setup-build.sh)
|
||||
file( COPY ${PROJECT_BINARY_DIR}/tmp/setup-build.sh
|
||||
DESTINATION ${PROJECT_BINARY_DIR}
|
||||
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE )
|
||||
|
||||
configure_file(python/setup-test.sh.in tmp/setup-test.sh)
|
||||
file( COPY ${PROJECT_BINARY_DIR}/tmp/setup-test.sh
|
||||
DESTINATION ${PROJECT_BINARY_DIR}
|
||||
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE )
|
||||
|
||||
configure_file(python/enable-python.sh.in enable-python.sh)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# 2: Embed the Python interpreter for keywords like PYACTION and PYINPUT
|
||||
if (OPM_ENABLE_EMBEDDED_PYTHON)
|
||||
add_subdirectory(python/pybind11)
|
||||
target_include_directories(opmcommon PRIVATE "python/pybind11/include;${PYTHON_INCLUDE_DIRS}")
|
||||
target_link_libraries(opmcommon PUBLIC ${PYTHON_LIBRARY})
|
||||
|
||||
add_definitions(-DEMBEDDED_PYTHON)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# This file sets up five lists:
|
||||
# MAIN_SOURCE_FILES List of compilation units which will be included in
|
||||
# MAIN_SOURCE_FILES List of compilation units which will be included in
|
||||
# the library. If it isn't on this list, it won't be
|
||||
# part of the library. Please try to keep it sorted to
|
||||
# maintain sanity.
|
||||
@@ -35,16 +35,20 @@ list (APPEND MAIN_SOURCE_FILES
|
||||
src/opm/common/utility/parameters/ParameterGroup.cpp
|
||||
src/opm/common/utility/parameters/ParameterTools.cpp
|
||||
src/opm/common/utility/numeric/calculateCellVol.cpp
|
||||
src/opm/common/utility/TimeService.cpp
|
||||
)
|
||||
if(ENABLE_ECL_INPUT)
|
||||
list(APPEND MAIN_SOURCE_FILES
|
||||
src/opm/json/JsonObject.cpp
|
||||
src/opm/parser/eclipse/Deck/Deck.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckItem.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckValue.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckKeyword.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckRecord.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckOutput.cpp
|
||||
src/opm/parser/eclipse/Deck/Section.cpp
|
||||
src/opm/parser/eclipse/Deck/UDAValue.cpp
|
||||
src/opm/parser/eclipse/Python/Python.cpp
|
||||
src/opm/parser/eclipse/EclipseState/AquiferCT.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Aquifetp.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Aquancon.cpp
|
||||
@@ -71,38 +75,54 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/parser/eclipse/EclipseState/Grid/setKeywordBox.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/TransMult.cpp
|
||||
src/opm/parser/eclipse/EclipseState/InitConfig/Equil.cpp
|
||||
src/opm/parser/eclipse/EclipseState/InitConfig/FoamConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/InitConfig/InitConfig.cpp
|
||||
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/ActionAST.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/ActionContext.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Actions.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/ActionX.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Connection.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellConnections.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/ActionResult.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/Actdims.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/Action/Condition.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/Group/Group2.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Group/GTNode.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/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/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/WellTracerProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellTestConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellTestState.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/Connection.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/eval_uda.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/Well2.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/WellFoamProperties.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
|
||||
@@ -117,45 +137,92 @@ if(ENABLE_ECL_INPUT)
|
||||
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/UDQActive.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/UDQConfig.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/UDQ/UDQInput.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
|
||||
src/opm/parser/eclipse/Parser/ParserItem.cpp
|
||||
src/opm/parser/eclipse/Parser/ParserKeyword.cpp
|
||||
src/opm/parser/eclipse/Parser/ParserRecord.cpp
|
||||
src/opm/parser/eclipse/RawDeck/RawKeyword.cpp
|
||||
src/opm/parser/eclipse/RawDeck/RawRecord.cpp
|
||||
src/opm/parser/eclipse/RawDeck/StarToken.cpp
|
||||
src/opm/parser/eclipse/Parser/raw/RawKeyword.cpp
|
||||
src/opm/parser/eclipse/Parser/raw/RawRecord.cpp
|
||||
src/opm/parser/eclipse/Parser/raw/StarToken.cpp
|
||||
src/opm/parser/eclipse/Units/Dimension.cpp
|
||||
src/opm/parser/eclipse/Units/UnitSystem.cpp
|
||||
src/opm/parser/eclipse/Utility/Functional.cpp
|
||||
src/opm/parser/eclipse/Utility/Stringview.cpp
|
||||
)
|
||||
|
||||
if (OPM_ENABLE_EMBEDDED_PYTHON)
|
||||
list( APPEND PYTHON_SOURCE_FILES
|
||||
src/opm/parser/eclipse/Python/PythonInterp.cpp
|
||||
python/cxx/connection.cpp
|
||||
python/cxx/deck.cpp
|
||||
python/cxx/deck_keyword.cpp
|
||||
python/cxx/eclipse_3d_properties.cpp
|
||||
python/cxx/eclipse_config.cpp
|
||||
python/cxx/eclipse_grid.cpp
|
||||
python/cxx/eclipse_state.cpp
|
||||
python/cxx/group.cpp
|
||||
python/cxx/parsecontext.cpp
|
||||
python/cxx/parser.cpp
|
||||
python/cxx/schedule.cpp
|
||||
python/cxx/export.cpp
|
||||
python/cxx/common_state.cpp
|
||||
python/cxx/table_manager.cpp
|
||||
python/cxx/well.cpp
|
||||
python/cxx/log.cpp
|
||||
)
|
||||
set_source_files_properties(${PYTHON_SOURCE_FILES} PROPERTIES COMPILE_FLAGS -Wno-shadow)
|
||||
list( APPEND MAIN_SOURCE_FILES ${PYTHON_SOURCE_FILES})
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
if(NOT cjson_FOUND)
|
||||
list(APPEND MAIN_SOURCE_FILES external/cjson/cJSON.c)
|
||||
endif()
|
||||
endif()
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
list( APPEND MAIN_SOURCE_FILES
|
||||
src/opm/io/eclipse/EclFile.cpp
|
||||
src/opm/io/eclipse/EclOutput.cpp
|
||||
src/opm/io/eclipse/EclUtil.cpp
|
||||
src/opm/io/eclipse/EGrid.cpp
|
||||
src/opm/io/eclipse/ERft.cpp
|
||||
src/opm/io/eclipse/ERst.cpp
|
||||
src/opm/io/eclipse/ESmry.cpp
|
||||
src/opm/io/eclipse/OutputStream.cpp
|
||||
src/opm/output/eclipse/AggregateConnectionData.cpp
|
||||
src/opm/output/eclipse/AggregateGroupData.cpp
|
||||
src/opm/output/eclipse/AggregateMSWData.cpp
|
||||
src/opm/output/eclipse/AggregateUDQData.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/CreateUdqDims.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
|
||||
@@ -164,6 +231,8 @@ if(ENABLE_ECL_OUTPUT)
|
||||
src/opm/output/eclipse/Tables.cpp
|
||||
src/opm/output/eclipse/RegionCache.cpp
|
||||
src/opm/output/eclipse/RestartValue.cpp
|
||||
src/opm/output/eclipse/WriteInit.cpp
|
||||
src/opm/output/eclipse/WriteRFT.cpp
|
||||
src/opm/output/data/Solution.cpp
|
||||
)
|
||||
endif()
|
||||
@@ -193,15 +262,18 @@ if(ENABLE_ECL_INPUT)
|
||||
tests/parser/ConnectionTests.cpp
|
||||
tests/parser/COMPSEGUnits.cpp
|
||||
tests/parser/CopyRegTests.cpp
|
||||
tests/parser/DeckValueTests.cpp
|
||||
tests/parser/DeckTests.cpp
|
||||
tests/parser/DynamicStateTests.cpp
|
||||
tests/parser/DynamicVectorTests.cpp
|
||||
tests/parser/Eclipse3DPropertiesTests.cpp
|
||||
tests/parser/EclipseGridTests.cpp
|
||||
tests/parser/EmbeddedPython.cpp
|
||||
tests/parser/EqualRegTests.cpp
|
||||
tests/parser/EventTests.cpp
|
||||
tests/parser/FaceDirTests.cpp
|
||||
tests/parser/FaultTests.cpp
|
||||
tests/parser/FoamTests.cpp
|
||||
tests/parser/FunctionalTests.cpp
|
||||
tests/parser/GeomodifierTests.cpp
|
||||
tests/parser/GridPropertyTests.cpp
|
||||
@@ -214,9 +286,14 @@ if(ENABLE_ECL_INPUT)
|
||||
tests/parser/MULTREGTScannerTests.cpp
|
||||
tests/parser/OrderedMapTests.cpp
|
||||
tests/parser/ParseContextTests.cpp
|
||||
tests/parser/ParseContext_EXIT1.cpp
|
||||
tests/parser/ParseDATAWithDefault.cpp
|
||||
tests/parser/PYACTION.cpp
|
||||
tests/parser/PORVTests.cpp
|
||||
tests/parser/RawKeywordTests.cpp
|
||||
tests/parser/ResinsightTest.cpp
|
||||
tests/parser/RestartConfigTests.cpp
|
||||
tests/parser/RockTableTests.cpp
|
||||
tests/parser/RunspecTests.cpp
|
||||
tests/parser/SatfuncPropertyInitializersTests.cpp
|
||||
tests/parser/ScheduleTests.cpp
|
||||
@@ -241,20 +318,25 @@ if(ENABLE_ECL_INPUT)
|
||||
tests/parser/WellSolventTests.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_AggregateWellData.cpp
|
||||
#The unit tests are not finished yet, will be added in a separate pullrequest soon
|
||||
#tests/test_AggregateMSWData.cpp
|
||||
tests/test_CharArrayNullTerm.cpp
|
||||
tests/test_AggregateGroupData.cpp
|
||||
tests/test_AggregateMSWData.cpp
|
||||
tests/test_AggregateConnectionData.cpp
|
||||
tests/test_AggregateUDQData.cpp
|
||||
tests/test_ArrayDimChecker.cpp
|
||||
tests/test_EclipseIO.cpp
|
||||
tests/test_DoubHEAD.cpp
|
||||
tests/test_InteHEAD.cpp
|
||||
tests/test_LinearisedOutputTable.cpp
|
||||
tests/test_LogiHEAD.cpp
|
||||
tests/test_OutputStream.cpp
|
||||
tests/test_regionCache.cpp
|
||||
tests/test_PaddedOutputString.cpp
|
||||
tests/test_Restart.cpp
|
||||
tests/test_RFT.cpp
|
||||
tests/test_Solution.cpp
|
||||
@@ -262,9 +344,7 @@ if(ENABLE_ECL_OUTPUT)
|
||||
tests/test_Tables.cpp
|
||||
tests/test_Wells.cpp
|
||||
tests/test_WindowedArray.cpp
|
||||
tests/test_writenumwells.cpp
|
||||
tests/test_serialize_ICON.cpp
|
||||
tests/test_serialize_SCON.cpp
|
||||
tests/test_restartwellinfo.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -273,6 +353,8 @@ list (APPEND TEST_DATA_FILES
|
||||
)
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
list (APPEND TEST_DATA_FILES
|
||||
tests/expect-wdims.chldg.err.out
|
||||
tests/expect-wdims.err.out
|
||||
tests/FIRST_SIM.DATA
|
||||
tests/FIRST_SIM_THPRES.DATA
|
||||
tests/summary_deck.DATA
|
||||
@@ -283,17 +365,35 @@ if(ENABLE_ECL_OUTPUT)
|
||||
tests/summary_deck_non_constant_porosity.DATA
|
||||
tests/SUMMARY_EFF_FAC.DATA
|
||||
tests/SPE1CASE1.DATA
|
||||
tests/SPE1CASE1.SMSPEC
|
||||
tests/SPE1CASE1A.SMSPEC
|
||||
tests/SPE9_CP_PACKED.DATA
|
||||
tests/SOFR_TEST.DATA
|
||||
tests/UDQ_TEST_WCONPROD_IUAD-2.DATA
|
||||
)
|
||||
endif()
|
||||
|
||||
list (APPEND EXAMPLE_SOURCE_FILES
|
||||
)
|
||||
if(ENABLE_ECL_INPUT)
|
||||
list (APPEND TEST_DATA_FILES
|
||||
tests/ECLFILE.INIT
|
||||
tests/ECLFILE.FINIT
|
||||
tests/SPE1CASE1.EGRID
|
||||
tests/SPE1CASE1.RFT
|
||||
tests/SPE1_TESTCASE.UNRST
|
||||
tests/SPE1_TESTCASE.FUNRST
|
||||
tests/SPE1_TESTCASE.F0025
|
||||
tests/SPE1_TESTCASE.X0025
|
||||
tests/SPE1CASE1.UNSMRY
|
||||
tests/SPE1CASE1A.UNSMRY
|
||||
tests/SPE1CASE1_RST60.SMSPEC
|
||||
tests/SPE1CASE1_RST60.UNSMRY
|
||||
)
|
||||
list (APPEND EXAMPLE_SOURCE_FILES
|
||||
examples/opmi.cpp
|
||||
examples/opmpack.cpp
|
||||
examples/opmhash.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -305,6 +405,7 @@ if(ENABLE_ECL_INPUT)
|
||||
list (APPEND PROGRAM_SOURCE_FILES
|
||||
examples/opmi.cpp
|
||||
examples/opmpack.cpp
|
||||
examples/opmhash.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -341,6 +442,7 @@ list( APPEND PUBLIC_HEADER_FILES
|
||||
opm/common/utility/parameters/ParameterStrings.hpp
|
||||
opm/common/utility/parameters/ParameterTools.hpp
|
||||
opm/common/utility/numeric/calculateCellVol.hpp
|
||||
opm/common/utility/TimeService.hpp
|
||||
)
|
||||
if(ENABLE_ECL_INPUT)
|
||||
list(APPEND PUBLIC_HEADER_FILES
|
||||
@@ -354,6 +456,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
|
||||
@@ -364,7 +467,9 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/Parser/ParserConst.hpp
|
||||
opm/parser/eclipse/EclipseState/InitConfig/InitConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/InitConfig/Equil.hpp
|
||||
opm/parser/eclipse/EclipseState/InitConfig/FoamConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Util/Value.hpp
|
||||
opm/parser/eclipse/EclipseState/Util/IOrderSet.hpp
|
||||
opm/parser/eclipse/EclipseState/Util/OrderedMap.hpp
|
||||
opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Edit/EDITNNC.hpp
|
||||
@@ -426,6 +531,8 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/Tables/TableContainer.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/AqutabTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PlyadsTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/FoamadsTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/FoammobTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PbvdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SorwmisTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PlymaxTable.hpp
|
||||
@@ -439,6 +546,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
|
||||
@@ -452,77 +563,108 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/Aquancon.hpp
|
||||
opm/parser/eclipse/EclipseState/AquiferCT.hpp
|
||||
opm/parser/eclipse/EclipseState/Aquifetp.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/ActionAST.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/ActionContext.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Actions.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/ActionX.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/ActionAST.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/ActionContext.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/ActionResult.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/Actdims.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/Actions.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/Condition.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/ProductionControls.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/InjectionControls.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/Well2.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/WellFoamProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellInjectionProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellPolymerProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellTracerProperties.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/WellTracerProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Tuning.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group/GTNode.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group/Group2.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MessageLimits.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Events.hpp
|
||||
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/Connection.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/WellSegments.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/updatingConnectionsWithSegments.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellTestConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellTestState.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellConnections.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/UDQConfig.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/UDQActive.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
|
||||
opm/parser/eclipse/Deck/DeckOutput.hpp
|
||||
opm/parser/eclipse/Deck/DeckValue.hpp
|
||||
opm/parser/eclipse/Deck/DeckKeyword.hpp
|
||||
opm/parser/eclipse/Deck/DeckRecord.hpp
|
||||
opm/parser/eclipse/RawDeck/StarToken.hpp
|
||||
opm/parser/eclipse/RawDeck/RawEnums.hpp
|
||||
opm/parser/eclipse/RawDeck/RawRecord.hpp
|
||||
opm/parser/eclipse/RawDeck/RawKeyword.hpp
|
||||
opm/parser/eclipse/RawDeck/RawConsts.hpp)
|
||||
opm/parser/eclipse/Deck/UDAValue.hpp
|
||||
opm/parser/eclipse/Python/Python.hpp)
|
||||
endif()
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
list(APPEND PUBLIC_HEADER_FILES
|
||||
opm/io/eclipse/EclFile.hpp
|
||||
opm/io/eclipse/EclIOdata.hpp
|
||||
opm/io/eclipse/EclOutput.hpp
|
||||
opm/io/eclipse/EclUtil.hpp
|
||||
opm/io/eclipse/EGrid.hpp
|
||||
opm/io/eclipse/ERft.hpp
|
||||
opm/io/eclipse/ERst.hpp
|
||||
opm/io/eclipse/ESmry.hpp
|
||||
opm/io/eclipse/PaddedOutputString.hpp
|
||||
opm/io/eclipse/OutputStream.hpp
|
||||
opm/output/data/Cells.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/logihead.hpp
|
||||
opm/output/eclipse/VectorItems/msw.hpp
|
||||
opm/output/eclipse/VectorItems/tabdims.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/AggregateUDQData.hpp
|
||||
opm/output/eclipse/AggregateWellData.hpp
|
||||
opm/output/eclipse/CharArrayNullTerm.hpp
|
||||
opm/output/eclipse/DoubHEAD.hpp
|
||||
opm/output/eclipse/EclipseGridInspector.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
|
||||
@@ -531,6 +673,8 @@ if(ENABLE_ECL_OUTPUT)
|
||||
opm/output/eclipse/Summary.hpp
|
||||
opm/output/eclipse/Tables.hpp
|
||||
opm/output/eclipse/WindowedArray.hpp
|
||||
opm/output/eclipse/WriteInit.hpp
|
||||
opm/output/eclipse/WriteRFT.hpp
|
||||
opm/output/eclipse/WriteRestartHelpers.hpp
|
||||
opm/output/OutputWriter.hpp
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Libs to link tests against
|
||||
set(TEST_LIBS opmcommon ecl Boost::unit_test_framework)
|
||||
set(TEST_LIBS opmcommon Boost::unit_test_framework)
|
||||
set(EXTRA_TESTS)
|
||||
|
||||
# Generated source, needs to be here
|
||||
@@ -49,15 +49,13 @@ list(APPEND EXTRA_TESTS EclipseStateTests)
|
||||
foreach (test BoxTest
|
||||
CheckDeckValidity
|
||||
EclipseGridCreateFromDeck
|
||||
EDITNNCTests
|
||||
EDITNNCTests
|
||||
IncludeTest
|
||||
IntegrationTests
|
||||
IOConfigIntegrationTest
|
||||
NNCTests
|
||||
ParseKEYWORD
|
||||
ParseDATAWithDefault
|
||||
Polymer
|
||||
ResinsightTest
|
||||
ScheduleCreateFromDeck
|
||||
TransMultIntegrationTests)
|
||||
|
||||
@@ -87,6 +85,8 @@ if(HAVE_OPM_TESTS)
|
||||
${OPM_TESTS_ROOT}/spe3/SPE3CASE2.DATA
|
||||
${OPM_TESTS_ROOT}/spe9/SPE9_CP.DATA
|
||||
${OPM_TESTS_ROOT}/spe9/SPE9_CP_GROUP.DATA
|
||||
${OPM_TESTS_ROOT}/spe9/SPE9_CP_SHORT.DATA
|
||||
${OPM_TESTS_ROOT}/spe9/SPE9_CP_SHORT_RESTART.DATA
|
||||
${OPM_TESTS_ROOT}/spe9/SPE9.DATA
|
||||
${OPM_TESTS_ROOT}/spe10model1/SPE10_MODEL1.DATA
|
||||
${OPM_TESTS_ROOT}/spe10model2/SPE10_MODEL2.DATA
|
||||
@@ -96,6 +96,7 @@ if(HAVE_OPM_TESTS)
|
||||
EXE_NAME parse_write
|
||||
TEST_ARGS ${deck})
|
||||
endforeach()
|
||||
opm_add_test("SPE9_CP_GROUP2" NO_COMPILE EXE_NAME parse_write TEST_ARGS "${OPM_TESTS_ROOT}/spe9group/SPE9_CP_GROUP.DATA")
|
||||
set_property(TEST NORNE_ATW2013
|
||||
PROPERTY ENVIRONMENT "OPM_ERRORS_IGNORE=PARSE_RANDOM_SLASH")
|
||||
endif()
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
set(genkw_SOURCES src/opm/json/JsonObject.cpp
|
||||
src/opm/parser/eclipse/Parser/createDefaultKeywordList.cpp
|
||||
src/opm/parser/eclipse/Deck/UDAValue.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckValue.cpp
|
||||
src/opm/parser/eclipse/Deck/Deck.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckItem.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckKeyword.cpp
|
||||
@@ -7,14 +9,15 @@ 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
|
||||
src/opm/parser/eclipse/Parser/ParserKeyword.cpp
|
||||
src/opm/parser/eclipse/Parser/ParserRecord.cpp
|
||||
src/opm/parser/eclipse/RawDeck/RawKeyword.cpp
|
||||
src/opm/parser/eclipse/RawDeck/RawRecord.cpp
|
||||
src/opm/parser/eclipse/RawDeck/StarToken.cpp
|
||||
src/opm/parser/eclipse/Parser/raw/RawKeyword.cpp
|
||||
src/opm/parser/eclipse/Parser/raw/RawRecord.cpp
|
||||
src/opm/parser/eclipse/Parser/raw/StarToken.cpp
|
||||
src/opm/parser/eclipse/Units/Dimension.cpp
|
||||
src/opm/parser/eclipse/Units/UnitSystem.cpp
|
||||
src/opm/parser/eclipse/Utility/Stringview.cpp
|
||||
@@ -29,7 +32,7 @@ if(NOT cjson_FOUND)
|
||||
endif()
|
||||
add_executable(genkw ${genkw_SOURCES})
|
||||
|
||||
target_link_libraries(genkw ecl Boost::regex Boost::filesystem Boost::system)
|
||||
target_link_libraries(genkw Boost::regex Boost::filesystem Boost::system)
|
||||
|
||||
# Generate keyword list
|
||||
include(src/opm/parser/eclipse/share/keywords/keyword_list.cmake)
|
||||
|
||||
18
changelog.md
18
changelog.md
@@ -3,6 +3,24 @@
|
||||
A short month-by-month synopsis of change highlights. Most bugfixes won't make
|
||||
it in here, only the bigger features and interface changes.
|
||||
|
||||
# Important changes between release 2019.04 and 2019.10
|
||||
|
||||
* opm-common and the rest of OPM does not use libecl anymore and
|
||||
supports reading and writing Eclipse files directly
|
||||
* Improved Eclipse compatible restart, support for unified and non unified
|
||||
files, and formatted and unformatted files
|
||||
* Support for reading and checking various additional keywords was introduced (those
|
||||
starting with A - M, R, T, V, W, Z).
|
||||
* ACTIONX support implemented
|
||||
* NUPCOL support implemented
|
||||
* UDA, UDQ support implemented
|
||||
* Implemented writing saturation function scaled end-point arrays (e.g., SWL, SGU,
|
||||
SOWCR, KRORW, PCG) to INIT file
|
||||
* Fixes concerning interaction of WELOPEN and WCON* with WECON and
|
||||
WTEST
|
||||
* Added support for FOAM keywords (FOAMMOB, FOAMROCK, WFOAM)
|
||||
* Refactored and reimplemented Well representation in deck
|
||||
|
||||
# 2016.12
|
||||
* ZCORN adjustments improved, considers cell-cell relations
|
||||
* Slightly more robust compilation - won't crash if locales are broken
|
||||
|
||||
@@ -1,287 +0,0 @@
|
||||
# - Find the Ensemble-based Reservoir Tool (ERT)
|
||||
#
|
||||
# Set the cache variable ERT_ROOT to the install location of the ERT
|
||||
# libraries and header files.
|
||||
#
|
||||
# If found, it sets these variables:
|
||||
#
|
||||
# ERT_INCLUDE_DIRS Header file directories
|
||||
# ERT_LIBRARIES Archives and shared objects
|
||||
# ERT_CONFIG_VARS Definitions that goes in config.h
|
||||
# ERT_LINKER_FLAGS Options that must be passed to linker
|
||||
#
|
||||
# It will also add to CMAKE_C_FLAGS and CMAKE_CXX_FLAGS if necessary to
|
||||
# link with the ERT libraries.
|
||||
|
||||
# variables to pass on to other packages
|
||||
if (FIND_QUIETLY)
|
||||
set (ERT_QUIET "QUIET")
|
||||
else (FIND_QUIETLY)
|
||||
set (ERT_QUIET "")
|
||||
endif (FIND_QUIETLY)
|
||||
|
||||
# if a directory has been specified by the user, then don't go look
|
||||
# in the system directories as well
|
||||
if (ERT_ROOT)
|
||||
set (_no_default_path "NO_DEFAULT_PATH")
|
||||
else (ERT_ROOT)
|
||||
set (_no_default_path "")
|
||||
endif (ERT_ROOT)
|
||||
|
||||
# ERT doesn't have any config-mode file, so we need to specify the root
|
||||
# directory in its own variable
|
||||
find_path (ERT_ECL_INCLUDE_DIR
|
||||
NAMES "ert/ecl/ecl_util.h"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../libecl" "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATH_SUFFIXES "libecl/include/" "include"
|
||||
DOC "Path to ERT Eclipse library header files"
|
||||
${_no_default_path}
|
||||
)
|
||||
find_path (ERT_ECL_WELL_INCLUDE_DIR
|
||||
NAMES "ert/ecl_well/well_const.h"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../libecl" "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATH_SUFFIXES "libecl_well/include/" "include"
|
||||
DOC "Path to ERT Eclipse library header files"
|
||||
${_no_default_path}
|
||||
)
|
||||
find_path (ERT_ECLXX_INCLUDE_DIR
|
||||
NAMES "ert/ecl/EclKW.hpp"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../libecl" "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATH_SUFFIXES "libeclxx/include/" "include"
|
||||
DOC "Path to ERT Eclipse C++ library header files"
|
||||
${_no_default_path}
|
||||
)
|
||||
find_path (ERT_UTIL_INCLUDE_DIR
|
||||
NAMES "ert/util/stringlist.h"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../libecl" "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATH_SUFFIXES "libert_util/include/" "include"
|
||||
DOC "Path to ERT Eclipse library header files"
|
||||
${_no_default_path}
|
||||
)
|
||||
find_path (ERT_UTILXX_INCLUDE_DIR
|
||||
NAMES "ert/util/ert_unique_ptr.hpp"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../libecl" "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATH_SUFFIXES "libert_utilxx/include/" "include"
|
||||
DOC "Path to ERT Eclipse C++ library header files"
|
||||
${_no_default_path}
|
||||
)
|
||||
find_path (ERT_GEN_INCLUDE_DIR
|
||||
NAMES "ert/util/int_vector.h"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../libecl" "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATH_SUFFIXES "libert_util/include"
|
||||
"include" "build/libert_util/include" "build/libert_util/include"
|
||||
DOC "Path to ERT generated library header files"
|
||||
${_no_default_path}
|
||||
)
|
||||
|
||||
|
||||
# need all of these libraries
|
||||
if (CMAKE_SIZEOF_VOID_P)
|
||||
math (EXPR _BITS "8 * ${CMAKE_SIZEOF_VOID_P}")
|
||||
endif (CMAKE_SIZEOF_VOID_P)
|
||||
find_library (ERT_LIBRARY_ECL
|
||||
NAMES "ecl"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_BINARY_DIR}/../libecl"
|
||||
"${PROJECT_SOURCE_DIR}/../libecl/build"
|
||||
"${PROJECT_BINARY_DIR}/../libecl-build"
|
||||
"${PROJECT_BINARY_DIR}/../ert"
|
||||
"${PROJECT_SOURCE_DIR}/../ert/build"
|
||||
"${PROJECT_BINARY_DIR}/../ert-build"
|
||||
PATH_SUFFIXES "lib" "lib/Release" "lib/Debug" "lib${_BITS}" "lib/${CMAKE_LIBRARY_ARCHITECTURE}"
|
||||
DOC "Path to ERT Eclipse library archive/shared object files"
|
||||
${_no_default_path}
|
||||
)
|
||||
find_library (ERT_LIBRARY_ECLXX
|
||||
NAMES "eclxx"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_BINARY_DIR}/../libecl"
|
||||
"${PROJECT_SOURCE_DIR}/../libecl/build"
|
||||
"${PROJECT_BINARY_DIR}/../libecl-build"
|
||||
"${PROJECT_BINARY_DIR}/../ert"
|
||||
"${PROJECT_SOURCE_DIR}/../ert/build"
|
||||
"${PROJECT_BINARY_DIR}/../ert-build"
|
||||
PATH_SUFFIXES "lib" "lib/Release" "lib/Debug" "lib${_BITS}" "lib/${CMAKE_LIBRARY_ARCHITECTURE}"
|
||||
DOC "Path to ERT Eclipse C++ library archive/shared object files"
|
||||
${_no_default_path}
|
||||
)
|
||||
find_library (ERT_LIBRARY_ECL_WELL
|
||||
NAMES "ecl_well"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_BINARY_DIR}/../libecl"
|
||||
"${PROJECT_SOURCE_DIR}/../libecl/build"
|
||||
"${PROJECT_BINARY_DIR}/../libecl-build"
|
||||
"${PROJECT_BINARY_DIR}/../ert"
|
||||
"${PROJECT_SOURCE_DIR}/../ert/build"
|
||||
"${PROJECT_BINARY_DIR}/../ert-build"
|
||||
PATH_SUFFIXES "lib" "lib/Release" "lib/Debug" "lib${_BITS}" "lib/${CMAKE_LIBRARY_ARCHITECTURE}"
|
||||
DOC "Path to ERT Eclipse library archive/shared object files"
|
||||
${_no_default_path}
|
||||
)
|
||||
find_library (ERT_LIBRARY_GEOMETRY
|
||||
NAMES "ert_geometry"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_BINARY_DIR}/../libecl"
|
||||
"${PROJECT_SOURCE_DIR}/../libecl/build"
|
||||
"${PROJECT_BINARY_DIR}/../libecl-build"
|
||||
"${PROJECT_BINARY_DIR}/../ert"
|
||||
"${PROJECT_SOURCE_DIR}/../ert/build"
|
||||
"${PROJECT_BINARY_DIR}/../ert-build"
|
||||
PATH_SUFFIXES "lib" "lib/Release" "lib/Debug" "lib${_BITS}" "lib/${CMAKE_LIBRARY_ARCHITECTURE}"
|
||||
DOC "Path to ERT Geometry library archive/shared object files"
|
||||
${_no_default_path}
|
||||
)
|
||||
find_library (ERT_LIBRARY_UTIL
|
||||
NAMES "ert_util"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_BINARY_DIR}/../libecl"
|
||||
"${PROJECT_SOURCE_DIR}/../libecl/build"
|
||||
"${PROJECT_BINARY_DIR}/../libecl-build"
|
||||
"${PROJECT_BINARY_DIR}/../ert"
|
||||
"${PROJECT_SOURCE_DIR}/../ert/build"
|
||||
"${PROJECT_BINARY_DIR}/../ert-build"
|
||||
PATH_SUFFIXES "lib" "lib/Release" "lib/Debug" "lib${_BITS}" "lib/${CMAKE_LIBRARY_ARCHITECTURE}"
|
||||
DOC "Path to ERT Utilities library archive/shared object files"
|
||||
${_no_default_path}
|
||||
)
|
||||
find_library (ERT_LIBRARY_UTILXX
|
||||
NAMES "ert_utilxx"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_BINARY_DIR}/../libecl"
|
||||
"${PROJECT_SOURCE_DIR}/../libecl/build"
|
||||
"${PROJECT_BINARY_DIR}/../libecl-build"
|
||||
"${PROJECT_BINARY_DIR}/../ert"
|
||||
"${PROJECT_SOURCE_DIR}/../ert/build"
|
||||
"${PROJECT_BINARY_DIR}/../ert-build"
|
||||
PATH_SUFFIXES "lib" "lib/Release" "lib/Debug" "lib${_BITS}" "lib/${CMAKE_LIBRARY_ARCHITECTURE}"
|
||||
DOC "Path to ERT Utilities library archive/shared object files"
|
||||
${_no_default_path}
|
||||
)
|
||||
# the "library" found here is actually a list of several files
|
||||
list (APPEND ERT_INCLUDE_DIR
|
||||
${ERT_ECL_INCLUDE_DIR}
|
||||
${ERT_ECL_WELL_INCLUDE_DIR}
|
||||
${ERT_ECLXX_INCLUDE_DIR}
|
||||
${ERT_UTIL_INCLUDE_DIR}
|
||||
${ERT_UTILXX_INCLUDE_DIR}
|
||||
${ERT_GEN_INCLUDE_DIR}
|
||||
)
|
||||
list (APPEND ERT_LIBRARY
|
||||
${ERT_LIBRARY_ECL}
|
||||
${ERT_LIBRARY_ECLXX}
|
||||
${ERT_LIBRARY_ECL_WELL}
|
||||
${ERT_LIBRARY_GEOMETRY}
|
||||
${ERT_LIBRARY_UTIL}
|
||||
${ERT_LIBRARY_UTILXX}
|
||||
)
|
||||
list (APPEND ERT_LIBRARIES ${ERT_LIBRARY})
|
||||
list (APPEND ERT_INCLUDE_DIRS ${ERT_INCLUDE_DIR})
|
||||
|
||||
# if we didn't find any files, then don't proceed through the entire dependency list
|
||||
include (FindPackageHandleStandardArgs)
|
||||
if (ERT_INCLUDE_DIR MATCHES "-NOTFOUND" OR ERT_LIBRARIES MATCHES "-NOTFOUND")
|
||||
find_package_handle_standard_args (ERT
|
||||
DEFAULT_MSG
|
||||
ERT_INCLUDE_DIR ERT_LIBRARY
|
||||
)
|
||||
# clear the cache so the find probe is attempted again if files becomes
|
||||
# available (only upon a unsuccessful *compile* should we disable further
|
||||
# probing)
|
||||
set (HAVE_ERT)
|
||||
unset (HAVE_ERT CACHE)
|
||||
return ()
|
||||
endif (ERT_INCLUDE_DIR MATCHES "-NOTFOUND" OR ERT_LIBRARIES MATCHES "-NOTFOUND")
|
||||
|
||||
|
||||
# dependencies
|
||||
|
||||
# parallel programming
|
||||
include (UseOpenMP)
|
||||
find_openmp (ERT)
|
||||
|
||||
# compression library
|
||||
find_package (ZLIB ${ERT_QUIET})
|
||||
if (ZLIB_FOUND)
|
||||
list (APPEND ERT_INCLUDE_DIRS ${ZLIB_INCLUDE_DIRS})
|
||||
list (APPEND ERT_LIBRARIES ${ZLIB_LIBRARIES})
|
||||
endif (ZLIB_FOUND)
|
||||
|
||||
# numerics
|
||||
find_package (BLAS ${ERT_QUIET})
|
||||
if (BLAS_FOUND)
|
||||
list (APPEND ERT_INCLUDE_DIRS ${BLAS_INCLUDE_DIRS})
|
||||
list (APPEND ERT_LIBRARIES ${BLAS_LIBRARIES})
|
||||
list (APPEND ERT_LINKER_FLAGS ${BLAS_LINKER_FLAGS})
|
||||
endif (BLAS_FOUND)
|
||||
|
||||
find_package (LAPACK ${ERT_QUIET})
|
||||
if (LAPACK_FOUND)
|
||||
list (APPEND ERT_INCLUDE_DIRS ${LAPACK_INCLUDE_DIRS})
|
||||
list (APPEND ERT_LIBRARIES ${LAPACK_LIBRARIES})
|
||||
list (APPEND ERT_LINKER_FLAGS ${LAPACK_LINKER_FLAGS})
|
||||
endif (LAPACK_FOUND)
|
||||
|
||||
# math library (should exist on all unices; automatically linked on Windows)
|
||||
if (UNIX)
|
||||
find_library (MATH_LIBRARY
|
||||
NAMES "m"
|
||||
)
|
||||
list (APPEND ERT_LIBRARIES ${MATH_LIBRARY})
|
||||
endif (UNIX)
|
||||
|
||||
# if shared libraries are disabled on linux, explcitly linking to the
|
||||
# pthreads library is required by ERT
|
||||
find_package(Threads ${ERT_QUIET})
|
||||
if (CMAKE_THREAD_LIBS_INIT)
|
||||
list (APPEND ERT_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
|
||||
# Platform specific library where dlopen with friends lives
|
||||
list (APPEND ERT_LIBRARIES ${CMAKE_DL_LIBS})
|
||||
|
||||
# since OpenMP often implies pthreads, we need to tidy up
|
||||
# (last instance of library must be left standing, thus reversing that
|
||||
# list before removing duplicates)
|
||||
include (Duplicates)
|
||||
remove_dup_deps (ERT)
|
||||
|
||||
# see if we can compile a minimum example
|
||||
# CMake logical test doesn't handle lists (sic)
|
||||
if (NOT (ERT_INCLUDE_DIR MATCHES "-NOTFOUND" OR ERT_LIBRARIES MATCHES "-NOTFOUND"))
|
||||
include (CMakePushCheckState)
|
||||
include (CheckCSourceCompiles)
|
||||
cmake_push_check_state ()
|
||||
set (CMAKE_REQUIRED_INCLUDES ${ERT_INCLUDE_DIR})
|
||||
set (CMAKE_REQUIRED_LIBRARIES ${ERT_LIBRARIES})
|
||||
check_cxx_source_compiles (
|
||||
"#include <ert/ecl/ecl_grid.h>
|
||||
int main ( ) {
|
||||
ecl_grid_type * grid = ecl_grid_alloc_rectangular( 10,10,10,1,1,1, NULL);
|
||||
ecl_grid_free( grid );
|
||||
return 0;
|
||||
}" HAVE_ERT)
|
||||
cmake_pop_check_state ()
|
||||
else (NOT (ERT_INCLUDE_DIR MATCHES "-NOTFOUND" OR ERT_LIBRARIES MATCHES "-NOTFOUND"))
|
||||
# clear the cache so the find probe is attempted again if files becomes
|
||||
# available (only upon a unsuccessful *compile* should we disable further
|
||||
# probing)
|
||||
set (HAVE_ERT)
|
||||
unset (HAVE_ERT CACHE)
|
||||
endif (NOT (ERT_INCLUDE_DIR MATCHES "-NOTFOUND" OR ERT_LIBRARIES MATCHES "-NOTFOUND"))
|
||||
|
||||
# if the test program didn't compile, but was required to do so, bail
|
||||
# out now and display an error; otherwise limp on
|
||||
find_package_handle_standard_args (ERT
|
||||
DEFAULT_MSG
|
||||
ERT_INCLUDE_DIR ERT_LIBRARY HAVE_ERT
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
# - Find the Python wrappers for Ensemble-based Reservoir Tool (ERT)
|
||||
#
|
||||
# Set the cache variable ERT_PYTHON_PATH to the install location of
|
||||
# the root ert package.
|
||||
|
||||
find_package(PythonInterp)
|
||||
if(PYTHONINTERP_FOUND)
|
||||
|
||||
# We try to find the ert Python distribution. This is done by running
|
||||
# Python code which tries to 'import ert' and prints out the path to
|
||||
# the module if the import succeeds.
|
||||
#
|
||||
# The normal Python import machinery is employed, so if you have
|
||||
# installed ert python in a default location, or alternatively set the
|
||||
# PYTHONPATH variable the ert Python distribution will eventually be
|
||||
# found there, independently of the alternatives which are tested with
|
||||
# the ${PATH_LIST} variable.
|
||||
|
||||
if (EXISTS "/etc/debian_version")
|
||||
set( PYTHON_PACKAGE_PATH "dist-packages")
|
||||
else()
|
||||
set( PYTHON_PACKAGE_PATH "site-packages")
|
||||
endif()
|
||||
set(PYTHON_INSTALL_PREFIX "lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/${PYTHON_PACKAGE_PATH}" CACHE STRING "Subdirectory to install Python modules in")
|
||||
|
||||
set(PATH_LIST)
|
||||
if (ERT_ROOT)
|
||||
list(APPEND PATH_LIST ${ERT_ROOT})
|
||||
endif()
|
||||
list(APPEND PATH_LIST ${CMAKE_PREFIX_PATH})
|
||||
|
||||
# Add various popular sibling alternatives.
|
||||
list(APPEND PATH_LIST "${PROJECT_SOURCE_DIR}/../ert/build"
|
||||
"${PROJECT_BINARY_DIR}/../ert-build")
|
||||
|
||||
foreach( PATH ${PATH_LIST})
|
||||
set( python_code "import sys; sys.path.insert(0 , '${PATH}/${PYTHON_INSTALL_PREFIX}'); import os.path; import inspect; import ert; print os.path.dirname(os.path.dirname(inspect.getfile(ert))); from ert.ecl import EclSum")
|
||||
execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "${python_code}"
|
||||
RESULT_VARIABLE import_result
|
||||
OUTPUT_VARIABLE stdout_output
|
||||
ERROR_VARIABLE stderr_output
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE )
|
||||
|
||||
if (${import_result} EQUAL 0)
|
||||
set( ERT_PYTHON_PATH ${stdout_output} CACHE PATH "Python path for ERT Python" )
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
find_package_handle_standard_args("ERTPython" DEFAULT_MSG ERT_PYTHON_PATH)
|
||||
|
||||
|
||||
|
||||
@@ -66,10 +66,6 @@ set (_opm_proj_exemptions
|
||||
dune-fem
|
||||
)
|
||||
|
||||
# although a DUNE module, it is delivered in the OPM suite
|
||||
set (opm-core_SUITE "opm")
|
||||
set (ewoms_SUITE "opm")
|
||||
|
||||
# insert this boilerplate whenever we are going to find a new package
|
||||
macro (find_and_append_package_to prefix name)
|
||||
# special handling for Boost to avoid inadvertedly picking up system
|
||||
@@ -156,25 +152,7 @@ macro (find_and_append_package_to prefix name)
|
||||
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})
|
||||
endif()
|
||||
if(${name} STREQUAL "ecl")
|
||||
# Give us a chance to find ecl installed to CMAKE_INSTALL_PREFIX.
|
||||
# We need to deactivate the package registry for this.
|
||||
create_module_dir_var(ecl)
|
||||
set(ARGN_NO_REQUIRED ${ARGN})
|
||||
if(ARGN)
|
||||
list(REMOVE_ITEM ARGN_NO_REQUIRED "REQUIRED")
|
||||
endif()
|
||||
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)
|
||||
set(ecl_LIBRARIES ecl)
|
||||
set(HAVE_ERT 1)
|
||||
endif()
|
||||
elseif(_${name}_exempted LESS 0 AND NOT _is_opm)
|
||||
if(_${name}_exempted LESS 0 AND NOT _is_opm)
|
||||
find_package (${name} ${ARGN})
|
||||
elseif(_${name}_exempted GREATER -1)
|
||||
find_package (${name} ${ARGN})
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
# - CMP0026 to allow access to the LOCATION target property
|
||||
# - CMP0048 to indicate that we want to deal with the *VERSION*
|
||||
# variables ourselves
|
||||
# - CMP0064 to indicate that we want TEST if conditions to be evaluated
|
||||
if (POLICY CMP0026)
|
||||
cmake_policy(SET CMP0026 OLD)
|
||||
endif()
|
||||
@@ -28,6 +29,10 @@ if (POLICY CMP0048)
|
||||
cmake_policy(SET CMP0048 OLD)
|
||||
endif()
|
||||
|
||||
if(POLICY CMP0064)
|
||||
cmake_policy(SET CMP0064 NEW)
|
||||
endif()
|
||||
|
||||
# set the behavior of the policy 0054 to NEW. (i.e. do not implicitly
|
||||
# expand variables in if statements)
|
||||
if (POLICY CMP0054)
|
||||
@@ -256,9 +261,13 @@ macro (cond_disable_test name)
|
||||
endif ((NOT DEFINED HAVE_${name}) OR (NOT HAVE_${name}))
|
||||
endmacro (cond_disable_test name)
|
||||
|
||||
# use this target to run all tests
|
||||
# use this target to run all tests, with parallel execution
|
||||
cmake_host_system_information(RESULT TESTJOBS QUERY NUMBER_OF_PHYSICAL_CORES)
|
||||
if(TESTJOBS EQUAL 0)
|
||||
set(TESTJOBS 1)
|
||||
endif()
|
||||
add_custom_target (check
|
||||
COMMAND ${CMAKE_CTEST_COMMAND}
|
||||
COMMAND ${CMAKE_CTEST_COMMAND} -j${TESTJOBS}
|
||||
DEPENDS test-suite
|
||||
COMMENT "Checking if library is functional"
|
||||
VERBATIM
|
||||
|
||||
@@ -162,7 +162,7 @@ macro (find_package_deps module)
|
||||
# (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")
|
||||
if(_dep MATCHES "opm-")
|
||||
set(deplist ${_dep})
|
||||
string(STRIP "${_dep}" _dep)
|
||||
string(REPLACE " " ";" deplist "${_dep}")
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
# - Build satellites that are dependent of main library
|
||||
|
||||
option(ADD_DISABLED_CTESTS "Add the tests which are disabled due to failed preconditions to the ctest output (this makes ctest return an error if such a test is present)" ON)
|
||||
mark_as_advanced(ADD_DISABLED_CTESTS)
|
||||
|
||||
#
|
||||
# Enumerate all source code in a "satellite" directory such as tests/,
|
||||
# compile each of them and optionally set them as a test for CTest to
|
||||
@@ -11,144 +8,136 @@ mark_as_advanced(ADD_DISABLED_CTESTS)
|
||||
# The following suffices must be defined for the opm prefix passed as
|
||||
# parameter:
|
||||
#
|
||||
# _LINKER_FLAGS Necessary flags to link with this library
|
||||
# _TARGET CMake target which creates the library
|
||||
# _LIBRARIES Other dependencies that must also be linked
|
||||
# _LINKER_FLAGS Necessary flags to link with this library
|
||||
# _TARGET CMake target which creates the library
|
||||
# _LIBRARIES Other dependencies that must also be linked
|
||||
|
||||
# Synopsis:
|
||||
# opm_compile_satellites (opm satellite excl_all test_regexp)
|
||||
# opm_compile_satellites (opm satellite excl_all test_regexp)
|
||||
#
|
||||
# Parameters:
|
||||
# opm Prefix of the variable which contain information
|
||||
# about the library these satellites depends on, e.g.
|
||||
# pass "opm-core" if opm-core_TARGET is the name of
|
||||
# the target the builds this library. Variables with
|
||||
# suffixes _TARGET and _LIBRARIES must exist.
|
||||
# opm Prefix of the variable which contain information
|
||||
# about the library these satellites depends on, e.g.
|
||||
# pass "opm-core" if opm-core_TARGET is the name of
|
||||
# the target the builds this library. Variables with
|
||||
# suffixes _TARGET and _LIBRARIES must exist.
|
||||
#
|
||||
# satellite Prefix of variable which contain the names of the
|
||||
# files, e.g. pass "tests" if the files are in the
|
||||
# variable tests_SOURCES. Variables with suffixes
|
||||
# _DATAFILES, _SOURCES and _DIR should exist. This
|
||||
# name is also used as name of the target that builds
|
||||
# all these files.
|
||||
# satellite Prefix of variable which contain the names of the
|
||||
# files, e.g. pass "tests" if the files are in the
|
||||
# variable tests_SOURCES. Variables with suffixes
|
||||
# _DATAFILES, _SOURCES and _DIR should exist. This
|
||||
# name is also used as name of the target that builds
|
||||
# all these files.
|
||||
#
|
||||
# excl_all EXCLUDE_FROM_ALL if these targets should not be built by
|
||||
# default, otherwise empty string.
|
||||
# excl_all EXCLUDE_FROM_ALL if these targets should not be built by
|
||||
# default, otherwise empty string.
|
||||
#
|
||||
# test_regexp Regular expression which picks the name of a test
|
||||
# out of the filename, or blank if no test should be
|
||||
# setup.
|
||||
# test_regexp Regular expression which picks the name of a test
|
||||
# out of the filename, or blank if no test should be
|
||||
# setup.
|
||||
#
|
||||
# Example:
|
||||
# opm_compile_satellites (opm-core test "" "^test_([^/]*)$")
|
||||
# opm_compile_satellites (opm-core test "" "^test_([^/]*)$")
|
||||
#
|
||||
macro (opm_compile_satellites opm satellite excl_all test_regexp)
|
||||
# if we are going to build the tests always, then make sure that
|
||||
# the datafiles are present too
|
||||
if (NOT (${excl_all} MATCHES "EXCLUDE_FROM_ALL"))
|
||||
set (_incl_all "ALL")
|
||||
set (_incl_all "ALL")
|
||||
else (NOT (${excl_all} MATCHES "EXCLUDE_FROM_ALL"))
|
||||
set (_incl_all "")
|
||||
set (_incl_all "")
|
||||
endif (NOT (${excl_all} MATCHES "EXCLUDE_FROM_ALL"))
|
||||
|
||||
# if a set of datafiles has been setup, pull those in
|
||||
add_custom_target (${satellite} ${_incl_all})
|
||||
if (${satellite}_DATAFILES)
|
||||
add_dependencies (${satellite} ${${satellite}_DATAFILES})
|
||||
add_dependencies (${satellite} ${${satellite}_DATAFILES})
|
||||
endif (${satellite}_DATAFILES)
|
||||
|
||||
# compile each of these separately
|
||||
foreach (_sat_FILE IN LISTS ${satellite}_SOURCES)
|
||||
get_filename_component (_sat_NAME "${_sat_FILE}" NAME_WE)
|
||||
add_executable (${_sat_NAME} ${excl_all} ${_sat_FILE})
|
||||
add_dependencies (${satellite} ${_sat_NAME})
|
||||
set_target_properties (${_sat_NAME} PROPERTIES
|
||||
LINK_FLAGS "${${opm}_LINKER_FLAGS_STR}"
|
||||
)
|
||||
if(HAVE_DYNAMIC_BOOST_TEST)
|
||||
set_target_properties (${_sat_NAME} PROPERTIES
|
||||
COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK
|
||||
)
|
||||
endif()
|
||||
# are we building a test? luckily, the testing framework doesn't
|
||||
# require anything else, so we don't have to figure out where it
|
||||
# should go in the library list
|
||||
if (NOT "${test_regexp}" STREQUAL "")
|
||||
set (_test_lib "${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}")
|
||||
else (NOT "${test_regexp}" STREQUAL "")
|
||||
set (_test_lib "")
|
||||
add_static_analysis_tests(_sat_FILE ${opm}_INCLUDE_DIRS)
|
||||
endif (NOT "${test_regexp}" STREQUAL "")
|
||||
target_link_libraries (${_sat_NAME} ${${opm}_TARGET} ${${opm}_LIBRARIES} ${_test_lib})
|
||||
if (STRIP_DEBUGGING_SYMBOLS)
|
||||
strip_debug_symbols (${_sat_NAME} _sat_DEBUG)
|
||||
list (APPEND ${satellite}_DEBUG ${_sat_DEBUG})
|
||||
get_filename_component (_sat_NAME "${_sat_FILE}" NAME_WE)
|
||||
add_executable (${_sat_NAME} ${excl_all} ${_sat_FILE})
|
||||
add_dependencies (${satellite} ${_sat_NAME})
|
||||
set_target_properties (${_sat_NAME} PROPERTIES
|
||||
LINK_FLAGS "${${opm}_LINKER_FLAGS_STR}")
|
||||
if(HAVE_DYNAMIC_BOOST_TEST)
|
||||
set_target_properties (${_sat_NAME} PROPERTIES
|
||||
COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK)
|
||||
endif()
|
||||
# are we building a test? luckily, the testing framework doesn't
|
||||
# require anything else, so we don't have to figure out where it
|
||||
# should go in the library list
|
||||
if (NOT "${test_regexp}" STREQUAL "")
|
||||
set (_test_lib "${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}")
|
||||
else (NOT "${test_regexp}" STREQUAL "")
|
||||
set (_test_lib "")
|
||||
add_static_analysis_tests(_sat_FILE ${opm}_INCLUDE_DIRS)
|
||||
endif (NOT "${test_regexp}" STREQUAL "")
|
||||
target_link_libraries (${_sat_NAME} ${${opm}_TARGET} ${${opm}_LIBRARIES} ${_test_lib})
|
||||
if (STRIP_DEBUGGING_SYMBOLS)
|
||||
strip_debug_symbols (${_sat_NAME} _sat_DEBUG)
|
||||
list (APPEND ${satellite}_DEBUG ${_sat_DEBUG})
|
||||
endif()
|
||||
|
||||
# variable with regular expression doubles as a flag for
|
||||
# whether tests should be setup or not
|
||||
set(_sat_FANCY)
|
||||
if (NOT "${test_regexp}" STREQUAL "")
|
||||
foreach (_regexp IN ITEMS ${test_regexp})
|
||||
if ("${_sat_NAME}" MATCHES "${_regexp}")
|
||||
string (REGEX REPLACE "${_regexp}" "\\1" _sat_FANCY "${_sat_NAME}")
|
||||
elseif(NOT _sat_FANCY)
|
||||
set(_sat_FANCY ${_sat_NAME})
|
||||
endif()
|
||||
endforeach (_regexp)
|
||||
get_target_property (_sat_LOC ${_sat_NAME} LOCATION)
|
||||
# Run tests through mpi-run. Ubuntu 14.04 provided mpi libs will crash
|
||||
# in the MPI_Finalize() call otherwise.
|
||||
if(MPI_FOUND)
|
||||
set(_sat_LOC ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} 1 ${_sat_LOC})
|
||||
endif()
|
||||
if (CMAKE_VERSION VERSION_LESS "2.8.4")
|
||||
add_test (NAME ${_sat_FANCY}
|
||||
COMMAND ${CMAKE_COMMAND} -E chdir "${PROJECT_BINARY_DIR}/${${satellite}_DIR}" ${_sat_LOC})
|
||||
else (CMAKE_VERSION VERSION_LESS "2.8.4")
|
||||
add_test (${_sat_FANCY} ${_sat_LOC})
|
||||
# run the test in the directory where the data files are
|
||||
set_tests_properties (${_sat_FANCY} PROPERTIES
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/${${satellite}_DIR})
|
||||
endif (CMAKE_VERSION VERSION_LESS "2.8.4")
|
||||
if(NOT TARGET test-suite)
|
||||
add_custom_target(test-suite)
|
||||
endif()
|
||||
add_dependencies(test-suite "${_sat_NAME}")
|
||||
endif(NOT "${test_regexp}" STREQUAL "")
|
||||
|
||||
# variable with regular expression doubles as a flag for
|
||||
# whether tests should be setup or not
|
||||
set(_sat_FANCY)
|
||||
if (NOT "${test_regexp}" STREQUAL "")
|
||||
foreach (_regexp IN ITEMS ${test_regexp})
|
||||
if ("${_sat_NAME}" MATCHES "${_regexp}")
|
||||
string (REGEX REPLACE "${_regexp}" "\\1" _sat_FANCY "${_sat_NAME}")
|
||||
elseif(NOT _sat_FANCY)
|
||||
set(_sat_FANCY ${_sat_NAME})
|
||||
endif()
|
||||
endforeach (_regexp)
|
||||
get_target_property (_sat_LOC ${_sat_NAME} LOCATION)
|
||||
# Run tests through mpi-run. Ubuntu 14.04 provided mpi libs will crash
|
||||
# in the MPI_Finalize() call otherwise.
|
||||
if(MPI_FOUND)
|
||||
set(_sat_LOC ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} 1 ${_sat_LOC})
|
||||
endif()
|
||||
if (CMAKE_VERSION VERSION_LESS "2.8.4")
|
||||
add_test (
|
||||
NAME ${_sat_FANCY}
|
||||
COMMAND ${CMAKE_COMMAND} -E chdir "${PROJECT_BINARY_DIR}/${${satellite}_DIR}" ${_sat_LOC}
|
||||
)
|
||||
else (CMAKE_VERSION VERSION_LESS "2.8.4")
|
||||
add_test (${_sat_FANCY} ${_sat_LOC})
|
||||
# run the test in the directory where the data files are
|
||||
set_tests_properties (${_sat_FANCY} PROPERTIES
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/${${satellite}_DIR}
|
||||
)
|
||||
endif (CMAKE_VERSION VERSION_LESS "2.8.4")
|
||||
if(NOT TARGET test-suite)
|
||||
add_custom_target(test-suite)
|
||||
endif()
|
||||
add_dependencies(test-suite "${_sat_NAME}")
|
||||
endif(NOT "${test_regexp}" STREQUAL "")
|
||||
|
||||
# if this program on the list of files that should be distributed?
|
||||
# we check by the name of the source file
|
||||
list (FIND ${satellite}_SOURCES_DIST "${_sat_FILE}" _is_util)
|
||||
if (NOT (_is_util EQUAL -1))
|
||||
install (TARGETS ${_sat_NAME} RUNTIME
|
||||
DESTINATION bin${${opm}_VER_DIR}/
|
||||
)
|
||||
endif (NOT (_is_util EQUAL -1))
|
||||
# if this program on the list of files that should be distributed?
|
||||
# we check by the name of the source file
|
||||
list (FIND ${satellite}_SOURCES_DIST "${_sat_FILE}" _is_util)
|
||||
if (NOT (_is_util EQUAL -1))
|
||||
install (TARGETS ${_sat_NAME} RUNTIME
|
||||
DESTINATION bin${${opm}_VER_DIR}/)
|
||||
endif (NOT (_is_util EQUAL -1))
|
||||
endforeach (_sat_FILE)
|
||||
endmacro (opm_compile_satellites opm prefix)
|
||||
|
||||
# Synopsis:
|
||||
# opm_data (satellite target dirname files)
|
||||
# opm_data (satellite target dirname files)
|
||||
#
|
||||
# provides these output variables:
|
||||
#
|
||||
# ${satellite}_INPUT_FILES List of all files that are copied
|
||||
# ${satellite}_DATAFILES Name of target which copies these files
|
||||
# ${satellite}_INPUT_FILES List of all files that are copied
|
||||
# ${satellite}_DATAFILES Name of target which copies these files
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# opm_data (tests datafiles "tests/")
|
||||
# opm_data (tests datafiles "tests/")
|
||||
#
|
||||
macro (opm_data satellite target dirname)
|
||||
# even if there are no datafiles, create the directory so the
|
||||
# satellite programs have a homedir to run in
|
||||
execute_process (
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/${dirname}
|
||||
)
|
||||
execute_process (COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/${dirname})
|
||||
|
||||
# if ever huge test datafiles are necessary, then change this
|
||||
# into "create_symlink" (on UNIX only, apparently)
|
||||
@@ -158,26 +147,27 @@ macro (opm_data satellite target dirname)
|
||||
# to a tests/ directory in the output tree (if different)
|
||||
set (${satellite}_INPUT_FILES)
|
||||
if (NOT PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
|
||||
foreach (input_datafile IN LISTS ${satellite}_DATA)
|
||||
file (RELATIVE_PATH rel_datafile "${PROJECT_SOURCE_DIR}" ${input_datafile})
|
||||
set (output_datafile "${PROJECT_BINARY_DIR}/${rel_datafile}")
|
||||
add_custom_command (
|
||||
OUTPUT ${output_datafile}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
ARGS -E ${make_avail} ${input_datafile} ${output_datafile}
|
||||
DEPENDS ${input_datafile}
|
||||
VERBATIM
|
||||
)
|
||||
list (APPEND ${satellite}_INPUT_FILES "${output_datafile}")
|
||||
endforeach (input_datafile)
|
||||
foreach (input_datafile IN LISTS ${satellite}_DATA)
|
||||
if (IS_ABSOLUTE ${input_datafile})
|
||||
file (RELATIVE_PATH rel_datafile "${PROJECT_SOURCE_DIR}" ${input_datafile})
|
||||
else()
|
||||
set(rel_datafile ${input_datafile})
|
||||
endif()
|
||||
set (output_datafile "${PROJECT_BINARY_DIR}/${rel_datafile}")
|
||||
add_custom_command (OUTPUT ${output_datafile}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
ARGS -E ${make_avail} ${input_datafile} ${output_datafile}
|
||||
DEPENDS ${input_datafile}
|
||||
VERBATIM)
|
||||
list (APPEND ${satellite}_INPUT_FILES "${output_datafile}")
|
||||
endforeach (input_datafile)
|
||||
endif(NOT PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
|
||||
|
||||
# setup a target which does all the copying
|
||||
set (${satellite}_DATAFILES "${target}")
|
||||
add_custom_target (${${satellite}_DATAFILES}
|
||||
DEPENDS ${${satellite}_INPUT_FILES}
|
||||
COMMENT "Making \"${satellite}\" data available in output tree"
|
||||
)
|
||||
DEPENDS ${${satellite}_INPUT_FILES}
|
||||
COMMENT "Making \"${satellite}\" data available in output tree")
|
||||
if(NOT TARGET test-suite)
|
||||
add_custom_target(test-suite)
|
||||
endif()
|
||||
@@ -192,6 +182,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 +209,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}")
|
||||
@@ -266,6 +257,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()
|
||||
@@ -303,6 +299,8 @@ macro(opm_add_test TestName)
|
||||
# only compile the binary but do not run it as a test
|
||||
add_executable("${CURTEST_EXE_NAME}" ${CURTEST_EXCLUDE_FROM_ALL} ${CURTEST_SOURCES})
|
||||
target_link_libraries (${CURTEST_EXE_NAME} ${CURTEST_LIBRARIES})
|
||||
get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
|
||||
add_static_analysis_tests(CURTEST_SOURCES dirs)
|
||||
|
||||
if(TARGET ${project}_prepare)
|
||||
add_dependencies("${CURTEST_EXE_NAME}" ${project}_prepare)
|
||||
@@ -318,10 +316,11 @@ macro(opm_add_test TestName)
|
||||
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()
|
||||
COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK)
|
||||
endif()
|
||||
target_link_libraries (${CURTEST_EXE_NAME} ${CURTEST_LIBRARIES})
|
||||
get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
|
||||
add_static_analysis_tests(CURTEST_SOURCES dirs)
|
||||
|
||||
if(CURTEST_DEPENDS)
|
||||
add_dependencies("${CURTEST_EXE_NAME}" ${CURTEST_DEPENDS})
|
||||
@@ -364,15 +363,6 @@ macro(opm_add_test TestName)
|
||||
endif()
|
||||
add_dependencies(test-suite "${CURTEST_EXE_NAME}")
|
||||
endif()
|
||||
|
||||
else() # test is skipped
|
||||
|
||||
# the following causes the test to appear as 'skipped' in the
|
||||
# CDash dashboard. it this is removed, the test is just silently
|
||||
# ignored.
|
||||
if (NOT CURTEST_ONLY_COMPILE AND ADD_DISABLED_CTESTS)
|
||||
add_test(${_FANCY} skip_test_dummy)
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
@@ -9,12 +9,7 @@ macro(create_module_dir_var module)
|
||||
get_filename_component(_parent_dir_name ${_parent_full_dir} NAME)
|
||||
#Try if <module-name>/<build-dir> is used
|
||||
get_filename_component(_modules_dir ${_parent_full_dir} DIRECTORY)
|
||||
if ("${module}" STREQUAL "ecl")
|
||||
#use clone directory libecl
|
||||
set(_clone_dir "libecl")
|
||||
else()
|
||||
set(_clone_dir "${module}")
|
||||
endif()
|
||||
set(_clone_dir "${module}")
|
||||
if(IS_DIRECTORY ${_modules_dir}/${_clone_dir}/${_leaf_dir_name})
|
||||
set(${module}_DIR ${_modules_dir}/${_clone_dir}/${_leaf_dir_name})
|
||||
else()
|
||||
@@ -23,7 +18,8 @@ macro(create_module_dir_var module)
|
||||
AND IS_DIRECTORY ${_parent_full_dir}/${_module_leaf})
|
||||
# We are using build directories named <prefix><module-name><postfix>
|
||||
set(${module}_DIR ${_parent_full_dir}/${_module_leaf})
|
||||
elseif(IS_DIRECTORY ${_parent_full_dir}/${_clone_dir})
|
||||
elseif(IS_DIRECTORY ${_parent_full_dir}/${_clone_dir} AND
|
||||
EXISTS ${_parent_full_dir}/${_clone_dir}/CMakeCache.txt)
|
||||
# All modules are in a common build dir
|
||||
set(${module}_DIR "${_parent_full_dir}/${_clone_dir}")
|
||||
endif()
|
||||
|
||||
@@ -34,16 +34,29 @@ function(add_static_analysis_tests sources includes)
|
||||
list(APPEND IPATHS -I ${dep})
|
||||
endforeach()
|
||||
foreach(src ${${sources}})
|
||||
file(RELATIVE_PATH name ${PROJECT_SOURCE_DIR} ${src})
|
||||
if(src MATCHES "TARGET_OBJECTS:")
|
||||
string(REGEX REPLACE "\\$<TARGET_OBJECTS:(.*)>" "\\1" TGT ${src})
|
||||
get_target_property(src ${TGT} SOURCES)
|
||||
endif()
|
||||
if(IS_ABSOLUTE ${src})
|
||||
file(RELATIVE_PATH name ${PROJECT_SOURCE_DIR} ${src})
|
||||
else()
|
||||
set(name ${src})
|
||||
set(src ${PROJECT_SOURCE_DIR}/${src})
|
||||
endif()
|
||||
if(CPPCHECK_FOUND)
|
||||
add_test(NAME cppcheck+${name}
|
||||
COMMAND bin/cppcheck-test.sh ${CPPCHECK_PROGRAM} ${src} ${IPATHS}
|
||||
CONFIGURATIONS analyze cppcheck)
|
||||
if(NOT TEST cppcheck+${name})
|
||||
add_test(NAME cppcheck+${name}
|
||||
COMMAND bin/cppcheck-test.sh ${CPPCHECK_PROGRAM} ${src} ${IPATHS}
|
||||
CONFIGURATIONS analyze cppcheck)
|
||||
endif()
|
||||
endif()
|
||||
if(CLANGCHECK_FOUND AND CMAKE_EXPORT_COMPILE_COMMANDS)
|
||||
add_test(NAME clang-check+${name}
|
||||
COMMAND bin/clang-check-test.sh ${CLANGCHECK_PROGRAM} ${src}
|
||||
CONFIGURATIONS analyze clang-check)
|
||||
if(NOT TEST clang-check+${name})
|
||||
add_test(NAME clang-check+${name}
|
||||
COMMAND bin/clang-check-test.sh ${CLANGCHECK_PROGRAM} ${src}
|
||||
CONFIGURATIONS analyze clang-check)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
@@ -6,7 +6,7 @@ is_compiler_gcc_compatible ()
|
||||
|
||||
if (CXX_COMPAT_GCC)
|
||||
# default warnings flags, if not set by user
|
||||
set_default_option (CXX _warn_flag "-Wall" "(^|\ )-W")
|
||||
set_default_option (CXX _warn_flag "-Wall -Wextra -Wshadow" "(^|\ )-W")
|
||||
if (_warn_flag)
|
||||
message (STATUS "All warnings enabled: ${_warn_flag}")
|
||||
add_options (ALL_LANGUAGES ALL_BUILDS "${_warn_flag}")
|
||||
|
||||
@@ -31,30 +31,15 @@ if(NOT check_target)
|
||||
endif()
|
||||
|
||||
# Build threads
|
||||
include(ProcessorCount)
|
||||
set(build_threads $ENV{CHECK_THREADS})
|
||||
if(NOT build_threads)
|
||||
if(UNIX)
|
||||
if(APPLE)
|
||||
execute_process(COMMAND sysctl hw.ncpu
|
||||
OUTPUT_VARIABLE build_threads)
|
||||
string(REPLACE " " ";" build_threads_list ${build_threads)
|
||||
list(GET build_threads_list 1 build_threads)
|
||||
else()
|
||||
find_program(NPROC_COMMAND nproc)
|
||||
if(NPROC_COMMAND)
|
||||
execute_process(COMMAND ${NPROC_COMMAND}
|
||||
OUTPUT_VARIABLE build_threads)
|
||||
string(REGEX REPLACE "(\r?\n)+$" "" build_threads "${build_threads}")
|
||||
endif()
|
||||
endif()
|
||||
ProcessorCount(build_threads)
|
||||
if(build_threads EQUAL 0)
|
||||
set(build_threads 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# If for some reason we could not find the info - e.g. centos5 where nproc is missing
|
||||
if(NOT build_threads)
|
||||
set(build_threads 1)
|
||||
endif()
|
||||
|
||||
# Record current HEAD
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
|
||||
OUTPUT_VARIABLE current_branch
|
||||
|
||||
2
debian/changelog
vendored
2
debian/changelog
vendored
@@ -1,4 +1,4 @@
|
||||
opm-common (2019.04-pre~xenial) xenial; urgency=medium
|
||||
opm-common (2019.10-rc2-1~xenial) xenial; urgency=medium
|
||||
|
||||
* New release
|
||||
|
||||
|
||||
2
debian/control
vendored
2
debian/control
vendored
@@ -5,7 +5,7 @@ Build-Depends: build-essential, debhelper (>= 9),
|
||||
pkg-config, cmake, git, libtool, doxygen,
|
||||
texlive-latex-extra, texlive-latex-recommended,
|
||||
ghostscript, libboost-system-dev, libboost-test-dev,
|
||||
libecl-dev, libboost-regex-dev, libboost-filesystem-dev,
|
||||
libboost-regex-dev, libboost-filesystem-dev,
|
||||
zlib1g-dev
|
||||
Standards-Version: 3.9.2
|
||||
Section: libs
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
Module: opm-common
|
||||
Description: Open Porous Media Initiative shared infrastructure
|
||||
Version: 2019.04-pre
|
||||
Label: 2019.04-pre
|
||||
Version: 2019.10-rc2
|
||||
Label: 2019.10-rc2
|
||||
Maintainer: opm@opm-project.org
|
||||
MaintainerName: OPM community
|
||||
Url: http://opm-project.org
|
||||
|
||||
@@ -11,7 +11,7 @@ _ewoms_parameter_completor()
|
||||
|
||||
cmd="${COMP_WORDS[0]}"
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
fullcmd="$(which "$cmd")"
|
||||
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}") )
|
||||
@@ -32,7 +32,7 @@ _ewoms_generic_parameter_completor()
|
||||
cmd="${COMP_WORDS[0]}"
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
|
||||
fullcmd="$(which "$cmd")"
|
||||
fullcmd="$(which "$cmd" 2> /dev/null)"
|
||||
if test -z "$fullcmd" || \
|
||||
! test -x "$fullcmd" || \
|
||||
(! test -f "$fullcmd" && ! test -h "$fullcmd" ) || \
|
||||
|
||||
@@ -17,12 +17,37 @@
|
||||
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;
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
Opm::msim msim(argv[1]);
|
||||
msim.run();
|
||||
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, false);
|
||||
}
|
||||
|
||||
|
||||
158
examples/opmhash.cpp
Normal file
158
examples/opmhash.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
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_arg, const std::string& filename_arg,
|
||||
std::size_t line_number_arg, std::size_t content_hash_arg) :
|
||||
name(name_arg),
|
||||
filename(filename_arg),
|
||||
line_number(line_number_arg),
|
||||
content_hash(content_hash_arg)
|
||||
{}
|
||||
|
||||
|
||||
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,29 +21,40 @@
|
||||
|
||||
#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>
|
||||
|
||||
#include <opm/common/OpmLog/OpmLog.hpp>
|
||||
#include <opm/common/OpmLog/StreamLog.hpp>
|
||||
#include <opm/common/OpmLog/LogUtil.hpp>
|
||||
|
||||
|
||||
void initLogging() {
|
||||
std::shared_ptr<Opm::StreamLog> cout_log = std::make_shared<Opm::StreamLog>(std::cout, Opm::Log::DefaultMessageTypes);
|
||||
Opm::OpmLog::addBackend( "COUT" , cout_log);
|
||||
}
|
||||
|
||||
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(), 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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
initLogging();
|
||||
for (int iarg = 1; iarg < argc; iarg++)
|
||||
loadDeck( argv[iarg] );
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#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>
|
||||
@@ -29,9 +30,10 @@
|
||||
|
||||
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);
|
||||
auto deck = parser.parseFile(deck_file, parseContext, errors);
|
||||
os << deck;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,300 +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 "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);
|
||||
}
|
||||
@@ -1,127 +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/>.
|
||||
*/
|
||||
|
||||
#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
|
||||
@@ -1,199 +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 "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;
|
||||
}
|
||||
@@ -1,78 +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/>.
|
||||
*/
|
||||
|
||||
#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
|
||||
@@ -1,352 +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 "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;
|
||||
}
|
||||
@@ -1,93 +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/>.
|
||||
*/
|
||||
|
||||
#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
|
||||
@@ -1,381 +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 "EclIntegrationTest.hpp"
|
||||
#include "EclRegressionTest.hpp"
|
||||
#include "summaryIntegrationTest.hpp"
|
||||
#include "summaryRegressionTest.hpp"
|
||||
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
|
||||
#include <ert/util/util.h>
|
||||
#include <ert/util/stringlist.h>
|
||||
#include <ert/ecl/ecl_endian_flip.h>
|
||||
#include <ert/ecl/ecl_file.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <getopt.h>
|
||||
|
||||
static void printHelp() {
|
||||
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"
|
||||
<< "-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"
|
||||
<< "Exceptions are thrown (and hence program exits) when deviations are larger than the specified "
|
||||
<< "tolerances, or when the number of cells does not match -- either in the grid file or for a "
|
||||
<< "specific keyword. Information about the keyword, keyword occurrence (zero based) and cell "
|
||||
<< "coordinate is printed when an exception is thrown. For more information about how the cases "
|
||||
<< "are compared, see the documentation of the EclFilesComparator class.\n\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
void splitBasename(const std::string& basename, std::string& path, std::string& filename) {
|
||||
const size_t lastSlashIndex = basename.find_last_of("/\\");
|
||||
path = basename.substr(0,lastSlashIndex);
|
||||
filename = basename.substr(lastSlashIndex+1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Inspired by the ecl_pack application in the ERT library
|
||||
void concatenateRestart(const std::string& basename) {
|
||||
std::string inputPath, inputBase;
|
||||
splitBasename(basename, inputPath, inputBase);
|
||||
stringlist_type* inputFiles = stringlist_alloc_new();
|
||||
const int numFiles = ecl_util_select_filelist(inputPath.c_str(), inputBase.c_str(), ECL_RESTART_FILE, false, inputFiles);
|
||||
|
||||
const char* target_file_name = ecl_util_alloc_filename(inputPath.c_str(), inputBase.c_str(), ECL_UNIFIED_RESTART_FILE, false, -1);
|
||||
fortio_type* target = fortio_open_writer(target_file_name, false, ECL_ENDIAN_FLIP);
|
||||
int dummy;
|
||||
ecl_kw_type* seqnum_kw = ecl_kw_alloc_new("SEQNUM", 1, ECL_INT, &dummy);
|
||||
|
||||
int reportStep = 0;
|
||||
for (int i = 0; i < numFiles; ++i) {
|
||||
ecl_util_get_file_type(stringlist_iget(inputFiles, i), nullptr, &reportStep);
|
||||
ecl_file_type* src_file = ecl_file_open(stringlist_iget(inputFiles, i), 0);
|
||||
ecl_kw_iset_int(seqnum_kw, 0, reportStep);
|
||||
ecl_kw_fwrite(seqnum_kw, target);
|
||||
ecl_file_fwrite_fortio(src_file, target, 0);
|
||||
ecl_file_close(src_file);
|
||||
}
|
||||
fortio_fclose(target);
|
||||
stringlist_free(inputFiles);
|
||||
}
|
||||
|
||||
//------------------------------------------------//
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
// Restart is default
|
||||
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:alnpPt:VRgs:m:vKx")) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
analysis = true;
|
||||
break;
|
||||
case 'g':
|
||||
findGreatestErrorRatio = true;
|
||||
throwTooGreatErrorRatio = false;
|
||||
break;
|
||||
case 'h':
|
||||
printHelp();
|
||||
return 0;
|
||||
case 'i':
|
||||
integrationTest = true;
|
||||
break;
|
||||
case 'I':
|
||||
integrationTest = true;
|
||||
checkNumKeywords = true;
|
||||
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' || 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') {
|
||||
std::cerr << "Option t requires an ECLIPSE filetype as argument, see manual (-h) for more information." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else {
|
||||
std::cerr << "Unknown option." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
default:
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
int argOffset = optind;
|
||||
if ((printKeywords && printKeywordsDifference) ||
|
||||
(integrationTest && specificFileType) ||
|
||||
(integrationTest && onlyLastOccurrence)) {
|
||||
std::cerr << "Error: Options given which can not be combined. "
|
||||
<< "Please see the manual (-h) for more information." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (argc != argOffset + 4) {
|
||||
std::cerr << "Error: The number of options and arguments given is not correct. "
|
||||
<< "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);
|
||||
double relTolerance = strtod(argv[argOffset + 3], nullptr);
|
||||
|
||||
if (specificFileType) {
|
||||
std::string fileTypeString(fileTypeCstr);
|
||||
for (auto& ch: fileTypeString) ch = toupper(ch);
|
||||
if (fileTypeString== "UNRST") {} //Do nothing
|
||||
else if (fileTypeString == "RST") {
|
||||
concatenateRestart(basename1);
|
||||
concatenateRestart(basename2);
|
||||
}
|
||||
else if (fileTypeString == "RST1") {
|
||||
concatenateRestart(basename1);
|
||||
}
|
||||
else if (fileTypeString == "RST2") {
|
||||
concatenateRestart(basename2);
|
||||
}
|
||||
else if (fileTypeString == "INIT") {
|
||||
file_type = ECL_INIT_FILE;
|
||||
}
|
||||
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 (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;
|
||||
}
|
||||
if (printKeywordsDifference) {
|
||||
comparator.printKeywordsDifference();
|
||||
return 0;
|
||||
}
|
||||
if (checkNumKeywords) {
|
||||
comparator.equalNumKeywords();
|
||||
}
|
||||
if (specificKeyword) {
|
||||
if (comparator.elementInWhitelist(keyword)) {
|
||||
comparator.resultsForKeyword(keyword);
|
||||
}
|
||||
else {
|
||||
std::cerr << "Keyword " << keyword << " is not supported for the integration test. Use SGAS, SWAT or PRESSURE." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
comparator.results();
|
||||
}
|
||||
}
|
||||
else {
|
||||
ECLRegressionTest comparator(file_type, basename1, basename2, absTolerance, relTolerance);
|
||||
comparator.throwOnErrors(throwOnError);
|
||||
comparator.doAnalysis(analysis);
|
||||
comparator.setAcceptExtraKeywords(acceptExtraKeywords);
|
||||
if (printKeywords) {
|
||||
comparator.printKeywords();
|
||||
return 0;
|
||||
}
|
||||
if (printKeywordsDifference) {
|
||||
comparator.printKeywordsDifference();
|
||||
return 0;
|
||||
}
|
||||
if (onlyLastOccurrence) {
|
||||
comparator.setOnlyLastOccurrence(true);
|
||||
}
|
||||
if (specificKeyword) {
|
||||
comparator.gridCompare(volumecheck);
|
||||
comparator.resultsForKeyword(keyword);
|
||||
}
|
||||
else {
|
||||
comparator.gridCompare(volumecheck);
|
||||
comparator.results();
|
||||
}
|
||||
if (comparator.getNoErrors() > 0)
|
||||
OPM_THROW(std::runtime_error, comparator.getNoErrors() << " errors encountered in comparisons.");
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "Program threw an exception: " << e.what() << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,240 +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 "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 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");
|
||||
}
|
||||
absoluteTolerance = absoluteTol;
|
||||
relativeTolerance = relativeTol;
|
||||
keys1 = stringlist_alloc_new();
|
||||
keys2 = stringlist_alloc_new();
|
||||
ecl_sum_select_matching_general_var_list( ecl_sum1 , "*" , this->keys1);
|
||||
stringlist_sort(this->keys1 , nullptr );
|
||||
ecl_sum_select_matching_general_var_list( ecl_sum2 , "*" , this->keys2);
|
||||
stringlist_sort(this->keys2 , nullptr );
|
||||
|
||||
if(stringlist_get_size(keys1) <= stringlist_get_size(keys2)){
|
||||
this->keysShort = this->keys1;
|
||||
this->keysLong = this->keys2;
|
||||
}else{
|
||||
this->keysShort = this->keys2;
|
||||
this->keysLong = this->keys1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SummaryComparator::~SummaryComparator(){
|
||||
ecl_sum_free(ecl_sum1);
|
||||
ecl_sum_free(ecl_sum2);
|
||||
stringlist_free(keys1);
|
||||
stringlist_free(keys2);
|
||||
}
|
||||
|
||||
|
||||
Deviation SummaryComparator::calculateDeviations(double val1, double val2){
|
||||
double absDev;
|
||||
Deviation deviation;
|
||||
absDev = std::abs(val1 - val2);
|
||||
deviation.abs = absDev;
|
||||
if (val1 != 0 || val2 != 0) {
|
||||
deviation.rel = absDev/double(std::max(std::abs(val1), std::abs(val2)));
|
||||
}
|
||||
return deviation;
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::setTimeVecs(std::vector<double> &timeVec1,
|
||||
std::vector<double> &timeVec2){
|
||||
timeVec1.reserve(ecl_sum_get_data_length(ecl_sum1));
|
||||
for (int time_index = 0; time_index < ecl_sum_get_data_length(ecl_sum1); time_index++){
|
||||
timeVec1.push_back(ecl_sum_iget_sim_days(ecl_sum1 , time_index ));
|
||||
}
|
||||
timeVec2.reserve(ecl_sum_get_data_length(ecl_sum2));
|
||||
for (int time_index = 0; time_index < ecl_sum_get_data_length(ecl_sum2); time_index++){
|
||||
timeVec2.push_back(ecl_sum_iget_sim_days(ecl_sum2 , time_index ));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::getDataVecs(std::vector<double> &dataVec1,
|
||||
std::vector<double> &dataVec2,
|
||||
const char* keyword){
|
||||
dataVec1.reserve(ecl_sum_get_data_length(ecl_sum1));
|
||||
for (int time_index = 0; time_index < ecl_sum_get_data_length(ecl_sum1); time_index++){
|
||||
dataVec1.push_back(ecl_sum_iget(ecl_sum1, time_index, ecl_sum_get_general_var_params_index( ecl_sum1 , keyword )));
|
||||
}
|
||||
dataVec2.reserve(ecl_sum_get_data_length(ecl_sum2));
|
||||
for (int time_index = 0; time_index < ecl_sum_get_data_length(ecl_sum2); time_index++){
|
||||
|
||||
dataVec2.push_back(ecl_sum_iget(ecl_sum2, time_index, ecl_sum_get_general_var_params_index( ecl_sum2 , keyword )));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::setDataSets(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2){
|
||||
if(timeVec1.size() < timeVec2.size()){
|
||||
ecl_sum_fileShort = this->ecl_sum1;
|
||||
ecl_sum_fileLong = this->ecl_sum2;
|
||||
}
|
||||
else{
|
||||
ecl_sum_fileShort = this->ecl_sum2;
|
||||
ecl_sum_fileLong = this->ecl_sum1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::chooseReference(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const std::vector<double>& dataVec1,
|
||||
const std::vector<double>& dataVec2){
|
||||
if(timeVec1.size() <= timeVec2.size()){
|
||||
referenceVec = &timeVec1; // time vector
|
||||
referenceDataVec = &dataVec1; //data vector
|
||||
checkVec = &timeVec2;
|
||||
checkDataVec = &dataVec2;
|
||||
}
|
||||
else{
|
||||
referenceVec = &timeVec2;
|
||||
referenceDataVec = &dataVec2;
|
||||
checkVec = &timeVec1;
|
||||
checkDataVec = &dataVec1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::getDeviation(size_t refIndex, size_t &checkIndex, Deviation &dev){
|
||||
if((*referenceVec)[refIndex] == (*checkVec)[checkIndex]){
|
||||
dev = SummaryComparator::calculateDeviations((*referenceDataVec)[refIndex], (*checkDataVec)[checkIndex]);
|
||||
checkIndex++;
|
||||
return;
|
||||
}
|
||||
else if((*referenceVec)[refIndex]<(*checkVec)[checkIndex]){
|
||||
double value = SummaryComparator::unitStep((*checkDataVec)[checkIndex]);
|
||||
/*Must be a little careful here. Flow writes out old value first,
|
||||
than changes value. Say there should be a change in production rate from A to B at timestep 300.
|
||||
Then the data of time step 300 is A and the next timestep will have value B. Must use the upper limit. */
|
||||
dev = SummaryComparator::calculateDeviations((*referenceDataVec)[refIndex], value);
|
||||
checkIndex++;
|
||||
return;
|
||||
}
|
||||
else{
|
||||
checkIndex++;
|
||||
getDeviation(refIndex, checkIndex , dev);
|
||||
}
|
||||
if(checkIndex == checkVec->size() -1 ){
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::printUnits(){
|
||||
std::vector<double> timeVec1, timeVec2;
|
||||
setTimeVecs(timeVec1, timeVec2); // Sets the time vectors, they are equal for all keywords (WPOR:PROD01 etc)
|
||||
setDataSets(timeVec1, timeVec2);
|
||||
for (int jvar = 0; jvar < stringlist_get_size(keysLong); jvar++){
|
||||
std::cout << stringlist_iget(keysLong, jvar) << " unit: " << ecl_sum_get_unit(ecl_sum_fileShort, stringlist_iget(keysLong, jvar)) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Called only when the keywords are equal in the getDeviations()-function
|
||||
const char* SummaryComparator::getUnit(const char* keyword){
|
||||
return ecl_sum_get_unit(ecl_sum_fileShort, keyword);
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::printKeywords(){
|
||||
int ivar = 0;
|
||||
std::vector<std::string> noMatchString;
|
||||
std::cout << "Keywords that are common for the files:" << std::endl;
|
||||
while(ivar < stringlist_get_size(keysLong)){
|
||||
const char* keyword = stringlist_iget(keysLong, ivar);
|
||||
if (stringlist_contains(keysLong, keyword) && stringlist_contains(keysShort, keyword)){
|
||||
std::cout << keyword << std::endl;
|
||||
ivar++;
|
||||
}
|
||||
else{
|
||||
noMatchString.push_back(keyword);
|
||||
ivar++;
|
||||
}
|
||||
}
|
||||
if(noMatchString.size() == 0){
|
||||
std::cout << "No keywords were different" << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout << "Keywords that are different: " << std::endl;
|
||||
for (const auto& it : noMatchString) std::cout << it << std::endl;
|
||||
|
||||
std::cout << "\nOf the " << stringlist_get_size(keysLong) << " keywords " << stringlist_get_size(keysLong)-noMatchString.size() << " were equal and " << noMatchString.size() << " were different" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::printDataOfSpecificKeyword(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);
|
||||
size_t ivar = 0;
|
||||
size_t jvar = 0;
|
||||
const char separator = ' ';
|
||||
const int numWidth = 14;
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << "Time";
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << "Ref data";
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << "Check data" << std::endl;
|
||||
|
||||
while(ivar < referenceVec->size()){
|
||||
if(ivar == referenceVec->size() || jvar == checkVec->size() ){
|
||||
break;
|
||||
}
|
||||
if((*referenceVec)[ivar] == (*checkVec)[jvar]){
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*referenceVec)[ivar];
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*referenceDataVec)[ivar];
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*checkDataVec)[jvar] << std::endl;
|
||||
ivar++;
|
||||
jvar++;
|
||||
}else if((*referenceVec)[ivar] < (*checkVec)[jvar]){
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*referenceVec)[ivar];
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*referenceDataVec)[ivar];
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << "" << std::endl;
|
||||
ivar++;
|
||||
}
|
||||
else{
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*checkVec)[jvar];
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << "";
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*checkDataVec)[jvar] << std::endl;
|
||||
jvar++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,182 +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/>.
|
||||
*/
|
||||
|
||||
#ifndef SUMMARYCOMPARATOR_HPP
|
||||
#define SUMMARYCOMPARATOR_HPP
|
||||
|
||||
#include "Deviation.hpp"
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
|
||||
// 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; \
|
||||
}
|
||||
|
||||
|
||||
//! \brief Prototyping struct, encapsuling the stringlist libraries.
|
||||
struct stringlist_struct;
|
||||
typedef struct stringlist_struct stringlist_type;
|
||||
|
||||
//! \brief Prototyping struct, encapsuling the ert libraries.
|
||||
struct ecl_sum_struct;
|
||||
typedef struct ecl_sum_struct ecl_sum_type;
|
||||
|
||||
|
||||
class SummaryComparator {
|
||||
private:
|
||||
double absoluteTolerance = 0; //!< The maximum absolute deviation that is allowed between two values.
|
||||
double relativeTolerance = 0; //!< The maximum relative deviation that is allowed between twi values.
|
||||
protected:
|
||||
ecl_sum_type * ecl_sum1 = nullptr; //!< Struct that contains file1
|
||||
ecl_sum_type * ecl_sum2 = nullptr; //!< Struct that contains file2
|
||||
ecl_sum_type * ecl_sum_fileShort = nullptr; //!< For keeping track of the file with most/fewest timesteps
|
||||
ecl_sum_type * ecl_sum_fileLong = nullptr; //!< For keeping track of the file with most/fewest timesteps
|
||||
stringlist_type* keys1 = nullptr; //!< For storing all the keywords of file1
|
||||
stringlist_type* keys2 = nullptr; //!< For storing all the keywords of file2
|
||||
stringlist_type * keysShort = nullptr; //!< For keeping track of the file with most/fewest keywords
|
||||
stringlist_type * keysLong = nullptr; //!< For keeping track of the file with most/fewest keywords
|
||||
const std::vector<double> * referenceVec = nullptr; //!< For storing the values of each time step for the file containing the fewer time steps.
|
||||
const std::vector<double> * referenceDataVec = nullptr; //!< For storing the data corresponding to each time step for the file containing the fewer time steps.
|
||||
const std::vector<double> * checkVec = nullptr; //!< For storing the values of each time step for the file containing the more time steps.
|
||||
const std::vector<double> * checkDataVec = nullptr; //!< For storing the data values corresponding to each time step for the file containing the more time steps.
|
||||
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
|
||||
//! \param[in] checkindex Index in data to be checked.
|
||||
//! \param[out] dev Holds the result from the comparison on return.
|
||||
//! \details Uses the #referenceVec as basis, and checks its values against the values in #checkDataVec. The function is reccursive, and will update the iterative index j of the #checkVec until #checkVec[j] >= #referenceVec[i]. \n When #referenceVec and #checkVec have the same time value (i.e. #referenceVec[i] == #checkVec[j]) a direct comparison is used, \n when this is not the case, when #referenceVec[i] do not excist as an element in #checkVec, a value is generated, either by the principle of unit step or by interpolation.
|
||||
void getDeviation(size_t refIndex, size_t &checkIndex, Deviation &dev);
|
||||
|
||||
//! \brief Figure out which data file contains the most / less timesteps and assign member variable pointers accordingly.
|
||||
//! \param[in] timeVec1 Data from first file
|
||||
//! \param[in] timeVec2 Data from second file
|
||||
//! \details Figure out which data file that contains the more/fewer time steps and assigns the private member variable pointers #ecl_sum_fileShort / #ecl_sum_fileLong to the correct data sets #ecl_sum1 / #ecl_sum2.
|
||||
void setDataSets(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2);
|
||||
|
||||
//! \brief Reads in the time values of each time step.
|
||||
//! \param[in] timeVec1 Vector for storing the time steps from file1
|
||||
//! \param[in] timeVec2 Vector for storing the time steps from file2
|
||||
void setTimeVecs(std::vector<double> &timeVec1,std::vector<double> &timeVec2);
|
||||
|
||||
//! \brief Read the data for one specific keyword into two separate vectors.
|
||||
//! \param[in] dataVec1 Vector for storing the data for one specific keyword from file1
|
||||
//! \param[in] dataVec2 Vector for storing the data for one specific keyword from file2
|
||||
//! \details The two data files do not necessarily have the same amount of data values, but the values must correspond to the same interval in time. Thus possible to interpolate values.
|
||||
void getDataVecs(std::vector<double> &dataVec1,
|
||||
std::vector<double> &dataVec2, const char* keyword);
|
||||
|
||||
//! \brief Sets one data set as a basis and the other as values to check against.
|
||||
//! \param[in] timeVec1 Used to figure out which dataset that have the more/fewer time steps.
|
||||
//! \param[in] timeVec2 Used to figure out which dataset that have the more/fewer time steps.
|
||||
//! \param[in] dataVec1 For assiging the the correct pointer to the data vector.
|
||||
//! \param[in] dataVec2 For assiging the the correct pointer to the data vector.
|
||||
//! \details Figures out which time vector that contains the fewer elements. Sets this as #referenceVec and its corresponding data as #referenceDataVec. \n The remaining data set is set as #checkVec (the time vector) and #checkDataVec.
|
||||
void chooseReference(const std::vector<double> &timeVec1,
|
||||
const std::vector<double> &timeVec2,
|
||||
const std::vector<double> &dataVec1,
|
||||
const std::vector<double> &dataVec2);
|
||||
|
||||
//! \brief Returns the relative tolerance.
|
||||
double getRelTolerance(){return this->relativeTolerance;}
|
||||
|
||||
//! \brief Returns the absolute tolerance.
|
||||
double getAbsTolerance(){return this->absoluteTolerance;}
|
||||
|
||||
//! \brief Returns the unit of the values of a keyword
|
||||
//! \param[in] keyword The keyword of interest.
|
||||
//! \param[out] ret The unit of the keyword as a const char*.
|
||||
const char* getUnit(const char* keyword);
|
||||
|
||||
//! \brief Prints the units of the files.
|
||||
void printUnits();
|
||||
|
||||
//! \brief Prints the keywords of the files.
|
||||
//! \details The function prints first the common keywords, than the keywords that are different.
|
||||
void printKeywords();
|
||||
|
||||
//! \brief Prints the summary vectors from the two files.
|
||||
//! \details The function requires that the summary vectors of the specific file have been read into the member variables referenceVec etc.
|
||||
void printDataOfSpecificKeyword(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const char* keyword);
|
||||
|
||||
public:
|
||||
//! \brief Creates an SummaryComparator class object
|
||||
//! \param[in] basename1 Path to file1 without extension.
|
||||
//! \param[in] basename1 Path to file2 without extension.
|
||||
//! \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 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.
|
||||
~SummaryComparator();
|
||||
|
||||
//! \brief Calculates the deviation between two values
|
||||
//! \param[in] val1 The first value of interest.
|
||||
//! \param[in] val2 The second value if interest.
|
||||
//! \param[out] ret Returns a Deviation struct.
|
||||
//! \details The function takes two values, calculates the absolute and relative deviation and returns the result as a Deviation struct.
|
||||
static Deviation calculateDeviations( double val1, double val2);
|
||||
|
||||
//! \brief Sets the private member variable printKeywords
|
||||
//! \param[in] boolean Boolean value
|
||||
//! \details The function sets the private member variable printKeywords. When it is true the function printKeywords will be called.
|
||||
void setPrintKeywords(bool boolean){this->printKeyword = boolean;}
|
||||
|
||||
//! \brief Sets the private member variable printSpecificKeyword
|
||||
//! \param[in] boolean Boolean value
|
||||
//! \details The function sets the private member variable printSpecificKeyword. When true, the summary vector of the keyword for both files will be printed.
|
||||
void setPrintSpecificKeyword(bool boolean){this->printSpecificKeyword = boolean;}
|
||||
|
||||
//! \brief Unit step function
|
||||
//! \param[in] value The input value should be the last know value
|
||||
//! \param[out] ret Return the unit-step-function value.
|
||||
//! \details In this case: The unit step function is used when the data from the two data set, which is to be compared, don't match in time. \n The unit step function is then to be called on the #checkDataVec 's value at the last time step which is before the time of comparison.
|
||||
|
||||
//! \brief Returns a value based on the unit step principle.
|
||||
static double unitStep(double value){return value;}
|
||||
|
||||
//! \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
|
||||
@@ -1,386 +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 "summaryIntegrationTest.hpp"
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <ert/ecl/ecl_sum.hpp>
|
||||
#include <ert/util/stringlist.hpp>
|
||||
#include <cmath>
|
||||
|
||||
|
||||
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);
|
||||
|
||||
int ivar = 0;
|
||||
if(!allowDifferentAmountOfKeywords){
|
||||
if(stringlist_get_size(keysShort) != stringlist_get_size(keysLong)){
|
||||
OPM_THROW(std::invalid_argument, "Different ammont of keywords in the two summary files.");
|
||||
}
|
||||
}
|
||||
if(printKeyword){
|
||||
printKeywords();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string keywordWithGreatestErrorRatio;
|
||||
double greatestRatio = 0;
|
||||
|
||||
//Iterates over all keywords from the restricted file, use iterator "ivar". Searches for a match in the file with more keywords, use the itarator "jvar".
|
||||
while(ivar < stringlist_get_size(keysShort)){
|
||||
const char* keyword = stringlist_iget(keysShort, ivar);
|
||||
|
||||
if(oneOfTheMainVariables){
|
||||
std::string keywordString(keyword);
|
||||
std::string substr = keywordString.substr(0,4);
|
||||
if(substr!= mainVariable){
|
||||
ivar++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
for (int jvar = 0; jvar < stringlist_get_size(keysLong); jvar++){
|
||||
|
||||
if (strcmp(keyword, stringlist_iget(keysLong, jvar)) == 0){ //When the keywords are equal, proceed in comparing summary files.
|
||||
/* if(!checkUnits(keyword)){
|
||||
OPM_THROW(std::runtime_error, "For keyword " << keyword << " the unit of the two files is not equal. Not possible to compare.");
|
||||
} //Comparing the unit of the two vectors.*/
|
||||
checkForKeyword(timeVec1, timeVec2, keyword);
|
||||
if(findVectorWithGreatestErrorRatio){
|
||||
WellProductionVolume volume = getSpecificWellVolume(timeVec1,timeVec2, keyword);
|
||||
findGreatestErrorRatio(volume,greatestRatio, keyword, keywordWithGreatestErrorRatio);
|
||||
}
|
||||
break;
|
||||
}
|
||||
//will only enter here if no keyword match
|
||||
if(jvar == stringlist_get_size(keysLong)-1){
|
||||
if(!allowDifferentAmountOfKeywords){
|
||||
OPM_THROW(std::invalid_argument, "No match on keyword");
|
||||
}
|
||||
}
|
||||
}
|
||||
ivar++;
|
||||
}
|
||||
if(findVectorWithGreatestErrorRatio){
|
||||
std::cout << "The keyword " << keywordWithGreatestErrorRatio << " had the greatest error ratio, which was " << greatestRatio << std::endl;
|
||||
}
|
||||
if((findVolumeError || oneOfTheMainVariables) && !findVectorWithGreatestErrorRatio){
|
||||
evaluateWellProductionVolume();
|
||||
}
|
||||
if(allowSpikes){
|
||||
std::cout << "checkWithSpikes succeeded." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
setDataSets(timeVec1, timeVec2);
|
||||
|
||||
if(printSpecificKeyword){
|
||||
printDataOfSpecificKeyword(timeVec1, timeVec2, keyword);
|
||||
}
|
||||
if(findVolumeError){
|
||||
WellProductionVolume volume = getSpecificWellVolume(timeVec1, timeVec2, keyword);
|
||||
if(volume.error == 0){
|
||||
std::cout << "For keyword " << keyword << " the total production volume is 0" << std::endl;
|
||||
}
|
||||
else{
|
||||
std::cout << "For keyword " << keyword << " the total production volume is "<< volume.total;
|
||||
std::cout << ", the error volume is " << volume.error << " the error ratio is " << volume.error/volume.total << std::endl;
|
||||
}
|
||||
}
|
||||
checkForKeyword(timeVec1, timeVec2, keyword);
|
||||
return;
|
||||
}
|
||||
OPM_THROW(std::invalid_argument, "The keyword used is not common for the two files.");
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
if(allowSpikes){
|
||||
checkWithSpikes(keyword);
|
||||
}
|
||||
if(findVolumeError ||oneOfTheMainVariables ){
|
||||
volumeErrorCheck(keyword);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int SummaryIntegrationTest::checkDeviation(const Deviation& deviation){
|
||||
double absTol = getAbsTolerance();
|
||||
double relTol = getRelTolerance();
|
||||
if (deviation.rel> relTol && deviation.abs > absTol){
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
std::string currentKeywordStr(currentKeyword);
|
||||
greatestErrorRatio = currentKeywordStr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
if(mainVariable == firstFour && firstFour == "WOPR"){
|
||||
if(firstFour == "WOPR"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WOP += result;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(mainVariable == firstFour && firstFour == "WWPR"){
|
||||
if(firstFour == "WWPR"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WWP += result;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(mainVariable == firstFour && firstFour == "WGPR"){
|
||||
if(firstFour == "WGPR"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WGP += result;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(mainVariable == firstFour && firstFour == "WBHP"){
|
||||
if(firstFour == "WBHP"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WBHP += result;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
updateVolumeError(keyword);
|
||||
}
|
||||
|
||||
|
||||
void SummaryIntegrationTest::updateVolumeError(const char* keyword){
|
||||
std::string keywordString(keyword);
|
||||
std::string firstFour = keywordString.substr(0,4);
|
||||
|
||||
if(firstFour == "WOPR"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WOP += result;
|
||||
}
|
||||
if(firstFour == "WWPR"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WWP += result;
|
||||
}
|
||||
if(firstFour == "WGPR"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WGP += result;
|
||||
|
||||
}
|
||||
if(firstFour == "WBHP"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WBHP += result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WellProductionVolume SummaryIntegrationTest::getWellProductionVolume(const char * keyword){
|
||||
double total = integrate(*referenceVec, *referenceDataVec);
|
||||
double error = integrateError(*referenceVec, *referenceDataVec,
|
||||
*checkVec, *checkDataVec);
|
||||
WellProductionVolume wPV;
|
||||
wPV.total = total;
|
||||
wPV.error = error;
|
||||
if(wPV.total != 0 && wPV.total-wPV.error > getAbsTolerance()){
|
||||
if( (wPV.error/wPV.total > getRelTolerance()) && throwExceptionForTooGreatErrorRatio){
|
||||
OPM_THROW(std::runtime_error, "For the keyword "<< keyword << " the error ratio was " << wPV.error/wPV.total << " which is greater than the tolerance " << getRelTolerance());
|
||||
}
|
||||
}
|
||||
return wPV;
|
||||
}
|
||||
|
||||
|
||||
void SummaryIntegrationTest::evaluateWellProductionVolume(){
|
||||
if(mainVariable.empty()){
|
||||
double ratioWOP, ratioWWP, ratioWGP, ratioWBHP;
|
||||
ratioWOP = WOP.error/WOP.total;
|
||||
ratioWWP = WWP.error/WWP.total;
|
||||
ratioWGP = WGP.error/WGP.total;
|
||||
ratioWBHP = WBHP.error/WBHP.total;
|
||||
std::cout << "\n The total oil volume is " << WOP.total << ". The error volume is "<< WOP.error << ". The error ratio is " << ratioWOP << std::endl;
|
||||
std::cout << "\n The total water volume is " << WWP.total << ". The error volume is "<< WWP.error << ". The error ratio is " << ratioWWP << std::endl;
|
||||
std::cout << "\n The total gas volume is " << WGP.total <<". The error volume is "<< WGP.error << ". The error ratio is " << ratioWGP << std::endl;
|
||||
std::cout << "\n The total area under the WBHP curve is " << WBHP.total << ". The area under the error curve is "<< WBHP.error << ". The error ratio is " << ratioWBHP << std::endl << std::endl;
|
||||
}
|
||||
if(mainVariable == "WOPR"){
|
||||
std::cout << "\nThe total oil volume is " << WOP.total << ". The error volume is "<< WOP.error << ". The error ratio is " << WOP.error/WOP.total << std::endl<< std::endl;
|
||||
}
|
||||
if(mainVariable == "WWPR"){
|
||||
std::cout << "\nThe total water volume is " << WWP.total << ". The error volume is "<< WWP.error << ". The error ratio is " << WWP.error/WWP.total << std::endl<< std::endl;
|
||||
}
|
||||
if(mainVariable == "WGPR"){
|
||||
std::cout << "\nThe total gas volume is " << WGP.total <<". The error volume is "<< WGP.error << ". The error ratio is " << WGP.error/WGP.total << std::endl<< std::endl;
|
||||
}
|
||||
if(mainVariable == "WBHP"){
|
||||
std::cout << "\nThe total area under the WBHP curve " << WBHP.total << ". The area under the error curve is "<< WBHP.error << ". The error ratio is " << WBHP.error/WBHP.total << std::endl << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryIntegrationTest::checkWithSpikes(const char* keyword){
|
||||
int errorOccurrences = 0;
|
||||
size_t jvar = 0 ;
|
||||
bool spikeCurrent = false;
|
||||
Deviation deviation;
|
||||
|
||||
for (size_t ivar = 0; ivar < referenceVec->size(); ivar++){
|
||||
int errorOccurrencesPrev = errorOccurrences;
|
||||
bool spikePrev = spikeCurrent;
|
||||
getDeviation(ivar,jvar, deviation);
|
||||
errorOccurrences += checkDeviation(deviation);
|
||||
if (errorOccurrences != errorOccurrencesPrev){
|
||||
spikeCurrent = true;
|
||||
} else{
|
||||
spikeCurrent = false;
|
||||
}
|
||||
if(spikePrev&&spikeCurrent){
|
||||
std::cout << "For keyword " << keyword << " at time step " << (*referenceVec)[ivar] <<std::endl;
|
||||
OPM_THROW(std::invalid_argument, "For keyword " << keyword << " at time step " << (*referenceVec)[ivar] << ", wwo deviations in a row exceed the limit. Not a spike value. Integration test fails." );
|
||||
}
|
||||
if(errorOccurrences > this->spikeLimit){
|
||||
std::cout << "For keyword " << keyword << std::endl;
|
||||
OPM_THROW(std::invalid_argument, "For keyword " << keyword << " too many spikes in the vector. Integration test fails.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WellProductionVolume
|
||||
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);
|
||||
return getWellProductionVolume(keyword);
|
||||
}
|
||||
|
||||
|
||||
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.");
|
||||
}
|
||||
for(size_t i = 0; i < timeVec.size()-1; i++){
|
||||
double width = timeVec[i+1] - timeVec[i];
|
||||
double height = dataVec[i+1];
|
||||
totalSum += getRectangleArea(height, width);
|
||||
}
|
||||
return totalSum;
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
// When a change occur (e.g. change of a rate), the data (value and time) is
|
||||
// written to file, THEN the change happens in the simulator, i.e., we will
|
||||
// notice the change at the next step.
|
||||
//
|
||||
// Keep in mind that the summary vector is NOT a continuous curve, only points
|
||||
// of data (time, value). We have to guess what happens between the data
|
||||
// points, we do this by saying: "There are no change, the only change happens
|
||||
// at the data points." As stated above, the value of this constant "height" of
|
||||
// the rectangle corresponds to the value of the last time step. Thus we have
|
||||
// to use the "right hand side value of the rectangle as height
|
||||
//
|
||||
// someDataVector[ivar] instead of someDataVector[ivar-1]
|
||||
//
|
||||
// (which intuition is saying is the correct value to use).
|
||||
|
||||
if(timeVec1.size() != dataVec1.size() || timeVec2.size() != dataVec2.size() ){
|
||||
OPM_THROW(std::runtime_error, "The size of the time vector does not match the size of the data vector.");
|
||||
}
|
||||
double errorSum = 0;
|
||||
double rightEdge, leftEdge, width;
|
||||
size_t i = 1;
|
||||
size_t j = 1;
|
||||
leftEdge = timeVec1[0];
|
||||
while(i < timeVec1.size()){
|
||||
if(j == timeVec2.size() ){
|
||||
break;
|
||||
}
|
||||
if(timeVec1[i] == timeVec2[j]){
|
||||
rightEdge = timeVec1[i];
|
||||
width = rightEdge - leftEdge;
|
||||
double dev = std::fabs(dataVec1[i] - dataVec2[j]);
|
||||
errorSum += getRectangleArea(dev, width);
|
||||
leftEdge = rightEdge;
|
||||
i++;
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
if(timeVec1[i] < timeVec2[j]){
|
||||
rightEdge = timeVec1[i];
|
||||
width = rightEdge - leftEdge;
|
||||
double value = unitStep(dataVec2[j]);
|
||||
double dev = std::fabs(dataVec1[i]-value);
|
||||
errorSum += getRectangleArea(dev, width);
|
||||
leftEdge = rightEdge;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if(timeVec2[j] < timeVec1[i]){
|
||||
rightEdge = timeVec2[j];
|
||||
width = rightEdge - leftEdge;
|
||||
double value = unitStep(dataVec1[i]);
|
||||
double dev = std::fabs(dataVec2[j]-value);
|
||||
errorSum += getRectangleArea(dev, width);
|
||||
leftEdge = rightEdge;
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return errorSum;
|
||||
}
|
||||
@@ -1,217 +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 "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.
|
||||
struct WellProductionVolume{
|
||||
double total=0; //!< The total area under the graph when plotting the summary vector against time. In most cases the total production volume.
|
||||
double error=0; //!< The total area under the graph when plotting the deviation vector against time. In most cases the total error volume.
|
||||
|
||||
//! \brief Overloaded operator
|
||||
//! \param[in] rhs WellProductionVolume struct
|
||||
WellProductionVolume& operator+=(const WellProductionVolume& rhs){
|
||||
this->total += rhs.total;
|
||||
this->error += rhs.error;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
//! \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 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.
|
||||
bool allowDifferentAmountOfKeywords = true; //!< Boolean value, when false the integration test will check wheter the two files have the same amount of keywords. \nIf they don't, an exception will be thrown. By default: true.
|
||||
bool findVectorWithGreatestErrorRatio = false; //!< Boolean value, when true the integration test will find the vector that has the greatest error ratio. By default: false.
|
||||
bool oneOfTheMainVariables = false; //!< Boolean value, when true the integration test will only check for one of the primary variables (WOPR, WGPR, WWPR. WBHP), which will be specified by user. By default: false.
|
||||
bool throwExceptionForTooGreatErrorRatio = true; //!< Boolean value, when true any volume error ratio that exceeds the relativeTolerance will cause an exception to be thrown. By default: true.
|
||||
std::string mainVariable; //!< String variable, where the name of the main variable of interest (one of WOPR, WBHP, WWPR, WGPR) is stored. Can be empty.
|
||||
int spikeLimit = 13370; //!< The limit for how many spikes to allow in the data set of a certain keyword. By default: Set to a high number, \n should not trig the (if spikeOccurrences > spikeLimit){ // throw exception }.
|
||||
|
||||
WellProductionVolume WOP; //!< WellProductionVolume struct for storing the total production volume and total error volume of all the keywords which start with WOPR
|
||||
WellProductionVolume WWP; //!< WellProductionVolume struct for storing the total production volume and total error volume of all the keywords which start with WWPR
|
||||
WellProductionVolume WGP;//!< WellProductionVolume struct for storing the total production volume and total error volume of all the keywords which start with WGPR
|
||||
WellProductionVolume WBHP; //!< WellProductionVolume struct for storing the value of the area under the graph when plotting summary vector/deviation vector against time.This is for keywords starting with WBHP. \nNote: the name of the struct may be misleading, this is not an actual volume.
|
||||
|
||||
|
||||
//! \brief The function gathers the correct data for comparison for a specific keyword
|
||||
//! \param[in] timeVec1 A std::vector<double> that contains the time steps of file 1.
|
||||
//! \param[in] timeVec2 A std::vector<double> that contains the time steps of file 2.
|
||||
//! \param[in] keyword The keyword of interest
|
||||
//! \details The function requires an outer loop which iterates over the keywords of the files. It prepares an integration test by gathering the data, stroing it into two vectors, \n deciding which is to be used as a reference/basis and calling the test function.
|
||||
void checkForKeyword(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2, const char* keyword);
|
||||
|
||||
//! \brief The function compares the volume error to the total production volume of a certain type of keyword.
|
||||
//! param[in] keyword The keyword of interest.
|
||||
//! \details The function takes in a keyword and checks if it is of interest. Only keywords which say something about the well oil production, well water production, \n well gas production and the well BHP are of interest. The function sums up the total production in the cases where it is possible, \n and sums up the error volumes by a trapezoid integration method. The resulting values are stored in member variable structs of type WellProductionVolume, and double variables. For proper use of the function all the keywords of the file should be checked. This is satisfied if it is called by checkForKeyword.
|
||||
void volumeErrorCheck(const char* keyword);
|
||||
|
||||
//! \brief The function calculates the total production volume and total error volume of a specific keyword
|
||||
//! \param[in] timeVec1 A std::vector<double> that contains the time steps of file 1.
|
||||
//! \param[in] timeVec2 A std::vector<double> that contains the time steps of file 2.
|
||||
//! \param[in] keyword The keyword of interest
|
||||
//! \param[out] ret Returns a WellProductionWolume struct
|
||||
//! \details The function reads the data from the two files into the member variable vectors (of the super class). It returns a WellProductionVolume struct calculated from the vectors corresponding to the keyword.
|
||||
WellProductionVolume getSpecificWellVolume(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const char* keyword);
|
||||
|
||||
//! \brief The function is a regression test which allows spikes.
|
||||
//! \param[in] keyword The keyword of interest, the keyword the summary vectors "belong" to.
|
||||
//! \details The function requires the protected member variables referenceVec, referenceDataVec, checkVec and checkDataVec to be stored with data, which is staisfied if it is called by checkForKeyword. \n It compares the two vectors value by value, and if the deviation is unsatisfying, the errorOccurrenceCounter is incremented. If the errorOccurrenceCounter becomes greater than the errorOccurrenceLimit, \n a exception is thrown. The function will allow spike values, however, if two values in a row exceed the deviation limit, they are no longer spikes, and an exception is thrown.
|
||||
void checkWithSpikes(const char* keyword);
|
||||
|
||||
//! \brief Caluculates a deviation, throws exceptions and writes and error message.
|
||||
//! \param[in] deviation Deviation struct
|
||||
//! \param[out] int Returns 0/1, depending on wheter the deviation exceeded the limit or not.
|
||||
//! \details The function checks the values of the Deviation struct against the absolute and relative tolerance, which are private member values of the super class. \n When comparing against the relative tolerance an additional term is added, the absolute deviation has to be greater than 1e-6 for the function to throw an exception. \n When the deviations are too great, the function returns 1.
|
||||
int checkDeviation(const Deviation& deviation);
|
||||
|
||||
//! \brief Calculates the keyword's total production volume and error volume
|
||||
//! \param[in] keyword The keyword of interest.
|
||||
//! \param[out] wellProductionVolume A struct containing the total production volume and the total error volume.
|
||||
//! \details The function calculates the total production volume and total error volume of a keyword, by the trapezoid integral method. \n The function throws and exception if the total error volume is negative. The function returns the results as a struct.
|
||||
WellProductionVolume getWellProductionVolume(const char* keyword);
|
||||
|
||||
//! \brief The function function works properly when the private member variables are set (after running the integration test which findVolumeError = true). \n It prints out the total production volume, the total error volume and the error ratio.
|
||||
void evaluateWellProductionVolume();
|
||||
|
||||
//! \brief The function calculates the total production volume and total error volume
|
||||
//! \param keyword The keyword of interest
|
||||
//! \details The function uses the data that is stored in the member variable vectors. It calculates the total production volume \n and the total error volume of the specified keyword, and adds the result to the private member WellProductionVolume variables of the class.
|
||||
void updateVolumeError(const char* keyword);
|
||||
|
||||
//! \brief Finds the keyword which has the greates error volume ratio
|
||||
//! \param[in] volume WellProductionVolume struct which contains the data used for comparison
|
||||
//! \param[in] greatestRatio Double value taken in by reference. Stores the greatest error ratio value.
|
||||
//! \param[in] currentKeyword The keyword that is under evaluation
|
||||
//! \param[in] greatestErrorRatio String which contains the name of the keyword which has the greatest error ratio
|
||||
//! \details The function requires an outer loop which iterates over the keywords in the files, and calls the function for each keyword. \nThe valiables double greatestRatio and std::string keywordWithTheGreatestErrorRatio must be declared outside the loop. \nWhen the current error ratio is greater than the value stored in greatestRatio, the gratestRatio value is updated with the current error ratio.
|
||||
void findGreatestErrorRatio(const WellProductionVolume& volume,
|
||||
double &greatestRatio,
|
||||
const char* currentKeyword,
|
||||
std::string &greatestErrorRatio);
|
||||
|
||||
#if 0
|
||||
//! \brief Checks whether the unit of the two data vectors is the same
|
||||
//! \param[in] keyword The keyword of interest
|
||||
//! \param[out] boolean True/false, depending on whether the units are equal or not
|
||||
bool checkUnits(const char* keyword);
|
||||
#endif
|
||||
public:
|
||||
//! \brief Constructor, creates an object of IntegrationTest class.
|
||||
//! \param[in] basename1 Path to file1 without extension.
|
||||
//! \param[in] basename1 Path to file2 without extension.
|
||||
//! \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.
|
||||
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.
|
||||
//! \param[in] allowSpikes Boolean value
|
||||
//! \details When allowSpikes is true, the integration test checkWithSpikes is excecuted.
|
||||
void setAllowSpikes(bool allowSpikesArg){this->allowSpikes = allowSpikesArg;}
|
||||
|
||||
//! \brief This function sets the private member variable findVolumeError.
|
||||
//! \param[in] findVolumeError Boolean value
|
||||
//! \details When findVolumeError is true, the integration test volumeErrorCheck and the function evaluateWellProductionVolume are excecuted.
|
||||
void setFindVolumeError(bool findVolumeErrorArg){this->findVolumeError = findVolumeErrorArg;}
|
||||
|
||||
//! \brief This function sets the private member variable oneOfTheMainVariables
|
||||
//! \param[in] oneOfTheMainVariables Boolean value
|
||||
//! \details When oneOfTheMainVariables is true, the integration test runs the substest volumeErrorCheckForOneSpecificVariable.
|
||||
void setOneOfTheMainVariables(bool oneOfTheMainVariablesArg){this->oneOfTheMainVariables = oneOfTheMainVariablesArg;}
|
||||
|
||||
//! \brief This function sets the member variable string #mainVariable
|
||||
//! \param[in] mainVar This is the string should contain one of the main variables. e.g. WOPR
|
||||
void setMainVariable(std::string mainVar){this->mainVariable = mainVar;}
|
||||
|
||||
//! \brief This function sets the private member variable spikeLimit.
|
||||
//! \param[in] lim The value which the spike limit is to be given.
|
||||
void setSpikeLimit(int lim){this->spikeLimit = lim;}
|
||||
|
||||
//! \brief This function sets the private member variable findVectorWithGreatestErrorRatio
|
||||
//! \param[in] findVolumeError Boolean value
|
||||
//! \details When findVectorWithGreatestErrorRatio is true, the integration test will print the vector with the greatest error ratio.
|
||||
void setFindVectorWithGreatestErrorRatio(bool boolean){this->findVectorWithGreatestErrorRatio = boolean;}
|
||||
|
||||
//! \brief This function sets the private member variable allowDifferentAmountsOfKeywords
|
||||
//! \param[in] boolean Boolean value
|
||||
//! \details When allowDifferentAmountOfKeywords is false, the amount of kewyord in the two files will be compared. \nIf the number of keywords are different an exception will be thrown.
|
||||
void setAllowDifferentAmountOfKeywords(bool boolean){this->allowDifferentAmountOfKeywords = boolean;}
|
||||
|
||||
//! \brief This function sets the private member variable throwExceptionForTooGreatErrorRatio
|
||||
//! \param[in] boolean Boolean value
|
||||
//! \details When throwExceptionForTooGreatErrorRatio is false, the function getWellProductionVolume will throw an exception.
|
||||
void setThrowExceptionForTooGreatErrorRatio(bool boolean){this->throwExceptionForTooGreatErrorRatio = boolean;}
|
||||
|
||||
//! \brief This function executes a integration test for all the keywords. If the two files do not match in amount of keywords, an exception is thrown. \n Uses the boolean member variables to know which tests to execute.
|
||||
void getIntegrationTest();
|
||||
|
||||
//! \brief This function executes a integration test for one specific keyword. If one or both of the files do not have the keyword, an exception is thorwn. \n Uses the boolean member variables to know which tests to execute.
|
||||
void getIntegrationTest(const char* keyword);
|
||||
|
||||
//! \brief This function calculates the area of an rectangle of height height and width time-timePrev
|
||||
//! \param[in] height The height of the rectangle. See important statement of use below.
|
||||
//! \param[in] width The width of the rectangle
|
||||
//! \param[out] area Returns the area of the rectangle
|
||||
//! \details This function is simple. When using it on a summary vector (data values plotted againt time), calculating the area between the two points i and i+1 note this:\nThe width is time_of_i+1 - time_of_i, the height is data_of_i+1 NOT data_of_i. The upper limit must be used.
|
||||
static double getRectangleArea(double height, double width){return height*width;}
|
||||
|
||||
//! \brief This function calculates the area under a graph by doing a Riemann sum
|
||||
//! \param[in] timeVec Contains the time values
|
||||
//! \param[in] dataVec Contains the data values
|
||||
//! \details The function does a Riemann sum integration of the graph formed
|
||||
//! by the points (timeVec[i] , dataVec[i]).
|
||||
//! In the case of a summary vector, the summary vector of quantity
|
||||
//! corresponding to a rate, is a piecewise continus function consisting
|
||||
//! of unit step functions. Thus the Riemann sum will become an
|
||||
//! exact expression for the integral of the graph.
|
||||
//! Important: For the data values correspoding to time i and i-1,
|
||||
//! the fixed value of the height of the rectangles in the Riemann sum
|
||||
//! is set by the data value i. The upper limit must be used.
|
||||
static double integrate(const std::vector<double>& timeVec,
|
||||
const std::vector<double>& dataVec);
|
||||
|
||||
//! \brief This function calculates the Riemann sum of the error between two graphs.
|
||||
//! \param[in] timeVec1 Contains the time values of graph 1
|
||||
//! \param[in] dataVec1 Contains the data values of graph 1
|
||||
//! \param[in] timeVec2 Contains the time values of graph 2
|
||||
//! \param[in] dataVec2 Contains the data values of graph 2
|
||||
//! \details This function takes in two graphs and returns the integrated error.
|
||||
//! In case of ecl summary vectors: if the vectors correspond to a
|
||||
//! quantity which is a rate, the vectors will be piecewise
|
||||
//! continous unit step functions. In this case the error will also
|
||||
//! be a piecewise continous unit step function. The function uses
|
||||
//! a Riemann sum when calculating the integral. Thus the integral
|
||||
//! will become exact. Important: For the data values corresponding
|
||||
//! to time i and i-1, the fixed value of the height of the rectangles
|
||||
//! in the Riemann sum is set by the data value i.
|
||||
//! The upper limit must be used.
|
||||
static double integrateError(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& dataVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const std::vector<double>& dataVec2);
|
||||
};
|
||||
@@ -1,178 +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 "summaryRegressionTest.hpp"
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <ert/ecl/ecl_sum.hpp>
|
||||
#include <ert/util/stringlist.h>
|
||||
#include <string>
|
||||
|
||||
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((! this->allowDifferentNumberOfKeywords) &&
|
||||
(stringlist_get_size(keysShort) != stringlist_get_size(keysLong)))
|
||||
{
|
||||
int missing_count = 0;
|
||||
std::cout << "Keywords missing from one case: " << std::endl;
|
||||
|
||||
for (int i=0; i < stringlist_get_size( keysLong); i++) {
|
||||
const char * key = stringlist_iget( keysLong , i );
|
||||
if (!stringlist_contains( keysShort , key)) {
|
||||
std::cout << key << " ";
|
||||
|
||||
missing_count++;
|
||||
if ((missing_count % 8) == 0)
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
HANDLE_ERROR(std::runtime_error, "Different amount of keywords in the two summary files.");
|
||||
}
|
||||
if(printKeyword){
|
||||
printKeywords();
|
||||
}
|
||||
|
||||
|
||||
//Iterates over all keywords from the restricted file, use iterator "ivar". Searches for a match in the file with more keywords, use the iterator "jvar".
|
||||
bool throwAtEnd = false;
|
||||
while(ivar < stringlist_get_size(keysShort)){
|
||||
const char* keyword = stringlist_iget(keysShort, ivar);
|
||||
std::string keywordString(keyword);
|
||||
for (int jvar = 0; jvar < stringlist_get_size(keysLong); jvar++){
|
||||
if (strcmp(keyword, stringlist_iget(keysLong, jvar)) == 0){ //When the keywords are equal, proceed in comparing summary files.
|
||||
if (isRestartFile && keywordString.substr(3,1)=="T"){
|
||||
break;
|
||||
}
|
||||
throwAtEnd |= !checkForKeyword(timeVec1, timeVec2, keyword);
|
||||
break;
|
||||
}
|
||||
//will only enter here if no keyword match
|
||||
if(jvar == stringlist_get_size(keysLong)-1){
|
||||
std::cout << "Could not find keyword: " << stringlist_iget(keysShort, ivar) << std::endl;
|
||||
OPM_THROW(std::runtime_error, "No match on keyword");
|
||||
}
|
||||
}
|
||||
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 if (deviations.empty())
|
||||
std::cout << "Regression test succeeded." << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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.
|
||||
std::string keywordString(keyword);
|
||||
if(stringlist_contains(keysShort,keyword) && stringlist_contains(keysLong, keyword)){
|
||||
if (isRestartFile && keywordString.substr(3,1)=="T"){
|
||||
return;
|
||||
}
|
||||
if (checkForKeyword(timeVec1, timeVec2, keyword))
|
||||
std::cout << "Regression test succeeded." << std::endl;
|
||||
else
|
||||
OPM_THROW(std::runtime_error, "Regression test failed");
|
||||
|
||||
return;
|
||||
}
|
||||
std::cout << "The keyword suggested, " << keyword << ", is not supported by one or both of the summary files. Please use a different keyword." << std::endl;
|
||||
OPM_THROW(std::runtime_error, "Input keyword from user does not exist in/is not common for the two summary files.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
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){
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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);
|
||||
return startTest(keyword);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool SummaryRegressionTest::startTest(const char* keyword){
|
||||
size_t jvar = 0;
|
||||
Deviation deviation;
|
||||
bool result = true;
|
||||
for (size_t ivar = 0; ivar < referenceVec->size(); ivar++){
|
||||
getDeviation(ivar, jvar, deviation);//Reads from the protected member variables in the super class.
|
||||
result = checkDeviation(deviation, keyword,ivar, jvar);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void SummaryRegressionTest::setAllowDifferentNumberOfKeywords(const bool allow)
|
||||
{
|
||||
this->allowDifferentNumberOfKeywords = allow;
|
||||
}
|
||||
@@ -1,87 +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/>.
|
||||
*/
|
||||
|
||||
#ifndef SUMMARYREGRESSIONTEST_HPP
|
||||
#define SUMMARYREGRESSIONTEST_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 SummaryRegressionTest: public SummaryComparator {
|
||||
private:
|
||||
//! \brief Gathers the correct data for comparison for a specific keyword
|
||||
//! \param[in] timeVec1 The time steps of file 1.
|
||||
//! \param[in] timeVec2 The time steps of file 2.
|
||||
//! \param[in] keyword The keyword of interest
|
||||
//! \details The function prepares a regression test by gathering the data, stroing it into two vectors, \n deciding which is to be used as a reference/basis and calling the test function.
|
||||
//! \return True if check passed, false otherwise.
|
||||
bool checkForKeyword(std::vector<double>& timeVec1, std::vector<double>& timeVec2, const char* keyword);
|
||||
|
||||
//! \brief The regression test
|
||||
//! \param[in] keyword The keyword common for both the files. The vectors associated with the keyword are used for comparison.
|
||||
//! \details Start test uses the private member variables, pointers of std::vector<double> type, which are set to point to the correct vectors in SummaryComparison::chooseReference(...). \n The function iterates over the referenceVev/basis and for each iteration it calculates the deviation with SummaryComparison::getDeviation(..) and stors it in a Deviation struct. \n SummaryComparison::getDeviation takes the int jvar as an reference input, and using it as an iterative index for the values which are to be compared with the basis. \n Thus, by updating the jvar variable every time a deviation is calculated, one keep track jvar and do not have to iterate over already checked values.
|
||||
bool startTest(const char* keyword);
|
||||
|
||||
//! \brief Caluculates a deviation, throws exceptions and writes and error message.
|
||||
//! \param[in] deviation Deviation struct
|
||||
//! \param[in] keyword The keyword that the data that are being compared belongs to.
|
||||
//! \param[in] refIndex The report step of which the deviation originates from in #referenceDataVec.
|
||||
//! \param[in] checkIndex The report step of which the deviation originates from in #checkDataVec.
|
||||
//! \details The function checks the values of the Deviation struct against the absolute and relative tolerance, which are private member values of the super class. \n When comparing against the relative tolerance an additional term is added, the absolute deviation has to be greater than 1e-6 for the function to throw an exception. \n When the deviations are too great, the function writes out which keyword, and at what report step the deviation is too great before optionally throwing an exception.
|
||||
//! \return True if check passed, false otherwise.
|
||||
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.
|
||||
//! \param[in] basename1 Path to file2 without extension.
|
||||
//! \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.
|
||||
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.
|
||||
void getRegressionTest();
|
||||
|
||||
//! \details The function executes a regression test for one specific keyword. If one or both of the files do not have the keyword, an exception is thrown.
|
||||
void getRegressionTest(const char* keyword);///< Regression test for a certain keyword of the files.
|
||||
|
||||
//! \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-simulators]="-DBUILD_EBOS_EXTENSIONS=ON -DBUILD_EBOS_DEBUG_EXTENSIONS=ON"
|
||||
EXTRA_MODULE_FLAGS[opm-common]="-DOPM_ENABLE_PYTHON=ON -DOPM_ENABLE_EMBEDDED_PYTHON=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
|
||||
@@ -90,11 +110,12 @@ function build_module {
|
||||
cmake --build .
|
||||
fi
|
||||
test $? -eq 0 || exit 2
|
||||
TESTTHREADS=${TESTTHREADS:-1}
|
||||
if test -z "$CTEST_CONFIGURATION"
|
||||
then
|
||||
ctest -T Test --no-compress-output
|
||||
ctest -T Test --no-compress-output -j$TESTTHREADS
|
||||
else
|
||||
ctest -C $CTEST_CONFIGURATION --timeout 5000 -T Test --no-compress-output
|
||||
ctest -j$TESTTHREADS -C $CTEST_CONFIGURATION --timeout 5000 -T Test --no-compress-output
|
||||
fi
|
||||
|
||||
# Convert to junit format
|
||||
@@ -125,12 +146,7 @@ function clone_module {
|
||||
mkdir -p $WORKSPACE/deps/$1
|
||||
cd $WORKSPACE/deps/$1
|
||||
git init .
|
||||
if [ "$1" == "libecl" ]
|
||||
then
|
||||
git remote add origin https://github.com/Statoil/$1
|
||||
else
|
||||
git remote add origin https://github.com/OPM/$1
|
||||
fi
|
||||
git remote add origin https://github.com/OPM/$1
|
||||
git fetch --depth 1 origin $2:branch_to_build
|
||||
git checkout branch_to_build
|
||||
git log HEAD -1 | cat
|
||||
@@ -164,7 +180,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
|
||||
@@ -179,7 +195,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
|
||||
@@ -216,7 +232,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
|
||||
|
||||
@@ -6,17 +6,15 @@ source `dirname $0`/build-opm-module.sh
|
||||
mkdir deps
|
||||
ln -sf $WORKSPACE deps/opm-common
|
||||
|
||||
# No upstreams
|
||||
declare -a upstreams
|
||||
upstreams=(libecl)
|
||||
|
||||
declare -A upstreamRev
|
||||
upstreamRev[libecl]=master
|
||||
|
||||
# Downstreams and revisions
|
||||
declare -a downstreams
|
||||
downstreams=(opm-material
|
||||
opm-grid
|
||||
ewoms
|
||||
opm-models
|
||||
opm-simulators
|
||||
opm-upscaling
|
||||
)
|
||||
@@ -24,7 +22,7 @@ downstreams=(opm-material
|
||||
declare -A downstreamRev
|
||||
downstreamRev[opm-material]=master
|
||||
downstreamRev[opm-grid]=master
|
||||
downstreamRev[ewoms]=master
|
||||
downstreamRev[opm-models]=master
|
||||
downstreamRev[opm-simulators]=master
|
||||
downstreamRev[opm-upscaling]=master
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ upstreams=(libecl
|
||||
opm-common
|
||||
opm-material
|
||||
opm-grid
|
||||
ewoms
|
||||
opm-models
|
||||
opm-simulators
|
||||
opm-upscaling
|
||||
)
|
||||
@@ -19,7 +19,7 @@ upstreamRev[libecl]=master
|
||||
upstreamRev[opm-common]=master
|
||||
upstreamRev[opm-material]=master
|
||||
upstreamRev[opm-grid]=master
|
||||
upstreamRev[ewoms]=master
|
||||
upstreamRev[opm-models]=master
|
||||
upstreamRev[opm-simulators]=master
|
||||
upstreamRev[opm-upscaling]=master
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#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>
|
||||
@@ -18,32 +19,29 @@
|
||||
namespace Opm {
|
||||
|
||||
class EclipseIO;
|
||||
|
||||
|
||||
class ParseContext;
|
||||
class Parser;
|
||||
class SummaryState;
|
||||
class msim {
|
||||
|
||||
public:
|
||||
using well_rate_function = double(const EclipseState&, const Schedule&, const data::Solution&, size_t report_step, double seconds_elapsed);
|
||||
using well_rate_function = double(const EclipseState&, const Schedule&, const SummaryState& st, 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 std::string& deck_file);
|
||||
msim(const std::string& deck_file, const Parser& parser, const ParseContext& parse_context);
|
||||
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();
|
||||
void run(Schedule& schedule, EclipseIO& io, bool report_only);
|
||||
void post_step(Schedule& schedule, const SummaryState& st, data::Solution& sol, data::Wells& well_data, size_t report_step) const;
|
||||
private:
|
||||
|
||||
void run_step(data::Solution& sol, data::Wells& well_data, size_t report_step, EclipseIO& io) const;
|
||||
void run_step(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(data::Solution& sol, data::Wells& well_data, size_t report_step, double seconds_elapsed, double time_step) const;
|
||||
void run_step(const Schedule& schedule, SummaryState& st, data::Solution& sol, data::Wells& well_data, size_t report_step, EclipseIO& io) const;
|
||||
void run_step(const Schedule& schedule, SummaryState& st, data::Solution& sol, data::Wells& well_data, size_t report_step, double dt, EclipseIO& io) const;
|
||||
void output(SummaryState& st, 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, const SummaryState& st, data::Solution& sol, data::Wells& well_data, size_t report_step, double seconds_elapsed, double time_step) const;
|
||||
|
||||
Deck deck;
|
||||
EclipseState state;
|
||||
Schedule schedule;
|
||||
SummaryConfig summary_config;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -21,51 +21,67 @@
|
||||
|
||||
#include <opm/output/eclipse/EclipseIO.hpp>
|
||||
#include <opm/output/eclipse/RestartValue.hpp>
|
||||
#include <opm/output/eclipse/Summary.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 std::string& deck_file, const Parser& parser, const ParseContext& parse_context) :
|
||||
deck(parser.parseFile(deck_file, parse_context)),
|
||||
state(deck, parse_context),
|
||||
schedule(deck, state.getInputGrid(), state.get3DProperties(), state.runspec(), parse_context),
|
||||
summary_config(deck, schedule, state.getTableManager(), parse_context)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
msim::msim(const std::string& deck_file) :
|
||||
msim(deck_file, Parser(), ParseContext())
|
||||
msim::msim(const EclipseState& state_arg) :
|
||||
state(state_arg)
|
||||
{}
|
||||
|
||||
|
||||
void msim::run() {
|
||||
void msim::run(Schedule& schedule, EclipseIO& io, bool report_only) {
|
||||
const double week = 7 * 86400;
|
||||
EclipseIO io(this->state, this->state.getInputGrid(), this->schedule, this->summary_config);
|
||||
data::Solution sol;
|
||||
data::Wells well_data;
|
||||
SummaryState st(std::chrono::system_clock::from_time_t(schedule.getStartTime()));
|
||||
|
||||
io.writeInitial();
|
||||
for (size_t report_step = 1; report_step < this->schedule.size(); report_step++) {
|
||||
double time_step = std::min(week, 0.5*this->schedule.stepLength(report_step - 1));
|
||||
run_step(sol, well_data, report_step, time_step, io);
|
||||
for (size_t report_step = 1; report_step < schedule.size(); report_step++) {
|
||||
if (report_only)
|
||||
run_step(schedule, st, sol, well_data, report_step, io);
|
||||
else {
|
||||
double time_step = std::min(week, 0.5*schedule.stepLength(report_step - 1));
|
||||
run_step(schedule, st, sol, well_data, report_step, time_step, io);
|
||||
}
|
||||
post_step(schedule, st, sol, well_data, report_step);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msim::run_step(data::Solution& sol, data::Wells& well_data, size_t report_step, EclipseIO& io) const {
|
||||
this->run_step(sol, well_data, report_step, this->schedule.stepLength(report_step - 1), io);
|
||||
void msim::post_step(Schedule& schedule, const SummaryState& st, data::Solution& /* sol */, data::Wells& /* well_data */, size_t report_step) const {
|
||||
const auto& actions = schedule.actions(report_step);
|
||||
if (actions.empty())
|
||||
return;
|
||||
|
||||
Action::Context context( st );
|
||||
|
||||
auto sim_time = schedule.simTime(report_step);
|
||||
for (const auto& action : actions.pending(sim_time)) {
|
||||
auto result = action->eval(sim_time, context);
|
||||
if (result)
|
||||
schedule.applyAction(report_step, *action, result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msim::run_step(data::Solution& sol, data::Wells& well_data, size_t report_step, double dt, EclipseIO& io) const {
|
||||
double start_time = this->schedule.seconds(report_step - 1);
|
||||
double end_time = this->schedule.seconds(report_step);
|
||||
|
||||
void msim::run_step(const Schedule& schedule, SummaryState& st, data::Solution& sol, data::Wells& well_data, size_t report_step, EclipseIO& io) const {
|
||||
this->run_step(schedule, st, sol, well_data, report_step, schedule.stepLength(report_step - 1), io);
|
||||
}
|
||||
|
||||
|
||||
void msim::run_step(const Schedule& schedule, SummaryState& st, 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) {
|
||||
@@ -73,10 +89,20 @@ void msim::run_step(data::Solution& sol, data::Wells& well_data, size_t report_s
|
||||
if ((seconds_elapsed + time_step) > end_time)
|
||||
time_step = end_time - seconds_elapsed;
|
||||
|
||||
this->simulate(sol, well_data, report_step, seconds_elapsed, time_step);
|
||||
this->simulate(schedule, st, sol, well_data, report_step, seconds_elapsed, time_step);
|
||||
|
||||
seconds_elapsed += time_step;
|
||||
this->output(report_step,
|
||||
|
||||
io.summary().eval(st,
|
||||
report_step,
|
||||
seconds_elapsed,
|
||||
this->state,
|
||||
schedule,
|
||||
well_data,
|
||||
{});
|
||||
|
||||
this->output(st,
|
||||
report_step,
|
||||
(seconds_elapsed < end_time),
|
||||
seconds_elapsed,
|
||||
sol,
|
||||
@@ -87,22 +113,20 @@ void msim::run_step(data::Solution& sol, data::Wells& well_data, size_t report_s
|
||||
|
||||
|
||||
|
||||
void msim::output(size_t report_step, bool substep, double seconds_elapsed, const data::Solution& sol, const data::Wells& well_data, EclipseIO& io) const {
|
||||
void msim::output(SummaryState& st, 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,
|
||||
io.writeTimeStep(st,
|
||||
report_step,
|
||||
false,
|
||||
seconds_elapsed,
|
||||
value,
|
||||
{},
|
||||
{},
|
||||
{});
|
||||
value);
|
||||
}
|
||||
|
||||
|
||||
void msim::simulate(data::Solution& sol, data::Wells& well_data, size_t report_step, double seconds_elapsed, double time_step) const {
|
||||
void msim::simulate(const Schedule& schedule, const SummaryState& st, 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, this->schedule, sol, report_step, seconds_elapsed + time_step);
|
||||
func(this->state, schedule, sol, report_step, seconds_elapsed + time_step);
|
||||
}
|
||||
|
||||
for (const auto& well_pair : this->well_rates) {
|
||||
@@ -112,8 +136,12 @@ void msim::simulate(data::Solution& sol, data::Wells& well_data, size_t report_s
|
||||
auto rate = rate_pair.first;
|
||||
auto func = rate_pair.second;
|
||||
|
||||
well.rates.set(rate, func(this->state, this->schedule, sol, report_step, seconds_elapsed + time_step));
|
||||
well.rates.set(rate, func(this->state, schedule, st, 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ set (opm-common_DEPS
|
||||
|
||||
if(ENABLE_ECL_INPUT)
|
||||
list(APPEND opm-common_DEPS
|
||||
"ecl REQUIRED"
|
||||
# various runtime library enhancements
|
||||
"Boost 1.44.0
|
||||
COMPONENTS system filesystem unit_test_framework regex REQUIRED")
|
||||
|
||||
68
opm/common/utility/TimeService.hpp
Normal file
68
opm/common/utility/TimeService.hpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
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_TIMESERVICE_HEADER_INCLUDED
|
||||
#define OPM_TIMESERVICE_HEADER_INCLUDED
|
||||
|
||||
#include <ctime>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class TimeStampUTC
|
||||
{
|
||||
public:
|
||||
struct YMD {
|
||||
int year{0};
|
||||
int month{0};
|
||||
int day{0};
|
||||
};
|
||||
|
||||
TimeStampUTC() = default;
|
||||
|
||||
explicit TimeStampUTC(const std::time_t tp);
|
||||
explicit TimeStampUTC(const YMD& ymd);
|
||||
|
||||
TimeStampUTC& operator=(const std::time_t tp);
|
||||
|
||||
TimeStampUTC& hour(const int h);
|
||||
TimeStampUTC& minutes(const int m);
|
||||
TimeStampUTC& seconds(const int s);
|
||||
TimeStampUTC& microseconds(const int us);
|
||||
|
||||
int year() const { return this->ymd_.year; }
|
||||
int month() const { return this->ymd_.month; }
|
||||
int day() const { return this->ymd_.day; }
|
||||
int hour() const { return this->hour_; }
|
||||
int minutes() const { return this->minutes_; }
|
||||
int seconds() const { return this->seconds_; }
|
||||
int microseconds() const { return this->usec_; }
|
||||
|
||||
private:
|
||||
YMD ymd_{};
|
||||
int hour_{0};
|
||||
int minutes_{0};
|
||||
int seconds_{0};
|
||||
int usec_{0};
|
||||
};
|
||||
|
||||
std::time_t asTimeT(const TimeStampUTC& tp);
|
||||
|
||||
} // namespace Opm
|
||||
|
||||
#endif // OPM_TIMESERVICE_HEADER_INCLUDED
|
||||
@@ -16,9 +16,10 @@
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
double calculateCellVol(const std::vector<double>& X, const std::vector<double>& Y, const std::vector<double>& Z);
|
||||
double calculateCellVol(const std::array<double,8>& X, const std::array<double,8>& Y, const std::array<double,8>& Z);
|
||||
|
||||
|
||||
|
||||
65
opm/io/eclipse/EGrid.hpp
Normal file
65
opm/io/eclipse/EGrid.hpp
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
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_IO_EGRID_HPP
|
||||
#define OPM_IO_EGRID_HPP
|
||||
|
||||
#include <opm/io/eclipse/EclFile.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <ctime>
|
||||
#include <map>
|
||||
|
||||
namespace Opm { namespace EclIO {
|
||||
|
||||
class EGrid : public EclFile
|
||||
{
|
||||
public:
|
||||
explicit EGrid(const std::string& filename);
|
||||
|
||||
int global_index(int i, int j, int k) const;
|
||||
int active_index(int i, int j, int k) const;
|
||||
|
||||
const std::array<int, 3>& dimension() const { return nijk; }
|
||||
|
||||
std::array<int, 3> ijk_from_active_index(int actInd) const;
|
||||
std::array<int, 3> ijk_from_global_index(int globInd) const;
|
||||
|
||||
void getCellCorners(int globindex, std::array<double,8>& X, std::array<double,8>& Y, std::array<double,8>& Z) const;
|
||||
void getCellCorners(const std::array<int, 3>& ijk, std::array<double,8>& X, std::array<double,8>& Y, std::array<double,8>& Z) const;
|
||||
|
||||
int activeCells() const { return nactive; }
|
||||
int totalNumberOfCells() const { return nijk[0] * nijk[1] * nijk[2]; }
|
||||
|
||||
private:
|
||||
std::array<int, 3> nijk;
|
||||
int nactive;
|
||||
|
||||
std::vector<int> act_index;
|
||||
std::vector<int> glob_index;
|
||||
std::vector<float> coord_array;
|
||||
std::vector<float> zcorn_array;
|
||||
};
|
||||
|
||||
}} // namespace Opm::EclIO
|
||||
|
||||
#endif // OPM_IO_EGRID_HPP
|
||||
84
opm/io/eclipse/ERft.hpp
Normal file
84
opm/io/eclipse/ERft.hpp
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
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_IO_ERFT_HPP
|
||||
#define OPM_IO_ERFT_HPP
|
||||
|
||||
#include <opm/io/eclipse/EclFile.hpp>
|
||||
|
||||
#include <ctime>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm { namespace EclIO {
|
||||
|
||||
class ERft : public EclFile
|
||||
{
|
||||
public:
|
||||
explicit ERft(const std::string &filename);
|
||||
|
||||
using RftDate = std::tuple<int,int,int>;
|
||||
template <typename T>
|
||||
const std::vector<T>& getRft(const std::string& name, const std::string& wellName,
|
||||
const RftDate& date) const;
|
||||
|
||||
template <typename T>
|
||||
const std::vector<T>& getRft(const std::string& name, const std::string& wellName,
|
||||
int year, int month, int day) const;
|
||||
|
||||
std::vector<std::string> listOfWells() const;
|
||||
std::vector<RftDate> listOfdates() const;
|
||||
|
||||
using RftReportList = std::vector<std::pair<std::string, RftDate>>;
|
||||
const RftReportList& listOfRftReports() const { return rftReportList; }
|
||||
|
||||
bool hasRft(const std::string& wellName, const RftDate& date) const;
|
||||
bool hasRft(const std::string& wellName, int year, int month, int day) const;
|
||||
|
||||
std::vector<EclEntry> listOfRftArrays(const std::string& wellName,
|
||||
const RftDate& date) const;
|
||||
|
||||
std::vector<EclEntry> listOfRftArrays(const std::string& wellName,
|
||||
int year, int month, int day) const;
|
||||
|
||||
bool hasArray(const std::string& arrayName, const std::string& wellName,
|
||||
const RftDate& date) const;
|
||||
|
||||
private:
|
||||
std::map<int, std::pair<int,int>> arrIndexRange;
|
||||
int numReports;
|
||||
std::vector<float> timeList;
|
||||
|
||||
std::set<std::string> wellList;
|
||||
std::set<RftDate> dateList;
|
||||
RftReportList rftReportList;
|
||||
|
||||
std::map<std::pair<std::string,RftDate>,int> reportIndex; // mapping report index to wellName and date (tupe)
|
||||
|
||||
int getReportIndex(const std::string& wellName, const RftDate& date) const;
|
||||
int getArrayIndex(const std::string& name, const std::string& wellName,
|
||||
const RftDate& date) const;
|
||||
};
|
||||
|
||||
}} // namespace Opm::EclIO
|
||||
|
||||
#endif // OPM_IO_ERFT_HPP
|
||||
70
opm/io/eclipse/ERst.hpp
Normal file
70
opm/io/eclipse/ERst.hpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
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_IO_ERST_HPP
|
||||
#define OPM_IO_ERST_HPP
|
||||
|
||||
#include <opm/io/eclipse/EclFile.hpp>
|
||||
|
||||
#include <ios>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm { namespace EclIO { namespace OutputStream {
|
||||
class Restart;
|
||||
}}}
|
||||
|
||||
namespace Opm { namespace EclIO {
|
||||
|
||||
class ERst : public EclFile
|
||||
{
|
||||
public:
|
||||
explicit ERst(const std::string& filename);
|
||||
bool hasReportStepNumber(int number) const;
|
||||
|
||||
void loadReportStepNumber(int number);
|
||||
|
||||
template <typename T>
|
||||
const std::vector<T>& getRst(const std::string& name, int reportStepNumber);
|
||||
|
||||
const std::vector<int>& listOfReportStepNumbers() const { return seqnum; }
|
||||
|
||||
std::vector<EclEntry> listOfRstArrays(int reportStepNumber);
|
||||
|
||||
friend class OutputStream::Restart;
|
||||
|
||||
private:
|
||||
int nReports;
|
||||
std::vector<int> seqnum; // report step numbers, from SEQNUM array in restart file
|
||||
std::unordered_map<int,bool> reportLoaded;
|
||||
std::map<int, std::pair<int,int>> arrIndexRange; // mapping report step number to array indeces (start and end)
|
||||
|
||||
void initUnified();
|
||||
void initSeparate(const int number);
|
||||
|
||||
int getArrayIndex(const std::string& name, int seqnum) const;
|
||||
|
||||
std::streampos
|
||||
restartStepWritePosition(const int seqnumValue) const;
|
||||
};
|
||||
|
||||
}} // namespace Opm::EclIO
|
||||
|
||||
#endif // OPM_IO_ERST_HPP
|
||||
70
opm/io/eclipse/ESmry.hpp
Normal file
70
opm/io/eclipse/ESmry.hpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
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_IO_ESMRY_HPP
|
||||
#define OPM_IO_ESMRY_HPP
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace Opm { namespace EclIO {
|
||||
|
||||
class ESmry
|
||||
{
|
||||
public:
|
||||
|
||||
// input is smspec (or fsmspec file)
|
||||
explicit ESmry(const std::string& filename, bool loadBaseRunData=false);
|
||||
|
||||
int numberOfVectors() const { return nVect; }
|
||||
|
||||
bool hasKey(const std::string& key) const;
|
||||
|
||||
const std::vector<float>& get(const std::string& name) const;
|
||||
|
||||
std::vector<float> get_at_rstep(const std::string& name) const;
|
||||
|
||||
const std::vector<std::string>& keywordList() const { return keyword; }
|
||||
|
||||
int timestepIdxAtReportstepStart(const int reportStep) const;
|
||||
|
||||
private:
|
||||
int nVect, nI, nJ, nK;
|
||||
|
||||
void ijk_from_global_index(int glob, int &i, int &j, int &k) const;
|
||||
std::vector<std::vector<float>> param;
|
||||
std::vector<std::string> keyword;
|
||||
|
||||
std::vector<int> seqIndex;
|
||||
std::vector<float> seqTime;
|
||||
|
||||
std::vector<std::string> checkForMultipleResultFiles(const boost::filesystem::path& rootN, bool formatted) const;
|
||||
|
||||
void getRstString(const std::vector<std::string>& restartArray,
|
||||
boost::filesystem::path& pathRst,
|
||||
boost::filesystem::path& rootN) const;
|
||||
|
||||
void updatePathAndRootName(boost::filesystem::path& dir, boost::filesystem::path& rootN) const;
|
||||
|
||||
std::string makeKeyString(const std::string& keyword, const std::string& wgname, int num) const;
|
||||
};
|
||||
|
||||
}} // namespace Opm::EclIO
|
||||
|
||||
#endif // OPM_IO_ESMRY_HPP
|
||||
116
opm/io/eclipse/EclFile.hpp
Normal file
116
opm/io/eclipse/EclFile.hpp
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
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_IO_ECLFILE_HPP
|
||||
#define OPM_IO_ECLFILE_HPP
|
||||
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
|
||||
#include <opm/io/eclipse/EclIOdata.hpp>
|
||||
|
||||
#include <ios>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm { namespace EclIO {
|
||||
|
||||
class EclFile
|
||||
{
|
||||
public:
|
||||
explicit EclFile(const std::string& filename);
|
||||
bool formattedInput() { return formatted; }
|
||||
|
||||
void loadData(); // load all data
|
||||
void loadData(const std::string& arrName); // load all arrays with array name equal to arrName
|
||||
void loadData(int arrIndex); // load data based on array indices in vector arrIndex
|
||||
void loadData(const std::vector<int>& arrIndex); // load data based on array indices in vector arrIndex
|
||||
|
||||
void clearData()
|
||||
{
|
||||
inte_array.clear();
|
||||
real_array.clear();
|
||||
doub_array.clear();
|
||||
logi_array.clear();
|
||||
char_array.clear();
|
||||
}
|
||||
|
||||
using EclEntry = std::tuple<std::string, eclArrType, int>;
|
||||
std::vector<EclEntry> getList() const;
|
||||
|
||||
template <typename T>
|
||||
const std::vector<T>& get(int arrIndex);
|
||||
|
||||
template <typename T>
|
||||
const std::vector<T>& get(const std::string& name);
|
||||
|
||||
bool hasKey(const std::string &name) const;
|
||||
|
||||
const std::vector<std::string>& arrayNames() const { return array_name; }
|
||||
|
||||
protected:
|
||||
bool formatted;
|
||||
std::string inputFilename;
|
||||
|
||||
std::unordered_map<int, std::vector<int>> inte_array;
|
||||
std::unordered_map<int, std::vector<bool>> logi_array;
|
||||
std::unordered_map<int, std::vector<double>> doub_array;
|
||||
std::unordered_map<int, std::vector<float>> real_array;
|
||||
std::unordered_map<int, std::vector<std::string>> char_array;
|
||||
|
||||
std::vector<std::string> array_name;
|
||||
std::vector<eclArrType> array_type;
|
||||
std::vector<int> array_size;
|
||||
|
||||
std::vector<unsigned long int> ifStreamPos;
|
||||
|
||||
std::map<std::string, int> array_index;
|
||||
|
||||
template<class T>
|
||||
const std::vector<T>& getImpl(int arrIndex, eclArrType type,
|
||||
const std::unordered_map<int, std::vector<T>>& array,
|
||||
const std::string& typeStr)
|
||||
{
|
||||
if (array_type[arrIndex] != type) {
|
||||
std::string message = "Array with index " + std::to_string(arrIndex) + " is not of type " + typeStr;
|
||||
OPM_THROW(std::runtime_error, message);
|
||||
}
|
||||
|
||||
if (!arrayLoaded[arrIndex]) {
|
||||
loadData(arrIndex);
|
||||
}
|
||||
|
||||
return array.at(arrIndex);
|
||||
}
|
||||
|
||||
std::streampos
|
||||
seekPosition(const std::vector<std::string>::size_type arrIndex) const;
|
||||
|
||||
private:
|
||||
std::vector<bool> arrayLoaded;
|
||||
|
||||
void loadBinaryArray(std::fstream& fileH, std::size_t arrIndex);
|
||||
void loadFormattedArray(const std::string& fileStr, std::size_t arrIndex, long int fromPos);
|
||||
|
||||
};
|
||||
|
||||
}} // namespace Opm::EclIO
|
||||
|
||||
#endif // OPM_IO_ECLFILE_HPP
|
||||
69
opm/io/eclipse/EclIOdata.hpp
Normal file
69
opm/io/eclipse/EclIOdata.hpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
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_IO_ECLIODATA_HPP
|
||||
#define OPM_IO_ECLIODATA_HPP
|
||||
|
||||
#include <tuple>
|
||||
|
||||
namespace Opm { namespace EclIO {
|
||||
|
||||
// type MESS have no assisiated data
|
||||
enum eclArrType {
|
||||
INTE, REAL, DOUB, CHAR, LOGI, MESS
|
||||
};
|
||||
|
||||
// named constants related to binary file format
|
||||
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
|
||||
|
||||
// named constants related to formatted file file format
|
||||
const int MaxNumBlockInte = 1000; // maximum number of Inte values in block => hard line shift
|
||||
const int MaxNumBlockReal = 1000; // maximum number of Real values in block => hard line shift
|
||||
const int MaxNumBlockDoub = 1000; // maximum number of Doub values in block => hard line shift
|
||||
const int MaxNumBlockLogi = 1000; // maximum number of Logi values in block => hard line shift
|
||||
const int MaxNumBlockChar = 105; // maximum number of Char values in block => hard line shift
|
||||
|
||||
const int numColumnsInte = 6; // number of columns for Inte values
|
||||
const int numColumnsReal = 4; // number of columns for Real values
|
||||
const int numColumnsDoub = 3; // number of columns for Doub values
|
||||
const int numColumnsLogi = 25; // number of columns for Logi values
|
||||
const int numColumnsChar = 7; // number of columns for Char values
|
||||
|
||||
const int columnWidthInte = 12; // number of characters fore each Inte Element
|
||||
const int columnWidthReal = 17; // number of characters fore each Inte Element
|
||||
const int columnWidthDoub = 23; // number of characters fore each Inte Element
|
||||
const int columnWidthLogi = 3; // number of characters fore each Inte Element
|
||||
const int columnWidthChar = 11; // number of characters fore each Inte Element
|
||||
|
||||
}} // namespace Opm::EclIO
|
||||
|
||||
#endif // OPM_IO_ECLIODATA_HPP
|
||||
116
opm/io/eclipse/EclOutput.hpp
Normal file
116
opm/io/eclipse/EclOutput.hpp
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
Copyright 2019 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_IO_ECLOUTPUT_HPP
|
||||
#define OPM_IO_ECLOUTPUT_HPP
|
||||
|
||||
#include <fstream>
|
||||
#include <ios>
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <vector>
|
||||
|
||||
#include <opm/io/eclipse/EclIOdata.hpp>
|
||||
#include <opm/io/eclipse/PaddedOutputString.hpp>
|
||||
|
||||
namespace Opm { namespace EclIO { namespace OutputStream {
|
||||
class Restart;
|
||||
class SummarySpecification;
|
||||
}}}
|
||||
|
||||
namespace Opm { namespace EclIO {
|
||||
|
||||
class EclOutput
|
||||
{
|
||||
public:
|
||||
EclOutput(const std::string& filename,
|
||||
const bool formatted,
|
||||
const std::ios_base::openmode mode = std::ios::out);
|
||||
|
||||
template<typename T>
|
||||
void write(const std::string& name,
|
||||
const std::vector<T>& data)
|
||||
{
|
||||
eclArrType arrType = MESS;
|
||||
if (typeid(T) == typeid(int))
|
||||
arrType = INTE;
|
||||
else if (typeid(T) == typeid(float))
|
||||
arrType = REAL;
|
||||
else if (typeid(T) == typeid(double))
|
||||
arrType = DOUB;
|
||||
else if (typeid(T) == typeid(bool))
|
||||
arrType = LOGI;
|
||||
else if (typeid(T) == typeid(char))
|
||||
arrType = MESS;
|
||||
|
||||
if (isFormatted)
|
||||
{
|
||||
writeFormattedHeader(name, data.size(), arrType);
|
||||
if (arrType != MESS)
|
||||
writeFormattedArray(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeBinaryHeader(name, data.size(), arrType);
|
||||
if (arrType != MESS)
|
||||
writeBinaryArray(data);
|
||||
}
|
||||
}
|
||||
|
||||
void message(const std::string& msg);
|
||||
void flushStream();
|
||||
|
||||
friend class OutputStream::Restart;
|
||||
friend class OutputStream::SummarySpecification;
|
||||
|
||||
private:
|
||||
void writeBinaryHeader(const std::string& arrName, int size, eclArrType arrType);
|
||||
|
||||
template <typename T>
|
||||
void writeBinaryArray(const std::vector<T>& data);
|
||||
|
||||
void writeBinaryCharArray(const std::vector<std::string>& data);
|
||||
void writeBinaryCharArray(const std::vector<PaddedOutputString<8>>& data);
|
||||
|
||||
void writeFormattedHeader(const std::string& arrName, int size, eclArrType arrType);
|
||||
|
||||
template <typename T>
|
||||
void writeFormattedArray(const std::vector<T>& data);
|
||||
|
||||
void writeFormattedCharArray(const std::vector<std::string>& data);
|
||||
void writeFormattedCharArray(const std::vector<PaddedOutputString<8>>& data);
|
||||
|
||||
std::string make_real_string(float value) const;
|
||||
std::string make_doub_string(double value) const;
|
||||
|
||||
bool isFormatted;
|
||||
std::ofstream ofileH;
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
void EclOutput::write<std::string>(const std::string& name,
|
||||
const std::vector<std::string>& data);
|
||||
|
||||
template <>
|
||||
void EclOutput::write<PaddedOutputString<8>>
|
||||
(const std::string& name,
|
||||
const std::vector<PaddedOutputString<8>>& data);
|
||||
|
||||
}} // namespace Opm::EclIO
|
||||
|
||||
#endif // OPM_IO_ECLOUTPUT_HPP
|
||||
40
opm/io/eclipse/EclUtil.hpp
Normal file
40
opm/io/eclipse/EclUtil.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
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_IO_ECLUTIL_HPP
|
||||
#define OPM_IO_ECLUTIL_HPP
|
||||
|
||||
#include <opm/io/eclipse/EclIOdata.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
namespace Opm { namespace EclIO {
|
||||
|
||||
int flipEndianInt(int num);
|
||||
float flipEndianFloat(float num);
|
||||
double flipEndianDouble(double num);
|
||||
|
||||
std::tuple<int, int> block_size_data_binary(eclArrType arrType);
|
||||
std::tuple<int, int, int> block_size_data_formatted(eclArrType arrType);
|
||||
|
||||
std::string trimr(const std::string &str1);
|
||||
|
||||
}} // namespace Opm::EclIO
|
||||
|
||||
#endif // OPM_IO_ECLUTIL_HPP
|
||||
455
opm/io/eclipse/OutputStream.hpp
Normal file
455
opm/io/eclipse/OutputStream.hpp
Normal file
@@ -0,0 +1,455 @@
|
||||
/*
|
||||
Copyright (c) 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_IO_OUTPUTSTREAM_HPP_INCLUDED
|
||||
#define OPM_IO_OUTPUTSTREAM_HPP_INCLUDED
|
||||
|
||||
#include <opm/io/eclipse/PaddedOutputString.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <ios>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm { namespace EclIO {
|
||||
|
||||
class EclOutput;
|
||||
|
||||
}} // namespace Opm::EclIO
|
||||
|
||||
namespace Opm { namespace EclIO { namespace OutputStream {
|
||||
|
||||
struct Formatted { bool set; };
|
||||
struct Unified { bool set; };
|
||||
|
||||
/// Abstract representation of an ECLIPSE-style result set.
|
||||
struct ResultSet
|
||||
{
|
||||
/// Output directory. Commonly "." or location of run's .DATA file.
|
||||
std::string outputDir;
|
||||
|
||||
/// Base name of simulation run.
|
||||
std::string baseName;
|
||||
};
|
||||
|
||||
/// File manager for "init" output streams.
|
||||
class Init
|
||||
{
|
||||
public:
|
||||
/// Constructor.
|
||||
///
|
||||
/// Opens file stream for writing.
|
||||
///
|
||||
/// \param[in] rset Output directory and base name of output stream.
|
||||
///
|
||||
/// \param[in] fmt Whether or not to create formatted output files.
|
||||
explicit Init(const ResultSet& rset,
|
||||
const Formatted& fmt);
|
||||
|
||||
~Init();
|
||||
|
||||
Init(const Init& rhs) = delete;
|
||||
Init(Init&& rhs);
|
||||
|
||||
Init& operator=(const Init& rhs) = delete;
|
||||
Init& operator=(Init&& rhs);
|
||||
|
||||
/// Write integer data to underlying output stream.
|
||||
///
|
||||
/// \param[in] kw Name of output vector (keyword).
|
||||
///
|
||||
/// \param[in] data Output values.
|
||||
void write(const std::string& kw,
|
||||
const std::vector<int>& data);
|
||||
|
||||
/// Write boolean data to underlying output stream.
|
||||
///
|
||||
/// \param[in] kw Name of output vector (keyword).
|
||||
///
|
||||
/// \param[in] data Output values.
|
||||
void write(const std::string& kw,
|
||||
const std::vector<bool>& data);
|
||||
|
||||
/// Write single precision floating point data to underlying
|
||||
/// output stream.
|
||||
///
|
||||
/// \param[in] kw Name of output vector (keyword).
|
||||
///
|
||||
/// \param[in] data Output values.
|
||||
void write(const std::string& kw,
|
||||
const std::vector<float>& data);
|
||||
|
||||
/// Write double precision floating point data to underlying
|
||||
/// output stream.
|
||||
///
|
||||
/// \param[in] kw Name of output vector (keyword).
|
||||
///
|
||||
/// \param[in] data Output values.
|
||||
void write(const std::string& kw,
|
||||
const std::vector<double>& data);
|
||||
|
||||
private:
|
||||
/// Init file output stream.
|
||||
std::unique_ptr<EclOutput> stream_;
|
||||
|
||||
/// Open output stream.
|
||||
///
|
||||
/// Writes to \c stream_.
|
||||
///
|
||||
/// \param[in] fname Filename of new output stream.
|
||||
///
|
||||
/// \param[in] formatted Whether or not to create a
|
||||
/// formatted output file.
|
||||
void open(const std::string& fname,
|
||||
const bool formatted);
|
||||
|
||||
/// Access writable output stream.
|
||||
EclOutput& stream();
|
||||
|
||||
/// Implementation function for public \c write overload set.
|
||||
template <typename T>
|
||||
void writeImpl(const std::string& kw,
|
||||
const std::vector<T>& data);
|
||||
};
|
||||
|
||||
/// File manager for restart output streams.
|
||||
class Restart
|
||||
{
|
||||
public:
|
||||
/// Constructor.
|
||||
///
|
||||
/// Opens file stream pertaining to restart of particular report
|
||||
/// step and also outputs a SEQNUM record in the case of a unified
|
||||
/// output stream.
|
||||
///
|
||||
/// Must be called before accessing the stream object through the
|
||||
/// stream() member function.
|
||||
///
|
||||
/// \param[in] rset Output directory and base name of output stream.
|
||||
///
|
||||
/// \param[in] seqnum Sequence number of new report. One-based
|
||||
/// report step ID.
|
||||
///
|
||||
/// \param[in] fmt Whether or not to create formatted output files.
|
||||
///
|
||||
/// \param[in] unif Whether or not to create unified output files.
|
||||
explicit Restart(const ResultSet& rset,
|
||||
const int seqnum,
|
||||
const Formatted& fmt,
|
||||
const Unified& unif);
|
||||
|
||||
~Restart();
|
||||
|
||||
Restart(const Restart& rhs) = delete;
|
||||
Restart(Restart&& rhs);
|
||||
|
||||
Restart& operator=(const Restart& rhs) = delete;
|
||||
Restart& operator=(Restart&& rhs);
|
||||
|
||||
/// Generate a message string (keyword type 'MESS') in underlying
|
||||
/// output stream.
|
||||
///
|
||||
/// \param[in] msg Message string (e.g., "STARTSOL").
|
||||
void message(const std::string& msg);
|
||||
|
||||
/// Write integer data to underlying output stream.
|
||||
///
|
||||
/// \param[in] kw Name of output vector (keyword).
|
||||
///
|
||||
/// \param[in] data Output values.
|
||||
void write(const std::string& kw,
|
||||
const std::vector<int>& data);
|
||||
|
||||
/// Write boolean data to underlying output stream.
|
||||
///
|
||||
/// \param[in] kw Name of output vector (keyword).
|
||||
///
|
||||
/// \param[in] data Output values.
|
||||
void write(const std::string& kw,
|
||||
const std::vector<bool>& data);
|
||||
|
||||
/// Write single precision floating point data to underlying
|
||||
/// output stream.
|
||||
///
|
||||
/// \param[in] kw Name of output vector (keyword).
|
||||
///
|
||||
/// \param[in] data Output values.
|
||||
void write(const std::string& kw,
|
||||
const std::vector<float>& data);
|
||||
|
||||
/// Write double precision floating point data to underlying
|
||||
/// output stream.
|
||||
///
|
||||
/// \param[in] kw Name of output vector (keyword).
|
||||
///
|
||||
/// \param[in] data Output values.
|
||||
void write(const std::string& kw,
|
||||
const std::vector<double>& data);
|
||||
|
||||
/// Write unpadded string data to underlying output stream.
|
||||
///
|
||||
/// \param[in] kw Name of output vector (keyword).
|
||||
///
|
||||
/// \param[in] data Output values.
|
||||
void write(const std::string& kw,
|
||||
const std::vector<std::string>& data);
|
||||
|
||||
/// Write padded character data (8 characters per string)
|
||||
/// to underlying output stream.
|
||||
///
|
||||
/// \param[in] kw Name of output vector (keyword).
|
||||
///
|
||||
/// \param[in] data Output values.
|
||||
void write(const std::string& kw,
|
||||
const std::vector<PaddedOutputString<8>>& data);
|
||||
|
||||
private:
|
||||
/// Restart output stream.
|
||||
std::unique_ptr<EclOutput> stream_;
|
||||
|
||||
/// Open unified output file and place stream's output indicator
|
||||
/// in appropriate location.
|
||||
///
|
||||
/// Writes to \c stream_.
|
||||
///
|
||||
/// \param[in] fname Filename of output stream.
|
||||
///
|
||||
/// \param[in] formatted Whether or not to create a
|
||||
/// formatted output file.
|
||||
///
|
||||
/// \param[in] seqnum Sequence number of new report. One-based
|
||||
/// report step ID.
|
||||
void openUnified(const std::string& fname,
|
||||
const bool formatted,
|
||||
const int seqnum);
|
||||
|
||||
/// Open new output stream.
|
||||
///
|
||||
/// Handles the case of separate output files or unified output file
|
||||
/// that does not already exist. Writes to \c stream_.
|
||||
///
|
||||
/// \param[in] fname Filename of new output stream.
|
||||
///
|
||||
/// \param[in] formatted Whether or not to create a
|
||||
/// formatted output file.
|
||||
void openNew(const std::string& fname,
|
||||
const bool formatted);
|
||||
|
||||
/// Open existing output file and place stream's output indicator
|
||||
/// in appropriate location.
|
||||
///
|
||||
/// Writes to \c stream_.
|
||||
///
|
||||
/// \param[in] fname Filename of output stream.
|
||||
///
|
||||
/// \param[in] writePos Position at which to place stream's output
|
||||
/// indicator. Use \code streampos{ streamoff{-1} } \endcode to
|
||||
/// place output indicator at end of file (i.e, simple append).
|
||||
void openExisting(const std::string& fname,
|
||||
const bool formatted,
|
||||
const std::streampos writePos);
|
||||
|
||||
/// Access writable output stream.
|
||||
///
|
||||
/// Must not be called prior to \c prepareStep.
|
||||
EclOutput& stream();
|
||||
|
||||
/// Implementation function for public \c write overload set.
|
||||
template <typename T>
|
||||
void writeImpl(const std::string& kw,
|
||||
const std::vector<T>& data);
|
||||
};
|
||||
|
||||
/// File manager for RFT output streams
|
||||
class RFT
|
||||
{
|
||||
public:
|
||||
struct OpenExisting { bool set; };
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// Opens file stream for writing.
|
||||
///
|
||||
/// \param[in] rset Output directory and base name of output stream.
|
||||
///
|
||||
/// \param[in] fmt Whether or not to create formatted output files.
|
||||
///
|
||||
/// \param[in] existing Whether or not to open an existing output file.
|
||||
explicit RFT(const ResultSet& rset,
|
||||
const Formatted& fmt,
|
||||
const OpenExisting& existing);
|
||||
|
||||
~RFT();
|
||||
|
||||
RFT(const RFT& rhs) = delete;
|
||||
RFT(RFT&& rhs);
|
||||
|
||||
RFT& operator=(const RFT& rhs) = delete;
|
||||
RFT& operator=(RFT&& rhs);
|
||||
|
||||
/// Write integer data to underlying output stream.
|
||||
///
|
||||
/// \param[in] kw Name of output vector (keyword).
|
||||
///
|
||||
/// \param[in] data Output values.
|
||||
void write(const std::string& kw,
|
||||
const std::vector<int>& data);
|
||||
|
||||
/// Write single precision floating point data to underlying
|
||||
/// output stream.
|
||||
///
|
||||
/// \param[in] kw Name of output vector (keyword).
|
||||
///
|
||||
/// \param[in] data Output values.
|
||||
void write(const std::string& kw,
|
||||
const std::vector<float>& data);
|
||||
|
||||
/// Write padded character data (8 characters per string)
|
||||
/// to underlying output stream.
|
||||
///
|
||||
/// \param[in] kw Name of output vector (keyword).
|
||||
///
|
||||
/// \param[in] data Output values.
|
||||
void write(const std::string& kw,
|
||||
const std::vector<PaddedOutputString<8>>& data);
|
||||
|
||||
private:
|
||||
/// Init file output stream.
|
||||
std::unique_ptr<EclOutput> stream_;
|
||||
|
||||
/// Open output stream.
|
||||
///
|
||||
/// Writes to \c stream_.
|
||||
///
|
||||
/// \param[in] fname Filename of new output stream.
|
||||
///
|
||||
/// \param[in] formatted Whether or not to create a
|
||||
/// formatted output file.
|
||||
///
|
||||
/// \param[in] existing Whether or not to open an
|
||||
/// existing output file (mode ios_base::app).
|
||||
void open(const std::string& fname,
|
||||
const bool formatted,
|
||||
const bool existing);
|
||||
|
||||
/// Access writable output stream.
|
||||
EclOutput& stream();
|
||||
|
||||
/// Implementation function for public \c write overload set.
|
||||
template <typename T>
|
||||
void writeImpl(const std::string& kw,
|
||||
const std::vector<T>& data);
|
||||
};
|
||||
|
||||
class SummarySpecification
|
||||
{
|
||||
public:
|
||||
using StartTime = std::chrono::system_clock::time_point;
|
||||
|
||||
enum class UnitConvention
|
||||
{
|
||||
Metric = 1,
|
||||
Field = 2,
|
||||
Lab = 3,
|
||||
Pvt_M = 4,
|
||||
};
|
||||
|
||||
struct RestartSpecification
|
||||
{
|
||||
std::string root;
|
||||
int step;
|
||||
};
|
||||
|
||||
class Parameters
|
||||
{
|
||||
public:
|
||||
void add(const std::string& keyword,
|
||||
const std::string& wgname,
|
||||
const int num,
|
||||
const std::string& unit);
|
||||
|
||||
friend class SummarySpecification;
|
||||
|
||||
private:
|
||||
std::vector<PaddedOutputString<8>> keywords{};
|
||||
std::vector<PaddedOutputString<8>> wgnames{};
|
||||
std::vector<int> nums{};
|
||||
std::vector<PaddedOutputString<8>> units{};
|
||||
};
|
||||
|
||||
explicit SummarySpecification(const ResultSet& rset,
|
||||
const Formatted& fmt,
|
||||
const UnitConvention uconv,
|
||||
const std::array<int,3>& cartDims,
|
||||
const RestartSpecification& restart,
|
||||
const StartTime start);
|
||||
|
||||
~SummarySpecification();
|
||||
|
||||
SummarySpecification(const SummarySpecification& rhs) = delete;
|
||||
SummarySpecification(SummarySpecification&& rhs);
|
||||
|
||||
SummarySpecification& operator=(const SummarySpecification& rhs) = delete;
|
||||
SummarySpecification& operator=(SummarySpecification&& rhs);
|
||||
|
||||
void write(const Parameters& params);
|
||||
|
||||
private:
|
||||
int unit_;
|
||||
int restartStep_;
|
||||
std::array<int,3> cartDims_;
|
||||
StartTime startDate_;
|
||||
std::vector<PaddedOutputString<8>> restart_;
|
||||
|
||||
/// Summary specification (SMSPEC) file output stream.
|
||||
std::unique_ptr<EclOutput> stream_;
|
||||
|
||||
void rewindStream();
|
||||
void flushStream();
|
||||
|
||||
EclOutput& stream();
|
||||
};
|
||||
|
||||
std::unique_ptr<EclOutput>
|
||||
createSummaryFile(const ResultSet& rset,
|
||||
const int seqnum,
|
||||
const Formatted& fmt,
|
||||
const Unified& unif);
|
||||
|
||||
/// Derive filename corresponding to output stream of particular result
|
||||
/// set, with user-specified file extension.
|
||||
///
|
||||
/// Low-level string concatenation routine that does not know specific
|
||||
/// relations between base names and file extensions. Handles details
|
||||
/// of base name ending in a period (full stop) or having a name that
|
||||
/// might otherwise appear to contain a file extension (e.g., CASE.01).
|
||||
///
|
||||
/// \param[in] rsetDescriptor Output directory and base name of result set.
|
||||
///
|
||||
/// \param[in] ext Filename extension.
|
||||
///
|
||||
/// \return outputDir/baseName.ext
|
||||
std::string outputFileName(const ResultSet& rsetDescriptor,
|
||||
const std::string& ext);
|
||||
|
||||
}}} // namespace Opm::EclIO::OutputStream
|
||||
|
||||
#endif // OPM_IO_OUTPUTSTREAM_HPP_INCLUDED
|
||||
@@ -17,8 +17,8 @@
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_CHARARRAY_HEADER_HPP
|
||||
#define OPM_CHARARRAY_HEADER_HPP
|
||||
#ifndef OPM_PADDEDOUTPUTSTRING_HEADER_HPP
|
||||
#define OPM_PADDEDOUTPUTSTRING_HEADER_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
namespace Opm { namespace EclIO {
|
||||
|
||||
/// Null-terminated, left adjusted, space padded array of N characters.
|
||||
///
|
||||
@@ -36,30 +36,30 @@ namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
///
|
||||
/// \tparam N Number of characters.
|
||||
template <std::size_t N>
|
||||
class CharArrayNullTerm
|
||||
class PaddedOutputString
|
||||
{
|
||||
public:
|
||||
CharArrayNullTerm()
|
||||
PaddedOutputString()
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
explicit CharArrayNullTerm(const std::string& s)
|
||||
: CharArrayNullTerm()
|
||||
explicit PaddedOutputString(const std::string& s)
|
||||
: PaddedOutputString()
|
||||
{
|
||||
this->copy_in(s.c_str(), s.size());
|
||||
}
|
||||
|
||||
~CharArrayNullTerm() = default;
|
||||
~PaddedOutputString() = default;
|
||||
|
||||
CharArrayNullTerm(const CharArrayNullTerm& rhs) = default;
|
||||
CharArrayNullTerm(CharArrayNullTerm&& rhs) = default;
|
||||
PaddedOutputString(const PaddedOutputString& rhs) = default;
|
||||
PaddedOutputString(PaddedOutputString&& rhs) = default;
|
||||
|
||||
CharArrayNullTerm& operator=(const CharArrayNullTerm& rhs) = default;
|
||||
CharArrayNullTerm& operator=(CharArrayNullTerm&& rhs) = default;
|
||||
PaddedOutputString& operator=(const PaddedOutputString& rhs) = default;
|
||||
PaddedOutputString& operator=(PaddedOutputString&& rhs) = default;
|
||||
|
||||
/// Assign from \code std::string \endcode.
|
||||
CharArrayNullTerm& operator=(const std::string& s)
|
||||
PaddedOutputString& operator=(const std::string& s)
|
||||
{
|
||||
this->clear();
|
||||
this->copy_in(s.data(), s.size());
|
||||
@@ -99,5 +99,5 @@ namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
}
|
||||
};
|
||||
|
||||
}}} // Opm::RestartIO::Helpers
|
||||
#endif // CHARARRAY_HEADER
|
||||
}} // Opm::EclIO
|
||||
#endif // OPM_PADDEDOUTPUTSTRING_HEADER_HPP
|
||||
@@ -20,140 +20,135 @@
|
||||
#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 <opm/io/eclipse/PaddedOutputString.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace Opm {
|
||||
class Schedule;
|
||||
class SummaryState;
|
||||
class Group;
|
||||
class Schedule;
|
||||
class SummaryState;
|
||||
class Group2;
|
||||
} // 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;
|
||||
class AggregateGroupData
|
||||
{
|
||||
public:
|
||||
explicit AggregateGroupData(const std::vector<int>& inteHead);
|
||||
|
||||
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);
|
||||
void captureDeclaredGroupData(const Opm::Schedule& sched,
|
||||
const std::size_t simStep,
|
||||
const Opm::SummaryState& sumState,
|
||||
const std::vector<int>& inteHead);
|
||||
|
||||
private:
|
||||
std::map <size_t, const Opm::Group*> m_indexGroupMap;
|
||||
std::map <const std::string, size_t> m_groupNameIndexMap;
|
||||
};
|
||||
|
||||
class AggregateGroupData
|
||||
const std::vector<int>& getIGroup() const
|
||||
{
|
||||
public:
|
||||
explicit AggregateGroupData(const std::vector<int>& inteHead);
|
||||
return this->iGroup_.data();
|
||||
}
|
||||
|
||||
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<float>& getSGroup() const
|
||||
{
|
||||
return this->sGroup_.data();
|
||||
}
|
||||
|
||||
const std::vector<int>& getIGroup() const
|
||||
{
|
||||
return this->iGroup_.data();
|
||||
}
|
||||
const std::vector<double>& getXGroup() const
|
||||
{
|
||||
return this->xGroup_.data();
|
||||
}
|
||||
|
||||
const std::vector<float>& getSGroup() const
|
||||
{
|
||||
return this->sGroup_.data();
|
||||
}
|
||||
const std::vector<EclIO::PaddedOutputString<8>>& getZGroup() const
|
||||
{
|
||||
return this->zGroup_.data();
|
||||
}
|
||||
|
||||
const std::vector<double>& getXGroup() const
|
||||
{
|
||||
return this->xGroup_.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<CharArrayNullTerm<8>>& getZGroup() const
|
||||
{
|
||||
return this->zGroup_.data();
|
||||
}
|
||||
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::vector<std::string> restart_group_keys = {"GOPP", "GWPP", "GOPR", "GWPR", "GGPR",
|
||||
"GVPR", "GWIR", "GGIR", "GWCT", "GGOR",
|
||||
"GOPT", "GWPT", "GGPT", "GVPT", "GWIT",
|
||||
"GGIT"};
|
||||
|
||||
const std::vector<std::string> restart_field_keys = {"FOPP", "FWPP", "FOPR", "FWPR", "FGPR",
|
||||
"FVPR", "FWIR", "FGIR", "FWCT", "FGOR",
|
||||
"FOPT", "FWPT", "FGPT", "FVPT", "FWIT",
|
||||
"FGIT"};
|
||||
|
||||
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},
|
||||
};
|
||||
|
||||
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},
|
||||
};
|
||||
|
||||
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_;
|
||||
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<EclIO::PaddedOutputString<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
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#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>
|
||||
@@ -55,13 +54,13 @@ namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
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,
|
||||
|
||||
142
opm/output/eclipse/AggregateUDQData.hpp
Normal file
142
opm/output/eclipse/AggregateUDQData.hpp
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
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_UDQ_DATA_HPP
|
||||
#define OPM_AGGREGATE_UDQ_DATA_HPP
|
||||
|
||||
#include <opm/output/eclipse/WindowedArray.hpp>
|
||||
#include <opm/io/eclipse/PaddedOutputString.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQAssign.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunctionTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace Opm {
|
||||
class Schedule;
|
||||
class UDQInput;
|
||||
class UDQActive;
|
||||
} // Opm
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
|
||||
class igphData {
|
||||
public:
|
||||
const std::vector<int> ig_phase(const Opm::Schedule& sched, const std::size_t simStep, const std::vector<int>& inteHead);
|
||||
};
|
||||
|
||||
class AggregateUDQData
|
||||
{
|
||||
public:
|
||||
explicit AggregateUDQData(const std::vector<int>& udqDims);
|
||||
|
||||
void captureDeclaredUDQData(const Opm::Schedule& sched,
|
||||
const std::size_t simStep,
|
||||
const Opm::SummaryState& st,
|
||||
const std::vector<int>& inteHead);
|
||||
|
||||
const std::vector<int>& getIUDQ() const
|
||||
{
|
||||
return this->iUDQ_.data();
|
||||
}
|
||||
|
||||
const std::vector<int>& getIUAD() const
|
||||
{
|
||||
return this->iUAD_.data();
|
||||
}
|
||||
|
||||
const std::vector<EclIO::PaddedOutputString<8>>& getZUDN() const
|
||||
{
|
||||
return this->zUDN_.data();
|
||||
}
|
||||
|
||||
const std::vector<EclIO::PaddedOutputString<8>>& getZUDL() const
|
||||
{
|
||||
return this->zUDL_.data();
|
||||
}
|
||||
|
||||
const std::vector<int>& getIGPH() const
|
||||
{
|
||||
return this->iGPH_.data();
|
||||
}
|
||||
|
||||
const std::vector<int>& getIUAP() const
|
||||
{
|
||||
return this->iUAP_.data();
|
||||
}
|
||||
|
||||
const std::vector<double>& getDUDW() const
|
||||
{
|
||||
return this->dUDW_.data();
|
||||
}
|
||||
|
||||
const std::vector<double>& getDUDG() const
|
||||
{
|
||||
return this->dUDG_.data();
|
||||
}
|
||||
|
||||
const std::vector<double>& getDUDF() const
|
||||
{
|
||||
return this->dUDF_.data();
|
||||
}
|
||||
|
||||
private:
|
||||
/// Aggregate 'IUDQ' array (Integer) for all UDQ data (3 integers pr UDQ)
|
||||
WindowedArray<int> iUDQ_;
|
||||
|
||||
/// Aggregate 'IUAD' array (Integer) for all UDQ data (5 integers pr UDQ that is used for various well and group controls)
|
||||
WindowedArray<int> iUAD_;
|
||||
|
||||
|
||||
/// Aggregate 'ZUDN' array (Character) for all UDQ data. (2 * 8 chars pr UDQ -> UNIT keyword)
|
||||
WindowedArray<EclIO::PaddedOutputString<8>> zUDN_;
|
||||
|
||||
/// Aggregate 'ZUDL' array (Character) for all UDQ data. (16 * 8 chars pr UDQ DEFINE "Data for operation - Msth Expression)
|
||||
WindowedArray<EclIO::PaddedOutputString<8>> zUDL_;
|
||||
|
||||
/// Aggregate 'IGPH' array (Integer) for all UDQ data (3 - zeroes - as of current understanding)
|
||||
WindowedArray<int> iGPH_;
|
||||
|
||||
/// Aggregate 'IUAP' array (ICharArrayNullTermnteger) for all UDQ data (1 integer pr UDQ constraint used)
|
||||
WindowedArray<int> iUAP_;
|
||||
|
||||
/// Aggregate 'DUDW' array (Double Precision) for all UDQ data. (Dimension = max no wells * noOfUDQ's)
|
||||
WindowedArray<double> dUDW_;
|
||||
|
||||
/// Aggregate 'DUDG' array (Double Precision) for all UDQ data. (Dimension = (max no groups + 1) * noOfUDQ's)
|
||||
WindowedArray<double> dUDG_;
|
||||
|
||||
/// Aggregate 'DUDF' array (Double Precision) for all UDQ data. (Dimension = Number of FU - UDQ's, with value equal to the actual constraint)
|
||||
WindowedArray<double> dUDF_;
|
||||
|
||||
|
||||
};
|
||||
|
||||
}}} // Opm::RestartIO::Helpers
|
||||
|
||||
#endif //OPM_AGGREGATE_WELL_DATA_HPP
|
||||
@@ -20,9 +20,10 @@
|
||||
#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 <opm/io/eclipse/PaddedOutputString.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -52,7 +53,6 @@ namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
|
||||
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);
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
}
|
||||
|
||||
/// Retrieve Character Well Data Array.
|
||||
const std::vector<CharArrayNullTerm<8>>& getZWell() const
|
||||
const std::vector<EclIO::PaddedOutputString<8>>& getZWell() const
|
||||
{
|
||||
return this->zWell_.data();
|
||||
}
|
||||
@@ -93,7 +93,7 @@ namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
WindowedArray<double> xWell_;
|
||||
|
||||
/// Aggregate 'ZWEL' array (Character) for all wells.
|
||||
WindowedArray<CharArrayNullTerm<8>> zWell_;
|
||||
WindowedArray<EclIO::PaddedOutputString<8>> zWell_;
|
||||
|
||||
/// Maximum number of groups in model.
|
||||
int nWGMax_;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
namespace Opm {
|
||||
class Tuning;
|
||||
class Schedule;
|
||||
class UDQParams;
|
||||
}
|
||||
|
||||
namespace Opm { namespace RestartIO {
|
||||
@@ -38,7 +39,7 @@ namespace Opm { namespace RestartIO {
|
||||
std::chrono::time_point<std::chrono::system_clock> start;
|
||||
std::chrono::duration<double, std::chrono::seconds::period> elapsed;
|
||||
};
|
||||
|
||||
|
||||
DoubHEAD();
|
||||
|
||||
~DoubHEAD() = default;
|
||||
@@ -53,9 +54,13 @@ namespace Opm { namespace RestartIO {
|
||||
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 std::size_t lookup_step,
|
||||
const double cnvT);
|
||||
|
||||
DoubHEAD& udq_param(const UDQParams& udqPar);
|
||||
|
||||
const std::vector<double>& data() const
|
||||
{
|
||||
|
||||
@@ -23,10 +23,9 @@
|
||||
#define OPM_ECLIPSE_WRITER_HPP
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/NNC.hpp>
|
||||
@@ -36,11 +35,16 @@
|
||||
#include <opm/output/data/Wells.hpp>
|
||||
#include <opm/output/eclipse/RestartValue.hpp>
|
||||
|
||||
namespace Opm { namespace out {
|
||||
class Summary;
|
||||
}} // namespace Opm::out
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class EclipseState;
|
||||
class SummaryConfig;
|
||||
class Schedule;
|
||||
class SummaryConfig;
|
||||
class SummaryState;
|
||||
|
||||
/*!
|
||||
* \brief A class to write the reservoir state and the well state of a
|
||||
@@ -170,13 +174,11 @@ public:
|
||||
* hardcoded static map misc_units in Summary.cpp.
|
||||
*/
|
||||
|
||||
void writeTimeStep( int report_step,
|
||||
void writeTimeStep( const SummaryState& st,
|
||||
int report_step,
|
||||
bool isSubstep,
|
||||
double seconds_elapsed,
|
||||
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 bool write_double = false);
|
||||
|
||||
|
||||
@@ -218,8 +220,8 @@ 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::vector<RestartKey>& solution_keys, const std::vector<RestartKey>& extra_keys = {}) const;
|
||||
|
||||
RestartValue loadRestart(SummaryState& summary_state, const std::vector<RestartKey>& solution_keys, const std::vector<RestartKey>& extra_keys = {}) const;
|
||||
const out::Summary& summary();
|
||||
|
||||
EclipseIO( const EclipseIO& ) = delete;
|
||||
~EclipseIO();
|
||||
|
||||
@@ -39,6 +39,7 @@ namespace Opm { namespace RestartIO {
|
||||
int maxPerf;
|
||||
int maxWellInGroup;
|
||||
int maxGroupInField;
|
||||
int maxWellsInField;
|
||||
};
|
||||
|
||||
struct WellSegDims {
|
||||
@@ -89,6 +90,10 @@ namespace Opm { namespace RestartIO {
|
||||
struct Group {
|
||||
int ngroups;
|
||||
};
|
||||
|
||||
struct UdqParam {
|
||||
int udqParam_1;
|
||||
};
|
||||
|
||||
InteHEAD();
|
||||
~InteHEAD() = default;
|
||||
@@ -117,6 +122,7 @@ namespace Opm { namespace RestartIO {
|
||||
InteHEAD& wellSegDimensions(const WellSegDims& wsdim);
|
||||
InteHEAD& regionDimensions(const RegDims& rdim);
|
||||
InteHEAD& ngroups(const Group& gr);
|
||||
InteHEAD& udqParam_1(const UdqParam& udqpar);
|
||||
|
||||
const std::vector<int>& data() const
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
///
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
Copyright 2019 Equinor ASA.
|
||||
Copyright 2016, 2017 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media Project (OPM).
|
||||
@@ -27,6 +28,49 @@ namespace Opm { namespace RestartIO {
|
||||
class LogiHEAD
|
||||
{
|
||||
public:
|
||||
/// Key characteristics of simulation run's PVT model.
|
||||
struct PVTModel
|
||||
{
|
||||
/// Whether or not simulation run uses a live oil model (with
|
||||
/// dissolved gas).
|
||||
bool isLiveOil { false };
|
||||
|
||||
/// Whether or not simulation run uses a wet gas model (with
|
||||
/// vaporised oil).
|
||||
bool isWetGas { false };
|
||||
|
||||
/// Whether or not simulation run uses a constant
|
||||
/// compressibility oil model (keyword PVCDO).
|
||||
bool constComprOil { false };
|
||||
};
|
||||
|
||||
/// Key characteristics of simulation model's saturation functions.
|
||||
struct SatfuncFlags
|
||||
{
|
||||
/// Whether or not simulation run uses directionally dependent
|
||||
/// relative permeability.
|
||||
bool useDirectionalRelPerm { false };
|
||||
|
||||
/// Whether or not simulation run uses reversible relative
|
||||
/// permeability functions.
|
||||
bool useReversibleRelPerm { true };
|
||||
|
||||
/// Whether or not simulation run uses end-point scaling.
|
||||
bool useEndScale { false };
|
||||
|
||||
/// Whether or not simulation run uses directionally dependent
|
||||
/// end-point scaling.
|
||||
bool useDirectionalEPS { false };
|
||||
|
||||
/// Whether or not simulation run uses reversible end-point
|
||||
/// scaling.
|
||||
bool useReversibleEPS { true };
|
||||
|
||||
/// Whether or not simulation run activates the alternative
|
||||
/// (three-point) end-point scaling feature.
|
||||
bool useAlternateEPS { false };
|
||||
};
|
||||
|
||||
LogiHEAD();
|
||||
~LogiHEAD() = default;
|
||||
|
||||
@@ -38,7 +82,24 @@ namespace Opm { namespace RestartIO {
|
||||
|
||||
LogiHEAD& variousParam(const bool e300_radial,
|
||||
const bool e100_radial,
|
||||
const int nswlmx);
|
||||
const int nswlmx,
|
||||
const bool enableHyster
|
||||
);
|
||||
|
||||
/// Assign PVT model characteristics.
|
||||
///
|
||||
/// \param[in] pvt Current run's PVT model characteristics.
|
||||
///
|
||||
/// \return \code *this \endcode.
|
||||
LogiHEAD& pvtModel(const PVTModel& pvt);
|
||||
|
||||
/// Assign saturation function characteristics.
|
||||
///
|
||||
/// \param[in] satfunc Current run's saturation function
|
||||
/// characteristics.
|
||||
///
|
||||
/// \return \code *this \endcode.
|
||||
LogiHEAD& saturationFunction(const SatfuncFlags& satfunc);
|
||||
|
||||
const std::vector<bool>& data() const
|
||||
{
|
||||
|
||||
@@ -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,36 +24,30 @@
|
||||
#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/output/data/Cells.hpp>
|
||||
#include <opm/output/data/Solution.hpp>
|
||||
#include <opm/output/data/Wells.hpp>
|
||||
#include <opm/output/eclipse/RestartValue.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 <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class EclipseGrid;
|
||||
class EclipseState;
|
||||
class Phases;
|
||||
class Schedule;
|
||||
class SummaryState;
|
||||
class EclipseGrid;
|
||||
class EclipseState;
|
||||
class Schedule;
|
||||
|
||||
namespace RestartIO {
|
||||
} // namespace Opm
|
||||
|
||||
namespace Opm { namespace EclIO { namespace OutputStream {
|
||||
|
||||
class Restart;
|
||||
|
||||
}}}
|
||||
|
||||
/*
|
||||
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
|
||||
@@ -69,39 +64,31 @@ 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);
|
||||
void save(EclIO::OutputStream::Restart& rstFile,
|
||||
int report_step,
|
||||
double seconds_elapsed,
|
||||
RestartValue value,
|
||||
const EclipseState& es,
|
||||
const EclipseGrid& grid,
|
||||
const Schedule& schedule,
|
||||
const SummaryState& sumState,
|
||||
bool write_double = false);
|
||||
|
||||
RestartValue 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 = {});
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
RestartValue load(const std::string& filename,
|
||||
int report_step,
|
||||
SummaryState& summary_state,
|
||||
const std::vector<RestartKey>& solution_keys,
|
||||
const EclipseState& es,
|
||||
const EclipseGrid& grid,
|
||||
const Schedule& schedule,
|
||||
const std::vector<RestartKey>& extra_keys = {});
|
||||
|
||||
}} // namespace Opm::RestartIO
|
||||
|
||||
#endif // RESTART_IO_HPP
|
||||
|
||||
@@ -34,7 +34,9 @@ namespace Opm {
|
||||
|
||||
std::string key;
|
||||
UnitSystem::measure dim;
|
||||
bool required;
|
||||
bool required = false;
|
||||
|
||||
RestartKey() = default;
|
||||
|
||||
RestartKey( const std::string& _key, UnitSystem::measure _dim)
|
||||
: key(_key),
|
||||
|
||||
@@ -21,60 +21,58 @@
|
||||
#define OPM_OUTPUT_SUMMARY_HPP
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <ert/ecl/ecl_sum.h>
|
||||
|
||||
#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>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class EclipseGrid;
|
||||
class EclipseState;
|
||||
class Schedule;
|
||||
class SummaryConfig;
|
||||
class EclipseGrid;
|
||||
class Schedule;
|
||||
class SummaryState;
|
||||
} // namespace Opm
|
||||
|
||||
namespace out {
|
||||
namespace Opm { namespace data {
|
||||
class WellRates;
|
||||
}} // namespace Opm::data
|
||||
|
||||
namespace Opm { namespace out {
|
||||
|
||||
class Summary {
|
||||
public:
|
||||
Summary( const EclipseState&, const SummaryConfig&, const EclipseGrid&, const Schedule& );
|
||||
Summary( const EclipseState&, const SummaryConfig&, const EclipseGrid&, const Schedule&, const std::string& );
|
||||
Summary( const EclipseState&, const SummaryConfig&, const EclipseGrid&, const Schedule&, const char* basename );
|
||||
public:
|
||||
using GlobalProcessParameters = std::map<std::string, double>;
|
||||
using RegionParameters = std::map<std::string, std::vector<double>>;
|
||||
using BlockValues = std::map<std::pair<std::string, int>, double>;
|
||||
|
||||
void add_timestep(int report_step,
|
||||
double secs_elapsed,
|
||||
const EclipseState& es,
|
||||
const Schedule& schedule,
|
||||
const data::Wells&,
|
||||
const std::map<std::string, double>& single_values,
|
||||
const std::map<std::string, std::vector<double>>& region_values = {},
|
||||
const std::map<std::pair<std::string, int>, double>& block_values = {});
|
||||
Summary(const EclipseState& es,
|
||||
const SummaryConfig& sumcfg,
|
||||
const EclipseGrid& grid,
|
||||
const Schedule& sched,
|
||||
const std::string& basename = "");
|
||||
|
||||
void write();
|
||||
~Summary();
|
||||
|
||||
~Summary();
|
||||
void add_timestep(const SummaryState& st, const int report_step);
|
||||
|
||||
const SummaryState& get_restart_vectors() const;
|
||||
void eval(SummaryState& summary_state,
|
||||
const int report_step,
|
||||
const double secs_elapsed,
|
||||
const EclipseState& es,
|
||||
const Schedule& schedule,
|
||||
const data::WellRates& well_solution,
|
||||
const GlobalProcessParameters& single_values,
|
||||
const RegionParameters& region_values = {},
|
||||
const BlockValues& block_values = {}) const;
|
||||
|
||||
private:
|
||||
class keyword_handlers;
|
||||
void write() const;
|
||||
|
||||
const EclipseGrid& grid;
|
||||
out::RegionCache regionCache;
|
||||
ERT::ert_unique_ptr< ecl_sum_type, ecl_sum_free > ecl_sum;
|
||||
std::unique_ptr< keyword_handlers > handlers;
|
||||
double prev_time_elapsed = 0;
|
||||
SummaryState prev_state;
|
||||
private:
|
||||
class SummaryImplementation;
|
||||
std::unique_ptr<SummaryImplementation> pImpl_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}} // namespace Opm::out
|
||||
|
||||
#endif //OPM_OUTPUT_SUMMARY_HPP
|
||||
|
||||
@@ -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).
|
||||
@@ -22,11 +24,6 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <ert/ecl/FortIO.hpp>
|
||||
#include <ert/ecl/EclKW.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/PvtoTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/PvtgTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/FlatTable.hpp>
|
||||
|
||||
namespace Opm {
|
||||
@@ -37,11 +34,17 @@ namespace Opm {
|
||||
public:
|
||||
explicit Tables( const UnitSystem& units);
|
||||
|
||||
void addPVTO(const std::vector<PvtoTable>& pvtoTables);
|
||||
void addPVTG(const std::vector<PvtgTable>& pvtgTables);
|
||||
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,21 +104,31 @@ namespace Opm {
|
||||
const bool gas,
|
||||
const bool oil,
|
||||
const bool wat);
|
||||
};
|
||||
|
||||
/// Emit normalised tabular information (TABDIMS and TAB vectors) to
|
||||
/// ECL-like result set file (typically INIT file).
|
||||
///
|
||||
/// \param[in] tables Collection of normalised tables. Its \code
|
||||
/// tabdims() \endcode and \code tab() \endcode vectors will be
|
||||
/// emitted to \p fortio as ECL keywords "TABDIMS" and "TAB",
|
||||
/// respectively.
|
||||
///
|
||||
/// \param[in,out] fortio ECL-like result set file. Typically
|
||||
/// corresponds to a preopened stream attached to the INIT file.
|
||||
void fwrite(const Tables& tables,
|
||||
ERT::FortIO& fortio);
|
||||
/// 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);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
#endif // OUTPUT_TABLES_HPP
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
|
||||
|
||||
EffectiveKH = 3, // Effective Kh product of connection
|
||||
|
||||
item12 = 11, // Unknown
|
||||
item12 = 11, // Connection transmissibility factor
|
||||
|
||||
SegDistEnd = 20, // Distance to end of connection in segment
|
||||
SegDistStart = 21, // Distance to start of connection in segment
|
||||
@@ -66,6 +66,8 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
|
||||
WaterRate = 1, // Surface flow rate (water)
|
||||
GasRate = 2, // Surface Flow rate (gas)
|
||||
|
||||
Pressure = 34, // Connection pressure value
|
||||
|
||||
ResVRate = 49, // Reservoir voidage rate
|
||||
};
|
||||
} // XConn
|
||||
|
||||
40
opm/output/eclipse/VectorItems/doubhead.hpp
Normal file
40
opm/output/eclipse/VectorItems/doubhead.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
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
|
||||
UdqPar_2 = 212, // UDQPARAM item number 2 (Permitted range (+/-) of user-defined quantities)
|
||||
UdqPar_3 = 213, // UDQPARAM item number 3 (Value given to undefined elements when outputting data)
|
||||
UdqPar_4 = 214, // UDQPARAM item number 4 (fractional equality tolerance used in ==, <= etc. functions)
|
||||
};
|
||||
|
||||
}}}} // 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
|
||||
@@ -76,6 +76,8 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
|
||||
NSCAQZ = 46, // Number of data elements per aquifer connection in SCAQ array
|
||||
NACAQZ = 47, // Number of data elements per aquifer connection in ACAQ array
|
||||
|
||||
NWMAXZ = 163, // Maximum number of wells in the model
|
||||
|
||||
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)
|
||||
@@ -84,6 +86,7 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
|
||||
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
|
||||
UDQPAR_1 = 267, // Integer seed value for the RAND /
|
||||
};
|
||||
}}}} // Opm::RestartIO::Helpers::VectorItems
|
||||
|
||||
|
||||
48
opm/output/eclipse/VectorItems/logihead.hpp
Normal file
48
opm/output/eclipse/VectorItems/logihead.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
Copyright (c) 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_OUTPUT_ECLIPSE_VECTOR_LOGIHEAD_HPP
|
||||
#define OPM_OUTPUT_ECLIPSE_VECTOR_LOGIHEAD_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems {
|
||||
|
||||
// This is a subset of the items in src/opm/output/eclipse/LogiHEAD.cpp .
|
||||
// Promote items from that list to this in order to make them public.
|
||||
enum logihead : std::vector<bool>::size_type {
|
||||
IsLiveOil = 0, // Oil phase w/dissolved gas
|
||||
IsWetGas = 1, // Gas phase w/vaporised oil
|
||||
DirKr = 2, // Directional relative permeability
|
||||
E100RevKr = 3, // Reversible rel. perm. (E100)
|
||||
E100Radial = 4, // Radial model (E100)
|
||||
E300Radial = 3, // Radial model (E300, others)
|
||||
E300RevKr = 4, // Reversible rel. perm. (E300, others)
|
||||
Hyster = 6, // Enable hysteresis
|
||||
DualPoro = 14, // Enable dual porosity
|
||||
EndScale = 16, // Enable end-point scaling
|
||||
DirEPS = 17, // Directional end-point scaling
|
||||
RevEPS = 18, // Reversible end-point scaling
|
||||
AltEPS = 19, // Alternative (3-pt) end-point scaling
|
||||
ConstCo = 38, // Constant oil compressibility (PVCDO)
|
||||
HasMSWells = 75, // Whether or not model has MS Wells.
|
||||
};
|
||||
}}}} // Opm::RestartIO::Helpers::VectorItems
|
||||
|
||||
#endif // OPM_OUTPUT_ECLIPSE_VECTOR_LOGIHEAD_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
|
||||
76
opm/output/eclipse/VectorItems/tabdims.hpp
Normal file
76
opm/output/eclipse/VectorItems/tabdims.hpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Copyright (c) 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_OUTPUT_ECLIPSE_VECTOR_TABDIMS_HPP
|
||||
#define OPM_OUTPUT_ECLIPSE_VECTOR_TABDIMS_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems {
|
||||
|
||||
namespace TabDims {
|
||||
enum index : std::vector<int>::size_type {
|
||||
// Number of elements in 'TAB' array
|
||||
TabSize = 0,
|
||||
|
||||
// Oil PVT table
|
||||
PvtoMainStart = 6,
|
||||
PvtoCompStart = 7,
|
||||
NumPvtoCompNodes = 8,
|
||||
NumPvtoPressNodes = 9,
|
||||
NumPvtoTables = 10,
|
||||
|
||||
// Water PVT table
|
||||
PvtwStart = 11,
|
||||
NumPvtwTables = 12,
|
||||
|
||||
// Gas PVT tables
|
||||
PvtgMainStart = 13,
|
||||
PvtgPressStart = 14,
|
||||
NumPvtgCompNodes = 15,
|
||||
NumPvtgPressNodes = 16,
|
||||
NumPvtgTables = 17,
|
||||
|
||||
// Density tables
|
||||
DensityTableStart = 18,
|
||||
DensityNumTables = 19,
|
||||
|
||||
// SWFN tables
|
||||
SwfnTableStart = 20,
|
||||
SwfnNumSatNodes = 21,
|
||||
SwfnNumTables = 22,
|
||||
|
||||
// SGFN tables
|
||||
SgfnTableStart = 23,
|
||||
SgfnNumSatNodes = 24,
|
||||
SgfnNumTables = 25,
|
||||
|
||||
// SOFN tables
|
||||
SofnTableStart = 26,
|
||||
SofnNumSatNodes = 28,
|
||||
SofnNumTables = 29,
|
||||
|
||||
// Size of TABDIMS array
|
||||
TabDimsNumElems = 100,
|
||||
};
|
||||
} // namespace TabDims
|
||||
|
||||
}}}} // namespace Opm::RestartIO::Helpers::VectorItems
|
||||
|
||||
#endif // OPM_OUTPUT_ECLIPSE_VECTOR_TABDIMS_HPP
|
||||
@@ -26,25 +26,30 @@ 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
|
||||
WCtrl = 7, // Well control
|
||||
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
|
||||
item9 = 8, // Unknown
|
||||
item11 = 10, // Unknown
|
||||
VFPTab = 11, // ID (one-based) of well's current VFP table.
|
||||
|
||||
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
|
||||
item50 = 49, // Unknown
|
||||
|
||||
HistReqWCtrl = 49, // Well's requested control mode from
|
||||
// simulation deck (WCONHIST, WCONINJH)
|
||||
|
||||
MsWID = 70, // Multisegment well ID
|
||||
// Value 0 for regular wells
|
||||
@@ -115,6 +120,15 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
|
||||
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
|
||||
|
||||
@@ -141,13 +155,22 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
|
||||
|
||||
GasFVF = 34, // Well's producing gas formation volume factor.
|
||||
|
||||
item37 = 36, // Unknown
|
||||
item38 = 37, // Unknown
|
||||
item37 = 36, // Unknown
|
||||
item38 = 37, // Unknown
|
||||
|
||||
BHPTarget = 41, // Well's current BHP Target/Limit
|
||||
BHPTarget = 41, // Well's current BHP Target/Limit
|
||||
|
||||
item82 = 81, // Unknown
|
||||
item83 = 82, // Unknown
|
||||
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
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
#define OPM_WINDOWED_ARRAY_HPP
|
||||
|
||||
#include <cassert>
|
||||
#include <exception>
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
@@ -72,7 +74,10 @@ namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
explicit WindowedArray(const NumWindows n, const WindowSize sz)
|
||||
: x_ (n.value * sz.value)
|
||||
, windowSize_(sz.value)
|
||||
{}
|
||||
{
|
||||
if (sz.value == 0)
|
||||
throw std::invalid_argument("Window array with windowsize==0 is not permitted");
|
||||
}
|
||||
|
||||
/// Retrieve number of windows allocated for this array.
|
||||
Idx numWindows() const
|
||||
@@ -179,7 +184,10 @@ namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
const WindowSize& sz)
|
||||
: data_ (NumWindows{ nRows.value * nCols.value }, sz)
|
||||
, numCols_(nCols.value)
|
||||
{}
|
||||
{
|
||||
if (nCols.value == 0)
|
||||
throw std::invalid_argument("Window matrix with columns==0 is not permitted");
|
||||
}
|
||||
|
||||
/// Retrieve number of columns allocated for this matrix.
|
||||
Idx numCols() const
|
||||
|
||||
60
opm/output/eclipse/WriteInit.hpp
Normal file
60
opm/output/eclipse/WriteInit.hpp
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
Copyright (c) 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_WRITE_INIT_HPP
|
||||
#define OPM_WRITE_INIT_HPP
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class EclipseGrid;
|
||||
class EclipseState;
|
||||
class NNC;
|
||||
class Schedule;
|
||||
|
||||
} // namespace Opm
|
||||
|
||||
namespace Opm { namespace data {
|
||||
|
||||
class Solution;
|
||||
|
||||
}} // namespace Opm::data
|
||||
|
||||
namespace Opm { namespace EclIO { namespace OutputStream {
|
||||
|
||||
class Init;
|
||||
|
||||
}}} // namespace Opm::EclIO::OutputStream
|
||||
|
||||
namespace Opm { namespace InitIO {
|
||||
|
||||
void write(const ::Opm::EclipseState& es,
|
||||
const ::Opm::EclipseGrid& grid,
|
||||
const ::Opm::Schedule& schedule,
|
||||
const ::Opm::data::Solution& simProps,
|
||||
std::map<std::string, std::vector<int>> int_data,
|
||||
const ::Opm::NNC& nnc,
|
||||
::Opm::EclIO::OutputStream::Init& initFile);
|
||||
|
||||
}} // namespace Opm::InitIO
|
||||
|
||||
#endif // OPM_WRITE_INIT_HPP
|
||||
89
opm/output/eclipse/WriteRFT.hpp
Normal file
89
opm/output/eclipse/WriteRFT.hpp
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
Copyright (c) 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_WRITE_RFT_HPP
|
||||
#define OPM_WRITE_RFT_HPP
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class EclipseGrid;
|
||||
class Schedule;
|
||||
class UnitSystem;
|
||||
|
||||
} // namespace Opm
|
||||
|
||||
namespace Opm { namespace data {
|
||||
|
||||
class WellRates;
|
||||
|
||||
}} // namespace Opm::data
|
||||
|
||||
namespace Opm { namespace EclIO { namespace OutputStream {
|
||||
|
||||
class RFT;
|
||||
|
||||
}}} // namespace Opm::EclIO::OutputStream
|
||||
|
||||
namespace Opm { namespace RftIO {
|
||||
|
||||
/// Collect RFT data and output to pre-opened output stream.
|
||||
///
|
||||
/// RFT data is output for all affected wells at a given timestep,
|
||||
/// and consists of
|
||||
///
|
||||
/// 1) Time stamp (elapsed and date)
|
||||
/// 2) Metadata about the output (units of measure, well types,
|
||||
/// data type identifier)
|
||||
/// 3) Depth, pressure, Sw, Sg, (I,J,K), and hostgrid for each
|
||||
/// reservoir connection of the affected well.
|
||||
///
|
||||
/// If no RFT output is requested at given timestep, then this
|
||||
/// function returns with no output written to the RFT file.
|
||||
///
|
||||
/// \param[in] reportStep Report step time point for which to output
|
||||
/// RFT data.
|
||||
///
|
||||
/// \param[in] elapsed Number of seconds of simulated time until
|
||||
/// this report step (\p reportStep).
|
||||
///
|
||||
/// \param[in] usys Unit system conventions for output. Typically
|
||||
/// corresponds to run's active unit system (i.e., \code
|
||||
/// EclipseState::getUnits() \endcode).
|
||||
///
|
||||
/// \param[in] grid Run's active grid. Used to determine which
|
||||
/// reservoir connections are in active grid cells.
|
||||
///
|
||||
/// \param[in] schedule Run's SCHEDULE section from which to access
|
||||
/// the active wells and the RFT configuration.
|
||||
///
|
||||
/// \param[in,out] rftFile RFT output stream. On input, appropriately
|
||||
/// positioned for new content (i.e., at end-of-file). On output,
|
||||
/// containing new RFT output (if applicable) and positioned after
|
||||
/// new contents.
|
||||
void write(const int reportStep,
|
||||
const double elapsed,
|
||||
const ::Opm::UnitSystem& usys,
|
||||
const ::Opm::EclipseGrid& grid,
|
||||
const ::Opm::Schedule& schedule,
|
||||
const ::Opm::data::WellRates& wellSol,
|
||||
::Opm::EclIO::OutputStream::RFT& rftFile);
|
||||
|
||||
}} // namespace Opm::RftIO
|
||||
|
||||
#endif // OPM_WRITE_RFT_HPP
|
||||
@@ -36,6 +36,7 @@ namespace Opm {
|
||||
class Schedule;
|
||||
class Well;
|
||||
class UnitSystem;
|
||||
class UDQActive;
|
||||
|
||||
} // Opm
|
||||
|
||||
@@ -47,7 +48,8 @@ namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
createDoubHead(const EclipseState& es,
|
||||
const Schedule& sched,
|
||||
const std::size_t lookup_step,
|
||||
const double simTime);
|
||||
const double simTime,
|
||||
const double nextTimeStep);
|
||||
|
||||
|
||||
|
||||
@@ -62,17 +64,11 @@ namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
std::vector<bool>
|
||||
createLogiHead(const EclipseState& es);
|
||||
|
||||
std::vector<int>
|
||||
createUdqDims(const Schedule& sched,
|
||||
const std::size_t lookup_step,
|
||||
const std::vector<int>& inteHead);
|
||||
|
||||
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
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -124,10 +124,6 @@ namespace Opm {
|
||||
using iterator = std::vector< DeckKeyword >::iterator;
|
||||
|
||||
Deck();
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
Deck( std::initializer_list< DeckKeyword > );
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
Deck( std::initializer_list< std::string > );
|
||||
|
||||
Deck( const Deck& );
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <opm/parser/eclipse/Units/Dimension.hpp>
|
||||
#include <opm/parser/eclipse/Utility/Typetools.hpp>
|
||||
#include <opm/parser/eclipse/Deck/UDAValue.hpp>
|
||||
|
||||
namespace Opm {
|
||||
class DeckOutput;
|
||||
@@ -34,11 +35,10 @@ namespace Opm {
|
||||
class DeckItem {
|
||||
public:
|
||||
DeckItem() = default;
|
||||
explicit DeckItem( const std::string& );
|
||||
|
||||
DeckItem( const std::string&, int, size_t size_hint = 8 );
|
||||
DeckItem( const std::string&, double, size_t size_hint = 8 );
|
||||
DeckItem( const std::string&, std::string, size_t size_hint = 8 );
|
||||
DeckItem( const std::string&, int);
|
||||
DeckItem( const std::string&, double);
|
||||
DeckItem( const std::string&, std::string);
|
||||
DeckItem( const std::string&, UDAValue);
|
||||
|
||||
const std::string& name() const;
|
||||
|
||||
@@ -58,19 +58,23 @@ namespace Opm {
|
||||
size_t size() const;
|
||||
size_t out_size() const;
|
||||
|
||||
template< typename T > const T& get( size_t ) const;
|
||||
//template< typename T > T& get( size_t ) ;
|
||||
template< typename T > T get( size_t ) const;
|
||||
double getSIDouble( size_t ) const;
|
||||
std::string getTrimmedString( size_t ) const;
|
||||
|
||||
template< typename T > const std::vector< T >& getData() const;
|
||||
const std::vector< double >& getSIDoubleData() const;
|
||||
|
||||
void push_back( UDAValue );
|
||||
void push_back( int );
|
||||
void push_back( double );
|
||||
void push_back( std::string );
|
||||
void push_back( UDAValue, size_t );
|
||||
void push_back( int, size_t );
|
||||
void push_back( double, size_t );
|
||||
void push_back( std::string, size_t );
|
||||
void push_backDefault( UDAValue );
|
||||
void push_backDefault( int );
|
||||
void push_backDefault( double );
|
||||
void push_backDefault( std::string );
|
||||
@@ -105,19 +109,24 @@ 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;
|
||||
mutable std::vector< double > dval;
|
||||
std::vector< int > ival;
|
||||
std::vector< std::string > sval;
|
||||
std::vector< UDAValue > uval;
|
||||
|
||||
type_tag type = type_tag::unknown;
|
||||
|
||||
std::string item_name;
|
||||
std::vector< bool > defaulted;
|
||||
std::vector< Dimension > dimensions;
|
||||
mutable std::vector< double > SIdata;
|
||||
|
||||
/*
|
||||
To save space we mutate the dval object in place when asking for SI
|
||||
data; the current state of of the dval member is tracked with the
|
||||
raw_data bool member.
|
||||
*/
|
||||
mutable bool raw_data = true;
|
||||
template< typename T > std::vector< T >& value_ref();
|
||||
template< typename T > const std::vector< T >& value_ref() const;
|
||||
template< typename T > void push( T );
|
||||
|
||||
@@ -23,25 +23,36 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/ParserKeyword.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckValue.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
|
||||
|
||||
namespace Opm {
|
||||
class ParserKeyword;
|
||||
class DeckOutput;
|
||||
class ParserKeyword;
|
||||
|
||||
class DeckKeyword {
|
||||
public:
|
||||
typedef std::vector< DeckRecord >::const_iterator const_iterator;
|
||||
|
||||
explicit DeckKeyword(const std::string& keywordName);
|
||||
DeckKeyword(const std::string& keywordName, bool knownKeyword);
|
||||
explicit DeckKeyword(const ParserKeyword& parserKeyword);
|
||||
|
||||
DeckKeyword(const ParserKeyword& parserKeyword, const std::string& keywordName);
|
||||
|
||||
DeckKeyword(const ParserKeyword& parserKeyword, const std::vector<std::vector<DeckValue>>& record_list);
|
||||
|
||||
DeckKeyword(const ParserKeyword& parserKeyword, const std::vector<int>& data);
|
||||
DeckKeyword(const ParserKeyword& parserKeyword, const std::vector<double>& data);
|
||||
|
||||
const std::string& name() const;
|
||||
void setFixedSize();
|
||||
void setLocation(const std::string& fileName, int lineNumber);
|
||||
void setLocation(const std::pair<const std::string&, std::size_t>& location);
|
||||
const std::string& getFileName() const;
|
||||
int getLineNumber() const;
|
||||
std::pair<std::string, std::size_t> location() const;
|
||||
|
||||
|
||||
size_t size() const;
|
||||
void addRecord(DeckRecord&& record);
|
||||
@@ -49,13 +60,13 @@ namespace Opm {
|
||||
DeckRecord& getRecord(size_t index);
|
||||
const DeckRecord& getDataRecord() const;
|
||||
void setDataKeyword(bool isDataKeyword = true);
|
||||
bool isKnown() const;
|
||||
bool isDataKeyword() const;
|
||||
|
||||
const std::vector<int>& getIntData() const;
|
||||
const std::vector<double>& getRawDoubleData() const;
|
||||
const std::vector<double>& getSIDoubleData() const;
|
||||
const std::vector<std::string>& getStringData() const;
|
||||
const ParserKeyword& parserKeyword() const;
|
||||
size_t getDataSize() const;
|
||||
void write( DeckOutput& output ) const;
|
||||
void write_data( DeckOutput& output ) const;
|
||||
@@ -83,9 +94,9 @@ namespace Opm {
|
||||
int m_lineNumber;
|
||||
|
||||
std::vector< DeckRecord > m_recordList;
|
||||
bool m_knownKeyword;
|
||||
bool m_isDataKeyword;
|
||||
bool m_slashTerminated;
|
||||
ParserKeyword parser_keyword;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
58
opm/parser/eclipse/Deck/DeckValue.hpp
Normal file
58
opm/parser/eclipse/Deck/DeckValue.hpp
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
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 DECK_VALUE_HPP
|
||||
#define DECK_VALUE_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <opm/parser/eclipse/Utility/Typetools.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class DeckValue {
|
||||
|
||||
public:
|
||||
DeckValue();
|
||||
explicit DeckValue(int);
|
||||
explicit DeckValue(double);
|
||||
explicit DeckValue(const std::string&);
|
||||
|
||||
bool is_default() const;
|
||||
|
||||
template<typename T>
|
||||
T get() const;
|
||||
|
||||
template<typename T>
|
||||
bool is_compatible() const;
|
||||
|
||||
private:
|
||||
|
||||
bool default_value;
|
||||
type_tag value_enum;
|
||||
int int_value;
|
||||
double double_value;
|
||||
std::string string_value;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
69
opm/parser/eclipse/Deck/UDAValue.hpp
Normal file
69
opm/parser/eclipse/Deck/UDAValue.hpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
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 UDA_VALUE_HPP
|
||||
#define UDA_VALUE_HPP
|
||||
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
|
||||
#include <opm/parser/eclipse/Units/Dimension.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class UDAValue {
|
||||
public:
|
||||
UDAValue();
|
||||
explicit UDAValue(double);
|
||||
explicit UDAValue(const std::string&);
|
||||
|
||||
template<typename T>
|
||||
T get() const;
|
||||
|
||||
template<typename T>
|
||||
bool is() const;
|
||||
|
||||
void reset(double value);
|
||||
void reset(const std::string& value);
|
||||
|
||||
void assert_numeric() const;
|
||||
void assert_numeric(const std::string& error_msg) const;
|
||||
void set_dim(const Dimension& dim) const;
|
||||
const Dimension& get_dim() const;
|
||||
|
||||
bool operator==(const UDAValue& other) const;
|
||||
bool operator!=(const UDAValue& other) const;
|
||||
private:
|
||||
bool numeric_value;
|
||||
double double_value;
|
||||
std::string string_value;
|
||||
|
||||
/* This 'mutable' modifier is a hack to avoid tampering with the overall
|
||||
const-ness of the data in a deck item. */
|
||||
mutable Dimension dim;
|
||||
};
|
||||
|
||||
std::ostream& operator<<( std::ostream& stream, const UDAValue& uda_value );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -53,13 +53,13 @@ namespace Opm {
|
||||
Aquancon(const EclipseGrid& grid, const Deck& deck);
|
||||
|
||||
const std::vector<Aquancon::AquanconOutput>& getAquOutput() const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
std::vector<Aquancon::AquanconOutput> logic_application(const std::vector<Aquancon::AquanconOutput> original_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,21 +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>
|
||||
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class EclipseState;
|
||||
|
||||
class AquiferCT {
|
||||
public:
|
||||
|
||||
@@ -70,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_;
|
||||
|
||||
@@ -77,7 +77,8 @@ namespace Opm {
|
||||
const EclipseGrid& eclipseGrid);
|
||||
|
||||
void scanSection(const Section& section,
|
||||
const EclipseGrid& eclipseGrid);
|
||||
const EclipseGrid& eclipseGrid,
|
||||
bool edit_section);
|
||||
|
||||
void handleADDKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager);
|
||||
void handleBOXKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager);
|
||||
@@ -96,7 +97,10 @@ namespace Opm {
|
||||
void handleOPERATERKeyword( const DeckKeyword& deckKeyword);
|
||||
|
||||
void loadGridPropertyFromDeckKeyword(const Box& inputBox,
|
||||
const DeckKeyword& deckKeyword);
|
||||
const DeckKeyword& deckKeyword,
|
||||
bool edity_section);
|
||||
|
||||
void adjustSOGCRwithSWL();
|
||||
|
||||
std::string m_defaultRegion;
|
||||
UnitSystem m_deckUnitSystem;
|
||||
|
||||
@@ -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,6 +23,8 @@
|
||||
#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>
|
||||
@@ -32,7 +34,6 @@
|
||||
#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 {
|
||||
@@ -65,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();
|
||||
|
||||
@@ -118,7 +121,6 @@ namespace Opm {
|
||||
void complainAboutAmbiguousKeyword(const Deck& deck,
|
||||
const std::string& keywordName);
|
||||
|
||||
ParseContext m_parseContext;
|
||||
const TableManager m_tables;
|
||||
Runspec m_runspec;
|
||||
EclipseConfig m_eclipseConfig;
|
||||
|
||||
@@ -25,23 +25,24 @@
|
||||
#include <cstddef>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class EclipseGrid;
|
||||
class Box {
|
||||
public:
|
||||
Box() = default;
|
||||
Box(int nx , int ny , int nz);
|
||||
Box(const Box& globalBox , int i1 , int i2 , int j1 , int j2 , int k1 , int k2); // Zero offset coordinates.
|
||||
Box(int nx, int ny, int nz, int i1 , int i2 , int j1 , int j2 , int k1 , int k2);
|
||||
|
||||
struct index_pair {
|
||||
std::size_t global;
|
||||
std::size_t active;
|
||||
};
|
||||
|
||||
Box(const EclipseGrid& grid);
|
||||
Box(const EclipseGrid& grid , int i1 , int i2 , int j1 , int j2 , int k1 , int k2);
|
||||
size_t size() const;
|
||||
bool isGlobal() const;
|
||||
size_t getDim(size_t idim) const;
|
||||
const std::vector<index_pair>& index_list() const;
|
||||
const std::vector<size_t>& getIndexList() const;
|
||||
bool equal(const Box& other) const;
|
||||
|
||||
explicit operator bool() const;
|
||||
std::vector<size_t>::const_iterator begin() const;
|
||||
std::vector<size_t>::const_iterator end() const;
|
||||
|
||||
|
||||
int I1() const;
|
||||
int I2() const;
|
||||
@@ -52,12 +53,14 @@ namespace Opm {
|
||||
|
||||
private:
|
||||
void initIndexList();
|
||||
const EclipseGrid& grid;
|
||||
size_t m_dims[3] = { 0, 0, 0 };
|
||||
size_t m_offset[3];
|
||||
size_t m_stride[3];
|
||||
|
||||
bool m_isGlobal;
|
||||
std::vector<size_t> m_indexList;
|
||||
std::vector<size_t> global_index_list;
|
||||
std::vector<index_pair> m_index_list;
|
||||
|
||||
int lower(int dim) const;
|
||||
int upper(int dim) const;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/Box.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
|
||||
/*
|
||||
This class implements a simple book keeping system for the current
|
||||
@@ -53,7 +54,7 @@ namespace Opm {
|
||||
|
||||
class BoxManager {
|
||||
public:
|
||||
BoxManager(int nx , int ny , int nz);
|
||||
BoxManager(const EclipseGrid& grid);
|
||||
|
||||
void setInputBox( int i1,int i2 , int j1 , int j2 , int k1 , int k2);
|
||||
void setKeywordBox( int i1,int i2 , int j1 , int j2 , int k1 , int k2);
|
||||
@@ -63,14 +64,12 @@ namespace Opm {
|
||||
void endKeyword();
|
||||
|
||||
const Box& getActiveBox() const;
|
||||
const Box& getGlobalBox() const;
|
||||
const Box& getInputBox() const;
|
||||
const Box& getKeywordBox() const;
|
||||
|
||||
private:
|
||||
Box m_globalBox;
|
||||
Box m_inputBox;
|
||||
Box m_keywordBox;
|
||||
const EclipseGrid& grid;
|
||||
std::unique_ptr<Box> m_globalBox;
|
||||
std::unique_ptr<Box> m_inputBox;
|
||||
std::unique_ptr<Box> m_keywordBox;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/MinpvMode.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/PinchMode.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/GridDims.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/NNC.hpp>
|
||||
|
||||
#include <ert/ecl/ecl_grid.h>
|
||||
#include <ert/util/ert_unique_ptr.hpp>
|
||||
#include <opm/io/eclipse/EclFile.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
@@ -59,9 +59,9 @@ namespace Opm {
|
||||
These constructors will make a copy of the src grid, with
|
||||
zcorn and or actnum have been adjustments.
|
||||
*/
|
||||
EclipseGrid(const EclipseGrid& src, const double* zcorn , const std::vector<int>& actnum);
|
||||
EclipseGrid(const EclipseGrid& src, const std::vector<double>& zcorn , const std::vector<int>& actnum);
|
||||
EclipseGrid(const EclipseGrid& src) = default;
|
||||
EclipseGrid(const EclipseGrid& src, const std::vector<int>& actnum);
|
||||
EclipseGrid(const EclipseGrid& src, const double* zcorn, const std::vector<int>& actnum);
|
||||
|
||||
EclipseGrid(size_t nx, size_t ny, size_t nz,
|
||||
double dx = 1.0, double dy = 1.0, double dz = 1.0);
|
||||
@@ -77,7 +77,6 @@ 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&);
|
||||
@@ -88,8 +87,7 @@ 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);
|
||||
void save(const std::string& filename, bool formatted, const Opm::NNC& nnc, const Opm::UnitSystem& units) const;
|
||||
/*
|
||||
Observe that the there is a getGlobalIndex(i,j,k)
|
||||
implementation in the base class. This method - translating
|
||||
@@ -105,6 +103,7 @@ namespace Opm {
|
||||
applied in the 'THETA' direction; this will only apply if
|
||||
the theta keywords entered sum up to exactly 360 degrees!
|
||||
*/
|
||||
|
||||
bool circle( ) const;
|
||||
bool isPinchActive( ) const;
|
||||
double getPinchThresholdThickness( ) const;
|
||||
@@ -114,7 +113,6 @@ namespace Opm {
|
||||
MinpvMode::ModeEnum getMinpvMode() const;
|
||||
const std::vector<double>& getMinpvVector( ) const;
|
||||
|
||||
|
||||
/*
|
||||
Will return a vector of nactive elements. The method will
|
||||
behave differently depending on the lenght of the
|
||||
@@ -127,6 +125,7 @@ namespace Opm {
|
||||
|
||||
??? : Exception.
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
std::vector<T> compressedVector(const std::vector<T>& input_vector) const {
|
||||
if( input_vector.size() == this->getNumActive() ) {
|
||||
@@ -151,13 +150,13 @@ namespace Opm {
|
||||
/// Will return a vector a length num_active; where the value
|
||||
/// of each element is the corresponding global index.
|
||||
const std::vector<int>& getActiveMap() const;
|
||||
std::array<double, 3> getCellCenter(size_t i,size_t j, size_t k) const;
|
||||
std::array<double, 3> getCellCenter(size_t globalIndex) const;
|
||||
const std::array<double, 3>& getCellCenter(size_t i,size_t j, size_t k) const;
|
||||
const std::array<double, 3>& getCellCenter(size_t globalIndex) const;
|
||||
std::array<double, 3> getCornerPos(size_t i,size_t j, size_t k, size_t corner_index) const;
|
||||
double getCellVolume(size_t globalIndex) const;
|
||||
double getCellVolume(size_t i , size_t j , size_t k) const;
|
||||
double getCellThicknes(size_t globalIndex) const;
|
||||
double getCellThicknes(size_t i , size_t j , size_t k) const;
|
||||
double getCellThickness(size_t globalIndex) const;
|
||||
double getCellThickness(size_t i , size_t j , size_t k) const;
|
||||
std::array<double, 3> getCellDims(size_t i,size_t j, size_t k) const;
|
||||
std::array<double, 3> getCellDims(size_t globalIndex) const;
|
||||
bool cellActive( size_t globalIndex ) const;
|
||||
@@ -166,19 +165,28 @@ namespace Opm {
|
||||
double getCellDepth(size_t globalIndex) const;
|
||||
ZcornMapper zcornMapper() const;
|
||||
|
||||
const std::vector<double>& getCOORD() const;
|
||||
const std::vector<double>& getZCORN() const;
|
||||
const std::vector<int>& getACTNUM( ) const;
|
||||
const std::vector<double>& getMAPAXES() const;
|
||||
const std::string& getMAPUNITS() const { return m_mapunits; } ;
|
||||
|
||||
/*
|
||||
The exportZCORN method will adjust the z coordinates to ensure that cells do not
|
||||
overlap. The return value is the number of points which have been adjusted.
|
||||
The fixupZCORN method is run as part of constructiong the grid. This will adjust the
|
||||
z-coordinates to ensure that cells do not overlap. The return value is the number of
|
||||
points which have been adjusted. The number of zcorn nodes that has ben fixed is
|
||||
stored in private member zcorn_fixed.
|
||||
*/
|
||||
size_t exportZCORN( std::vector<double>& zcorn) const;
|
||||
|
||||
size_t fixupZCORN();
|
||||
size_t getZcornFixed() { return zcorn_fixed; };
|
||||
|
||||
// resetACTNUM with no arguments will make all cells in the grid active.
|
||||
|
||||
void resetACTNUM();
|
||||
void resetACTNUM( const std::vector<int>& actnum);
|
||||
|
||||
void exportMAPAXES( std::vector<double>& mapaxes) const;
|
||||
void exportCOORD( std::vector<double>& coord) const;
|
||||
void exportACTNUM( std::vector<int>& actnum) const;
|
||||
void resetACTNUM( const int * actnum);
|
||||
bool equal(const EclipseGrid& other) const;
|
||||
const ecl_grid_type * c_ptr() const;
|
||||
|
||||
private:
|
||||
std::vector<double> m_minpvVector;
|
||||
@@ -186,25 +194,35 @@ namespace Opm {
|
||||
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
|
||||
that the EclipseGrid class can now use the default
|
||||
implementation for the copy and move constructors.
|
||||
*/
|
||||
using ert_ptr = ERT::ert_unique_ptr<ecl_grid_type , ecl_grid_free>;
|
||||
class grid_ptr : public ert_ptr {
|
||||
public:
|
||||
using ert_ptr::unique_ptr;
|
||||
grid_ptr() = default;
|
||||
grid_ptr(grid_ptr&&) = default;
|
||||
grid_ptr(const grid_ptr& src) :
|
||||
ert_ptr( ecl_grid_alloc_copy( src.get() ) ) {}
|
||||
};
|
||||
grid_ptr m_grid;
|
||||
|
||||
size_t zcorn_fixed = 0;
|
||||
bool m_useActnumFromGdfile = false;
|
||||
|
||||
// Input grid data.
|
||||
std::vector<double> m_zcorn;
|
||||
std::vector<double> m_coord;
|
||||
std::vector<double> m_mapaxes;
|
||||
std::vector<int> m_actnum;
|
||||
std::string m_mapunits;
|
||||
|
||||
// Mapping to/from active cells.
|
||||
int m_nactive;
|
||||
std::vector<int> m_active_to_global;
|
||||
std::vector<int> m_global_to_active;
|
||||
|
||||
// Geometry data.
|
||||
std::vector<double> m_volume;
|
||||
std::vector<double> m_depth;
|
||||
std::vector<double> m_dx;
|
||||
std::vector<double> m_dy;
|
||||
std::vector<double> m_dz;
|
||||
std::vector<std::array<double, 3>> m_cellCenter;
|
||||
|
||||
void initGridFromEGridFile(Opm::EclIO::EclFile& egridfile, std::string fileName);
|
||||
|
||||
void initBinaryGrid(const Deck& deck);
|
||||
|
||||
void initCornerPointGrid(const std::array<int,3>& dims ,
|
||||
@@ -213,6 +231,8 @@ namespace Opm {
|
||||
const int * actnum,
|
||||
const double * mapaxes);
|
||||
|
||||
bool keywInputBeforeGdfile(const Deck& deck, const std::string keyword) const;
|
||||
|
||||
void initCylindricalGrid( const std::array<int, 3>&, const Deck&);
|
||||
void initCartesianGrid( const std::array<int, 3>&, const Deck&);
|
||||
void initCornerPointGrid( const std::array<int, 3>&, const Deck&);
|
||||
@@ -229,6 +249,20 @@ namespace Opm {
|
||||
static std::vector<double> createDVector(const std::array<int, 3>& dims, size_t dim, const std::string& DKey,
|
||||
const std::string& DVKey, const Deck&);
|
||||
static void scatterDim(const std::array<int, 3>& dims , size_t dim , const std::vector<double>& DV , std::vector<double>& D);
|
||||
|
||||
|
||||
std::vector<double> makeCoordDxDyDzTops(const std::array<int, 3>& dims, const std::vector<double>& dx, const std::vector<double>& dy, const std::vector<double>& dz, const std::vector<double>& tops) const;
|
||||
std::vector<double> makeZcornDzTops(const std::array<int, 3>& dims, const std::vector<double>& dz, const std::vector<double>& tops) const ;
|
||||
std::vector<double> makeZcornDzvDepthz(const std::array<int, 3>& dims, const std::vector<double>& dzv, const std::vector<double>& depthz) const;
|
||||
std::vector<double> makeCoordDxvDyvDzvDepthz(const std::array<int, 3>& dims, const std::vector<double>& dxv, const std::vector<double>& dyv, const std::vector<double>& dzv, const std::vector<double>& depthz) const;
|
||||
|
||||
double sumIdir(int j, int k, int i1, const std::array<int, 3>& dims, const std::vector<double>& dx) const;
|
||||
double sumJdir(int i, int k, int j1, const std::array<int, 3>& dims, const std::vector<double>& dy) const;
|
||||
double sumKdir(int i, int j, const std::array<int, 3>& dims, const std::vector<double>& dz) const;
|
||||
|
||||
void calculateGeometryData();
|
||||
|
||||
void getCellCorners(const std::array<int, 3>& ijk, const std::array<int, 3>& dims, std::array<double,8>& X, std::array<double,8>& Y, std::array<double,8>& Z) const;
|
||||
};
|
||||
|
||||
class CoordMapper {
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user