pyslammer demo: batch simulations

This notebook shows an example use case of pyslammer for running batch simulations. ## Setup

Assumes pyslammer is installed in the current python environment. Documentation on installation pending, but for now, you can install it using pip:

pip install pyslammer

Import pyslammer using:

import pyslammer as slam

Additional Python libraries, such as matplotlib may also be useful.

%matplotlib widget
import pyslammer as slam
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
kys = np.linspace(0.1,0.7,100)
histories = slam.sample_ground_motions()
output = {}

Single simulation

All the sample ground motions that come with pyslammer have now been loaded into histories as a dictionary of name:time_history pairs. The cells below print the list of available ground motions and then run a single simulation on one example (Chi-Chi_1999_TCU068-090).

motion_options = [print(history) for history in histories.keys()]
Morgan_Hill_1984_CYC-285
Nisqually_2001_UNR-058
Imperial_Valley_1979_BCR-230
Chi-Chi_1999_TCU068-090
Cape_Mendocino_1992_PET-090
Loalinga_1983_PVB-045
Coalinga_1983_PVB-045
Mammoth_Lakes-2_1980_CVK-090
Northridge_VSP-360
Kocaeli_1999_ATS-090
Nahanni_1985_NS1-280
Mammoth_Lakes-1_1980_CVK-090
Duzce_1999_375-090
Loma_Prieta_1989_HSP-000
Landers_1992_LCN-345
N_Palm_Springs_1986_WWT-180
Kobe_1995_TAK-090
Coyote_Lake_1979_G02-050
# single simulation
ky = 0.2
motion = "Imperial_Valley_1979_BCR-230"

single_result = slam.RigidAnalysis(histories[motion].accel, histories[motion].dt, ky)

plt.close('all')
fig = single_result.sliding_block_plot()
plt.show()

Batch Simulations

The code below evaluates all combinations of \(k_y\) contained in kys and every motion in histories. Some key features (motion, ky, max displacement, and displacement time histories) are stored in a dictionary, which is then converted to a pandas dataframe.

run = 0
for ky in kys:
    for motion, hist in histories.items():
        result = slam.RigidAnalysis(histories[motion].accel, histories[motion].dt, ky)
        output[run] = {"motion":motion, "ky":ky, "d_max": result.max_sliding_disp, "dt":result.dt, "disp": result
        .sliding_disp}
        run += 1
# convert the output to a pandas dataframe
df = pd.DataFrame.from_dict(output,orient='index')
df
motion ky d_max dt disp
0 Morgan_Hill_1984_CYC-285 0.1 3.586510e-01 0.005 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...
1 Nisqually_2001_UNR-058 0.1 4.090052e-02 0.010 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...
2 Imperial_Valley_1979_BCR-230 0.1 5.531286e-01 0.005 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...
3 Chi-Chi_1999_TCU068-090 0.1 1.913807e+00 0.005 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...
4 Cape_Mendocino_1992_PET-090 0.1 4.112337e-01 0.020 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...
... ... ... ... ... ...
1795 Loma_Prieta_1989_HSP-000 0.7 4.394658e-16 0.005 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...
1796 Landers_1992_LCN-345 0.7 2.669527e-16 0.005 [1.3552527156068806e-24, 5.421010862427522e-24...
1797 N_Palm_Springs_1986_WWT-180 0.7 1.171560e-16 0.005 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...
1798 Kobe_1995_TAK-090 0.7 9.322589e-16 0.010 [0.0, 0.0, 0.0, 6.776263578034403e-25, 2.71050...
1799 Coyote_Lake_1979_G02-050 0.7 2.290104e-17 0.005 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...

1800 rows × 5 columns

Comparing multiple motions

The results of the analyses can be plotted to show trends in total accumulated displacement with \(k_y\) for each ground motion in the sample ground motion suite.

plt.close('all')
fig, ax = plt.subplots()
fig.set_size_inches(10,6)   
for key, grp in df.groupby(['motion']):
    ax.scatter(grp["ky"], grp["d_max"], label=key[0], alpha=0.5)
ax.legend(loc='upper left', bbox_to_anchor=(1, 1))
ax.set_yscale('log')
ax.set_ylim(1e-3,1e1)
ax.set_xlabel('Yield Acceleration (g)')
ax.set_ylabel('Maximum Displacement (m)')
ax.set_title('Maximum Displacement vs. Yield Acceleration')

plt.tight_layout()
plt.show()

Variation in a single motion’s time history

Alternatively, for any given motion, the displacement time histories for different values of \(k_y\). The data for all the other motions could get plotted, too, but there’s not really much to compare at that point because the plots get too messy.

df
motion ky d_max dt disp
0 Morgan_Hill_1984_CYC-285 0.1 3.586510e-01 0.005 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...
1 Nisqually_2001_UNR-058 0.1 4.090052e-02 0.010 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...
2 Imperial_Valley_1979_BCR-230 0.1 5.531286e-01 0.005 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...
3 Chi-Chi_1999_TCU068-090 0.1 1.913807e+00 0.005 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...
4 Cape_Mendocino_1992_PET-090 0.1 4.112337e-01 0.020 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...
... ... ... ... ... ...
1795 Loma_Prieta_1989_HSP-000 0.7 4.394658e-16 0.005 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...
1796 Landers_1992_LCN-345 0.7 2.669527e-16 0.005 [1.3552527156068806e-24, 5.421010862427522e-24...
1797 N_Palm_Springs_1986_WWT-180 0.7 1.171560e-16 0.005 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...
1798 Kobe_1995_TAK-090 0.7 9.322589e-16 0.010 [0.0, 0.0, 0.0, 6.776263578034403e-25, 2.71050...
1799 Coyote_Lake_1979_G02-050 0.7 2.290104e-17 0.005 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...

1800 rows × 5 columns

import matplotlib.cm as cm
from matplotlib.colors import LogNorm

motion = "Imperial_Valley_1979_BCR-230"

plt.close('all')

# Create a figure and axes
fig, ax = plt.subplots(figsize=(6, 4))

# Create a color map
cmap = plt.colormaps['Spectral']#cm.get_cmap('viridis')
norm = LogNorm(df['ky'].min(), df['ky'].max())

dt = df[df["motion"]==motion].iloc[0]['dt']
npts = df[df["motion"]==motion].iloc[0]['disp'].shape[0]
time = np.linspace(0, dt*npts, npts)

for index, row in df[df["motion"]==motion].iterrows():
    color = cmap(norm(row['ky']))
    ax.plot(time, row['disp'], color=color)

# Add a color bar
sm = cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])
cbar = fig.colorbar(sm, ax=ax, label='ky')

# Set the colorbar ticks and labels
ticks = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7]
cbar.set_ticks(ticks)
cbar.set_ticklabels([f'{tick:.2f}' for tick in ticks]) 

# Set the x-axis and y-axis labels
ax.set_xlabel('Time')
ax.set_ylabel('Displacement')
ax.set_title(motion)
plt.show()