xtgeo 4.14.1__cp313-cp313-win_amd64.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.
Files changed (122) hide show
  1. cxtgeo.py +558 -0
  2. cxtgeoPYTHON_wrap.c +19537 -0
  3. xtgeo/__init__.py +248 -0
  4. xtgeo/_cxtgeo.cp313-win_amd64.pyd +0 -0
  5. xtgeo/_internal.cp313-win_amd64.pyd +0 -0
  6. xtgeo/common/__init__.py +19 -0
  7. xtgeo/common/_angles.py +29 -0
  8. xtgeo/common/_xyz_enum.py +50 -0
  9. xtgeo/common/calc.py +396 -0
  10. xtgeo/common/constants.py +30 -0
  11. xtgeo/common/exceptions.py +42 -0
  12. xtgeo/common/log.py +93 -0
  13. xtgeo/common/sys.py +166 -0
  14. xtgeo/common/types.py +18 -0
  15. xtgeo/common/version.py +34 -0
  16. xtgeo/common/xtgeo_dialog.py +604 -0
  17. xtgeo/cube/__init__.py +9 -0
  18. xtgeo/cube/_cube_export.py +214 -0
  19. xtgeo/cube/_cube_import.py +532 -0
  20. xtgeo/cube/_cube_roxapi.py +180 -0
  21. xtgeo/cube/_cube_utils.py +287 -0
  22. xtgeo/cube/_cube_window_attributes.py +273 -0
  23. xtgeo/cube/cube1.py +1023 -0
  24. xtgeo/grid3d/__init__.py +15 -0
  25. xtgeo/grid3d/_ecl_grid.py +778 -0
  26. xtgeo/grid3d/_ecl_inte_head.py +152 -0
  27. xtgeo/grid3d/_ecl_logi_head.py +71 -0
  28. xtgeo/grid3d/_ecl_output_file.py +81 -0
  29. xtgeo/grid3d/_egrid.py +1004 -0
  30. xtgeo/grid3d/_find_gridprop_in_eclrun.py +625 -0
  31. xtgeo/grid3d/_grdecl_format.py +309 -0
  32. xtgeo/grid3d/_grdecl_grid.py +400 -0
  33. xtgeo/grid3d/_grid3d.py +29 -0
  34. xtgeo/grid3d/_grid3d_fence.py +284 -0
  35. xtgeo/grid3d/_grid3d_utils.py +228 -0
  36. xtgeo/grid3d/_grid_boundary.py +76 -0
  37. xtgeo/grid3d/_grid_etc1.py +1683 -0
  38. xtgeo/grid3d/_grid_export.py +222 -0
  39. xtgeo/grid3d/_grid_hybrid.py +50 -0
  40. xtgeo/grid3d/_grid_import.py +79 -0
  41. xtgeo/grid3d/_grid_import_ecl.py +101 -0
  42. xtgeo/grid3d/_grid_import_roff.py +135 -0
  43. xtgeo/grid3d/_grid_import_xtgcpgeom.py +375 -0
  44. xtgeo/grid3d/_grid_refine.py +258 -0
  45. xtgeo/grid3d/_grid_roxapi.py +292 -0
  46. xtgeo/grid3d/_grid_translate_coords.py +154 -0
  47. xtgeo/grid3d/_grid_wellzone.py +165 -0
  48. xtgeo/grid3d/_gridprop_export.py +202 -0
  49. xtgeo/grid3d/_gridprop_import_eclrun.py +164 -0
  50. xtgeo/grid3d/_gridprop_import_grdecl.py +132 -0
  51. xtgeo/grid3d/_gridprop_import_roff.py +52 -0
  52. xtgeo/grid3d/_gridprop_import_xtgcpprop.py +168 -0
  53. xtgeo/grid3d/_gridprop_lowlevel.py +171 -0
  54. xtgeo/grid3d/_gridprop_op1.py +272 -0
  55. xtgeo/grid3d/_gridprop_roxapi.py +301 -0
  56. xtgeo/grid3d/_gridprop_value_init.py +140 -0
  57. xtgeo/grid3d/_gridprops_import_eclrun.py +344 -0
  58. xtgeo/grid3d/_gridprops_import_roff.py +83 -0
  59. xtgeo/grid3d/_roff_grid.py +470 -0
  60. xtgeo/grid3d/_roff_parameter.py +303 -0
  61. xtgeo/grid3d/grid.py +3010 -0
  62. xtgeo/grid3d/grid_properties.py +699 -0
  63. xtgeo/grid3d/grid_property.py +1313 -0
  64. xtgeo/grid3d/types.py +15 -0
  65. xtgeo/interfaces/rms/__init__.py +18 -0
  66. xtgeo/interfaces/rms/_regular_surface.py +460 -0
  67. xtgeo/interfaces/rms/_rms_base.py +100 -0
  68. xtgeo/interfaces/rms/_rmsapi_package.py +69 -0
  69. xtgeo/interfaces/rms/rmsapi_utils.py +438 -0
  70. xtgeo/io/__init__.py +1 -0
  71. xtgeo/io/_file.py +603 -0
  72. xtgeo/metadata/__init__.py +17 -0
  73. xtgeo/metadata/metadata.py +435 -0
  74. xtgeo/roxutils/__init__.py +7 -0
  75. xtgeo/roxutils/_roxar_loader.py +54 -0
  76. xtgeo/roxutils/_roxutils_etc.py +122 -0
  77. xtgeo/roxutils/roxutils.py +207 -0
  78. xtgeo/surface/__init__.py +20 -0
  79. xtgeo/surface/_regsurf_boundary.py +26 -0
  80. xtgeo/surface/_regsurf_cube.py +210 -0
  81. xtgeo/surface/_regsurf_cube_window.py +391 -0
  82. xtgeo/surface/_regsurf_cube_window_v2.py +297 -0
  83. xtgeo/surface/_regsurf_cube_window_v3.py +360 -0
  84. xtgeo/surface/_regsurf_export.py +388 -0
  85. xtgeo/surface/_regsurf_grid3d.py +275 -0
  86. xtgeo/surface/_regsurf_gridding.py +347 -0
  87. xtgeo/surface/_regsurf_ijxyz_parser.py +278 -0
  88. xtgeo/surface/_regsurf_import.py +347 -0
  89. xtgeo/surface/_regsurf_lowlevel.py +122 -0
  90. xtgeo/surface/_regsurf_oper.py +538 -0
  91. xtgeo/surface/_regsurf_utils.py +81 -0
  92. xtgeo/surface/_surfs_import.py +43 -0
  93. xtgeo/surface/_zmap_parser.py +138 -0
  94. xtgeo/surface/regular_surface.py +3043 -0
  95. xtgeo/surface/surfaces.py +276 -0
  96. xtgeo/well/__init__.py +24 -0
  97. xtgeo/well/_blockedwell_roxapi.py +241 -0
  98. xtgeo/well/_blockedwells_roxapi.py +68 -0
  99. xtgeo/well/_well_aux.py +30 -0
  100. xtgeo/well/_well_io.py +327 -0
  101. xtgeo/well/_well_oper.py +483 -0
  102. xtgeo/well/_well_roxapi.py +304 -0
  103. xtgeo/well/_wellmarkers.py +486 -0
  104. xtgeo/well/_wells_utils.py +158 -0
  105. xtgeo/well/blocked_well.py +220 -0
  106. xtgeo/well/blocked_wells.py +134 -0
  107. xtgeo/well/well1.py +1516 -0
  108. xtgeo/well/wells.py +211 -0
  109. xtgeo/xyz/__init__.py +6 -0
  110. xtgeo/xyz/_polygons_oper.py +272 -0
  111. xtgeo/xyz/_xyz.py +758 -0
  112. xtgeo/xyz/_xyz_data.py +646 -0
  113. xtgeo/xyz/_xyz_io.py +737 -0
  114. xtgeo/xyz/_xyz_lowlevel.py +42 -0
  115. xtgeo/xyz/_xyz_oper.py +613 -0
  116. xtgeo/xyz/_xyz_roxapi.py +766 -0
  117. xtgeo/xyz/points.py +698 -0
  118. xtgeo/xyz/polygons.py +827 -0
  119. xtgeo-4.14.1.dist-info/METADATA +146 -0
  120. xtgeo-4.14.1.dist-info/RECORD +122 -0
  121. xtgeo-4.14.1.dist-info/WHEEL +5 -0
  122. xtgeo-4.14.1.dist-info/licenses/LICENSE.md +165 -0
