Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Field] refactoring and update #112

Merged
merged 28 commits into from
Nov 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
6020e1e
Generator: remove structured option from generators
MuellerSeb Nov 18, 2020
3eb6c58
Generator: explicitly assert dim=2;3 when generating vector fields
MuellerSeb Nov 18, 2020
74b12f7
Field: simplify pre_pos routine; use new CovModel.isometrize routine …
MuellerSeb Nov 19, 2020
0ca920c
Tools: add routines to format pos tuple with given dim or shape
MuellerSeb Nov 19, 2020
88fbb79
Variogram: better care about pos tuple with given field shape
MuellerSeb Nov 19, 2020
3ffdf39
Field: update pre_pos routine: name of attribute to set selectable
MuellerSeb Nov 19, 2020
898c8b1
CovModel.plot: update spatial plotting routines to use new Field rout…
MuellerSeb Nov 19, 2020
f9fb673
VTK: refactor VTK export to drop usage of pos2xyz
MuellerSeb Nov 19, 2020
21d3fb5
SRF: update conditioned SRF to drop pos2xyz usage
MuellerSeb Nov 19, 2020
cffc830
Field.pre_pos: generate correct shape for vector fields
MuellerSeb Nov 19, 2020
ecdf527
SRF: correct shape handling for upscaling variance
MuellerSeb Nov 19, 2020
8eeeaa5
Field.plot: drop usage of pos2xyz
MuellerSeb Nov 19, 2020
4c929c4
Variogram: cleanup
MuellerSeb Nov 19, 2020
97ef9f1
Krige: refactor Kriging routines to drop usage of pos2xyz
MuellerSeb Nov 19, 2020
0380f06
Tests: skip some structured testing (dropped); fix some input missmat…
MuellerSeb Nov 19, 2020
1081a14
Field.plot: only plot for dim=1,2,3
MuellerSeb Nov 19, 2020
7523ae0
COMMIT #1000 HOORAY!
MuellerSeb Nov 19, 2020
18c0c02
Examples: update variogram fitting plots with scatter plots; add mode…
MuellerSeb Nov 19, 2020
f78f8c0
Field: add meshio as dependency; update Field.mesh routine to meshio 4
MuellerSeb Nov 19, 2020
67fd5ce
Field.mesh: better handling of directions
MuellerSeb Nov 19, 2020
4a601cb
Field.mesh: check mesh dimension
MuellerSeb Nov 20, 2020
05f7da4
Field.mesh: check for meshio mesh
MuellerSeb Nov 20, 2020
9b97f87
Examples: add an example with meshes
MuellerSeb Nov 20, 2020
e1dd8d4
Examples: add a 4D example
MuellerSeb Nov 20, 2020
24dfc1d
Docs: add meshzoo as doc dependency
MuellerSeb Nov 20, 2020
de4c923
Geometric: bugfix in 'format_unstruct_pos_shape': wrong dimension det…
MuellerSeb Nov 23, 2020
04c4c6c
Fix some typos
LSchueler Nov 23, 2020
713843e
Randmeth: rename summators; remove superfluous tests for structured s…
MuellerSeb Nov 23, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/requirements_doc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ sphinx-gallery
matplotlib
pyvista
pykrige
meshzoo
94 changes: 94 additions & 0 deletions examples/01_random_field/05_mesh_ensemble.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
"""
Generating fields on meshes
---------------------------

GSTools provides an interface for meshes, to support
`meshio <https://github.com/nschloe/meshio>`_ and
`ogs5py <https://github.com/GeoStat-Framework/ogs5py>`_ meshes.

When using `meshio`, the generated fields will be stored imediatly in the mesh
container.

One has two options to generate a field on a given mesh:

- `points="points"` will generate a field on the mesh points
- `points="centroids"` will generate a field on the cell centroids

In this example, we will generate a simple mesh with the aid of
`meshzoo <https://github.com/nschloe/meshzoo>`_.
"""

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.tri as tri
import meshzoo
import meshio
import gstools as gs

# generate a triangulated hexagon with meshzoo
points, cells = meshzoo.ngon(6, 4)
mesh = meshio.Mesh(points, {"triangle": cells})

###############################################################################
# Now we prepare the SRF class as always. We will generate an ensemble of
# fields on the generated mesh.

# number of fields
fields_no = 12
# model setup
model = gs.Gaussian(dim=2, len_scale=0.5)
srf = gs.SRF(model, mean=1)

###############################################################################
# To generate fields on a mesh, we provide a separate method: :any:`SRF.mesh`.
# First we generate fields on the mesh-centroids controlled by a seed.
# You can specify the field name by the keyword `name`.

for i in range(fields_no):
srf.mesh(mesh, points="centroids", name="c-field-{}".format(i), seed=i)

###############################################################################
# Now we generate fields on the mesh-points again controlled by a seed.

for i in range(fields_no):
srf.mesh(mesh, points="points", name="p-field-{}".format(i), seed=i)

