Professional Documents
Culture Documents
All clastic sediments are subject to compaction (and reduction of porosity) as the result of increasingly
5 COMMENTS tighter packing of grains under a thickening overburden. Decompaction – the estimation of the
decompacted thickness of a rock column – is an important part of subsidence (or geohistory) analysis.
The following exercise is loosely based on the excellent basin analysis textbook by Allen & Allen (2013),
especially their Appendix 56. You can download the Jupyter notebook version of this post from Github.
Import stuff
1 import numpy as np
2 import matplotlib.pyplot as plt
3 import functools
4 from scipy.optimize import bisect
5 %matplotlib inline
6 %config InlineBackend.figure_format = 'svg'
7 plt.rcParams['mathtext.fontset'] = 'cm'
Given a sediment column of a certain lithology with its top at and its base at , we are trying to find
the thickness and average porosity of the same sediment column at a different depth (see figure below).
We are going to set the new top and work towards finding the new base .
1 plt.figure(figsize=(2,5))
2 x = [0,1,1,0,0]
3 y = [1,1,1.5,1.5,1]
4 plt.text(-0.6,1.02,'$y_1$',fontsize=16)
5 plt.text(-0.6,1.52,'$y_2$',fontsize=16)
6 plt.text(-0.6,1.27,'$\phi$',fontsize=16)
7 plt.fill(x,y,'y')
8 x = [3,4,4,3,3]
9 y = [0.5,0.5,1.15,1.15,0.5]
10 plt.text(2.25,0.52,'$y_1\'$',fontsize=16)
11 plt.text(2.25,1.17,'$y_2\'$',fontsize=16)
12 plt.text(2.25,0.9,'$\phi\'$',fontsize=16)
13 plt.fill(x,y,'y')
14 plt.plot([1,3],[1,0.5],'k--')
15 plt.plot([1,3],[1.5,1.15],'k--')
16 plt.gca().invert_yaxis()
17 plt.axis('off');
https://hinderedsettling.com/2017/04/12/exploring-decompaction-with-python/ 1/6
23/07/2020 Exploring (de)compaction with Python « Hindered Settling
Porosity decreases with depth, initially largely due to mechanical compaction of the sediment. The
decrease in porosity is relatively large close to the seafloor, where sediment is loosely packed; the lower
the porosity, the less room there is for further compaction. This decrease in porosity with depth is
commonly modeled as a negative exponential function (Athy, 1930):
where is the porosity at depth and is the depth where the initial porosity was reduced by .
This is an empirical equation, as there is no direct physical link between depth and porosity; compaction
and porosity reduction are more directly related to the increase in effective stress under a thicker
overburden. Here we only address the simplest scenario with no overpressured zones. For normally
pressured sediments, Athy’s porosity-depth relationship can be expressed in a slightly different form:
where c is a coefficient with the units . The idea is that c is a characteristic constant for a certain
lithology and it can measured if porosity values are available from different depths. Muds have higher
porosities at the seafloor than sands but they compact faster than sands. The plot below show some
typical curves that illustrate the exponential decrease in porosity with depth for sand and mud. The
continuous lines correspond to the parameters for sand and mud in Appendix 56 of Allen & Allen
(2013); the dashed lines are exponential fits to data from the Ocean Drilling Program (Kominz et al.,
2011).
https://hinderedsettling.com/2017/04/12/exploring-decompaction-with-python/ 2/6
23/07/2020 Exploring (de)compaction with Python « Hindered Settling
1 c_sand = 0.27 # porosity-depth coefficient for sand (km-1)
2 c_mud = 0.57 # porosity-depth coefficent for mud (km-1)
3 phi_sand_0 = 0.49 # surface porosity for sand
4 phi_mud_0 = 0.63 # surface porosity for mud
5 y = np.arange(0,3.01,0.01)
6
7 phi_sand = phi_sand_0 * np.exp(-c_sand*y)
8 phi_mud = phi_mud_0 * np.exp(-c_mud*y)
9
10 plt.figure(figsize=(4,7))
11 plt.plot(phi_sand,y,'y',linewidth=2,label='sand')
12 plt.plot(phi_mud,y,'brown',linewidth=2,label='mud')
13 plt.xlabel('porosity')
14 plt.ylabel('depth (km)')
15 plt.xlim(0,0.65)
16 plt.gca().invert_yaxis()
17
18 c_sand = 1000/18605.0 # Kominz et al. 2011 >90% sand curve
19 c_mud = 1000/1671.0 # Kominz et al. 2011 >90% mud curve
20 phi_sand_0 = 0.407 # Kominz et al. 2011 >90% sand curve
21 phi_mud_0 = 0.614 # Kominz et al. 2011 >90% mud curve
22 phi_sand = phi_sand_0 * np.exp(-c_sand*y)
23 phi_mud = phi_mud_0 * np.exp(-c_mud*y)
24 plt.plot(phi_sand,y,'y--',linewidth=2,label='90% sand')
25 plt.plot(phi_mud,y,'--',color='brown',linewidth=2,label='90% mud')
26 plt.legend(loc=0, fontsize=10);
While the compaction trends for mud happen to be fairly similar in the plot above, the ones for sandy
lithologies are very different. This highlights that porosity-depth curves vary significantly from one
basin to another, and are strongly affected by overpressures and exhumation. Using local data and
geological information is critical. As Giles et al. (1998) have put it, “The use of default compaction curves
can introduce significant errors into thermal history and pore- fluid pressure calculations, particularly
where little well data are available to calibrate the model.” To see how widely – and wildly – variable
compaction trends can be, check out the review paper by Giles et al. (1998).
https://hinderedsettling.com/2017/04/12/exploring-decompaction-with-python/ 3/6
23/07/2020 Exploring (de)compaction with Python « Hindered Settling
Compacting or decompacting a column of sediment means that we have to move it along the curves in
the figure above. Let’s consider the volume of water in a small segment of the sediment column (over
which porosity does not vary a lot):
But
and
where and are the thicknesses that the water and total volumes occupy respectively, and A is the
area of the column we are looking at. So the relationship is equivalent to
As the total thickness equals the sediment thickness plus the water “thickness”, we get
https://hinderedsettling.com/2017/04/12/exploring-decompaction-with-python/ 4/6
23/07/2020 Exploring (de)compaction with Python « Hindered Settling
That is,
The decompaction equation could be solved in the ‘brute force’ way, that is, by gradually changing the
value of until the right hand side (RHS) of the equation is the same as the left hand side (LHS) – see
for example the Excel spreadsheet that accompanies Appendix 56 in Allen & Allen (2013). However, we
(and scipy) can do better than that; we will use bisection, one the simplest optimization methods to find
the root of the function that we set up as RHS-LHS.
Now we can do the calculations; here we set the initial depths of a sandstone column to 2 and 3
kilometers, and we estimate the new thickness and porosity assuming that the column is brought to the
surface ( ).
One issue we need to address is that ‘comp_func’ six input parameters, but the scipy ‘bisect’ function
only takes one parameter. We create a partial function ‘comp_func_1’ in which the only variable is ‘y2a’,
the rest are treated as constants:
Next we write a function that does the depth calculation for more than one layer in a sedimentary
column:
https://hinderedsettling.com/2017/04/12/exploring-decompaction-with-python/ 5/6
23/07/2020 Exploring (de)compaction with Python « Hindered Settling
1 def decompact(tops,lith,new_top,phi_sand,phi_mud,c_sand,c_mud):
2 tops_new = [] # list for decompacted tops
3 tops_new.append(new_top) # starting value
4 for i in range(len(tops)-1):
5 if lith[i] == 0:
6 phi = phi_mud; c = c_mud
7 if lith[i] == 1:
8 phi = phi_sand; c = c_sand
9 comp_func_1 = functools.partial(comp_func,y1=tops[i],y2=tops[i+1
10 base_new_a = tops_new[-1]+tops[i+1]-tops[i]
11 base_new = bisect(comp_func_1, base_new_a, 4*base_new_a) # bisec
12 tops_new.append(base_new)
13 return tops_new
Let’s use this function to decompact a simple stratigraphic column that consists of 5 alternating layers of
sand and mud.
1 tops = np.array([1.0,1.1,1.15,1.3,1.5,2.0])
2 lith = np.array([0,1,0,1,0]) # lithology labels: 0 = mud, 1 = sand
3 phi_sand_0 = 0.49 # surface porosity for sand
4 phi_mud_0 = 0.63 # surface porosity for mud
5 c_sand = 0.27 # porosity-depth coefficient for sand (km-1)
6 c_mud = 0.57 # porosity-depth coefficent for mud (km-1)
7 tops_new = decompact(tops,lith,0.0,phi_sand_0,phi_mud_0,c_sand,c_mud) # c
1 def plot_decompaction(tops,tops_new):
2 for i in range(len(tops)-1):
3 x = [0,1,1,0]
4 y = [tops[i], tops[i], tops[i+1], tops[i+1]]
5 if lith[i] == 0:
6 color = 'xkcd:umber'
7 if lith[i] == 1:
8 color = 'xkcd:yellowish'
9 plt.fill(x,y,color=color)
10 x = np.array([2,3,3,2])
11 y = np.array([tops_new[i], tops_new[i], tops_new[i+1], tops_new[
12 if lith[i] == 0:
13 color = 'xkcd:umber'
14 if lith[i] == 1:
15 color = 'xkcd:yellowish'
16 plt.fill(x,y,color=color)
17 plt.gca().invert_yaxis()
18 plt.tick_params(axis='x',which='both',bottom='off',top='off',labelbo
19 plt.ylabel('depth (km)');
20
21 plot_decompaction(tops,tops_new)
Now let’s see what happens if we use the 90% mud and 90% sand curves from Kominz et al. (2011).
1 tops = np.array([1.0,1.1,1.15,1.3,1.5,2.0])
2 lith = np.array([0,1,0,1,0]) # lithology labels: 0 = mud, 1 = sand
3 c_sand = 1000/18605.0 # Kominz et al. 2011 >90% sand curve
4 c_mud = 1000/1671.0 # Kominz et al. 2011 >90% mud curve
5 phi_sand_0 = 0.407 # Kominz et al. 2011 >90% sand curve
6 phi_mud_0 = 0.614 # Kominz et al. 2011 >90% mud curve
7 tops_new = decompact(tops,lith,0.0,phi_sand_0,phi_mud_0,c_sand,c_mud) # c
8
9 plot_decompaction(tops,tops_new)
https://hinderedsettling.com/2017/04/12/exploring-decompaction-with-python/ 6/6