@@ -0,0 +1,152 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, Literal, cast
4
+
5
+ import numpy as np
6
+ import numpy.typing as npt
7
+
8
+ from xtgeo.common.log import null_logger
9
+
10
+ from ._ecl_output_file import Phases, Simulator, TypeOfGrid, UnitSystem
11
+
12
+ _logger = null_logger(__name__)
13
+
14
+
15
+ class InteHead:
16
+ """Contains the values for the INTEHEAD array in ecl restart
17
+ and init files.
18
+
19
+ Output files from eclipse and opm flow will contain sections
20
+ starting with keyword-array headers. One of these is the INTEHEAD
21
+ keyword. The values in the array are integers, and the meaning
22
+ of each index is described in the e.g. the OPM user manual (2021-04 rev_01
23
+ section D.6-D.7).
24
+
25
+ The length of the array is not specified, meaning some values are missing,
26
+ the InteHead class creates a lookup for these values:
27
+
28
+ >>> intehead = InteHead(np.array([0,1,2,3,4,5,6,7,8]))
29
+ >>> intehead.num_x
30
+ 8
31
+ >>> # The year field is missing in the input
32
+ >>> intehead.year is None
33
+ True
34
+ """
35
+
36
+ def __init__(self, values: npt.NDArray[np.int_]) -> None:
37
+ """Create an InteHead from the corresponding array.
38
+
39
+ Args:
40
+ values: Array of values following the INTEHEAD keyword
41
+ in an ECL restart or init file.
42
+ """
43
+ self.values = values
44
+
45
+ def __eq__(self, other: Any) -> bool:
46
+ if not isinstance(other, InteHead):
47
+ return False
48
+
49
+ return np.array_equal(self.values, other.values)
50
+
51
+ def __repr__(self) -> str:
52
+ return f"InteHead(values={self.values})"
53
+
54
+ def __str__(self) -> str:
55
+ return self.__repr__()
56
+
57
+ def _optional_index_lookup(self, index: int) -> int | None:
58
+ """Looks up the value at the given index, returning None if out of bound.
59
+
60
+ Args:
61
+ index: The index in the value array to look up
62
+ constructor: Constructor function to wrap non-None values in, defaults
63
+ to identity.
64
+ Returns:
65
+ value at the index, None if out of bounds.
66
+ """
67
+ return self.values[index] if len(self.values) > index else None
68
+
69
+ @property
70
+ def unit_system(self) -> UnitSystem | None:
71
+ """
72
+ The unit system used in the file.
73
+ """
74
+ v = self._optional_index_lookup(2)
75
+ return None if v is None else UnitSystem(v)
76
+
77
+ @property
78
+ def num_x(self) -> int | None:
79
+ """The number of columns (x direction) of cells"""
80
+ return self._optional_index_lookup(8)
81
+
82
+ @property
83
+ def num_y(self) -> int | None:
84
+ """The number of rows (y direction) of cells"""
85
+ return self._optional_index_lookup(9)
86
+
87
+ @property
88
+ def num_z(self) -> int | None:
89
+ """The number of layers (z direction) of cells"""
90
+ return self._optional_index_lookup(10)
91
+
92
+ @property
93
+ def num_active(self) -> int | None:
94
+ """The number of active cells"""
95
+ return self._optional_index_lookup(11)
96
+
97
+ @property
98
+ def phases(self) -> Phases | None:
99
+ """The phase system used for simulation"""
100
+ if any(ids in str(self.simulator) for ids in ["300", "INTERSECT"]):
101
+ # item 14 in E300 runs is number of tracers, not IPHS; assume oil/wat/gas
102
+ # item 14 in INTERSECT is always(?) undef., not IPHS; assume oil/wat/gas
103
+ return Phases.OIL_WATER_GAS
104
+ v = self._optional_index_lookup(14)
105
+ return None if v is None else Phases(v)
106
+
107
+ @property
108
+ def day(self) -> int | None:
109
+ """The simulated time calendar day
110
+
111
+ (e.g. 3rd of april 2018)
112
+
113
+ """
114
+ return self._optional_index_lookup(64)
115
+
116
+ @property
117
+ def month(self) -> int | None:
118
+ """The simulated time calendar month
119
+
120
+ 4 for simulation being in month 4.
121
+
122
+ """
123
+ return self._optional_index_lookup(65)
124
+
125
+ @property
126
+ def year(self) -> int | None:
127
+ """The simulated time calendar month
128
+
129
+ e.g. 2018 for simulation being done in year 2018
130
+ """
131
+ return self._optional_index_lookup(66)
132
+
133
+ @property
134
+ def simulator(self) -> Simulator | int | None:
135
+ """The simulator used for producing the run, or integer code if unknown"""
136
+ s_code = self._optional_index_lookup(94)
137
+ try:
138
+ return Simulator(s_code)
139
+ except ValueError:
140
+ # changed from a UserWarning to a logging message
141
+ _logger.warning("Unknown simulator code %s", s_code)
142
+ return s_code
143
+
144
+ @property
145
+ def type_of_grid(self) -> TypeOfGrid | None:
146
+ """The type of grid used in the simulation"""
147
+ value = self._optional_index_lookup(13)
148
+ return (
149
+ None
150
+ if value is None
151
+ else TypeOfGrid.alternate_code(cast("Literal[0, 1, 2, 3]", value))
152
+ )
@@ -0,0 +1,71 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+
5
+ from ._ecl_output_file import Simulator
6
+
7
+
8
+ def lookup_optional_code(values: list[bool], index: int) -> bool | None:
9
+ if len(values) <= index:
10
+ return None
11
+ return values[index]
12
+
13
+
14
+ @dataclass
15
+ class LogiHead:
16
+ """Contains the values for the LOGIHEAD array in restart and init files.
17
+
18
+ Output files from eclipse and opm flow will contain sections
19
+ starting with keyword-array headers. One of these is the LOGIHEAD
20
+ keyword. The values in the array are booleans, and the meaning
21
+ of each index is described in the e.g. the OPM user manual (2021-04 rev_01
22
+ section D.6-D.7).
23
+
24
+ The length of the array is not specified, meaning some values are missing,
25
+ the InteHead class creates a lookup for these values:
26
+
27
+ Generally, the field describe whether an option has been enabled in the
28
+ model, ie. if logihead.dual_porosity is True then the model uses the
29
+ dual porosity feature.
30
+
31
+ >>> logihead = LogiHead.from_file_values([True, True, False], Simulator.ECLIPSE_100)
32
+ >>> logihead.dissolved_gas
33
+ True
34
+ >>> # Whether coal bed methane is used is missing
35
+ >>> logihead.coal_bed_methane is None
36
+ True
37
+
38
+ """
39
+
40
+ dissolved_gas: bool | None = None
41
+ vaporized_oil: bool | None = None
42
+ directional: bool | None = None
43
+ radial: bool | None = None
44
+ reversible: bool | None = None
45
+ hysterisis: bool | None = None
46
+ dual_porosity: bool | None = None
47
+ end_point_scaling: bool | None = None
48
+ directional_end_point_scaling: bool | None = None
49
+ reversible_end_point_scaling: bool | None = None
50
+ alternate_end_point_scaling: bool | None = None
51
+ miscible_displacement: bool | None = None
52
+ scale_water_pressure1: bool | None = None
53
+ scale_water_pressure2: bool | None = None
54
+ coal_bed_methane: bool | None = None
55
+
56
+ @classmethod
57
+ def from_file_values(cls, values: list[bool], simulator: Simulator) -> LogiHead:
58
+ """Construct a LogiHead from the array following the LOGIHEAD keyword
59
+ Args:
60
+ values: The iterable of boolean values following the LOGIHEAD keyword
61
+ simulator: The meaning of each field is simulator dependent, so
62
+ the simulator must be given.
63
+ """
64
+ if simulator == Simulator.ECLIPSE_100:
65
+ # Weirdly, eclipse_100 outputs reversible and radial flags
66
+ # in swapped order.
67
+ indices = [0, 1, 2, 4, 3, 6, 14, 16, 17, 18, 19, 35, 55, 56, 127]
68
+ else:
69
+ indices = [0, 1, 2, 3, 4, 6, 14, 16, 17, 18, 19, 35, 55, 56, 127]
70
+
71
+ return cls(*[lookup_optional_code(values, i) for i in indices])
@@ -0,0 +1,81 @@
1
+ from __future__ import annotations
2
+
3
+ from enum import Enum, unique
4
+ from typing import Literal
5
+
6
+
7
+ @unique
8
+ class TypeOfGrid(Enum):
9
+ """
10
+ A Grid has three possible data layout formats, UNSTRUCTURED, CORNER_POINT,
11
+ BLOCK_CENTER and COMPOSITE (meaning combination of the two former). Only
12
+ CORNER_POINT layout is supported by XTGeo.
13
+ """
14
+
15
+ COMPOSITE = 0
16
+ CORNER_POINT = 1
17
+ UNSTRUCTURED = 2
18
+ BLOCK_CENTER = 3
19
+
20
+ @classmethod
21
+ def alternate_code(cls, code: Literal[0, 1, 2, 3]) -> TypeOfGrid:
22
+ """Converts from alternate code to TypeOfGrid member.
23
+
24
+ weirdly, type of grid sometimes (For instance init's INTHEAD and
25
+ FILEHEAD) have an alternate integer code for type of grid.
26
+ """
27
+ if code == 0:
28
+ type_of_grid = cls.CORNER_POINT
29
+ elif code == 1:
30
+ type_of_grid = cls.UNSTRUCTURED
31
+ elif code == 2:
32
+ type_of_grid = cls.COMPOSITE
33
+ elif code == 3:
34
+ type_of_grid = cls.BLOCK_CENTER
35
+ else:
36
+ raise ValueError(f"Unknown grid type {code}")
37
+ return type_of_grid
38
+
39
+ @property
40
+ def alternate_value(self) -> int:
41
+ """Inverse of alternate_code."""
42
+ alternate_value = 0
43
+ if self == TypeOfGrid.CORNER_POINT:
44
+ alternate_value = 0
45
+ elif self == TypeOfGrid.UNSTRUCTURED:
46
+ alternate_value = 1
47
+ elif self == TypeOfGrid.COMPOSITE:
48
+ alternate_value = 2
49
+ elif self == TypeOfGrid.BLOCK_CENTER:
50
+ alternate_value = 3
51
+ else:
52
+ raise ValueError(f"Unknown grid type {self}")
53
+ return alternate_value
54
+
55
+
56
+ @unique
57
+ class UnitSystem(Enum):
58
+ METRIC = 1
59
+ FIELD = 2
60
+ LAB = 3
61
+
62
+
63
+ @unique
64
+ class Phases(Enum):
65
+ E300_GENERIC = 0
66
+ OIL = 1
67
+ WATER = 2
68
+ OIL_WATER = 3
69
+ GAS = 4
70
+ OIL_GAS = 5
71
+ GAS_WATER = 6
72
+ OIL_WATER_GAS = 7
73
+
74
+
75
+ @unique
76
+ class Simulator(Enum):
77
+ ECLIPSE_100 = 100
78
+ ECLIPSE_300 = 300
79
+ ECLIPSE_300_THERMAL = 500
80
+ INTERSECT = 700
81
+ FRONTSIM = 800