In [1]:
import itertools
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import pysra
%matplotlib inline
In [2]:
plt.rcParams['figure.dpi'] = 150
In [3]:
plast_indices = [0, 20, 50, 100]
stresses_mean = 101.3 * np.array([0.5, 1, 2])
ocrs = [1, 2, 4]
freqs = np.logspace(-1, 2, num=31)
df = pd.DataFrame(
itertools.product(freqs, stresses_mean, plast_indices, ocrs),
columns=['freq', 'stress_mean', 'plast_ind', 'ocr']
)
In [4]:
def calc_damp_min(row):
return pysra.site.DarendeliSoilType(
plas_index=row.plast_ind,
stress_mean=row.stress_mean,
ocr=row.ocr,
freq=row.freq,
)._calc_damping_min()
df['damp_min'] = df.apply(calc_damp_min, axis=1)
In [5]:
df.head()
Out[5]:
In [6]:
centers = {'plast_ind': 20, 'stress_mean': 101.3, 'ocr': 1}
In [7]:
for key in centers:
# Only select the centers
mask = np.all([df[k].eq(v) for k, v in centers.items() if k != key], axis=0)
selected = df[mask]
fig, ax = plt.subplots()
for name, group in selected.groupby(key):
ax.plot(group['freq'], group['damp_min'], label=name)
ax.set(
xlabel='Frequency (Hz)', xscale='log',
ylabel='Damping Min. (dec)', ylim=(0, 0.05),
)
ax.legend(title=key)
In [8]:
motion = pysra.motion.SourceTheoryRvtMotion(7.0, 30, 'wna')
motion.calc_fourier_amps()
Two profiles are created. The first is a typical profile with the minimum damping computed at 1 Hz (default value). The second profile has the minimum damping computed at each frequency of the input motion.
In [9]:
profiles = [
# Frequency independent soil properties
pysra.site.Profile([
pysra.site.Layer(
pysra.site.DarendeliSoilType(
18., plas_index=30, ocr=1, stress_mean=200),
30, 400
),
pysra.site.Layer(
pysra.site.SoilType(
'Rock', 24., None, 0.01
),
0, 1200
),
]),
# Frequency dependent minimum damping
pysra.site.Profile([
pysra.site.Layer(
pysra.site.DarendeliSoilType(
18., plas_index=30, ocr=1, stress_mean=200, freq=motion.freqs),
30, 400
),
pysra.site.Layer(
pysra.site.SoilType(
'Rock', 24., None, 0.01
),
0, 1200
),
])
]
profiles = [p.auto_discretize() for p in profiles]
In [10]:
calc_fdm = pysra.propagation.FrequencyDependentEqlCalculator(use_smooth_spectrum=False)
calc_eql = pysra.propagation.EquivalentLinearCalculator(strain_ratio=0.65)
In [11]:
freqs = np.logspace(-1, 2, num=500)
outputs = pysra.output.OutputCollection([
pysra.output.AccelTransferFunctionOutput(
# Frequency
freqs,
# Location in (denominator),
pysra.output.OutputLocation('outcrop', index=-1),
# Location out (numerator)
pysra.output.OutputLocation('outcrop', index=0),
),
pysra.output.ResponseSpectrumOutput(
# Frequency
freqs,
# Location of the output
pysra.output.OutputLocation('outcrop', index=0),
# Damping
0.05
),
])
In [12]:
for name, profile in zip(['FDM - Constant $D_{min}$', 'FDM - Variable $D_{min}$'], profiles):
calc_fdm(motion, profile, profile.location('outcrop', index=-1))
outputs(calc_fdm, name)
calc_eql(motion, profiles[0], profiles[0].location('outcrop', index=-1))
outputs(calc_eql, 'EQL')
In [13]:
for o in outputs:
fig, ax = plt.subplots()
for name, refs, values in o.iter_results():
ax.plot(refs, values, label=name)
ax.set(xlabel=o.xlabel, xscale='log', ylabel=o.ylabel)
ax.legend()
fig.tight_layout();
In [ ]: