Zone Modeling

A zone in Petres is defined by two horizons, where the volume enclosed between them forms the zone. Once defined using Zone, it can be:

  • Visualized in 2D/3D space

  • Subdivided into vertical layers

  • Used to generate Corner-Point grids

Creating a Zone

In Petres, a zone can be created in two ways:

  • From two horizons

  • From a single horizon with a specified thickness

Using Two Horizons

A zone can be defined explicitly by providing top and base horizons:

zone1 = Zone(name="Z1", top=horizon1, base=horizon2)

Here, horizon1 and horizon2 are previously defined Horizon objects representing the upper and lower bounding surfaces, respectively.

Using a Single Horizon

Alternatively, a zone can be created from a single horizon by specifying a constant thickness:

zone = horizon1.to_zone(name="Zone 1", depth=2)
zone.show(x=np.linspace(0, 5, 50), y=np.linspace(0, 5, 50))

This method generates a second (base) horizon by shifting the original horizon downward by the specified depth, resulting in a zone with constant thickness.

Important

to_zone() requires the horizon to retain its picks (store_picks=True) to generate the shifted base horizon. This is the default behavior, so no action is needed unless you have explicitly changed it.

Dividing a Zone into Layers

Zones can be subdivided into multiple layers to control vertical resolution in later modeling workflows. Petres provides several approaches for defining zone layering.

Uniform Layering

Divide the zone into an equal number of layers:

zone1.divide(nk=4)

This creates 4 layers evenly distributed between the top and base horizons.

Layering with Relative Fractions

Layer thicknesses can also be defined proportionally:

zone1.divide(fractions=[1, 1, 2])

In this example, the zone is divided into three layers where the thickness of each layer is proportional to the corresponding fraction. As a result, the first two layers have equal thickness, and the third layer is twice as thick as each of the first two.

Layering with Explicit Levels

Layer boundaries can be defined directly using normalized levels between the top and base horizons:

zone1.divide(levels=[0, 0.2, 1])

As a result, the first layer occupies 20% of the total zone thickness, and the second layer occupies the remaining 80%. Here, 0 corresponds to the top horizon, 1 to the base horizon, and intermediate values define internal boundaries.

Important

Layering is applied per zone and directly controls the vertical discretization of the final corner-point grid.

Visualizing a Zone

Like horizons, zones are continuous and need to be sampled for visualization. They can be displayed directly using the show() method, or with more control in 2D and 3D using show2d() and show3d(), respectively.

The grid sampling options are the same as those described for visualizing horizons. That is, you can specify the sampling grid using direct coordinates, limits and resolution, or grid spacing.

Visualizing Multiple Zones

Multiple zones can be displayed together using Viewer3D.

from petres.viewers import Viewer3D

viewer = Viewer3D()
viewer.add_zones(
   zones=[zone1, zone2],
   x=np.linspace(0, 100, 50),
   y=np.linspace(0, 100, 50),
   cmap="viridis",
)
 viewer.show()

Manual Color Assignment

Colors can also be assigned explicitly:

viewer = Viewer3D()
viewer.add_zone(zone1, x=np.linspace(0, 100, 50), y=np.linspace(0, 100, 50), color="red")
viewer.add_zone(zone2, x=np.linspace(0, 100, 50), y=np.linspace(0, 100, 50), color="blue")
viewer.show()

Next Steps