Skip to content

Commit 3366dc6

Browse files
authored
Merge pull request #499 from cgre-aachen/development_janN
[DOC] Warning of currently incomaptible pandas version and export functionality for shemat-suite
2 parents c64023b + 2ba21c0 commit 3366dc6

File tree

9 files changed

+199
-8
lines changed

9 files changed

+199
-8
lines changed

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
[![DOI](https://zenodo.org/badge/96211155.svg)](https://zenodo.org/badge/latestdoi/96211155)
1212
[![DOCKER](https://img.shields.io/docker/cloud/automated/leguark/gempy.svg)](https://cloud.docker.com/repository/docker/leguark/gempy)
1313

14+
:warning: **Warning: GemPy requires pandas version < 1.4.0. The new pandas release is not compatible with GemPy.
15+
We're actively working on this issue for a future release.
16+
Please make sure to use Pandas version 1.3.x when working with GemPy for the time being.** :warning:
1417
## Overview
1518

1619
[GemPy](https://www.gempy.org/) is a Python-based, **open-source geomodeling library**. It is
@@ -66,6 +69,8 @@ Follow these [guidelines](https://github.com/cgre-aachen/gempy/blob/WIP_readme-u
6669
https://www.sciencedirect.com/science/article/pii/B9780128140482000156).
6770
In Developments in Structural Geology and Tectonics (Vol. 5, pp. 189-204). Elsevier.
6871

72+
A continuously growing list of gempy-applications (e.g. listing real-world models) can be found [here](https://hackmd.io/@Japhiolite/B1juPvCxc).
73+
6974
## Gallery
7075

7176
### Geometries

gempy/__init__.py

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"""
77
import sys
88
import os
9+
import pandas
910

1011
import warnings
1112

@@ -37,6 +38,10 @@
3738
from gempy.plot import _plot as _plot
3839

3940
assert sys.version_info[0] >= 3, "GemPy requires Python 3.X" # sys.version_info[1] for minor e.g. 6
41+
assert pandas.__version__ <= '1.4.0', \
42+
"GemPy requires pandas version < 1.4.0. The new pandas release is not compatible with GemPy.\n" \
43+
"We're actively working on this issue for a future release.\n"
44+
4045
__version__ = '2.2.10'
4146

4247
if __name__ == '__main__':

gempy/assets/topology.py

+12
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,18 @@ def compute_topology(
5353
n_shift: int = 1,
5454
voxel_threshold: int = 1
5555
):
56+
"""Compute topology of a GemPy model
57+
58+
Args:
59+
geo_model (Project): GemPy model project
60+
cell_number (int, optional): Cell number in chosen direction. Defaults to None.
61+
direction (str, optional): one of the model's dimensions, x, y, or z. Defaults to None.
62+
n_shift (int, optional): number of voxels the model is shifted and then substracted for finding interfaces. Defaults to 1.
63+
voxel_threshold (int, optional): amount of voxels which have to be connected to be considered into the topology calculation. Defaults to 1.
64+
65+
Returns:
66+
edges, centroids [numpy array]: edges and centroids of the topology graph
67+
"""
5668
res = geo_model._grid.regular_grid.resolution
5769
fb = _get_fb(geo_model)
5870
lb = _get_lb(geo_model)

gempy/core/data_modules/geometric_data.py

+24
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import warnings
44
from typing import Union, Iterable
55

6+
import numpy
67
import numpy as np
78
import pandas as pn
89

@@ -291,6 +292,19 @@ def add_surface_points(self, x: Union[float, np.ndarray], y: Union[float, np.nda
291292

292293
self.df.loc[idx, ['X', 'Y', 'Z']] = coord_array.astype('float64')
293294
self.df.loc[idx, 'surface'] = surface
295+
# if isinstance(surface, np.ndarray): # If surface is a numpy array
296+
# # self.df.loc[idx, 'surface'] = surface
297+
# if self.df['surface'].dtype == 'category':
298+
# for s in surface:
299+
# if s not in self.df['surface'].cat.categories:
300+
# self.df['surface'].cat.add_categories(s, inplace=True)
301+
# self.df.loc[idx, 'surface'] = s
302+
# else:
303+
# for s in surface:
304+
# self.df.loc[idx, 'surface'] = s
305+
#
306+
# else:
307+
# self.df.loc[idx, 'surface'] = surface
294308
# ToDO test this
295309
except ValueError as error:
296310
self.del_surface_points(idx)
@@ -591,6 +605,11 @@ def add_orientation(self, x, y, z, surface, pole_vector: Union[list, tuple, np.n
591605

592606
if pole_vector is not None:
593607
self.df.loc[idx, ['X', 'Y', 'Z', 'G_x', 'G_y', 'G_z']] = np.array([x, y, z, *pole_vector], dtype=float)
608+
# if type(surface) is numpy.ndarray:
609+
# for s in surface:
610+
# self.df.loc[idx, 'surface'] = s
611+
# else:
612+
# self.df.loc[idx, 'surface'] = surface
594613
self.df.loc[idx, 'surface'] = surface
595614

596615
self.calculate_orientations(idx)
@@ -601,6 +620,11 @@ def add_orientation(self, x, y, z, surface, pole_vector: Union[list, tuple, np.n
601620
if orientation is not None:
602621
self.df.loc[idx, ['X', 'Y', 'Z', ]] = np.array([x, y, z], dtype=float)
603622
self.df.loc[idx, ['azimuth', 'dip', 'polarity']] = np.array(orientation, dtype=float)
623+
# if type(surface) is not str:
624+
# for s in surface:
625+
# self.df.loc[idx, 'surface'] = s
626+
# else:
627+
# self.df.loc[idx, 'surface'] = surface
604628
self.df.loc[idx, 'surface'] = surface
605629

606630
self.calculate_gradient(idx)

gempy/core/data_modules/stack.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ def reset_order_series(self):
215215
"""
216216
Reset the column order series to monotonic ascendant values.
217217
"""
218-
self.df.at[:, 'order_series'] = pn.RangeIndex(1, self.df.shape[0] + 1)
218+
# self.df['order_series'] = pn.RangeIndex(1, self.df.shape[0] + 1) pandas 1.4 change
219+
self.df.at[:, 'order_series'] = pn.RangeIndex(1, self.df.shape[0] + 1) # pandas 1.3 version
219220

220221
@_setdoc_pro(reset_order_series.__doc__)
221222
def set_series_index(self, series_order: Union[list, np.ndarray], reset_order_series=True):

gempy/plot/visualization_2d.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -455,8 +455,8 @@ def plot_data(self, ax, section_name=None, cell_number=None, direction='y',
455455
points_df = points[select_projected_p]
456456
points_df['colors'] = points_df['surface'].map(self._color_lot)
457457

458-
points_df.plot.scatter(x=x, y=y, ax=ax, c='colors', s=70, zorder=102,
459-
edgecolors='white',
458+
points_df.plot.scatter(x=x, y=y, ax=ax, c=points_df['surface'].map(self._color_lot),
459+
s=70, zorder=102, edgecolors='white',
460460
colorbar=False)
461461
# points_df.plot.scatter(x=x, y=y, ax=ax, c='white', s=80, zorder=101,
462462
# colorbar=False)

gempy/utils/docstring.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
pole_vector = '(numpy.ndarray[float, 3]): 2D numpy array where axis 1 is the gradient values G_x, G_y, G_z of the pole while axis 0 is n number of' \
1111
' orientations.'
1212

13-
orientations = '(numpy.ndarray[float, 3]): 2D numpy array where axis 1 is are orientation values [dip, azimuth, polarity] of the pole while axis 0' \
13+
orientations = '(numpy.ndarray[float, 3]): 2D numpy array where axis 1 is are orientation values [azimuth, dip, polarity] of the pole while axis 0' \
1414
' is n number of orientations. --- ' \
1515
'*Dip* is the inclination angle of 0 to 90 degrees measured from the horizontal plane downwards. ' \
1616
'*Azimuth* is the dip direction defined by a 360 degrees clockwise rotation, i.e. 0 = North,' \

gempy/utils/export.py

+147-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from gempy.plot._visualization_2d import PlotData2D
44
import numpy as np
55
import os
6+
import itertools as it
67

78

89
def export_geomap2geotiff(path, geo_model, geo_map=None, geotiff_filepath=None):
@@ -135,6 +136,147 @@ def export_moose_input(geo_model, path=None, filename='geo_model_units_moose_inp
135136

136137
print("Successfully exported geological model as moose input to "+path)
137138

139+
def export_shemat_suite_input_file(geo_model, path: str=None, filename: str='geo_model_SHEMAT_input'):
140+
"""
141+
Method to export a 3D geological model as SHEMAT-Suite input-file for a conductive HT-simulation.
142+
143+
Args:
144+
path (str): Filepath for the exported input file (default './')
145+
filename (str): name of exported input file (default 'geo_model_SHEMAT_input')
146+
"""
147+
# get model dimensions
148+
nx, ny, nz = geo_model.grid.regular_grid.resolution
149+
xmin, xmax, ymin, ymax, zmin, zmax = geo_model.solutions.grid.regular_grid.extent
150+
151+
delx = (xmax - xmin)/nx
152+
dely = (ymax - ymin)/ny
153+
delz = (zmax - zmin)/nz
154+
155+
# get unit IDs and restructure them
156+
ids = np.round(geo_model.solutions.lith_block)
157+
ids = ids.astype(int)
158+
159+
liths = ids.reshape((nx, ny, nz))
160+
liths = liths.flatten('F')
161+
162+
# group litho in space-saving way
163+
sequence = [len(list(group)) for key, group in it.groupby(liths)]
164+
unit_id = [key for key, group in it.groupby(liths)]
165+
combined = ["%s*%s" % (pair) for pair in zip(sequence,unit_id)]
166+
167+
combined_string = " ".join(combined)
168+
169+
# get number of units and set units string
170+
units = geo_model.surfaces.df[['surface', 'id']]
171+
172+
unitstring = ""
173+
for index, rows in units.iterrows():
174+
unitstring += f"0.01d-10 1.d0 1.d0 1.e-14 1.e-10 1.d0 1.d0 3.74 0. 2077074. 10 2e-3 !{rows['surface']} \n"
175+
176+
# input file as f-string
177+
fstring = f"""!==========>>>>> INFO
178+
# Title
179+
{filename}
180+
181+
# linfo
182+
1 2 1 1
183+
184+
# runmode
185+
1
186+
187+
# timestep control
188+
0
189+
1 1 0 0
190+
191+
# tunit
192+
1
193+
194+
# time periods, records=1
195+
0 60000000 200 lin
196+
197+
# output times, records=10
198+
1
199+
6000000
200+
12000000
201+
18000000
202+
24000000
203+
30000000
204+
36000000
205+
42000000
206+
48000000
207+
54000000
208+
209+
# file output: hdf vtk
210+
211+
# active temp
212+
213+
# PROPS=bas
214+
215+
# USER=none
216+
217+
218+
# grid
219+
{nx} {ny} {nz}
220+
221+
# delx
222+
{nx}*{delx}
223+
224+
# dely
225+
{ny}*{dely}
226+
227+
# delz
228+
{nz}*{delz}
229+
230+
!==========>>>>> NONLINEAR SOLVER
231+
# nlsolve
232+
50 0
233+
234+
!==========>>>>> FLOW
235+
# lsolvef (linear solver control)
236+
1.d-12 64 500
237+
# nliterf (nonlinear iteration control)
238+
1.0d-10 1.0
239+
240+
!==========>>>>> TEMPERATURE
241+
# lsolvet (linear solver control)
242+
1.d-12 64 500
243+
# nlitert (nonlinear iteration control)
244+
1.0d-10 1.0
245+
246+
!==========>>>>> INITIAL VALUES
247+
# temp init
248+
{nx*ny*nz}*15.0d0
249+
250+
# head init
251+
{nx*ny*nz}*7500
252+
253+
!==========>>>>> UNIT DESCRIPTION
254+
!!
255+
# units
256+
{unitstring}
257+
258+
!==========>>>>> define boundary properties
259+
# temp bcd, simple=top, value=init
260+
261+
# temp bcn, simple=base, error=ignore
262+
{nx*ny}*0.06
263+
264+
# uindex
265+
{combined_string}"""
266+
267+
if not path:
268+
path = './'
269+
if not os.path.exists(path):
270+
os.makedirs(path)
271+
272+
f = open(path+filename, 'w+')
273+
274+
f.write(fstring)
275+
f.close()
276+
277+
print("Successfully exported geological model as SHEMAT-Suite input to "+path)
278+
279+
138280
def export_pflotran_input(geo_model, path=None, filename='pflotran.ugi'):
139281
"""
140282
Method to export a 3D geological model as PFLOTRAN implicit unstructured grid
@@ -245,10 +387,11 @@ def export_flac3D_input(geo_model, path=None, filename='geomodel.f3grid'):
245387
vertices, elements, groups = __build_vertices_elements_groups__(geo_model)
246388

247389
#open output file
248-
if not path:
249-
path = './'
250-
if not os.path.exists(path):
251-
os.makedirs(path)
390+
#if not path:
391+
# path = './'
392+
#if not os.path.exists(path):
393+
# os.makedirs(path)
394+
252395
out = open(path+filename, 'w')
253396

254397
#write gridpoints

setup.py

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
packages=find_packages(exclude=('test', 'docs', 'examples')),
1111
include_package_data=True,
1212
install_requires=[
13+
'pandas==1.3.4',
1314
'Theano>=1.0.4',
1415
'matplotlib',
1516
'numpy',

0 commit comments

Comments
 (0)