###############################################################################
# To get an impression we now want to plot the generated fields.
# Luckily, matplotlib supports triangular meshes.


triangulation = tri.Triangulation(points[:, 0], points[:, 1], cells)
# figure setup
cols = 4
rows = int(np.ceil(fields_no / cols))

###############################################################################
# Cell data can be easily visualized with matplotlibs `tripcolor`.
# To highlight the cell structure, we use `triplot`.

fig = plt.figure(figsize=[2 * cols, 2 * rows])
for i, field in enumerate(mesh.cell_data, 1):
ax = fig.add_subplot(rows, cols, i)
ax.tripcolor(triangulation, mesh.cell_data[field][0])
ax.triplot(triangulation, linewidth=0.5, color="k")
ax.set_aspect("equal")
fig.tight_layout()

###############################################################################
# Point data is plotted via `tricontourf`.

fig = plt.figure(figsize=[2 * cols, 2 * rows])
for i, field in enumerate(mesh.point_data, 1):
ax = fig.add_subplot(rows, cols, i)
ax.tricontourf(triangulation, mesh.point_data[field])
ax.triplot(triangulation, linewidth=0.5, color="k")
ax.set_aspect("equal")
fig.tight_layout()
plt.show()

###############################################################################
# Last but not least, `meshio` can be used for what is does best: Exporting.
# Tada!

mesh.write("mesh_ensemble.vtk")
75 changes: 75 additions & 0 deletions examples/01_random_field/06_higher_dimensions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"""
Higher Dimensions
-----------------

GSTools provides experimental support for higher dimensions.
MuellerSeb marked this conversation as resolved.
Show resolved Hide resolved

Anisotropy is the same as in lower dimensions:

- in `n` dimensions we need `(n-1)` anisotropy ratios

Rotation on the other hand is a bit more complex.
With increasing dimensions more and more rotation angles are added in order
to properply describe the rotated axes of anisotropy.

By design the first rotation angles coincide with the lower ones:

- 2D (rotation in x-y plane) -> 3D: first angle describes xy-plane rotation
- 3D (tait-bryan angles) -> 4D: first 3 angles coincide with tait-bryan angles

By increasing the dimension from `n` to `(n+1)`, `n` angles are added:

- 2D (1 angle) -> 3D: 3 angles (2 added)
- 3D (3 angles) -> 4D: 6 angles (3 added)

the following list of rotation-planes are described by the list of
angles in the model:

1. x-y plane
2. x-z plane
3. y-z plane
4. x-v plane
5. y-v plane
6. z-v plane
7. ...

The rotation direction in these planes have alternating signs
in order to match tait-bryan in 3D.

Let's have a look at a 4D example, where we naively add a 4th dimension.
"""

import matplotlib.pyplot as plt
import gstools as gs

dim = 4
size = 20
pos = [range(size)] * dim
model = gs.Exponential(dim=dim, len_scale=5)
srf = gs.SRF(model, seed=20170519)
field = srf.structured(pos)

###############################################################################
# In order to "prove" correctnes, we can calculate an empirical variogram
# of the generated field and fit our model to it.

bin_edges = range(size)
bin_center, vario = gs.vario_estimate(
pos, field, bin_edges, sampling_size=2000, mesh_type="structured"
)
model.fit_variogram(bin_center, vario)
print(model)

###############################################################################
# As you can see, the estimated variance and length scale match our input
# quite good.
#
# Let's have a look at the fit and a x-y cross-section of the 4D field:

f, a = plt.subplots(1, 2, gridspec_kw={"width_ratios": [2, 1]}, figsize=[9, 3])
model.plot(x_max=size + 1, ax=a[0])
a[0].scatter(bin_center, vario)
a[1].imshow(field[:, :, 0, 0].T, origin="lower")
a[0].set_title("isotropic empirical variogram with fitted model")
a[1].set_title("x-y cross-section")
f.show()
2 changes: 1 addition & 1 deletion examples/03_variogram/00_fit_variogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@
# Plot the fitting result.

ax = fit_model.plot(x_max=40)
ax.plot(bin_center, gamma)
ax.scatter(bin_center, gamma)
print(fit_model)
20 changes: 11 additions & 9 deletions examples/03_variogram/02_find_best_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,24 @@
# Define a set of models to test.

models = {
"gaussian": gs.Gaussian,
"exponential": gs.Exponential,
"matern": gs.Matern,
"stable": gs.Stable,
"rational": gs.Rational,
"linear": gs.Linear,
"circular": gs.Circular,
"spherical": gs.Spherical,
"Gaussian": gs.Gaussian,
"Exponential": gs.Exponential,
"Matern": gs.Matern,
"Stable": gs.Stable,
"Rational": gs.Rational,
"Linear": gs.Linear,
"Circular": gs.Circular,
"Spherical": gs.Spherical,
"SuperSpherical": gs.SuperSpherical,
"JBessel": gs.JBessel,
}
scores = {}

###############################################################################
# Iterate over all models, fit their variogram and calculate the r2 score.

# plot the estimated variogram
plt.scatter(bin_center, gamma, label="data")
plt.scatter(bin_center, gamma, color="k", label="data")
ax = plt.gca()

# fit all models to the estimated variogram
Expand Down
4 changes: 2 additions & 2 deletions examples/03_variogram/04_directional_2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=[10, 5])

ax1.plot(bin_center, dir_vario[0], label="emp. vario: pi/8")
ax1.plot(bin_center, dir_vario[1], label="emp. vario: pi*5/8")
ax1.scatter(bin_center, dir_vario[0], label="emp. vario: pi/8")
ax1.scatter(bin_center, dir_vario[1], label="emp. vario: pi*5/8")
ax1.legend(loc="lower right")

model.plot("vario_axis", axis=0, ax=ax1, x_max=40, label="fit on axis 0")
Expand Down
12 changes: 6 additions & 6 deletions examples/03_variogram/05_directional_3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,12 @@
ax2.set_title("Tait-Bryan main axis")
ax2.legend(loc="lower left")

ax3.plot(bin_center, dir_vario[0], label="0. axis")
ax3.plot(bin_center, dir_vario[1], label="1. axis")
ax3.plot(bin_center, dir_vario[2], label="2. axis")
model.plot("vario_axis", axis=0, ax=ax3, label="fit on axis 0", linestyle=":")
model.plot("vario_axis", axis=1, ax=ax3, label="fit on axis 1", linestyle=":")
model.plot("vario_axis", axis=2, ax=ax3, label="fit on axis 2", linestyle=":")
ax3.scatter(bin_center, dir_vario[0], label="0. axis")
ax3.scatter(bin_center, dir_vario[1], label="1. axis")
ax3.scatter(bin_center, dir_vario[2], label="2. axis")
model.plot("vario_axis", axis=0, ax=ax3, label="fit on axis 0")
model.plot("vario_axis", axis=1, ax=ax3, label="fit on axis 1")
model.plot("vario_axis", axis=2, ax=ax3, label="fit on axis 2")
ax3.set_title("Fitting an anisotropic model")
ax3.legend()

Expand Down
2 changes: 1 addition & 1 deletion gstools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
vario_estimate
vario_estimate_axis
"""

# Hooray!
MuellerSeb marked this conversation as resolved.
Show resolved Hide resolved
from gstools import field, variogram, random, covmodel, tools, krige, transform
from gstools.field import SRF
from gstools.tools import (
Expand Down
28 changes: 9 additions & 19 deletions gstools/covmodel/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import numpy as np

import gstools
from gstools.field.tools import reshape_axis_from_struct_to_unstruct


__all__ = [
"plot_variogram",
Expand Down Expand Up @@ -70,13 +70,11 @@ def plot_vario_spatial(
field._value_type = "scalar"
if x_max is None:
x_max = 3 * model.len_scale
field.mesh_type = "structured"
x_s = np.linspace(-x_max, x_max) + x_min
pos = [x_s] * model.dim
x, y, z, shape = reshape_axis_from_struct_to_unstruct(model.dim, *pos)
vario = model.vario_spatial([x, y, z][: model.dim]).reshape(shape)
field.pos = pos
field.field = vario
iso_pos, shape = field.pre_pos([x_s] * model.dim, "structured")
field.field = model.vario_spatial(model.anisometrize(iso_pos)).reshape(
shape
)
return field.plot(fig=fig, ax=ax)


Expand All @@ -88,13 +86,9 @@ def plot_cov_spatial(
field._value_type = "scalar"
if x_max is None:
x_max = 3 * model.len_scale
field.mesh_type = "structured"
x_s = np.linspace(-x_max, x_max) + x_min
pos = [x_s] * model.dim
x, y, z, shape = reshape_axis_from_struct_to_unstruct(model.dim, *pos)
vario = model.cov_spatial([x, y, z][: model.dim]).reshape(shape)
field.pos = pos
field.field = vario
iso_pos, shape = field.pre_pos([x_s] * model.dim, "structured")
field.field = model.cov_spatial(model.anisometrize(iso_pos)).reshape(shape)
return field.plot(fig=fig, ax=ax)


Expand All @@ -106,13 +100,9 @@ def plot_cor_spatial(
field._value_type = "scalar"
if x_max is None:
x_max = 3 * model.len_scale
field.mesh_type = "structured"
x_s = np.linspace(-x_max, x_max) + x_min
pos = [x_s] * model.dim
x, y, z, shape = reshape_axis_from_struct_to_unstruct(model.dim, *pos)
vario = model.cor_spatial([x, y, z][: model.dim]).reshape(shape)
field.pos = pos
field.field = vario
iso_pos, shape = field.pre_pos([x_s] * model.dim, "structured")
field.field = model.cor_spatial(model.anisometrize(iso_pos)).reshape(shape)
return field.plot(fig=fig, ax=ax)


Expand Down
Loading