Note: we don't create a proper FE mesh here, but simply perform a "mapping" between a predefined mesh structure (in this case: a simple regular mesh, defined in MOOSE) and an exported GeoModeller model - with all limitations concerning refinement, problem size, etc. - however: a good way to get the first tests running!
In [31]:
# some basic imports:
import numpy as np
import os
import matplotlib.pyplot as plt
# for 3-D visualisation:
import ipyvolume.pylab as p3
We use here simply the export functionality of GeoModeller (note: far better results can be achieved with a dedicated export using the API). The exported file has some header information and then the formations simply listed in an $x$-dominant way.
We load this file here in a simple structure:
In [32]:
class GeoExport(object):
def __init__(self, filename):
"""Load exported model"""
self.filename = filename
def load_file(self):
"""Load file"""
pass
In [33]:
voxet_file = r'/Users/flow/Documents/01_work/61_simulation_results/PerthBasin/notebooks/voxet_NPB.vox'
In [34]:
vf = open(voxet_file, 'r').readlines()
In [35]:
vf_header = vf[:10]
vf_entries = vf[10:]
In [36]:
# remove newlines and convert to numpy array
vf_entries = np.array([entry.rstrip() for entry in vf_entries])
In [37]:
# determine all formation names in model:
form_names = np.unique(vf_entries)
In [38]:
nx, ny, nz = int(vf_header[0].rstrip().split(" ")[1]),\
int(vf_header[1].rstrip().split(" ")[1]),\
int(vf_header[2].rstrip().split(" ")[1])
In [39]:
nx, ny, nz
Out[39]:
In [87]:
nx * ny * nz
Out[87]:
In [40]:
# create dictionary with formation names
formation_dict = {}
for i in range(len(form_names)):
formation_dict[form_names[i]] = i
In [41]:
formation_dict
Out[41]:
In [42]:
# read file and transform string arrays into appropriate integer values
vox_int = [int(formation_dict[entry]) for entry in vf_entries]
vox_int = np.array(vox_int, dtype='int')
In [43]:
# reshape into 3-D array
vox_3d = vox_int.reshape(nz, ny, nx)
In [64]:
# swap axes to get x,y,z array
vox_3d = np.swapaxes(vox_3d, 0, 2)
In [65]:
plt.figure(figsize=(12,4))
plt.imshow(vox_3d[:,-1,:].transpose(), origin='bottom')
plt.xlabel('X')
plt.ylabel('Z')
plt.show()
In [66]:
plt.figure(figsize=(12,4))
plt.imshow(vox_3d[0,:,:].transpose(), origin='bottom')
plt.xlabel('Y')
plt.ylabel('Z')
plt.show()
In [67]:
plt.figure(figsize=(12,4))
plt.imshow(vox_3d[:,:,0].transpose(), origin='bottom')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
In [88]:
import ipyvolume
ipyvolume.quickvolshow(vox_3d)
In [69]:
# extract submodel for faster vis-test
nx_sub = nz
ny_sub = 80
nz_sub = nz
x = np.arange(nx_sub)
y = np.arange(ny_sub)
z = np.arange(nz_sub)
X,Y,Z = np.meshgrid(y,x,z)
# extract subvolume
vox_sub = vox_3d[:nx_sub, :ny_sub, :nz_sub]
vox_sub = np.swapaxes(vox_sub, 0, 2)
In [70]:
ipyvolume.quickvolshow(vox_sub)
# vox_sub.shape
In [71]:
np.unique(vox_sub)
Out[71]:
In [72]:
# create colour array:
nc = np.max(vox_sub)
vox_c = [plt.cm.viridis(i/nc)[:3] for i in vox_sub.ravel()]
In [73]:
print(X.ravel().shape)
print(vox_sub.ravel().shape)
In [74]:
p3.figure()
p3.scatter(X.ravel(), Y.ravel(), Z.ravel(), color=vox_c, marker='box', size=3.4)
In [75]:
p3.show()
In [84]:
np.save("PB_sub.txt", vox_sub)
In [86]:
vox_sub.shape
Out[86]:
In [ ]: