xtgeo 4.8.0__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.

Potentially problematic release.


This version of xtgeo might be problematic. Click here for more details.

Files changed (117) hide show
  1. cxtgeo.py +582 -0
  2. cxtgeoPYTHON_wrap.c +20938 -0
  3. xtgeo/__init__.py +246 -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 +21 -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 +340 -0
  23. xtgeo/cube/cube1.py +1023 -0
  24. xtgeo/grid3d/__init__.py +15 -0
  25. xtgeo/grid3d/_ecl_grid.py +774 -0
  26. xtgeo/grid3d/_ecl_inte_head.py +148 -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 +266 -0
  32. xtgeo/grid3d/_grdecl_grid.py +388 -0
  33. xtgeo/grid3d/_grid3d.py +29 -0
  34. xtgeo/grid3d/_grid3d_fence.py +181 -0
  35. xtgeo/grid3d/_grid3d_utils.py +228 -0
  36. xtgeo/grid3d/_grid_boundary.py +76 -0
  37. xtgeo/grid3d/_grid_etc1.py +1566 -0
  38. xtgeo/grid3d/_grid_export.py +221 -0
  39. xtgeo/grid3d/_grid_hybrid.py +66 -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 +125 -0
  45. xtgeo/grid3d/_grid_roxapi.py +292 -0
  46. xtgeo/grid3d/_grid_wellzone.py +165 -0
  47. xtgeo/grid3d/_gridprop_export.py +178 -0
  48. xtgeo/grid3d/_gridprop_import_eclrun.py +164 -0
  49. xtgeo/grid3d/_gridprop_import_grdecl.py +130 -0
  50. xtgeo/grid3d/_gridprop_import_roff.py +52 -0
  51. xtgeo/grid3d/_gridprop_import_xtgcpprop.py +168 -0
  52. xtgeo/grid3d/_gridprop_lowlevel.py +171 -0
  53. xtgeo/grid3d/_gridprop_op1.py +174 -0
  54. xtgeo/grid3d/_gridprop_roxapi.py +239 -0
  55. xtgeo/grid3d/_gridprop_value_init.py +140 -0
  56. xtgeo/grid3d/_gridprops_import_eclrun.py +344 -0
  57. xtgeo/grid3d/_gridprops_import_roff.py +83 -0
  58. xtgeo/grid3d/_roff_grid.py +469 -0
  59. xtgeo/grid3d/_roff_parameter.py +303 -0
  60. xtgeo/grid3d/grid.py +2537 -0
  61. xtgeo/grid3d/grid_properties.py +699 -0
  62. xtgeo/grid3d/grid_property.py +1341 -0
  63. xtgeo/grid3d/types.py +15 -0
  64. xtgeo/io/__init__.py +1 -0
  65. xtgeo/io/_file.py +592 -0
  66. xtgeo/metadata/__init__.py +17 -0
  67. xtgeo/metadata/metadata.py +431 -0
  68. xtgeo/roxutils/__init__.py +7 -0
  69. xtgeo/roxutils/_roxar_loader.py +54 -0
  70. xtgeo/roxutils/_roxutils_etc.py +122 -0
  71. xtgeo/roxutils/roxutils.py +207 -0
  72. xtgeo/surface/__init__.py +18 -0
  73. xtgeo/surface/_regsurf_boundary.py +26 -0
  74. xtgeo/surface/_regsurf_cube.py +210 -0
  75. xtgeo/surface/_regsurf_cube_window.py +391 -0
  76. xtgeo/surface/_regsurf_cube_window_v2.py +297 -0
  77. xtgeo/surface/_regsurf_cube_window_v3.py +360 -0
  78. xtgeo/surface/_regsurf_export.py +388 -0
  79. xtgeo/surface/_regsurf_grid3d.py +271 -0
  80. xtgeo/surface/_regsurf_gridding.py +347 -0
  81. xtgeo/surface/_regsurf_ijxyz_parser.py +278 -0
  82. xtgeo/surface/_regsurf_import.py +347 -0
  83. xtgeo/surface/_regsurf_lowlevel.py +122 -0
  84. xtgeo/surface/_regsurf_oper.py +631 -0
  85. xtgeo/surface/_regsurf_roxapi.py +241 -0
  86. xtgeo/surface/_regsurf_utils.py +81 -0
  87. xtgeo/surface/_surfs_import.py +43 -0
  88. xtgeo/surface/_zmap_parser.py +138 -0
  89. xtgeo/surface/regular_surface.py +2967 -0
  90. xtgeo/surface/surfaces.py +276 -0
  91. xtgeo/well/__init__.py +24 -0
  92. xtgeo/well/_blockedwell_roxapi.py +221 -0
  93. xtgeo/well/_blockedwells_roxapi.py +68 -0
  94. xtgeo/well/_well_aux.py +30 -0
  95. xtgeo/well/_well_io.py +327 -0
  96. xtgeo/well/_well_oper.py +574 -0
  97. xtgeo/well/_well_roxapi.py +304 -0
  98. xtgeo/well/_wellmarkers.py +486 -0
  99. xtgeo/well/_wells_utils.py +158 -0
  100. xtgeo/well/blocked_well.py +216 -0
  101. xtgeo/well/blocked_wells.py +122 -0
  102. xtgeo/well/well1.py +1514 -0
  103. xtgeo/well/wells.py +211 -0
  104. xtgeo/xyz/__init__.py +6 -0
  105. xtgeo/xyz/_polygons_oper.py +272 -0
  106. xtgeo/xyz/_xyz.py +741 -0
  107. xtgeo/xyz/_xyz_data.py +646 -0
  108. xtgeo/xyz/_xyz_io.py +490 -0
  109. xtgeo/xyz/_xyz_lowlevel.py +42 -0
  110. xtgeo/xyz/_xyz_oper.py +613 -0
  111. xtgeo/xyz/_xyz_roxapi.py +766 -0
  112. xtgeo/xyz/points.py +681 -0
  113. xtgeo/xyz/polygons.py +811 -0
  114. xtgeo-4.8.0.dist-info/METADATA +145 -0
  115. xtgeo-4.8.0.dist-info/RECORD +117 -0
  116. xtgeo-4.8.0.dist-info/WHEEL +5 -0
  117. xtgeo-4.8.0.dist-info/licenses/LICENSE.md +165 -0
