Skip to content

Commit f1473a5

Browse files
authored
Merge pull request #553 from bobmyhill/shearmod
add shear modulus example
2 parents 58536f2 + e994714 commit f1473a5

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# This file is part of BurnMan - a thermoelastic and thermodynamic toolkit for
2+
# the Earth and Planetary Sciences
3+
# Copyright (C) 2012 - 2023 by the BurnMan team, released under the GNU
4+
# GPL v2 or later.
5+
6+
7+
"""
8+
9+
example_add_shear_modulus
10+
-------------------------
11+
12+
This example shows how to create a new equation of state derived
13+
from another in order to calculate something new. In this case, we
14+
seek to create an equation of state that builds on the Holland and
15+
Powell (2011) equation of state, adding calculations for the shear
16+
modulus as proposed by Hacker and Abers (2004).
17+
18+
*Uses:*
19+
20+
* :doc:`mineral_database`
21+
* :class:`burnman.Mineral`
22+
23+
24+
*Demonstrates:*
25+
26+
* How to create a new equation of state and instantiate a mineral using it.
27+
* How to output thermoelastic properties from the new mineral object.
28+
29+
"""
30+
from __future__ import absolute_import
31+
32+
import numpy as np
33+
import matplotlib.pyplot as plt
34+
from copy import deepcopy
35+
36+
from burnman import Mineral
37+
from burnman.minerals import HGP_2018_ds633
38+
from burnman.eos.hp import HP_TMT
39+
40+
if __name__ == "__main__":
41+
# First, we create a new class, derived from HP_TMT
42+
# (the modified Tait equation of state derived by Holland and Powell, 2011).
43+
# We overwrite just a single function; the one to calculate the shear modulus.
44+
# Here we use the equations given by Hacker and Abers (2004).
45+
class HP_TMT_shear(HP_TMT):
46+
def shear_modulus(self, pressure, temperature, volume, params):
47+
x = params["V_0"] / volume
48+
phi = np.log(1.0 / x)
49+
gamma = params["Gamma_0"]
50+
f = 0.5 * (np.power(x, 2.0 / 3.0) - 1.0)
51+
f2 = np.power(1.0 + 2.0 * f, 5.0 / 2.0)
52+
G_T = params["shear_modulus_0"] * np.exp(-gamma * phi)
53+
K_PT = self.isothermal_bulk_modulus(pressure, temperature, volume, params)
54+
K_T = K_PT / ((1.0 - f * (5.0 - 3.0 * params["Kprime_0"])) * f2)
55+
G = G_T * f2 * (1.0 - f * (5.0 - 3.0 * params["Gprime_0"] * K_T / G_T))
56+
return G
57+
58+
# We want to create a forsterite object
59+
# that uses this new equation of state. For this, we need values
60+
# for the new parameters required by that equation of state.
61+
# Here we create a dictionary with the values from Hacker and Abers (2004).
62+
shear_params = {
63+
"fo": {"shear_modulus_0": 81.6e9, "Gamma_0": 5.19, "Gprime_0": 1.82}
64+
}
65+
66+
# One way to use the new equation of state is to first create a Mineral object
67+
# from the existing forsterite class in HGP_2018_ds633, update the parameters
68+
# and then use the set_method() method:
69+
fo = HGP_2018_ds633.fo()
70+
fo.params.update(shear_params["fo"])
71+
fo.set_method(HP_TMT_shear)
72+
73+
# Now we can use the modified object:
74+
P = 1.0e9
75+
T = 500.0
76+
fo.set_state(P, T)
77+
78+
# Print some values:
79+
print(f"P: {P/1.e9:.2f} GPa, T: {T:.2f} K")
80+
81+
print("\nProperties from modified object:")
82+
print(f" Shear modulus: {fo.G/1.e9:.2f} GPa")
83+
print(f" V_p: {fo.v_p/1.e3:.2f} km/s, V_s: {fo.v_s/1.e3:.2f} km/s")
84+
85+
# This method works well if we only want one instantiation, but what if
86+
# we want to create several? One way to do this is to define a new class
87+
# and put the required steps into the initialisation function:
88+
89+
class fo_w_shear(Mineral):
90+
def __init__(self):
91+
tmp = HGP_2018_ds633.fo()
92+
self.params = deepcopy(tmp.params)
93+
name = self.params["name"]
94+
self.params.update(shear_params[name])
95+
Mineral.__init__(self)
96+
self.set_method(HP_TMT_shear)
97+
98+
# Now we can create new object from the modified class
99+
fo = fo_w_shear()
100+
fo.set_state(P, T)
101+
102+
print("\nProperties from object created from modified class:")
103+
print(f" Shear modulus: {fo.G/1.e9:.2f} GPa")
104+
print(f" V_p: {fo.v_p/1.e3:.2f} km/s, V_s: {fo.v_s/1.e3:.2f} km/s")
105+
106+
# We can now do anything we like with this new mineral,
107+
# like use the evaluate method:
108+
pressures = np.linspace(1.0e5, 10.0e9, 101)
109+
T = 1500.0
110+
temperatures = np.ones_like(pressures) * T
111+
112+
v_p, v_s = fo.evaluate(["v_p", "v_s"], pressures, temperatures)
113+
plt.plot(pressures / 1.0e9, v_p / 1.0e3, label=f"$V_P$ for {fo.name} at {T} K")
114+
plt.plot(pressures / 1.0e9, v_s / 1.0e3, label=f"$V_S$ for {fo.name} at {T} K")
115+
plt.xlabel("Pressure (GPa)")
116+
plt.ylabel("Velocities (km/s)")
117+
plt.legend()
118+
plt.show()
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
P: 1.00 GPa, T: 500.00 K
2+
3+
Properties from modified object:
4+
Shear modulus: 82.52 GPa
5+
V_p: 8.66 km/s, V_s: 5.06 km/s
6+
7+
Properties from object created from modified class:
8+
Shear modulus: 82.52 GPa
9+
V_p: 8.66 km/s, V_s: 5.06 km/s

0 commit comments

Comments
 (0)