completor 1.1.2__py3-none-any.whl → 1.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- completor/completion.py +14 -3
- completor/constants.py +25 -6
- completor/create_output.py +51 -27
- completor/input_validation.py +58 -9
- completor/prepare_outputs.py +325 -104
- completor/read_casefile.py +125 -53
- completor/utils.py +3 -2
- completor/visualize_well.py +4 -2
- completor/wells.py +6 -4
- {completor-1.1.2.dist-info → completor-1.2.0.dist-info}/METADATA +15 -13
- {completor-1.1.2.dist-info → completor-1.2.0.dist-info}/RECORD +14 -14
- {completor-1.1.2.dist-info → completor-1.2.0.dist-info}/LICENSE +0 -0
- {completor-1.1.2.dist-info → completor-1.2.0.dist-info}/WHEEL +0 -0
- {completor-1.1.2.dist-info → completor-1.2.0.dist-info}/entry_points.txt +0 -0
completor/prepare_outputs.py
CHANGED
|
@@ -120,6 +120,7 @@ def dataframe_tostring(
|
|
|
120
120
|
"END_MD": "{:.3f}".format,
|
|
121
121
|
Headers.FLOW_COEFFICIENT: "{:.10g}".format,
|
|
122
122
|
"CV": "{:.10g}".format,
|
|
123
|
+
Headers.CROSS: "{:.3e}".format,
|
|
123
124
|
Headers.FLOW_CROSS_SECTIONAL_AREA: "{:.3e}".format,
|
|
124
125
|
"FLOW_CROSS_SECTIONAL_AREA": "{:.3e}".format,
|
|
125
126
|
Headers.OIL_FLOW_CROSS_SECTIONAL_AREA: "{:.3e}".format,
|
|
@@ -135,6 +136,13 @@ def dataframe_tostring(
|
|
|
135
136
|
Headers.ALPHA_PILOT: "{:.10g}".format,
|
|
136
137
|
}
|
|
137
138
|
|
|
139
|
+
# Cast floats to str befor headers are messed up (pandas formatter does not work reliably with MultiIndex headers).
|
|
140
|
+
for column, formatter in formatters.items():
|
|
141
|
+
try:
|
|
142
|
+
df_temp[column] = df_temp[column].map(formatter)
|
|
143
|
+
except (KeyError, ValueError):
|
|
144
|
+
pass
|
|
145
|
+
|
|
138
146
|
if header:
|
|
139
147
|
# Modify headers to reduce width.
|
|
140
148
|
column_splits = [tuple(column.split("_")) for column in df_temp.columns]
|
|
@@ -173,9 +181,7 @@ def dataframe_tostring(
|
|
|
173
181
|
df_temp.columns = pd.MultiIndex.from_frame(new_cols)
|
|
174
182
|
|
|
175
183
|
try:
|
|
176
|
-
output_string = df_temp.to_string(
|
|
177
|
-
index=False, justify="justify", formatters=formatters, header=header, sparsify=False
|
|
178
|
-
)
|
|
184
|
+
output_string = df_temp.to_string(index=False, justify="justify", header=header, sparsify=False)
|
|
179
185
|
except ValueError:
|
|
180
186
|
if df_temp.isnull().values.any():
|
|
181
187
|
raise CompletorError("Got NaN values in table, please report if encountered!")
|
|
@@ -184,18 +190,14 @@ def dataframe_tostring(
|
|
|
184
190
|
df_temp = df_temp.replace("1*", np.nan, inplace=False)
|
|
185
191
|
# Probably find columns where this is the case and cast to numeric after replacing with nan?
|
|
186
192
|
df_temp[columns_with_1_star] = df_temp[columns_with_1_star].astype(np.float64, errors="ignore")
|
|
187
|
-
output_string = df_temp.to_string(
|
|
188
|
-
index=False, justify="justify", formatters=formatters, header=header, sparsify=False, na_rep="1*"
|
|
189
|
-
)
|
|
193
|
+
output_string = df_temp.to_string(index=False, justify="justify", header=header, sparsify=False, na_rep="1*")
|
|
190
194
|
|
|
191
195
|
if output_string is None:
|
|
192
196
|
return ""
|
|
193
197
|
|
|
194
198
|
too_long_lines = check_width_lines(output_string, limit)
|
|
195
199
|
if too_long_lines:
|
|
196
|
-
output_string = df_temp.to_string(
|
|
197
|
-
index=False, justify="left", formatters=formatters, header=header, sparsify=False
|
|
198
|
-
)
|
|
200
|
+
output_string = df_temp.to_string(index=False, justify="left", header=header, sparsify=False)
|
|
199
201
|
if output_string is None:
|
|
200
202
|
return ""
|
|
201
203
|
too_long_lines2 = check_width_lines(output_string, limit)
|
|
@@ -448,13 +450,17 @@ def prepare_device_layer(df_well: pd.DataFrame, df_tubing: pd.DataFrame, device_
|
|
|
448
450
|
df_well[Headers.DEVICE_TYPE] == Content.VALVE,
|
|
449
451
|
"/ -- Valve types",
|
|
450
452
|
np.where(
|
|
451
|
-
df_well[Headers.DEVICE_TYPE] == Content.
|
|
452
|
-
"/ --
|
|
453
|
+
df_well[Headers.DEVICE_TYPE] == Content.DENSITY,
|
|
454
|
+
"/ -- DENSITY types",
|
|
453
455
|
np.where(
|
|
454
|
-
df_well[Headers.DEVICE_TYPE] == Content.
|
|
455
|
-
"/ --
|
|
456
|
+
df_well[Headers.DEVICE_TYPE] == Content.DUAL_RATE_CONTROLLED_PRODUCTION,
|
|
457
|
+
"/ -- DUALRCP types",
|
|
456
458
|
np.where(
|
|
457
|
-
df_well[Headers.DEVICE_TYPE] == Content.
|
|
459
|
+
df_well[Headers.DEVICE_TYPE] == Content.INJECTION_VALVE,
|
|
460
|
+
"/ -- INJV types",
|
|
461
|
+
np.where(
|
|
462
|
+
df_well[Headers.DEVICE_TYPE] == Content.INFLOW_CONTROL_VALVE, "/ -- ICV types", ""
|
|
463
|
+
),
|
|
458
464
|
),
|
|
459
465
|
),
|
|
460
466
|
),
|
|
@@ -852,6 +858,7 @@ def prepare_completion_segments(
|
|
|
852
858
|
}
|
|
853
859
|
)
|
|
854
860
|
compseg[Headers.EMPTY] = "/"
|
|
861
|
+
compseg.sort_values(Headers.START_MEASURED_DEPTH, inplace=True)
|
|
855
862
|
return compseg
|
|
856
863
|
|
|
857
864
|
|
|
@@ -1067,6 +1074,8 @@ def prepare_autonomous_inflow_control_device(
|
|
|
1067
1074
|
wsegaicd[Headers.D] = df_merge[Headers.D].to_numpy()
|
|
1068
1075
|
wsegaicd[Headers.E] = df_merge[Headers.E].to_numpy()
|
|
1069
1076
|
wsegaicd[Headers.F] = df_merge[Headers.F].to_numpy()
|
|
1077
|
+
if Headers.Z in df_merge.columns:
|
|
1078
|
+
wsegaicd[Headers.Z] = df_merge[Headers.Z].to_numpy()
|
|
1070
1079
|
wsegaicd[Headers.EMPTY] = "/"
|
|
1071
1080
|
return wsegaicd
|
|
1072
1081
|
|
|
@@ -1249,8 +1258,8 @@ def prepare_inflow_control_valve(
|
|
|
1249
1258
|
return wsegicv
|
|
1250
1259
|
|
|
1251
1260
|
|
|
1252
|
-
def
|
|
1253
|
-
"""Prepare data frame for
|
|
1261
|
+
def prepare_density_driven(well_name: str, df_well: pd.DataFrame, df_device: pd.DataFrame) -> pd.DataFrame:
|
|
1262
|
+
"""Prepare data frame for DENSITY.
|
|
1254
1263
|
|
|
1255
1264
|
Args:
|
|
1256
1265
|
well_name: Well name.
|
|
@@ -1258,7 +1267,7 @@ def prepare_density_activated_recovery(well_name: str, df_well: pd.DataFrame, df
|
|
|
1258
1267
|
df_device: Device data for this well and lateral.
|
|
1259
1268
|
|
|
1260
1269
|
Returns:
|
|
1261
|
-
DataFrame for
|
|
1270
|
+
DataFrame for DENSITY.
|
|
1262
1271
|
"""
|
|
1263
1272
|
df_well = df_well[(df_well[Headers.DEVICE_TYPE] == Content.PERFORATED) | (df_well[Headers.NUMBER_OF_DEVICES] > 0)]
|
|
1264
1273
|
if df_well.shape[0] == 0:
|
|
@@ -1270,34 +1279,84 @@ def prepare_density_activated_recovery(well_name: str, df_well: pd.DataFrame, df
|
|
|
1270
1279
|
right_on=[Headers.TUBING_MEASURED_DEPTH],
|
|
1271
1280
|
direction="nearest",
|
|
1272
1281
|
)
|
|
1273
|
-
df_merge = df_merge[df_merge[Headers.DEVICE_TYPE] == Content.
|
|
1274
|
-
|
|
1282
|
+
df_merge = df_merge[df_merge[Headers.DEVICE_TYPE] == Content.DENSITY]
|
|
1283
|
+
wsegdensity = pd.DataFrame()
|
|
1275
1284
|
if df_merge.shape[0] > 0:
|
|
1276
|
-
|
|
1277
|
-
|
|
1285
|
+
wsegdensity[Headers.WELL] = [well_name] * df_merge.shape[0]
|
|
1286
|
+
wsegdensity[Headers.START_SEGMENT_NUMBER] = df_merge[Headers.START_SEGMENT_NUMBER].to_numpy()
|
|
1278
1287
|
# the Cv is already corrected by the scaling factor
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1288
|
+
wsegdensity[Headers.FLOW_COEFFICIENT] = df_merge[Headers.FLOW_COEFFICIENT].to_numpy()
|
|
1289
|
+
wsegdensity[Headers.OIL_FLOW_CROSS_SECTIONAL_AREA] = df_merge[Headers.OIL_FLOW_CROSS_SECTIONAL_AREA].to_numpy()
|
|
1290
|
+
wsegdensity[Headers.GAS_FLOW_CROSS_SECTIONAL_AREA] = df_merge[Headers.GAS_FLOW_CROSS_SECTIONAL_AREA].to_numpy()
|
|
1291
|
+
wsegdensity[Headers.WATER_FLOW_CROSS_SECTIONAL_AREA] = df_merge[
|
|
1292
|
+
Headers.WATER_FLOW_CROSS_SECTIONAL_AREA
|
|
1293
|
+
].to_numpy()
|
|
1294
|
+
wsegdensity[Headers.WATER_HOLDUP_FRACTION_LOW_CUTOFF] = df_merge[
|
|
1284
1295
|
Headers.WATER_HOLDUP_FRACTION_LOW_CUTOFF
|
|
1285
1296
|
].to_numpy()
|
|
1286
|
-
|
|
1297
|
+
wsegdensity[Headers.WATER_HOLDUP_FRACTION_HIGH_CUTOFF] = df_merge[
|
|
1287
1298
|
Headers.WATER_HOLDUP_FRACTION_HIGH_CUTOFF
|
|
1288
1299
|
].to_numpy()
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1300
|
+
wsegdensity[Headers.GAS_HOLDUP_FRACTION_LOW_CUTOFF] = df_merge[
|
|
1301
|
+
Headers.GAS_HOLDUP_FRACTION_LOW_CUTOFF
|
|
1302
|
+
].to_numpy()
|
|
1303
|
+
wsegdensity[Headers.GAS_HOLDUP_FRACTION_HIGH_CUTOFF] = df_merge[
|
|
1304
|
+
Headers.GAS_HOLDUP_FRACTION_HIGH_CUTOFF
|
|
1305
|
+
].to_numpy()
|
|
1306
|
+
wsegdensity[Headers.DEFAULTS] = "5*"
|
|
1307
|
+
wsegdensity[Headers.MAX_FLOW_CROSS_SECTIONAL_AREA] = wsegdensity[
|
|
1308
|
+
Headers.OIL_FLOW_CROSS_SECTIONAL_AREA
|
|
1309
|
+
].to_numpy()
|
|
1310
|
+
wsegdensity[Headers.EMPTY] = "/"
|
|
1311
|
+
return wsegdensity
|
|
1295
1312
|
|
|
1296
1313
|
|
|
1297
|
-
def
|
|
1314
|
+
def prepare_injection_valve(well_name: str, df_well: pd.DataFrame, df_device: pd.DataFrame) -> pd.DataFrame:
|
|
1315
|
+
"""Prepare data frame for INJECTION VALVE.
|
|
1316
|
+
|
|
1317
|
+
Args:
|
|
1318
|
+
well_name: Well name.
|
|
1319
|
+
df_well: Well data.
|
|
1320
|
+
df_device: Device data for this well and lateral.
|
|
1321
|
+
|
|
1322
|
+
Returns:
|
|
1323
|
+
DataFrame for INJECTION VALVE.
|
|
1324
|
+
"""
|
|
1325
|
+
df_well = df_well[(df_well[Headers.DEVICE_TYPE] == Content.PERFORATED) | (df_well[Headers.NUMBER_OF_DEVICES] > 0)]
|
|
1326
|
+
if df_well.shape[0] == 0:
|
|
1327
|
+
return pd.DataFrame()
|
|
1328
|
+
df_merge = pd.merge_asof(
|
|
1329
|
+
left=df_device,
|
|
1330
|
+
right=df_well,
|
|
1331
|
+
left_on=[Headers.MEASURED_DEPTH],
|
|
1332
|
+
right_on=[Headers.TUBING_MEASURED_DEPTH],
|
|
1333
|
+
direction="nearest",
|
|
1334
|
+
)
|
|
1335
|
+
df_merge = df_merge[df_merge[Headers.DEVICE_TYPE] == Content.INJECTION_VALVE]
|
|
1336
|
+
wseginjv = pd.DataFrame()
|
|
1337
|
+
if df_merge.shape[0] > 0:
|
|
1338
|
+
wseginjv[Headers.WELL] = [well_name] * df_merge.shape[0]
|
|
1339
|
+
wseginjv[Headers.START_SEGMENT_NUMBER] = df_merge[Headers.START_SEGMENT_NUMBER].to_numpy()
|
|
1340
|
+
# the Cv is already corrected by the scaling factor
|
|
1341
|
+
wseginjv[Headers.FLOW_COEFFICIENT] = df_merge[Headers.FLOW_COEFFICIENT].to_numpy()
|
|
1342
|
+
wseginjv[Headers.PRIMARY_FLOW_CROSS_SECTIONAL_AREA] = df_merge[
|
|
1343
|
+
Headers.PRIMARY_FLOW_CROSS_SECTIONAL_AREA
|
|
1344
|
+
].to_numpy()
|
|
1345
|
+
wseginjv[Headers.SECONDARY_FLOW_CROSS_SECTIONAL_AREA] = df_merge[
|
|
1346
|
+
Headers.SECONDARY_FLOW_CROSS_SECTIONAL_AREA
|
|
1347
|
+
].to_numpy()
|
|
1348
|
+
wseginjv[Headers.TRIGGER_PARAMETER] = df_merge[Headers.TRIGGER_PARAMETER].to_numpy()
|
|
1349
|
+
wseginjv[Headers.TRIGGER_VALUE] = df_merge[Headers.TRIGGER_VALUE].to_numpy()
|
|
1350
|
+
wseginjv[Headers.DEFAULTS] = "5*"
|
|
1351
|
+
wseginjv[Headers.MAX_FLOW_CROSS_SECTIONAL_AREA] = wseginjv[Headers.PRIMARY_FLOW_CROSS_SECTIONAL_AREA].to_numpy()
|
|
1352
|
+
wseginjv[Headers.EMPTY] = "/"
|
|
1353
|
+
return wseginjv
|
|
1354
|
+
|
|
1355
|
+
|
|
1356
|
+
def prepare_dual_rate_controlled_production(
|
|
1298
1357
|
well_name: str, df_well: pd.DataFrame, df_device: pd.DataFrame
|
|
1299
1358
|
) -> pd.DataFrame:
|
|
1300
|
-
"""Prepare data frame for
|
|
1359
|
+
"""Prepare data frame for DUALRCP.
|
|
1301
1360
|
|
|
1302
1361
|
Args:
|
|
1303
1362
|
well_name: Well name.
|
|
@@ -1305,7 +1364,7 @@ def prepare_autonomous_inflow_control_valve(
|
|
|
1305
1364
|
df_device: Device data for this well and lateral.
|
|
1306
1365
|
|
|
1307
1366
|
Returns:
|
|
1308
|
-
DataFrame for
|
|
1367
|
+
DataFrame for DUALRCP.
|
|
1309
1368
|
"""
|
|
1310
1369
|
df_well = df_well[(df_well[Headers.DEVICE_TYPE] == Content.PERFORATED) | (df_well[Headers.NUMBER_OF_DEVICES] > 0)]
|
|
1311
1370
|
if df_well.shape[0] == 0:
|
|
@@ -1317,53 +1376,53 @@ def prepare_autonomous_inflow_control_valve(
|
|
|
1317
1376
|
right_on=[Headers.TUBING_MEASURED_DEPTH],
|
|
1318
1377
|
direction="nearest",
|
|
1319
1378
|
)
|
|
1320
|
-
df_merge = df_merge[df_merge[Headers.DEVICE_TYPE] == Content.
|
|
1321
|
-
|
|
1379
|
+
df_merge = df_merge[df_merge[Headers.DEVICE_TYPE] == Content.DUAL_RATE_CONTROLLED_PRODUCTION]
|
|
1380
|
+
wsegdualrcp = pd.DataFrame()
|
|
1322
1381
|
if df_merge.shape[0] > 0:
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
return
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
def
|
|
1356
|
-
"""Print
|
|
1382
|
+
wsegdualrcp[Headers.WELL] = [well_name] * df_merge.shape[0]
|
|
1383
|
+
wsegdualrcp[Headers.START_SEGMENT_NUMBER] = df_merge[Headers.START_SEGMENT_NUMBER].to_numpy()
|
|
1384
|
+
wsegdualrcp[Headers.END_SEGMENT_NUMBER] = df_merge[Headers.START_SEGMENT_NUMBER].to_numpy()
|
|
1385
|
+
wsegdualrcp[Headers.ALPHA_MAIN] = df_merge[Headers.ALPHA_MAIN].to_numpy()
|
|
1386
|
+
wsegdualrcp[Headers.SCALE_FACTOR] = df_merge[Headers.SCALE_FACTOR].to_numpy()
|
|
1387
|
+
wsegdualrcp[Headers.CALIBRATION_FLUID_DENSITY] = df_merge[Headers.DUALRCP_CALIBRATION_FLUID_DENSITY].to_numpy()
|
|
1388
|
+
wsegdualrcp[Headers.CALIBRATION_FLUID_VISCOSITY] = df_merge[Headers.DUALRCP_FLUID_VISCOSITY].to_numpy()
|
|
1389
|
+
wsegdualrcp[Headers.DEF] = ["5*"] * df_merge.shape[0]
|
|
1390
|
+
wsegdualrcp[Headers.X_MAIN] = df_merge[Headers.X_MAIN].to_numpy()
|
|
1391
|
+
wsegdualrcp[Headers.Y_MAIN] = df_merge[Headers.Y_MAIN].to_numpy()
|
|
1392
|
+
wsegdualrcp[Headers.FLAG] = [Headers.OPEN] * df_merge.shape[0]
|
|
1393
|
+
wsegdualrcp[Headers.A_MAIN] = df_merge[Headers.A_MAIN].to_numpy()
|
|
1394
|
+
wsegdualrcp[Headers.B_MAIN] = df_merge[Headers.B_MAIN].to_numpy()
|
|
1395
|
+
wsegdualrcp[Headers.C_MAIN] = df_merge[Headers.C_MAIN].to_numpy()
|
|
1396
|
+
wsegdualrcp[Headers.D_MAIN] = df_merge[Headers.D_MAIN].to_numpy()
|
|
1397
|
+
wsegdualrcp[Headers.E_MAIN] = df_merge[Headers.E_MAIN].to_numpy()
|
|
1398
|
+
wsegdualrcp[Headers.F_MAIN] = df_merge[Headers.F_MAIN].to_numpy()
|
|
1399
|
+
wsegdualrcp[Headers.ALPHA_PILOT] = df_merge[Headers.ALPHA_PILOT].to_numpy()
|
|
1400
|
+
wsegdualrcp[Headers.X_PILOT] = df_merge[Headers.X_PILOT].to_numpy()
|
|
1401
|
+
wsegdualrcp[Headers.Y_PILOT] = df_merge[Headers.Y_PILOT].to_numpy()
|
|
1402
|
+
wsegdualrcp[Headers.A_PILOT] = df_merge[Headers.A_PILOT].to_numpy()
|
|
1403
|
+
wsegdualrcp[Headers.B_PILOT] = df_merge[Headers.B_PILOT].to_numpy()
|
|
1404
|
+
wsegdualrcp[Headers.C_PILOT] = df_merge[Headers.C_PILOT].to_numpy()
|
|
1405
|
+
wsegdualrcp[Headers.D_PILOT] = df_merge[Headers.D_PILOT].to_numpy()
|
|
1406
|
+
wsegdualrcp[Headers.E_PILOT] = df_merge[Headers.E_PILOT].to_numpy()
|
|
1407
|
+
wsegdualrcp[Headers.F_PILOT] = df_merge[Headers.F_PILOT].to_numpy()
|
|
1408
|
+
wsegdualrcp[Headers.DUALRCP_WATER_CUT] = df_merge[Headers.DUALRCP_WATER_CUT].to_numpy()
|
|
1409
|
+
wsegdualrcp[Headers.DUALRCP_GAS_HOLDUP_FRACTION] = df_merge[Headers.DUALRCP_GAS_HOLDUP_FRACTION].to_numpy()
|
|
1410
|
+
wsegdualrcp[Headers.EMPTY] = "/"
|
|
1411
|
+
return wsegdualrcp
|
|
1412
|
+
|
|
1413
|
+
|
|
1414
|
+
def print_wsegdensity(df_wsegdensity: pd.DataFrame, well_number: int) -> str:
|
|
1415
|
+
"""Print DENSITY devices.
|
|
1357
1416
|
|
|
1358
1417
|
Args:
|
|
1359
|
-
|
|
1418
|
+
df_wsegdensity: Output from function prepare_wsegdensity.
|
|
1360
1419
|
well_number: Well number.
|
|
1361
1420
|
|
|
1362
1421
|
Returns:
|
|
1363
1422
|
Formatted actions to be included in the output file.
|
|
1364
1423
|
|
|
1365
1424
|
Raises:
|
|
1366
|
-
CompletorError: If there are to many wells and/or segments with
|
|
1425
|
+
CompletorError: If there are to many wells and/or segments with DENSITY.
|
|
1367
1426
|
"""
|
|
1368
1427
|
header = [
|
|
1369
1428
|
[
|
|
@@ -1403,9 +1462,9 @@ def print_wsegdar(df_wsegdar: pd.DataFrame, well_number: int) -> str:
|
|
|
1403
1462
|
sign_gas = [">", "<=", "<", ""]
|
|
1404
1463
|
suvtrig = ["0", "0", "1", "2"]
|
|
1405
1464
|
action = "UDQ\n"
|
|
1406
|
-
for idx in range(
|
|
1407
|
-
segment_number =
|
|
1408
|
-
well_name =
|
|
1465
|
+
for idx in range(df_wsegdensity.shape[0]):
|
|
1466
|
+
segment_number = df_wsegdensity[Headers.START_SEGMENT_NUMBER].iloc[idx]
|
|
1467
|
+
well_name = df_wsegdensity[Headers.WELL].iloc[idx]
|
|
1409
1468
|
action += f" ASSIGN SUVTRIG {well_name} {segment_number} 0 /\n"
|
|
1410
1469
|
action += "/\n\n"
|
|
1411
1470
|
iaction = 3
|
|
@@ -1414,25 +1473,25 @@ def print_wsegdar(df_wsegdar: pd.DataFrame, well_number: int) -> str:
|
|
|
1414
1473
|
for itm in header[iaction]:
|
|
1415
1474
|
header_string += " " + itm
|
|
1416
1475
|
action += header_string.rstrip() + "\n"
|
|
1417
|
-
for idx in range(
|
|
1418
|
-
segment_number =
|
|
1419
|
-
print_df =
|
|
1476
|
+
for idx in range(df_wsegdensity.shape[0]):
|
|
1477
|
+
segment_number = df_wsegdensity[Headers.START_SEGMENT_NUMBER].iloc[idx]
|
|
1478
|
+
print_df = df_wsegdensity[df_wsegdensity[Headers.START_SEGMENT_NUMBER] == segment_number]
|
|
1420
1479
|
print_df = print_df[header[iaction]]
|
|
1421
1480
|
print_df = dataframe_tostring(print_df, True, False, False) + "\n"
|
|
1422
1481
|
action += print_df
|
|
1423
1482
|
action += "/\n\n"
|
|
1424
|
-
for idx in range(
|
|
1425
|
-
segment_number =
|
|
1426
|
-
well_name =
|
|
1427
|
-
water_holdup_fraction_low_cutoff =
|
|
1428
|
-
water_holdup_fraction_high_cutoff =
|
|
1429
|
-
gas_holdup_fraction_low_cutoff =
|
|
1430
|
-
gas_holdup_fraction_high_cutoff =
|
|
1483
|
+
for idx in range(df_wsegdensity.shape[0]):
|
|
1484
|
+
segment_number = df_wsegdensity[Headers.START_SEGMENT_NUMBER].iloc[idx]
|
|
1485
|
+
well_name = df_wsegdensity[Headers.WELL].iloc[idx]
|
|
1486
|
+
water_holdup_fraction_low_cutoff = df_wsegdensity[Headers.WATER_HOLDUP_FRACTION_LOW_CUTOFF].iloc[idx]
|
|
1487
|
+
water_holdup_fraction_high_cutoff = df_wsegdensity[Headers.WATER_HOLDUP_FRACTION_HIGH_CUTOFF].iloc[idx]
|
|
1488
|
+
gas_holdup_fraction_low_cutoff = df_wsegdensity[Headers.GAS_HOLDUP_FRACTION_LOW_CUTOFF].iloc[idx]
|
|
1489
|
+
gas_holdup_fraction_high_cutoff = df_wsegdensity[Headers.GAS_HOLDUP_FRACTION_HIGH_CUTOFF].iloc[idx]
|
|
1431
1490
|
for iaction in range(2):
|
|
1432
1491
|
act_number = iaction + 1
|
|
1433
1492
|
act_name = f"D{well_number:03d}{segment_number:03d}{act_number:1d}"
|
|
1434
1493
|
if len(act_name) > 8:
|
|
1435
|
-
raise CompletorError("Too many wells and/or too many segments with
|
|
1494
|
+
raise CompletorError("Too many wells and/or too many segments with DENSITY")
|
|
1436
1495
|
action += (
|
|
1437
1496
|
f"ACTIONX\n{act_name} 1000000 /\n"
|
|
1438
1497
|
f"SWHF '{well_name}' {segment_number} "
|
|
@@ -1442,7 +1501,7 @@ def print_wsegdar(df_wsegdar: pd.DataFrame, well_number: int) -> str:
|
|
|
1442
1501
|
f"SUVTRIG '{well_name}' {segment_number} "
|
|
1443
1502
|
f"= {suvtrig[iaction]} /\n/\n\n"
|
|
1444
1503
|
)
|
|
1445
|
-
print_df =
|
|
1504
|
+
print_df = df_wsegdensity[df_wsegdensity[Headers.START_SEGMENT_NUMBER] == segment_number]
|
|
1446
1505
|
print_df = print_df[header[iaction]] # type: ignore
|
|
1447
1506
|
header_string = Keywords.WELL_SEGMENTS_VALVE + "\n--"
|
|
1448
1507
|
for item in header[iaction]:
|
|
@@ -1460,7 +1519,7 @@ def print_wsegdar(df_wsegdar: pd.DataFrame, well_number: int) -> str:
|
|
|
1460
1519
|
act_number = iaction + 1
|
|
1461
1520
|
act_name = f"D{well_number:03d}{segment_number:03d}{act_number:1d}"
|
|
1462
1521
|
if len(act_name) > 8:
|
|
1463
|
-
raise CompletorError("Too many wells and/or too many segments with
|
|
1522
|
+
raise CompletorError("Too many wells and/or too many segments with DENSITY")
|
|
1464
1523
|
action += (
|
|
1465
1524
|
f"ACTIONX\n{act_name} 1000000 /\n"
|
|
1466
1525
|
f"SGHF '{well_name}' {segment_number} "
|
|
@@ -1468,7 +1527,7 @@ def print_wsegdar(df_wsegdar: pd.DataFrame, well_number: int) -> str:
|
|
|
1468
1527
|
f"SUVTRIG '{well_name}' {segment_number} "
|
|
1469
1528
|
f"= {suvtrig[iaction]} /\n/\n\n"
|
|
1470
1529
|
)
|
|
1471
|
-
print_df =
|
|
1530
|
+
print_df = df_wsegdensity[df_wsegdensity[Headers.START_SEGMENT_NUMBER] == segment_number]
|
|
1472
1531
|
print_df = print_df[header[iaction]] # type: ignore
|
|
1473
1532
|
header_string = Keywords.WELL_SEGMENTS_VALVE + "\n--"
|
|
1474
1533
|
for item in header[iaction]:
|
|
@@ -1483,7 +1542,7 @@ def print_wsegdar(df_wsegdar: pd.DataFrame, well_number: int) -> str:
|
|
|
1483
1542
|
act_number = iaction + 1
|
|
1484
1543
|
act_name = f"D{well_number:03d}{segment_number:03d}{act_number:1d}"
|
|
1485
1544
|
if len(act_name) > 8:
|
|
1486
|
-
raise CompletorError("Too many wells and/or too many segments with
|
|
1545
|
+
raise CompletorError("Too many wells and/or too many segments with DENSITY")
|
|
1487
1546
|
action += (
|
|
1488
1547
|
f"ACTIONX\n{act_name} 1000000 /\n"
|
|
1489
1548
|
f"SWHF '{well_name}' {segment_number} "
|
|
@@ -1491,7 +1550,7 @@ def print_wsegdar(df_wsegdar: pd.DataFrame, well_number: int) -> str:
|
|
|
1491
1550
|
f"SUVTRIG '{well_name}' {segment_number} "
|
|
1492
1551
|
f"= {suvtrig[iaction]} /\n/\n\n"
|
|
1493
1552
|
)
|
|
1494
|
-
print_df =
|
|
1553
|
+
print_df = df_wsegdensity[df_wsegdensity[Headers.START_SEGMENT_NUMBER] == segment_number]
|
|
1495
1554
|
print_df = print_df[header[iaction]] # type: ignore
|
|
1496
1555
|
header_string = Keywords.WELL_SEGMENTS_VALVE + "\n--"
|
|
1497
1556
|
for item in header[iaction]:
|
|
@@ -1504,18 +1563,180 @@ def print_wsegdar(df_wsegdar: pd.DataFrame, well_number: int) -> str:
|
|
|
1504
1563
|
return action
|
|
1505
1564
|
|
|
1506
1565
|
|
|
1507
|
-
def
|
|
1508
|
-
"""Print
|
|
1566
|
+
def print_wseginjv(df_wseginjv: pd.DataFrame, well_number: int) -> str:
|
|
1567
|
+
"""Print INJECTION VALVE devices.
|
|
1568
|
+
|
|
1569
|
+
Args:
|
|
1570
|
+
df_wseginjv: Output from function prepare_wseginjv.
|
|
1571
|
+
well_number: Well number.
|
|
1572
|
+
|
|
1573
|
+
Returns:
|
|
1574
|
+
Formatted actions to be included in the output file.
|
|
1575
|
+
|
|
1576
|
+
Raises:
|
|
1577
|
+
CompletorError: If there are to many wells and/or segments with INJECTION VALVE.
|
|
1578
|
+
"""
|
|
1579
|
+
header = [
|
|
1580
|
+
[
|
|
1581
|
+
Headers.WELL,
|
|
1582
|
+
Headers.START_SEGMENT_NUMBER,
|
|
1583
|
+
Headers.FLOW_COEFFICIENT,
|
|
1584
|
+
Headers.SECONDARY_FLOW_CROSS_SECTIONAL_AREA,
|
|
1585
|
+
Headers.DEFAULTS,
|
|
1586
|
+
Headers.MAX_FLOW_CROSS_SECTIONAL_AREA,
|
|
1587
|
+
],
|
|
1588
|
+
[
|
|
1589
|
+
Headers.WELL,
|
|
1590
|
+
Headers.START_SEGMENT_NUMBER,
|
|
1591
|
+
Headers.FLOW_COEFFICIENT,
|
|
1592
|
+
Headers.PRIMARY_FLOW_CROSS_SECTIONAL_AREA,
|
|
1593
|
+
Headers.DEFAULTS,
|
|
1594
|
+
Headers.MAX_FLOW_CROSS_SECTIONAL_AREA,
|
|
1595
|
+
],
|
|
1596
|
+
]
|
|
1597
|
+
|
|
1598
|
+
sign = ["<", ">="]
|
|
1599
|
+
suvtrig = ["0", "1"]
|
|
1600
|
+
action = "UDQ\n"
|
|
1601
|
+
for idx in range(df_wseginjv.shape[0]):
|
|
1602
|
+
segment_number = df_wseginjv[Headers.START_SEGMENT_NUMBER].iloc[idx]
|
|
1603
|
+
well_name = df_wseginjv[Headers.WELL].iloc[idx]
|
|
1604
|
+
action += f" ASSIGN SUVTRIG {well_name} {segment_number} 0 /\n"
|
|
1605
|
+
action += "/\n\n"
|
|
1606
|
+
iaction = 1
|
|
1607
|
+
action += Keywords.WELL_SEGMENTS_VALVE + "\n"
|
|
1608
|
+
header_string = "--"
|
|
1609
|
+
for itm in header[iaction]:
|
|
1610
|
+
header_string += " " + itm
|
|
1611
|
+
action += header_string.rstrip() + "\n"
|
|
1612
|
+
for idx in range(df_wseginjv.shape[0]):
|
|
1613
|
+
segment_number = df_wseginjv[Headers.START_SEGMENT_NUMBER].iloc[idx]
|
|
1614
|
+
print_df = df_wseginjv[df_wseginjv[Headers.START_SEGMENT_NUMBER] == segment_number]
|
|
1615
|
+
print_df = print_df[header[iaction]]
|
|
1616
|
+
print_df = dataframe_tostring(print_df, True, False, False) + "\n"
|
|
1617
|
+
action += print_df
|
|
1618
|
+
action += "/\n\n"
|
|
1619
|
+
for idx in range(df_wseginjv.shape[0]):
|
|
1620
|
+
segment_number = df_wseginjv[Headers.START_SEGMENT_NUMBER].iloc[idx]
|
|
1621
|
+
well_name = df_wseginjv[Headers.WELL].iloc[idx]
|
|
1622
|
+
# Trigger paramater is segment water rate
|
|
1623
|
+
if df_wseginjv[Headers.TRIGGER_PARAMETER].iloc[idx] == "SWFR":
|
|
1624
|
+
water_segment_rate_cutoff = -1 * df_wseginjv[Headers.TRIGGER_VALUE].iloc[idx]
|
|
1625
|
+
iaction = 0
|
|
1626
|
+
act_number = iaction + 1
|
|
1627
|
+
act_name = f"INJVOP{well_number:03d}{segment_number:03d}{act_number:1d}"
|
|
1628
|
+
if len(act_name) > 13:
|
|
1629
|
+
raise CompletorError("Too many wells and/or too many segments with Injection Valve")
|
|
1630
|
+
action += (
|
|
1631
|
+
f"ACTIONX\n{act_name} 1000000 /\n"
|
|
1632
|
+
f"SWFR '{well_name}' {segment_number} "
|
|
1633
|
+
f"{sign[iaction]} {water_segment_rate_cutoff} AND /\n"
|
|
1634
|
+
f"SUVTRIG '{well_name}' {segment_number} "
|
|
1635
|
+
f"= {suvtrig[iaction]} /\n/\n\n"
|
|
1636
|
+
)
|
|
1637
|
+
print_df = df_wseginjv[df_wseginjv[Headers.START_SEGMENT_NUMBER] == segment_number]
|
|
1638
|
+
print_df = print_df[header[iaction]] # type: ignore
|
|
1639
|
+
header_string = Keywords.WELL_SEGMENTS_VALVE + "\n--"
|
|
1640
|
+
|
|
1641
|
+
for item in header[iaction]:
|
|
1642
|
+
header_string += " " + item
|
|
1643
|
+
header_string = header_string.rstrip() + "\n"
|
|
1644
|
+
print_df = header_string + dataframe_tostring(print_df, True, False, False) # type: ignore
|
|
1645
|
+
print_df += "\n/\n"
|
|
1646
|
+
print_df += f"\nUDQ\n ASSIGN SUVTRIG {well_name} {segment_number} 1 /\n/\n"
|
|
1647
|
+
action += print_df + "\nENDACTIO\n\n"
|
|
1648
|
+
|
|
1649
|
+
iaction = 1
|
|
1650
|
+
act_number = iaction + 1
|
|
1651
|
+
act_name = f"INJVCL{well_number:03d}{segment_number:03d}{act_number:1d}"
|
|
1652
|
+
if len(act_name) > 13:
|
|
1653
|
+
raise CompletorError("Too many wells and/or too many segments with Injection Valve")
|
|
1654
|
+
action += (
|
|
1655
|
+
f"ACTIONX\n{act_name} 1000000 /\n"
|
|
1656
|
+
f"SWFR '{well_name}' {segment_number} "
|
|
1657
|
+
f"{sign[iaction]} {water_segment_rate_cutoff} AND /\n"
|
|
1658
|
+
f"SUVTRIG '{well_name}' {segment_number} "
|
|
1659
|
+
f"= {suvtrig[iaction]} /\n/\n\n"
|
|
1660
|
+
)
|
|
1661
|
+
print_df = df_wseginjv[df_wseginjv[Headers.START_SEGMENT_NUMBER] == segment_number]
|
|
1662
|
+
print_df = print_df[header[iaction]] # type: ignore
|
|
1663
|
+
header_string = Keywords.WELL_SEGMENTS_VALVE + "\n--"
|
|
1664
|
+
|
|
1665
|
+
for item in header[iaction]:
|
|
1666
|
+
header_string += " " + item
|
|
1667
|
+
header_string = header_string.rstrip() + "\n"
|
|
1668
|
+
print_df = header_string + dataframe_tostring(print_df, True, False, False) # type: ignore
|
|
1669
|
+
print_df += "\n/\n"
|
|
1670
|
+
print_df += f"\nUDQ\n ASSIGN SUVTRIG {well_name} {segment_number} 0 /\n/\n"
|
|
1671
|
+
action += print_df + "\nENDACTIO\n\n"
|
|
1672
|
+
|
|
1673
|
+
# Trigger parameter is segment pressure drop
|
|
1674
|
+
elif df_wseginjv[Headers.TRIGGER_PARAMETER].iloc[idx] == "SPRD":
|
|
1675
|
+
pressure_drop_cutoff = -1 * df_wseginjv[Headers.TRIGGER_VALUE].iloc[idx]
|
|
1676
|
+
iaction = 0
|
|
1677
|
+
act_number = iaction + 1
|
|
1678
|
+
act_name = f"INJVOP{well_number:03d}{segment_number:03d}{act_number:1d}"
|
|
1679
|
+
if len(act_name) > 13:
|
|
1680
|
+
raise CompletorError("Too many wells and/or too many segments with Injection Valve")
|
|
1681
|
+
action += (
|
|
1682
|
+
f"ACTIONX\n{act_name} 1000000 /\n"
|
|
1683
|
+
f"SPRD '{well_name}' {segment_number} "
|
|
1684
|
+
f"{sign[iaction]} {pressure_drop_cutoff} AND /\n"
|
|
1685
|
+
f"SUVTRIG '{well_name}' {segment_number} "
|
|
1686
|
+
f"= {suvtrig[iaction]} /\n/\n\n"
|
|
1687
|
+
)
|
|
1688
|
+
print_df = df_wseginjv[df_wseginjv[Headers.START_SEGMENT_NUMBER] == segment_number]
|
|
1689
|
+
print_df = print_df[header[iaction]] # type: ignore
|
|
1690
|
+
header_string = Keywords.WELL_SEGMENTS_VALVE + "\n--"
|
|
1691
|
+
|
|
1692
|
+
for item in header[iaction]:
|
|
1693
|
+
header_string += " " + item
|
|
1694
|
+
header_string = header_string.rstrip() + "\n"
|
|
1695
|
+
print_df = header_string + dataframe_tostring(print_df, True, False, False) # type: ignore
|
|
1696
|
+
print_df += "\n/\n"
|
|
1697
|
+
print_df += f"\nUDQ\n ASSIGN SUVTRIG {well_name} {segment_number} 1 /\n/\n"
|
|
1698
|
+
action += print_df + "\nENDACTIO\n\n"
|
|
1699
|
+
|
|
1700
|
+
iaction = 1
|
|
1701
|
+
act_number = iaction + 1
|
|
1702
|
+
act_name = f"INJVCL{well_number:03d}{segment_number:03d}{act_number:1d}"
|
|
1703
|
+
if len(act_name) > 13:
|
|
1704
|
+
raise CompletorError("Too many wells and/or too many segments with Injection Valve")
|
|
1705
|
+
action += (
|
|
1706
|
+
f"ACTIONX\n{act_name} 1000000 /\n"
|
|
1707
|
+
f"SPRD '{well_name}' {segment_number} "
|
|
1708
|
+
f"{sign[iaction]} {pressure_drop_cutoff} AND /\n"
|
|
1709
|
+
f"SUVTRIG '{well_name}' {segment_number} "
|
|
1710
|
+
f"= {suvtrig[iaction]} /\n/\n\n"
|
|
1711
|
+
)
|
|
1712
|
+
print_df = df_wseginjv[df_wseginjv[Headers.START_SEGMENT_NUMBER] == segment_number]
|
|
1713
|
+
print_df = print_df[header[iaction]] # type: ignore
|
|
1714
|
+
header_string = Keywords.WELL_SEGMENTS_VALVE + "\n--"
|
|
1715
|
+
|
|
1716
|
+
for item in header[iaction]:
|
|
1717
|
+
header_string += " " + item
|
|
1718
|
+
header_string = header_string.rstrip() + "\n"
|
|
1719
|
+
print_df = header_string + dataframe_tostring(print_df, True, False, False) # type: ignore
|
|
1720
|
+
print_df += "\n/\n"
|
|
1721
|
+
print_df += f"\nUDQ\n ASSIGN SUVTRIG {well_name} {segment_number} 0 /\n/\n"
|
|
1722
|
+
action += print_df + "\nENDACTIO\n\n"
|
|
1723
|
+
else:
|
|
1724
|
+
raise CompletorError("Trigger paramater given is not supported")
|
|
1725
|
+
return action
|
|
1726
|
+
|
|
1727
|
+
|
|
1728
|
+
def print_wsegdualrcp(df_wsegdualrcp: pd.DataFrame, well_number: int) -> str:
|
|
1729
|
+
"""Print for DUALRCP devices.
|
|
1509
1730
|
|
|
1510
1731
|
Args:
|
|
1511
|
-
|
|
1732
|
+
df_wsegdualrcp: Output from function prepare_wsegdualrcp.
|
|
1512
1733
|
well_number: Well number.
|
|
1513
1734
|
|
|
1514
1735
|
Returns:
|
|
1515
1736
|
Formatted actions to be included in the output file.
|
|
1516
1737
|
|
|
1517
1738
|
Raises:
|
|
1518
|
-
CompletorError: If there are too many wells and/or segments with
|
|
1739
|
+
CompletorError: If there are too many wells and/or segments with DUALRCP.
|
|
1519
1740
|
"""
|
|
1520
1741
|
header = [
|
|
1521
1742
|
[
|
|
@@ -1583,17 +1804,17 @@ def print_wsegaicv(df_wsegaicv: pd.DataFrame, well_number: int) -> str:
|
|
|
1583
1804
|
sign_gas = ["<", ">="]
|
|
1584
1805
|
operator = ["AND", "OR"]
|
|
1585
1806
|
action = ""
|
|
1586
|
-
for idx in range(
|
|
1587
|
-
segment_number =
|
|
1588
|
-
well_name =
|
|
1589
|
-
wct =
|
|
1590
|
-
ghf =
|
|
1807
|
+
for idx in range(df_wsegdualrcp.shape[0]):
|
|
1808
|
+
segment_number = df_wsegdualrcp[Headers.START_SEGMENT_NUMBER].iloc[idx]
|
|
1809
|
+
well_name = df_wsegdualrcp[Headers.WELL].iloc[idx]
|
|
1810
|
+
wct = df_wsegdualrcp[Headers.DUALRCP_WATER_CUT].iloc[idx]
|
|
1811
|
+
ghf = df_wsegdualrcp[Headers.DUALRCP_GAS_HOLDUP_FRACTION].iloc[idx]
|
|
1591
1812
|
# LOWWCT_LOWGHF
|
|
1592
1813
|
for iaction in range(2):
|
|
1593
1814
|
act_number = iaction + 1
|
|
1594
1815
|
act_name = f"V{well_number:03d}{segment_number:03d}{act_number:1d}"
|
|
1595
1816
|
if len(act_name) > 8:
|
|
1596
|
-
raise CompletorError("Too many wells and/or too many segments with
|
|
1817
|
+
raise CompletorError("Too many wells and/or too many segments with DUALRCP")
|
|
1597
1818
|
action += (
|
|
1598
1819
|
f"ACTIONX\n{act_name} 1000000 /\n"
|
|
1599
1820
|
f"SUWCT '{well_name}' {segment_number} {sign_water[iaction]} "
|
|
@@ -1601,7 +1822,7 @@ def print_wsegaicv(df_wsegaicv: pd.DataFrame, well_number: int) -> str:
|
|
|
1601
1822
|
f"SGHF '{well_name}' {segment_number} {sign_gas[iaction]} {ghf} /\n/\n"
|
|
1602
1823
|
)
|
|
1603
1824
|
|
|
1604
|
-
print_df =
|
|
1825
|
+
print_df = df_wsegdualrcp[df_wsegdualrcp[Headers.START_SEGMENT_NUMBER] == segment_number]
|
|
1605
1826
|
print_df = print_df[header[iaction]]
|
|
1606
1827
|
print_df.columns = new_column
|
|
1607
1828
|
print_df = Keywords.AUTONOMOUS_INFLOW_CONTROL_DEVICE + "\n" + dataframe_tostring(print_df, True)
|