@@ -0,0 +1,148 @@
1
+ from __future__ import annotations
2
+
3
+ import warnings
4
+ from typing import Any, Literal, cast
5
+
6
+ import numpy as np
7
+ import numpy.typing as npt
8
+
9
+ from ._ecl_output_file import Phases, Simulator, TypeOfGrid, UnitSystem
10
+
11
+
12
+ class InteHead:
13
+ """Contains the values for the INTEHEAD array in ecl restart
14
+ and init files.
15
+
16
+ Output files from eclipse and opm flow will contain sections
17
+ starting with keyword-array headers. One of these is the INTEHEAD
18
+ keyword. The values in the array are integers, and the meaning
19
+ of each index is described in the e.g. the OPM user manual (2021-04 rev_01
20
+ section D.6-D.7).
21
+
22
+ The length of the array is not specified, meaning some values are missing,
23
+ the InteHead class creates a lookup for these values:
24
+
25
+ >>> intehead = InteHead(np.array([0,1,2,3,4,5,6,7,8]))
26
+ >>> intehead.num_x
27
+ 8
28
+ >>> # The year field is missing in the input
29
+ >>> intehead.year is None
30
+ True
31
+ """
32
+
33
+ def __init__(self, values: npt.NDArray[np.int_]) -> None:
34
+ """Create an InteHead from the corresponding array.
35
+
36
+ Args:
37
+ values: Array of values following the INTEHEAD keyword
38
+ in an ECL restart or init file.
39
+ """
40
+ self.values = values
41
+
42
+ def __eq__(self, other: Any) -> bool:
43
+ if not isinstance(other, InteHead):
44
+ return False
45
+
46
+ return np.array_equal(self.values, other.values)
47
+
48
+ def __repr__(self) -> str:
49
+ return f"InteHead(values={self.values})"
50
+
51
+ def __str__(self) -> str:
52
+ return self.__repr__()
53
+
54
+ def _optional_index_lookup(self, index: int) -> int | None:
55
+ """Looks up the value at the given index, returning None if out of bound.
56
+
57
+ Args:
58
+ index: The index in the value array to look up
59
+ constructor: Constructor function to wrap non-None values in, defaults
60
+ to identity.
61
+ Returns:
62
+ value at the index, None if out of bounds.
63
+ """
64
+ return self.values[index] if len(self.values) > index else None
65
+
66
+ @property
67
+ def unit_system(self) -> UnitSystem | None:
68
+ """
69
+ The unit system used in the file.
70
+ """
71
+ v = self._optional_index_lookup(2)
72
+ return None if v is None else UnitSystem(v)
73
+
74
+ @property
75
+ def num_x(self) -> int | None:
76
+ """The number of columns (x direction) of cells"""
77
+ return self._optional_index_lookup(8)
78
+
79
+ @property
80
+ def num_y(self) -> int | None:
81
+ """The number of rows (y direction) of cells"""
82
+ return self._optional_index_lookup(9)
83
+
84
+ @property
85
+ def num_z(self) -> int | None:
86
+ """The number of layers (z direction) of cells"""
87
+ return self._optional_index_lookup(10)
88
+
89
+ @property
90
+ def num_active(self) -> int | None:
91
+ """The number of active cells"""
92
+ return self._optional_index_lookup(11)
93
+
94
+ @property
95
+ def phases(self) -> Phases | None:
96
+ """The phase system used for simulation"""
97
+ if any(ids in str(self.simulator) for ids in ["300", "INTERSECT"]):
98
+ # item 14 in E300 runs is number of tracers, not IPHS; assume oil/wat/gas
99
+ # item 14 in INTERSECT is always(?) undef., not IPHS; assume oil/wat/gas
100
+ return Phases.OIL_WATER_GAS
101
+ v = self._optional_index_lookup(14)
102
+ return None if v is None else Phases(v)
103
+
104
+ @property
105
+ def day(self) -> int | None:
106
+ """The simulated time calendar day
107
+
108
+ (e.g. 3rd of april 2018)
109
+
110
+ """
111
+ return self._optional_index_lookup(64)
112
+
113
+ @property
114
+ def month(self) -> int | None:
115
+ """The simulated time calendar month
116
+
117
+ 4 for simulation being in month 4.
118
+
119
+ """
120
+ return self._optional_index_lookup(65)
121
+
122
+ @property
123
+ def year(self) -> int | None:
124
+ """The simulated time calendar month
125
+
126
+ e.g. 2018 for simulation being done in year 2018
127
+ """
128
+ return self._optional_index_lookup(66)
129
+
130
+ @property
131
+ def simulator(self) -> Simulator | int | None:
132
+ """The simulator used for producing the run, or integer code if unknown"""
133
+ s_code = self._optional_index_lookup(94)
134
+ try:
135
+ return Simulator(s_code)
136
+ except ValueError:
137
+ warnings.warn(f"Unknown simulator code {s_code}")
138
+ return s_code
139
+
140
+ @property
141
+ def type_of_grid(self) -> TypeOfGrid | None:
142
+ """The type of grid used in the simulation"""
143
+ value = self._optional_index_lookup(13)
144
+ return (
145
+ None
146
+ if value is None
147
+ else TypeOfGrid.alternate_code(cast("Literal[0, 1, 2, 3]", value))
148
+ )
@@ -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