completor 1.4.0__py3-none-any.whl → 1.5.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.
@@ -0,0 +1,845 @@
1
+ """This module create the resulting ICV-Control Eclipse functions"""
2
+
3
+ from __future__ import annotations
4
+
5
+ import re
6
+
7
+ import pandas as pd
8
+
9
+ from completor.constants import ICVMethod
10
+ from completor.initialization import Initialization
11
+ from completor.logger import logger
12
+ from completor.utils import insert_comment
13
+
14
+
15
+ class IcvFunctions:
16
+ """This class defines a framework of icv functions used by the icv-control
17
+ algorithm.
18
+
19
+ """
20
+
21
+ def __init__(self, initials: Initialization):
22
+ self.initials = initials
23
+ self.opening_icv_lim = [0.01, 0.99]
24
+ self.custom_conditions = initials.case.custom_conditions
25
+
26
+ def create_actionx(self, record1: str, record2: str, action: str) -> str:
27
+ """
28
+ Creates a general purpose Eclipse ACTIONX statement.
29
+
30
+ Args:
31
+ record1: Record 1 in the ACTIONX statement.
32
+ record2: Record 2 in the ACTIONX statement.
33
+ action: The action to be taken by the ACTIONX statement.
34
+
35
+ Returns:
36
+ Eclipse ACTIONX statement.
37
+
38
+ """
39
+ return f"ACTIONX\n{record1}{record2}\n{action}\n"
40
+
41
+ def create_action_name(
42
+ self, icv_name: str, icv_function: ICVMethod, step: int | None = None, criteria: int | None = None
43
+ ) -> str:
44
+ """
45
+ Creates an action name (first element of record1) for a specific action
46
+ to be taken by ACTIONX. Example: CH1W1_A01.
47
+
48
+ Args:
49
+ icv_name: Icv name. Letter from A through Z.
50
+ icv_function: Abbreviation for the type of icv function.
51
+ number_of_icvs: Number of icvs in well with current icv (icv_name).
52
+ step: The step number following the icv name in action name.
53
+ criteria: Integer value denoting the criteria.
54
+
55
+ Returns:
56
+ An icv-control action name.
57
+
58
+ """
59
+ crit = "_" if criteria is None else f"{criteria}"
60
+ step_str: str
61
+ if step is None:
62
+ step_str = "_"
63
+ elif step > 999:
64
+ step_str = str(step)
65
+ elif len(crit) == 2 or len(icv_name) == 2:
66
+ step_str = f"000{step}"[-3:]
67
+ else:
68
+ step_str = "_" + f"000{step}"[-3:]
69
+
70
+ if (
71
+ (len(crit) == 2 and len(icv_name) == 2)
72
+ or (len(crit) == 2 and len(step_str) == 4)
73
+ or (len(icv_name) == 2 and len(step_str) == 4)
74
+ ):
75
+ action_name_templates = {
76
+ ICVMethod.OPEN: f"O{crit}{icv_name}{step_str}",
77
+ ICVMethod.OPEN_WAIT: f"H{crit}{icv_name}{step_str}",
78
+ ICVMethod.OPEN_READY: f"RDYO{crit}{icv_name}",
79
+ ICVMethod.OPEN_STOP: f"STPO{crit}{icv_name}",
80
+ ICVMethod.OPEN_WAIT_STOP: f"SPOW{crit}{icv_name}",
81
+ ICVMethod.CHOKE: f"C{crit}{icv_name}{step_str}",
82
+ ICVMethod.CHOKE_WAIT: f"W{crit}{icv_name}{step_str}",
83
+ ICVMethod.CHOKE_READY: f"RDYC{crit}{icv_name}",
84
+ ICVMethod.CHOKE_STOP: f"STPC{crit}{icv_name}",
85
+ ICVMethod.CHOKE_WAIT_STOP: f"SPCW{crit}{icv_name}",
86
+ }
87
+ elif (len(crit) == 2 or len(icv_name) == 2) and len(step_str) < 4:
88
+ action_name_templates = {
89
+ ICVMethod.OPEN: f"OP{crit}{icv_name}{step_str}",
90
+ ICVMethod.OPEN_WAIT: f"WO{crit}{icv_name}{step_str}",
91
+ ICVMethod.OPEN_READY: f"REDYO{crit}{icv_name}",
92
+ ICVMethod.OPEN_STOP: f"STPO{crit}{icv_name}",
93
+ ICVMethod.OPEN_WAIT_STOP: f"STPOW{crit}{icv_name}",
94
+ ICVMethod.CHOKE: f"C{crit}{icv_name}{step_str}",
95
+ ICVMethod.CHOKE_WAIT: f"WC{crit}{icv_name}{step_str}",
96
+ ICVMethod.CHOKE_READY: f"REDYC{crit}{icv_name}",
97
+ ICVMethod.CHOKE_STOP: f"STPC{crit}{icv_name}",
98
+ ICVMethod.CHOKE_WAIT_STOP: f"STPCW{crit}{icv_name}",
99
+ }
100
+ else:
101
+ action_name_templates = {
102
+ ICVMethod.OPEN: f"OP{crit}{icv_name}{step_str}",
103
+ ICVMethod.OPEN_WAIT: f"WO{crit}{icv_name}{step_str}",
104
+ ICVMethod.OPEN_READY: f"READYO{crit}{icv_name}",
105
+ ICVMethod.OPEN_STOP: f"STOPO{crit}{icv_name}",
106
+ ICVMethod.OPEN_WAIT_STOP: f"STOPOW{crit}{icv_name}",
107
+ ICVMethod.CHOKE: f"CH{crit}{icv_name}{step_str}",
108
+ ICVMethod.CHOKE_WAIT: f"WC{crit}{icv_name}{step_str}",
109
+ ICVMethod.CHOKE_READY: f"READYC{crit}{icv_name}",
110
+ ICVMethod.CHOKE_STOP: f"STOPC{crit}{icv_name}",
111
+ ICVMethod.CHOKE_WAIT_STOP: f"STOPCW{crit}{icv_name}",
112
+ }
113
+ if len(action_name_templates[icv_function]) > 8:
114
+ logger.warning(
115
+ f"Function name '{action_name_templates[icv_function]}'"
116
+ f" exceed Eclipse's maximum of 8 characters for keywords."
117
+ f" Created for icv function '{icv_function}'."
118
+ )
119
+ return action_name_templates[icv_function]
120
+
121
+ def create_record1(self, action_name: str, trigger_number_times: int, trigger_minimum_interval: int | str) -> str:
122
+ """Creates record1 in the Eclipse ACTIONX statement for icv-control.
123
+
124
+ Args:
125
+ action_name: The action name, first element of ACTIONX record 1.
126
+ trigger_number_times: The number of times this action can be triggered.
127
+ trigger_minimum_interval: Minimum time interval between action triggers.
128
+
129
+ Returns:
130
+ Record 1 of the Eclipse ACTIONX keyword.
131
+
132
+ """
133
+
134
+ if trigger_minimum_interval == "":
135
+ return f" {action_name} {trigger_number_times} /\n"
136
+
137
+ return f" {action_name} {trigger_number_times} {trigger_minimum_interval} /\n"
138
+
139
+ def create_record2_choke_wait(self, icv_name: str, step: int, criteria: int) -> str:
140
+ """Creates the ACTIONX record 2 inequalities for the choke wait function.
141
+
142
+ Args:
143
+ icv_name: One or two symbols, I.E: A or Z9.
144
+ step: Counter for ACTIONX.
145
+ criteria: Integer value denoting the criteria.
146
+
147
+ Returns:
148
+ ACTIONX record 2 for the wait choke function.
149
+
150
+ """
151
+ icv_function = ICVMethod.CHOKE_WAIT
152
+ end_rec = " /\n/\n"
153
+ custom_content = self.initials.get_custom_content(icv_name, icv_function, criteria)
154
+
155
+ insert_futstp = ""
156
+ if step >= 2:
157
+ insert_futstp = f" FUTSTP > FUL_{icv_name} AND /\n"
158
+ insert_parameter_block = (
159
+ f"{insert_futstp}"
160
+ f" FUTC_{icv_name} <= FUD_{icv_name} AND /\n"
161
+ f" FUP_{icv_name} = 2 AND /\n"
162
+ f" FUT_{icv_name} > FUFRQ_{icv_name}"
163
+ )
164
+ if custom_content is not None and custom_content != "":
165
+ return f"{insert_parameter_block} AND /\n{custom_content}"
166
+ return insert_parameter_block + end_rec
167
+
168
+ def create_record2_choke_wait_stop(self, icv_name: str, criteria: int | None = None) -> str:
169
+ """Creates the ACTIONX record 2 for the choke wait stop function.
170
+
171
+ Args:
172
+ icv_name: One or two symbols naming the icv.
173
+ criteria: Integer value denoting the criteria. Defaults to 1 if None or not provided.
174
+
175
+ Returns:
176
+ ACTIONX record 2 for the wait open function.
177
+
178
+ """
179
+ if criteria is None:
180
+ criteria = 1
181
+
182
+ icv_function = ICVMethod.CHOKE_WAIT_STOP
183
+ end_rec = " /\n/\n"
184
+ custom_content = self.initials.get_custom_content(icv_name, icv_function, criteria)
185
+ insert_parameter_block = f" FUP_{icv_name} = 2 AND /\n FUTC_{icv_name} != 0"
186
+ if custom_content is not None and custom_content != "":
187
+ return f"{insert_parameter_block} AND /\n{custom_content}"
188
+ else:
189
+ return insert_parameter_block + end_rec
190
+
191
+ def create_record2_open_wait(self, icv_name: str, step: int, criteria: int) -> str:
192
+ """Creates the ACTIONX record 2 inequalities for the wait open function.
193
+
194
+ Args:
195
+ icv_name: One or two symbols naming the ICV.
196
+ step: Counter for ACTIONX.
197
+ criteria: Integer value denoting the criteria.
198
+
199
+ Output:
200
+ ACTIONX record 2 for the wait open function.
201
+
202
+ """
203
+ icv_function = ICVMethod.OPEN_WAIT
204
+ end_rec = " /\n/\n"
205
+ custom_content = self.initials.get_custom_content(icv_name, icv_function, criteria)
206
+
207
+ insert_futstp = ""
208
+ if step >= 2:
209
+ insert_futstp = f" FUTSTP > FUL_{icv_name} AND /\n"
210
+
211
+ insert_parameter_block = (
212
+ f"{insert_futstp}"
213
+ f" FUTO_{icv_name} <= FUD_{icv_name} AND /\n"
214
+ f" FUP_{icv_name} = 2 AND /\n"
215
+ f" FUT_{icv_name} > FUFRQ_{icv_name}"
216
+ )
217
+
218
+ if custom_content is not None and custom_content != "":
219
+ return f"{insert_parameter_block} AND /\n{custom_content}"
220
+ else:
221
+ return insert_parameter_block + end_rec
222
+
223
+ def create_record2_open_wait_stop(self, icv_name: str, criteria: int | None = None) -> str:
224
+ """Creates the ACTIONX record 2 for the open wait stop function.
225
+
226
+ Args:
227
+ icv_name: One or two symbols naming the ICV.
228
+ criteria: Integer value denoting the criteria. Defaults to 1 if None or not provided.
229
+
230
+ Returns:
231
+ ACTIONX record 2 for the wait open function.
232
+
233
+ """
234
+ if criteria is None:
235
+ criteria = 1
236
+ icv_function = ICVMethod.OPEN_WAIT_STOP
237
+ end_rec = " /\n/\n"
238
+ custom_content = self.initials.get_custom_content(icv_name, icv_function, criteria)
239
+ insert_parameter_block = f" FUP_{icv_name} = 2 AND /\n FUTO_{icv_name} != 0"
240
+ if custom_content is not None and custom_content != "":
241
+ return f"{insert_parameter_block} AND /\n{custom_content}"
242
+ else:
243
+ return insert_parameter_block + end_rec
244
+
245
+ def create_record2_choke_ready(self, icv_name: str, criteria: int | None) -> str:
246
+ """Creates the ACTIONX record 2 inequalities for the ready choke function.
247
+
248
+ Args:
249
+ icv_name: One or two symbols.
250
+ criteria: Integer value denoting the criteria.
251
+
252
+ Output:
253
+ ACTIONX record 2 for the ready choke function.
254
+
255
+ """
256
+ icv_function = ICVMethod.CHOKE_READY
257
+ end_rec = " /\n/\n"
258
+ custom_content = self.initials.get_custom_content(icv_name, icv_function, criteria)
259
+
260
+ insert_parameter_block = f" FUTC_{icv_name} > FUD_{icv_name} AND /\n FUP_{icv_name} = 2"
261
+ if custom_content is not None and custom_content != "":
262
+ return f"{insert_parameter_block} AND /\n{custom_content}"
263
+ else:
264
+ return insert_parameter_block + end_rec
265
+
266
+ def create_record2_open_ready(self, icv_name: str, criteria: int | None) -> str:
267
+ """Creates the ACTIONX record 2 inequalities for the ready open function.
268
+
269
+ Args:
270
+ icv_name: One or two symbols.
271
+ criteria: Integer value denoting the criteria.
272
+
273
+ Output:
274
+ ACTIONX record 2 for the ready open function.
275
+
276
+ """
277
+
278
+ icv_function = ICVMethod.OPEN_READY
279
+ end_rec = " /\n/\n"
280
+ custom_content = self.initials.get_custom_content(icv_name, icv_function, criteria)
281
+ insert_parameter_block = f" FUTO_{icv_name} > FUD_{icv_name} AND /\n FUP_{icv_name} = 2"
282
+ if custom_content is not None and custom_content != "":
283
+ return f"{insert_parameter_block} AND /\n{custom_content}"
284
+ else:
285
+ return insert_parameter_block + end_rec
286
+
287
+ def create_record2_choke_stop(self, icv_name: str, criteria: int | None) -> str:
288
+ """Creates the ACTIONX record 2 inequalities for the stop choke function.
289
+
290
+ Args:
291
+ icv_name: One or two symbols.
292
+ criteria: Integer value denoting the criteria.
293
+
294
+ Returns:
295
+ ACTIONX record 2 for the stop choke function.
296
+
297
+ """
298
+ icv_function = ICVMethod.CHOKE_STOP
299
+ insert_parameter_block = f" FUP_{icv_name} = 4 AND /\n FUTC_{icv_name} != 0"
300
+
301
+ end_rec = " /\n/\n"
302
+ custom_content = self.initials.get_custom_content(icv_name, icv_function, criteria)
303
+
304
+ if custom_content is not None and custom_content != "":
305
+ return f"{insert_parameter_block} AND /\n{custom_content}"
306
+ else:
307
+ return insert_parameter_block + end_rec
308
+
309
+ def create_record2_open_stop(self, icv_name: str, criteria: int | None) -> str:
310
+ """Creates the ACTIONX record 2 inequalities for the stop open function.
311
+
312
+ Args:
313
+ icv_name: One or two symbols naming the ICV.
314
+ criteria: Integer value denoting the criteria.
315
+
316
+ Returns:
317
+ ACTIONX record 2 for the stop open function.
318
+
319
+ """
320
+ icv_function = ICVMethod.OPEN_STOP
321
+ insert_parameter_block = f" FUP_{icv_name} = 3 AND /\n FUTO_{icv_name} != 0"
322
+ end_rec = " /\n/\n"
323
+ custom_content = self.initials.get_custom_content(icv_name, icv_function, criteria)
324
+ if custom_content is not None and custom_content != "":
325
+ return f"{insert_parameter_block} AND /\n{custom_content}"
326
+ else:
327
+ return insert_parameter_block + end_rec
328
+
329
+ def create_record2_choke(self, icv_name: str, step: int, criteria: int | None) -> str:
330
+ """Creates the ACTIONX record 2 inequalities for the choke function.
331
+
332
+ Args:
333
+ icv_name: One or two symbols naming the ICV.
334
+ step: Counter for ACTIONX.
335
+ criteria: Integer value denoting the criteria.
336
+
337
+ Returns:
338
+ ACTIONX record 2 for the choke function.
339
+
340
+ """
341
+ icv_function = ICVMethod.CHOKE
342
+ end_rec = " /\n/\n"
343
+ num_icvs = self.initials.number_of_icvs(icv_name)
344
+ custom_content = self.initials.get_custom_content(icv_name, icv_function, criteria)
345
+
346
+ insert_parameter_block = (
347
+ f" FUTSTP < FUH_{icv_name} AND /\n"
348
+ f" FUTSTP > FUL_{icv_name} AND /\n"
349
+ f" FUTC_{icv_name} > FUD_{icv_name} AND /\n"
350
+ f" FUP_{icv_name} = 4"
351
+ )
352
+ if step % 2 == 0:
353
+ return f" FUP_{icv_name} = 4{end_rec}"
354
+
355
+ if custom_content is not None and custom_content != "":
356
+ return f"{insert_parameter_block} AND /\n{custom_content}"
357
+
358
+ if num_icvs == 2:
359
+ return f"{insert_parameter_block}" f"{end_rec}"
360
+ insert_futstp = ""
361
+ if step == 1:
362
+ insert_futstp = f" FUTSTP < FUH_{icv_name} AND /\n" f" FUTSTP > FUL_{icv_name} AND /\n"
363
+ elif step >= 2:
364
+ insert_futstp = f" FUTSTP > FUL_{icv_name} AND /\n"
365
+ if custom_content is not None and custom_content != "":
366
+ return (
367
+ f"{insert_futstp}"
368
+ f" FUTC_{icv_name} > FUD_{icv_name} AND /\n"
369
+ f" FUP_{icv_name} = 4 AND /\n"
370
+ f"{custom_content}"
371
+ )
372
+ else:
373
+ return f"{insert_futstp}" f" FUTC_{icv_name} > FUD_{icv_name} AND /\n" f" FUP_{icv_name} = 4" f"{end_rec}"
374
+
375
+ def create_record2_open(self, icv_name: str, step: int, criteria: int | None) -> str:
376
+ """Creates the ACTIONX record 2 inequalities for the open function.
377
+
378
+ Args:
379
+ icv_name: One or two symbols naming the ICV.
380
+ step: Counter for ACTIONX.
381
+ criteria: Integer value denoting the criteria.
382
+
383
+ Returns:
384
+ ACTIONX record 2 for the open function.
385
+
386
+ """
387
+ icv_function = ICVMethod.OPEN
388
+ end_rec = " /\n/\n"
389
+ num_icvs = self.initials.number_of_icvs(icv_name)
390
+ custom_content = self.initials.get_custom_content(icv_name, icv_function, criteria)
391
+ insert_parameter_block = (
392
+ f" FUTSTP < FUH_{icv_name} AND /\n"
393
+ f" FUTSTP > FUL_{icv_name} AND /\n"
394
+ f" FUTO_{icv_name} > FUD_{icv_name} AND /\n"
395
+ f" FUP_{icv_name} = 3"
396
+ )
397
+ end_rec = " /\n/\n"
398
+ insert_futstp = ""
399
+ if step % 2 == 0:
400
+ return f" FUP_{icv_name} = 3{end_rec}"
401
+ if custom_content is not None and custom_content != "":
402
+ return f"{insert_parameter_block} AND /\n{custom_content}"
403
+ if num_icvs == 2:
404
+ return insert_parameter_block + end_rec
405
+
406
+ if step == 1:
407
+ insert_futstp = f" FUTSTP < FUH_{icv_name} AND /\n" f" FUTSTP > FUL_{icv_name} AND /\n"
408
+ elif step >= 2:
409
+ insert_futstp = f" FUTSTP > FUL_{icv_name} AND /\n"
410
+ return f"{insert_futstp}" f" FUTO_{icv_name} > FUD_{icv_name} AND /\n" f" FUP_{icv_name} = 3" f"{end_rec}"
411
+
412
+ def create_action(
413
+ self,
414
+ icv_name: str,
415
+ icv_function: str | ICVMethod,
416
+ step: int | None = None,
417
+ opening_table: dict[str, pd.DataFrame] | None = None,
418
+ ) -> str:
419
+ """Creates Eclipse ACTIONX actions for icv-control choke functions.
420
+
421
+ Args:
422
+ icv_name: One or two symbols naming the ICV.
423
+ icv_function: Abbreviation for icv functions.
424
+ step: value separating the first and remaining actions in the wait function.
425
+ opening_table: Table of openings from ICVTABLE keyword if exists.
426
+
427
+ Returns:
428
+ The action to be taken in different choke functions for icv-control.
429
+
430
+ Raises:
431
+ ValueError: if the icv_function keyword is not recognized.
432
+ ValueError: if step is None when required for OPEN or CHOKE functions.
433
+
434
+ """
435
+ well_name = self.initials.well_names[icv_name]
436
+ segment = self.initials.segments[icv_name]
437
+ area = self.initials.areas[icv_name]
438
+ table = True
439
+ if re.sub(r"[^a-zA-Z]", "", area) != "":
440
+ cv_area = self.initials.case.icv_table[area].iloc[-1]
441
+ eff_area = cv_area["CV"] * cv_area["AREA"]
442
+ area = f"{eff_area:.3e}" # put everything as scientific with 3 decimals
443
+ else:
444
+ table = False
445
+
446
+ if icv_function == ICVMethod.OPEN:
447
+ if step is None:
448
+ raise ValueError(f"step is required for {icv_function} function")
449
+ if (step % 2) == 0:
450
+ action = (
451
+ f"WSEGVALV\n"
452
+ f" {well_name} {segment} 1.0 FUARE_{icv_name} 5* {area} /\n/\n"
453
+ "NEXTSTEP\n"
454
+ f" {self.initials.operation_step[icv_name]} /\n"
455
+ )
456
+ else:
457
+ if opening_table and table:
458
+ opening_area = (
459
+ f" DEFINE FUPOS_{icv_name} (FUPOS_{icv_name} + 1) /\n" f" UPDATE FUPOS_{icv_name} NEXT /\n"
460
+ )
461
+ else:
462
+ opening_area = (
463
+ f" DEFINE FUARE_{icv_name} (FUARE_{icv_name} / 0.6) /\n" f" UPDATE FUARE_{icv_name} NEXT /\n"
464
+ )
465
+ action = f"UDQ\n{opening_area}/\nNEXTSTEP\n 0.1 /\n"
466
+ return action
467
+
468
+ if icv_function == ICVMethod.OPEN_WAIT:
469
+ return (
470
+ "UDQ\n"
471
+ f" DEFINE FUTO_{icv_name} FUTO_{icv_name} + TIMESTEP /\n/\n"
472
+ "NEXTSTEP\n"
473
+ f" {self.initials.wait_step[icv_name]} /\n"
474
+ )
475
+
476
+ if icv_function == ICVMethod.OPEN_READY:
477
+ return f"UDQ\n ASSIGN FUP_{icv_name} 3 /\n/"
478
+
479
+ if icv_function == ICVMethod.OPEN_STOP:
480
+ return (
481
+ "UDQ\n"
482
+ f" ASSIGN FUP_{icv_name} 2 /\n"
483
+ f" ASSIGN FUTO_{icv_name} 0 /\n"
484
+ f" ASSIGN FUT_{icv_name} 0 /\n"
485
+ f" UPDATE FUT_{icv_name} ON /\n/"
486
+ )
487
+
488
+ if icv_function == ICVMethod.OPEN_WAIT_STOP:
489
+ return f"UDQ\n ASSIGN FUTO_{icv_name} 0 /\n/"
490
+
491
+ if icv_function == ICVMethod.CHOKE_WAIT_STOP:
492
+ return f"UDQ\n ASSIGN FUTC_{icv_name} 0 /\n/"
493
+
494
+ if icv_function == ICVMethod.CHOKE:
495
+ if step is None:
496
+ raise ValueError(f"step is required for {icv_function} function")
497
+ if (step % 2) == 0:
498
+ action = (
499
+ f"WSEGVALV\n"
500
+ f" {well_name} {segment} 1.0 FUARE_{icv_name} 5* {area} /\n/\n"
501
+ "NEXTSTEP\n"
502
+ f" {self.initials.operation_step[icv_name]} /\n"
503
+ )
504
+ else:
505
+ if opening_table and table:
506
+ opening_area = (
507
+ f" DEFINE FUPOS_{icv_name} (FUPOS_{icv_name} - 1) /\n" f" UPDATE FUPOS_{icv_name} NEXT /\n"
508
+ )
509
+ else:
510
+ opening_area = (
511
+ f" DEFINE FUARE_{icv_name} (FUARE_{icv_name} * 0.6) /\n" f" UPDATE FUARE_{icv_name} NEXT /\n"
512
+ )
513
+
514
+ action = f"UDQ\n{opening_area}/\nNEXTSTEP\n 0.1 /\n"
515
+ return action
516
+
517
+ if icv_function == ICVMethod.CHOKE_WAIT:
518
+ return (
519
+ "UDQ\n"
520
+ f" DEFINE FUTC_{icv_name} FUTC_{icv_name} + TIMESTEP /\n/\n"
521
+ "NEXTSTEP\n"
522
+ f" {self.initials.wait_step[icv_name]} /\n"
523
+ )
524
+
525
+ if icv_function == ICVMethod.CHOKE_READY:
526
+ return f"UDQ\n ASSIGN FUP_{icv_name} 4 /\n/"
527
+
528
+ if icv_function == ICVMethod.CHOKE_STOP:
529
+ return (
530
+ "UDQ\n"
531
+ f" ASSIGN FUP_{icv_name} 2 /\n"
532
+ f" ASSIGN FUTC_{icv_name} 0 /\n"
533
+ f" ASSIGN FUT_{icv_name} 0 /\n"
534
+ f" UPDATE FUT_{icv_name} ON /\n/"
535
+ )
536
+
537
+ # All legal values of icv_function have already caused this function to return
538
+ # If we encounter something not caught, the value is wrong:
539
+ raise ValueError(f"The icv function type {icv_function} is not recognized")
540
+
541
+ def create_choke_wait(
542
+ self,
543
+ icv_name: str,
544
+ trigger_number_times: int,
545
+ trigger_minimum_interval: int,
546
+ actionx_repeater: int = 99,
547
+ criteria: int | None = None,
548
+ ) -> str:
549
+ """Creates the wait choke icv-control function.
550
+
551
+ Args:
552
+ icv_name: One or two symbols naming the ICV.
553
+ trigger_number_times: The number of times this action can be triggered.
554
+ trigger_minimum_interval: Minimum time interval between action triggers.
555
+ actionx_repeater: Times to repeat ACTIONX in the choke wait function.
556
+ criteria: Integer value denoting the criteria.
557
+
558
+ Returns:
559
+ The icv-control wait choke function.
560
+
561
+ """
562
+ if criteria is None:
563
+ criteria = 1
564
+
565
+ icv_function = ICVMethod.CHOKE_WAIT
566
+ step = 1
567
+ actionx = ""
568
+ action_name = self.create_action_name(icv_name, icv_function, step, criteria)
569
+ record1 = self.create_record1(action_name, trigger_number_times, trigger_minimum_interval)
570
+ record2 = self.create_record2_choke_wait(icv_name, step, criteria)
571
+ action = self.create_action(icv_name, icv_function, step)
572
+ actionx += insert_comment(icv_function, step, criteria)
573
+ actionx += self.create_actionx(record1, record2, action)
574
+ while step < actionx_repeater:
575
+ step += 1
576
+ actionx += insert_comment(icv_function, step, criteria)
577
+ action_name = self.create_action_name(icv_name, icv_function, step, criteria)
578
+ record1 = self.create_record1(action_name, 1, "")
579
+ record2 = self.create_record2_choke_wait(icv_name, step, criteria)
580
+ action = self.create_action(icv_name, icv_function, step)
581
+ actionx += self.create_actionx(record1, record2, action)
582
+ actionx += actionx_repeater * "ENDACTIO\n"
583
+ return actionx
584
+
585
+ def create_open_wait(self, icv_name: str, actionx_repeater: int = 99, criteria: int | None = None) -> str:
586
+ """Creates the icv-control wait open function.
587
+
588
+ Args:
589
+ icv_name: One or two symbols naming the ICV.
590
+ actionx_repeater: Times to repeat ACTIONX in the choke wait function.
591
+ criteria: Integer value denoting the criteria.
592
+ Returns:
593
+ The icv-control wait open function.
594
+
595
+ """
596
+ if criteria is None:
597
+ criteria = 1
598
+
599
+ icv_function = ICVMethod.OPEN_WAIT
600
+ step = 1
601
+ actionx = ""
602
+ action_name = self.create_action_name(icv_name, icv_function, step, criteria)
603
+ record1 = self.create_record1(action_name, 10000, 10)
604
+ record2 = self.create_record2_open_wait(icv_name, step, criteria)
605
+ action = self.create_action(icv_name, icv_function, step)
606
+ actionx += insert_comment(icv_function, step, criteria)
607
+ actionx += self.create_actionx(record1, record2, action)
608
+ while step < actionx_repeater:
609
+ step += 1
610
+ actionx += insert_comment(icv_function, step, criteria)
611
+ action_name = self.create_action_name(icv_name, icv_function, step, criteria)
612
+ record1 = self.create_record1(action_name, 1, "")
613
+ record2 = self.create_record2_open_wait(icv_name, step, criteria)
614
+ action = self.create_action(icv_name, icv_function, step)
615
+ actionx += self.create_actionx(record1, record2, action)
616
+ return actionx + actionx_repeater * "ENDACTIO\n"
617
+
618
+ def create_choke_wait_stop(self, icv_name: str, criteria: int | None = None) -> str:
619
+ """Creates the icv-control choke wait stop function.
620
+
621
+ Args:
622
+ icv_name: One or two symbols naming the ICV.
623
+ criteria: Integer value denoting the criteria.
624
+
625
+ Returns:
626
+ The icv-control wait open function.
627
+
628
+ """
629
+ icv_function = ICVMethod.CHOKE_WAIT_STOP
630
+ actionx = ""
631
+ action_name = self.create_action_name(icv_name, icv_function, None, criteria=criteria)
632
+ record1 = self.create_record1(action_name, 10000, 10)
633
+ record2 = self.create_record2_choke_wait_stop(icv_name, criteria=criteria)
634
+ action = self.create_action(icv_name, icv_function)
635
+ actionx += insert_comment(icv_function)
636
+ actionx += self.create_actionx(record1, record2, action)
637
+ return actionx + "ENDACTIO\n\n"
638
+
639
+ def create_open_wait_stop(self, icv_name: str, criteria: int | None = None) -> str:
640
+ """Creates the icv-control open wait stop function.
641
+
642
+ Args:
643
+ icv_name: Icv name. Letter from A through Z.
644
+
645
+ Returns:
646
+ The icv-control wait open function.
647
+
648
+ """
649
+ icv_function = ICVMethod.OPEN_WAIT_STOP
650
+ actionx = ""
651
+ action_name = self.create_action_name(icv_name, icv_function, None, criteria=criteria)
652
+ record1 = self.create_record1(action_name, 10000, 10)
653
+ record2 = self.create_record2_open_wait_stop(icv_name, criteria=criteria)
654
+ action = self.create_action(icv_name, icv_function)
655
+ actionx += insert_comment(icv_function)
656
+ actionx += self.create_actionx(record1, record2, action)
657
+ return actionx + "ENDACTIO\n\n"
658
+
659
+ def create_choke_ready(
660
+ self,
661
+ icv_name: str,
662
+ criteria: int | None = None,
663
+ trigger_number_times: int = 10,
664
+ trigger_minimum_interval: str = "",
665
+ ) -> str:
666
+ """Creates the ready choke function for icv-control.
667
+
668
+ Args:
669
+ icv_name: One or two symbols naming the ICV.
670
+ criteria: Integer value denoting the criteria.
671
+ trigger_number_times: The number of times this action can be triggered.
672
+ trigger_minimum_interval: Minimum time interval between action triggers.
673
+
674
+ Returns:
675
+ The icv-control ready choke function.
676
+
677
+ """
678
+ if criteria is None:
679
+ criteria = 1
680
+
681
+ icv_function = ICVMethod.CHOKE_READY
682
+ action_name = self.create_action_name(icv_name, icv_function, None, criteria)
683
+ record1 = self.create_record1(action_name, trigger_number_times, trigger_minimum_interval)
684
+ record2 = self.create_record2_choke_ready(icv_name, criteria)
685
+ action = self.create_action(icv_name, icv_function, None)
686
+ return (
687
+ insert_comment(icv_function, criteria=criteria)
688
+ + self.create_actionx(record1, record2, action)
689
+ + "ENDACTIO\n\n"
690
+ )
691
+
692
+ def create_open_ready(
693
+ self,
694
+ icv_name: str,
695
+ criteria: int | None = 1,
696
+ trigger_number_times: int = 10,
697
+ trigger_minimum_interval: str = "",
698
+ ) -> str:
699
+ """Creates the ready open function for icv-control.
700
+
701
+ Args:
702
+ icv_name: One or two symbols naming the ICV.
703
+ criteria: Integer value denoting the criteria.
704
+ trigger_number_times: The number of times this action can be triggered.
705
+ trigger_minimum_interval: Minimum time interval between action triggers.
706
+
707
+ Returns:
708
+ The icv-control ready open function.
709
+
710
+ """
711
+ icv_function = ICVMethod.OPEN_READY
712
+ action_name = self.create_action_name(icv_name, icv_function, None, criteria)
713
+ record1 = self.create_record1(action_name, trigger_number_times, trigger_minimum_interval)
714
+ record2 = self.create_record2_open_ready(icv_name, criteria)
715
+ action = self.create_action(icv_name, icv_function, None)
716
+ return (
717
+ insert_comment(icv_function, criteria=criteria)
718
+ + self.create_actionx(record1, record2, action)
719
+ + "ENDACTIO\n\n"
720
+ )
721
+
722
+ def create_choke_stop(
723
+ self, icv_name: str, criteria: int | None, trigger_number_times: int, trigger_minimum_interval: str
724
+ ) -> str:
725
+ """The icv-control stop choke function.
726
+
727
+ Args:
728
+ icv_name: One or two symbols naming the ICV.
729
+ criteria: Integer value denoting the criteria.
730
+ trigger_number_times: The number of times this action can be triggered.
731
+ trigger_minimum_interval: Minimum time interval between action triggers.
732
+
733
+ Returns:
734
+ The icv-control stop choke function.
735
+
736
+ """
737
+ icv_function = ICVMethod.CHOKE_STOP
738
+ action_name = self.create_action_name(icv_name, icv_function, None, criteria)
739
+ record1 = self.create_record1(action_name, trigger_number_times, trigger_minimum_interval)
740
+ record2 = self.create_record2_choke_stop(icv_name, criteria)
741
+ action = self.create_action(icv_name, icv_function, None)
742
+ return insert_comment(icv_function) + self.create_actionx(record1, record2, action) + "ENDACTIO\n\n"
743
+
744
+ def create_open_stop(
745
+ self, icv_name: str, criteria: int | None, trigger_number_times: int, trigger_minimum_interval: str
746
+ ) -> str:
747
+ """The icv-control stop open function.
748
+
749
+ Args:
750
+ icv_name: One or two symbols naming the ICV.
751
+ criteria: Integer value denoting the criteria.
752
+ trigger_number_times: The number of times this action can be triggered.
753
+ trigger_minimum_interval: Minimum time interval between action triggers.
754
+
755
+ Returns:
756
+ The icv-control stop open function.
757
+
758
+ """
759
+ icv_function = ICVMethod.OPEN_STOP
760
+ action_name = self.create_action_name(icv_name, icv_function, None, criteria)
761
+ record1 = self.create_record1(action_name, trigger_number_times, trigger_minimum_interval)
762
+ record2 = self.create_record2_open_stop(icv_name, criteria)
763
+ action = self.create_action(icv_name, icv_function, None)
764
+ return insert_comment(icv_function) + self.create_actionx(record1, record2, action) + "ENDACTIO\n\n"
765
+
766
+ def create_choke(
767
+ self,
768
+ icv_name: str,
769
+ criteria: int | None,
770
+ trigger_number_times: int,
771
+ trigger_minimum_interval: int | str = "",
772
+ actionx_repeater: int = 9,
773
+ ) -> str:
774
+ """The icv-control choke function.
775
+
776
+ Args:
777
+ icv_name: One or two symbols naming the ICV.
778
+ criteria: Integer value denoting the criteria.
779
+ trigger_number_times: The number of times this action can be triggered.
780
+ trigger_minimum_interval: Minimum time interval between action triggers.
781
+ actionx_repeater: Times to repeat ACTIONX in the choke wait function.
782
+
783
+ Returns:
784
+ The icv-control choke function.
785
+
786
+ """
787
+ icv_function = ICVMethod.CHOKE
788
+ step = 1
789
+ actionx = ""
790
+ action_name = self.create_action_name(icv_name, icv_function, step, criteria)
791
+ record1 = self.create_record1(action_name, trigger_number_times, trigger_minimum_interval)
792
+ record2 = self.create_record2_choke(icv_name, step, criteria)
793
+ action = self.create_action(icv_name, icv_function, step, self.initials.case.icv_table)
794
+ actionx += insert_comment(icv_function, step, criteria)
795
+ actionx += self.create_actionx(record1, record2, action)
796
+ while step < actionx_repeater:
797
+ step += 1
798
+ actionx += insert_comment(icv_function, step, criteria)
799
+ action_name = self.create_action_name(icv_name, icv_function, step, criteria)
800
+ record1 = self.create_record1(action_name, 1, "")
801
+ record2 = self.create_record2_choke(icv_name, step, criteria)
802
+ action = self.create_action(icv_name, icv_function, step, self.initials.case.icv_table)
803
+ actionx += self.create_actionx(record1, record2, action)
804
+ actionx += actionx_repeater * "ENDACTIO\n"
805
+ return actionx
806
+
807
+ def create_open(
808
+ self,
809
+ icv_name: str,
810
+ criteria: int | None,
811
+ trigger_number_times: int,
812
+ trigger_minimum_interval: int | str,
813
+ actionx_repeater: int = 9,
814
+ ) -> str:
815
+ """The icv-control open choke function.
816
+
817
+ Args:
818
+ icv_name: One or two symbols naming the ICV.
819
+ criteria: Integer value denoting the criteria.
820
+ trigger_number_times: The number of times this action can be triggered.
821
+ trigger_minimum_interval: Minimum time interval between action triggers.
822
+ actionx_repeater: Times to repeat ACTIONX in the choke wait function.
823
+
824
+ Returns:
825
+ The icv-control open choke function.
826
+
827
+ """
828
+ icv_function = ICVMethod.OPEN
829
+ step = 1
830
+ actionx = ""
831
+ action_name = self.create_action_name(icv_name, icv_function, step, criteria)
832
+ record1 = self.create_record1(action_name, trigger_number_times, trigger_minimum_interval)
833
+ record2 = self.create_record2_open(icv_name, step, criteria)
834
+ action = self.create_action(icv_name, icv_function, step, self.initials.case.icv_table)
835
+ actionx += insert_comment(icv_function, step, criteria)
836
+ actionx += self.create_actionx(record1, record2, action)
837
+ while step < actionx_repeater:
838
+ step += 1
839
+ actionx += insert_comment(icv_function, step, criteria)
840
+ action_name = self.create_action_name(icv_name, icv_function, step, criteria)
841
+ record1 = self.create_record1(action_name, 1, "")
842
+ record2 = self.create_record2_open(icv_name, step, criteria)
843
+ action = self.create_action(icv_name, icv_function, step, self.initials.case.icv_table)
844
+ actionx += self.create_actionx(record1, record2, action)
845
+ return actionx + actionx_repeater * "ENDACTIO\n"