Example 12: Compare impact of frequency dependent \(D_{min}\)

[1]:
import itertools

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

import pystrata

%matplotlib inline
[2]:
plt.rcParams["figure.dpi"] = 150

Damping calculation

[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"],
)
[4]:
def calc_damp_min(row):
    return pystrata.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)
[5]:
df.head()
[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
[6]:
centers = {"plast_ind": 20, "stress_mean": 101.3, "ocr": 1}
[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)
../_images/examples_example-12_8_0.png
../_images/examples_example-12_8_1.png
../_images/examples_example-12_8_2.png

Site Response Calculation

Input

[8]:
motion = pystrata.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.

[9]:
profiles = [
    # Frequency independent soil properties
    pystrata.site.Profile(
        [
            pystrata.site.Layer(
                pystrata.site.DarendeliSoilType(
                    18.0, plas_index=30, ocr=1, stress_mean=200
                ),
                30,
                400,
            ),
            pystrata.site.Layer(
                pystrata.site.SoilType("Rock", 24.0, None, 0.01), 0, 1200
            ),
        ]
    ),
    # Frequency dependent minimum damping
    pystrata.site.Profile(
        [
            pystrata.site.Layer(
                pystrata.site.DarendeliSoilType(
                    18.0, plas_index=30, ocr=1, stress_mean=200, freq=motion.freqs
                ),
                30,
                400,
            ),
            pystrata.site.Layer(
                pystrata.site.SoilType("Rock", 24.0, None, 0.01), 0, 1200
            ),
        ]
    ),
]

profiles = [p.auto_discretize() for p in profiles]
[10]:
calc_fdm = pystrata.propagation.FrequencyDependentEqlCalculator(method="raw")
calc_eql = pystrata.propagation.EquivalentLinearCalculator(strain_ratio=0.65)
[11]:
freqs = np.logspace(-1, 2, num=500)

outputs = pystrata.output.OutputCollection(
    [
        pystrata.output.AccelTransferFunctionOutput(
            # Frequency
            freqs,
            # Location in (denominator),
            pystrata.output.OutputLocation("outcrop", index=-1),
            # Location out (numerator)
            pystrata.output.OutputLocation("outcrop", index=0),
        ),
        pystrata.output.ResponseSpectrumOutput(
            # Frequency
            freqs,
            # Location of the output
            pystrata.output.OutputLocation("outcrop", index=0),
            # Damping
            0.05,
        ),
    ]
)

Run the analyses and save the output.

[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

[13]:
for o in outputs:
    o.plot(style="indiv")
../_images/examples_example-12_19_0.png
../_images/examples_example-12_19_1.png
[ ]: