Skip to content

Commit fcd08d2

Browse files
committed
Add Kamai et al. model.
1 parent 5a2e722 commit fcd08d2

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed

src/pystrata/generic.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
"""Generic velocity profiles."""
2+
3+
import warnings
4+
5+
import numpy as np
6+
import pandas as pd
7+
8+
9+
def kea16_profile(depth: float, vs30: float, region: str) -> pd.DataFrame:
10+
"""
11+
Calculate the median shear-wave velocity profile and its standard deviation
12+
at a given depth, based on the VS30 value and region, using the model from
13+
Kamai et al. (2016).
14+
15+
Parameters
16+
----------
17+
depth : float or np.ndarray
18+
The depth(s) in meters at which to calculate the profile.
19+
vs30 : float
20+
The VS30 value in m/sec.
21+
region : str
22+
The region for the model. Must be either 'California' or 'Japan'.
23+
24+
Returns
25+
-------
26+
pd.DataFrame
27+
DataFrame with index as depth and columns:
28+
- 'vs_median': float or np.ndarray
29+
The median shear-wave velocity at the given depth(s) in m/sec.
30+
- 'std_vs_ln_units': float
31+
The standard deviation of the shear-wave velocity in ln units.
32+
33+
Raises
34+
------
35+
ValueError
36+
If the region is not 'California' or 'Japan'.
37+
38+
Warns
39+
-----
40+
UserWarning
41+
If vs30 is outside the recommended range [250, 850] m/sec.
42+
43+
References
44+
----------
45+
Kamai, R., et al. (2016). "Nonlinear site response from the KiK-net
46+
database." Bulletin of the Seismological Society of America, 106(4),
47+
1710-1723.
48+
"""
49+
# Coefficients from Table 2 [cite: 184, 185]
50+
if region == "california":
51+
b1 = 0.25
52+
b2 = 104
53+
b3 = 0.22
54+
b4 = 166
55+
b5 = 53
56+
b6 = -0.00388
57+
b7 = 0.0002
58+
b8 = 0.195
59+
elif region == "japan":
60+
b1 = 0.2
61+
b2 = 40
62+
b3 = 0.25
63+
b4 = 260
64+
b5 = 28
65+
b6 = -0.00296
66+
b7 = 0
67+
b8 = 0.4
68+
else:
69+
raise ValueError("Region must be 'California' or 'Japan'")
70+
71+
if not (250 <= vs30 <= 850):
72+
# The model is recommended for VS30 between 250 and 850 m/sec.
73+
warnings.warn(
74+
"The model is recommended for VS30 between 250 and 850 m/sec. "
75+
"Values outside this range may lead to inaccurate results.",
76+
UserWarning,
77+
)
78+
79+
a0 = b1 * vs30 + b2 # Equation 3a
80+
a1 = b3 * vs30 + b4 # Equation 3b
81+
a2 = b5 * np.exp(b6 * vs30) # Equation 3c
82+
83+
# Ensure the argument to log is positive and handle depth=0 or negative depths
84+
log_arg = (np.array(depth) + a2) / a2
85+
vs_median = a0 + a1 * np.log(
86+
np.maximum(log_arg, 1e-9)
87+
) # Equation 3, using maximum to handle non-positive log arguments
88+
89+
a3 = b7 * vs30 + b8 # Equation 4a
90+
std_vs_ln_units = a3 # Equation 4
91+
92+
df = pd.DataFrame(
93+
{"vs_median": vs_median, "std_vs_ln_units": std_vs_ln_units},
94+
index=pd.Index(depth, name="depth"),
95+
)
96+
97+
return df

0 commit comments

Comments
 (0)