Compare impact of frequency dependent $D_{min}$


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

Frequency dependence of $D_{min}$ predicted by Darendeli (2001)

Calculation


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]:
freq stress_mean plast_ind ocr damp_min
0 0.1 50.65 0 1 0.003207
1 0.1 50.65 0 2 0.003207
2 0.1 50.65 0 4 0.003207
3 0.1 50.65 20 1 0.004240
4 0.1 50.65 20 2 0.004167

Plots


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)


Site Response Calculation

Input


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
    ),
])

Run the analyses and save the output.


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')

Plot the results


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 [ ]: