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.
@@ -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.DENSITY_ACTIVATED_RECOVERY,
452
- "/ -- DAR types",
453
+ df_well[Headers.DEVICE_TYPE] == Content.DENSITY,
454
+ "/ -- DENSITY types",
453
455
  np.where(
454
- df_well[Headers.DEVICE_TYPE] == Content.AUTONOMOUS_INFLOW_CONTROL_VALVE,
455
- "/ -- AICV types",
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.INFLOW_CONTROL_VALVE, "/ -- ICV types", ""
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 prepare_density_activated_recovery(well_name: str, df_well: pd.DataFrame, df_device: pd.DataFrame) -> pd.DataFrame:
1253
- """Prepare data frame for DAR.
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 DAR.
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.DENSITY_ACTIVATED_RECOVERY]
1274
- wsegdar = pd.DataFrame()
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
- wsegdar[Headers.WELL] = [well_name] * df_merge.shape[0]
1277
- wsegdar[Headers.START_SEGMENT_NUMBER] = df_merge[Headers.START_SEGMENT_NUMBER].to_numpy()
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
- wsegdar[Headers.FLOW_COEFFICIENT] = df_merge[Headers.FLOW_COEFFICIENT].to_numpy()
1280
- wsegdar[Headers.OIL_FLOW_CROSS_SECTIONAL_AREA] = df_merge[Headers.OIL_FLOW_CROSS_SECTIONAL_AREA].to_numpy()
1281
- wsegdar[Headers.GAS_FLOW_CROSS_SECTIONAL_AREA] = df_merge[Headers.GAS_FLOW_CROSS_SECTIONAL_AREA].to_numpy()
1282
- wsegdar[Headers.WATER_FLOW_CROSS_SECTIONAL_AREA] = df_merge[Headers.WATER_FLOW_CROSS_SECTIONAL_AREA].to_numpy()
1283
- wsegdar[Headers.WATER_HOLDUP_FRACTION_LOW_CUTOFF] = df_merge[
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
- wsegdar[Headers.WATER_HOLDUP_FRACTION_HIGH_CUTOFF] = df_merge[
1297
+ wsegdensity[Headers.WATER_HOLDUP_FRACTION_HIGH_CUTOFF] = df_merge[
1287
1298
  Headers.WATER_HOLDUP_FRACTION_HIGH_CUTOFF
1288
1299
  ].to_numpy()
1289
- wsegdar[Headers.GAS_HOLDUP_FRACTION_LOW_CUTOFF] = df_merge[Headers.GAS_HOLDUP_FRACTION_LOW_CUTOFF].to_numpy()
1290
- wsegdar[Headers.GAS_HOLDUP_FRACTION_HIGH_CUTOFF] = df_merge[Headers.GAS_HOLDUP_FRACTION_HIGH_CUTOFF].to_numpy()
1291
- wsegdar[Headers.DEFAULTS] = "5*"
1292
- wsegdar[Headers.MAX_FLOW_CROSS_SECTIONAL_AREA] = wsegdar[Headers.OIL_FLOW_CROSS_SECTIONAL_AREA].to_numpy()
1293
- wsegdar[Headers.EMPTY] = "/"
1294
- return wsegdar
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 prepare_autonomous_inflow_control_valve(
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 AICV.
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 AICV.
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.AUTONOMOUS_INFLOW_CONTROL_VALVE]
1321
- wsegaicv = pd.DataFrame()
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
- wsegaicv[Headers.WELL] = [well_name] * df_merge.shape[0]
1324
- wsegaicv[Headers.START_SEGMENT_NUMBER] = df_merge[Headers.START_SEGMENT_NUMBER].to_numpy()
1325
- wsegaicv[Headers.END_SEGMENT_NUMBER] = df_merge[Headers.START_SEGMENT_NUMBER].to_numpy()
1326
- wsegaicv[Headers.ALPHA_MAIN] = df_merge[Headers.ALPHA_MAIN].to_numpy()
1327
- wsegaicv[Headers.SCALE_FACTOR] = df_merge[Headers.SCALE_FACTOR].to_numpy()
1328
- wsegaicv[Headers.CALIBRATION_FLUID_DENSITY] = df_merge[Headers.AICV_CALIBRATION_FLUID_DENSITY].to_numpy()
1329
- wsegaicv[Headers.CALIBRATION_FLUID_VISCOSITY] = df_merge[Headers.AICV_FLUID_VISCOSITY].to_numpy()
1330
- wsegaicv[Headers.DEF] = ["5*"] * df_merge.shape[0]
1331
- wsegaicv[Headers.X_MAIN] = df_merge[Headers.X_MAIN].to_numpy()
1332
- wsegaicv[Headers.Y_MAIN] = df_merge[Headers.Y_MAIN].to_numpy()
1333
- wsegaicv[Headers.FLAG] = [Headers.OPEN] * df_merge.shape[0]
1334
- wsegaicv[Headers.A_MAIN] = df_merge[Headers.A_MAIN].to_numpy()
1335
- wsegaicv[Headers.B_MAIN] = df_merge[Headers.B_MAIN].to_numpy()
1336
- wsegaicv[Headers.C_MAIN] = df_merge[Headers.C_MAIN].to_numpy()
1337
- wsegaicv[Headers.D_MAIN] = df_merge[Headers.D_MAIN].to_numpy()
1338
- wsegaicv[Headers.E_MAIN] = df_merge[Headers.E_MAIN].to_numpy()
1339
- wsegaicv[Headers.F_MAIN] = df_merge[Headers.F_MAIN].to_numpy()
1340
- wsegaicv[Headers.ALPHA_PILOT] = df_merge[Headers.ALPHA_PILOT].to_numpy()
1341
- wsegaicv[Headers.X_PILOT] = df_merge[Headers.X_PILOT].to_numpy()
1342
- wsegaicv[Headers.Y_PILOT] = df_merge[Headers.Y_PILOT].to_numpy()
1343
- wsegaicv[Headers.A_PILOT] = df_merge[Headers.A_PILOT].to_numpy()
1344
- wsegaicv[Headers.B_PILOT] = df_merge[Headers.B_PILOT].to_numpy()
1345
- wsegaicv[Headers.C_PILOT] = df_merge[Headers.C_PILOT].to_numpy()
1346
- wsegaicv[Headers.D_PILOT] = df_merge[Headers.D_PILOT].to_numpy()
1347
- wsegaicv[Headers.E_PILOT] = df_merge[Headers.E_PILOT].to_numpy()
1348
- wsegaicv[Headers.F_PILOT] = df_merge[Headers.F_PILOT].to_numpy()
1349
- wsegaicv[Headers.AICV_WATER_CUT] = df_merge[Headers.AICV_WATER_CUT].to_numpy()
1350
- wsegaicv[Headers.AICV_GAS_HOLDUP_FRACTION] = df_merge[Headers.AICV_GAS_HOLDUP_FRACTION].to_numpy()
1351
- wsegaicv[Headers.EMPTY] = "/"
1352
- return wsegaicv
1353
-
1354
-
1355
- def print_wsegdar(df_wsegdar: pd.DataFrame, well_number: int) -> str:
1356
- """Print DAR devices.
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
- df_wsegdar: Output from function prepare_wsegdar.
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 DAR.
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(df_wsegdar.shape[0]):
1407
- segment_number = df_wsegdar[Headers.START_SEGMENT_NUMBER].iloc[idx]
1408
- well_name = df_wsegdar[Headers.WELL].iloc[idx]
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(df_wsegdar.shape[0]):
1418
- segment_number = df_wsegdar[Headers.START_SEGMENT_NUMBER].iloc[idx]
1419
- print_df = df_wsegdar[df_wsegdar[Headers.START_SEGMENT_NUMBER] == segment_number]
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(df_wsegdar.shape[0]):
1425
- segment_number = df_wsegdar[Headers.START_SEGMENT_NUMBER].iloc[idx]
1426
- well_name = df_wsegdar[Headers.WELL].iloc[idx]
1427
- water_holdup_fraction_low_cutoff = df_wsegdar[Headers.WATER_HOLDUP_FRACTION_LOW_CUTOFF].iloc[idx]
1428
- water_holdup_fraction_high_cutoff = df_wsegdar[Headers.WATER_HOLDUP_FRACTION_HIGH_CUTOFF].iloc[idx]
1429
- gas_holdup_fraction_low_cutoff = df_wsegdar[Headers.GAS_HOLDUP_FRACTION_LOW_CUTOFF].iloc[idx]
1430
- gas_holdup_fraction_high_cutoff = df_wsegdar[Headers.GAS_HOLDUP_FRACTION_HIGH_CUTOFF].iloc[idx]
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 DAR")
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 = df_wsegdar[df_wsegdar[Headers.START_SEGMENT_NUMBER] == segment_number]
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 DAR")
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 = df_wsegdar[df_wsegdar[Headers.START_SEGMENT_NUMBER] == segment_number]
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 DAR")
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 = df_wsegdar[df_wsegdar[Headers.START_SEGMENT_NUMBER] == segment_number]
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 print_wsegaicv(df_wsegaicv: pd.DataFrame, well_number: int) -> str:
1508
- """Print for AICV devices.
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
- df_wsegaicv: Output from function prepare_wsegaicv.
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 AICV.
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(df_wsegaicv.shape[0]):
1587
- segment_number = df_wsegaicv[Headers.START_SEGMENT_NUMBER].iloc[idx]
1588
- well_name = df_wsegaicv[Headers.WELL].iloc[idx]
1589
- wct = df_wsegaicv[Headers.AICV_WATER_CUT].iloc[idx]
1590
- ghf = df_wsegaicv[Headers.AICV_GAS_HOLDUP_FRACTION].iloc[idx]
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 AICV")
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 = df_wsegaicv[df_wsegaicv[Headers.START_SEGMENT_NUMBER] == segment_number]
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)