Module earthquakepy.singledof
Expand source code
import numpy as np
from scipy.integrate import solve_ivp
from scipy.integrate._ivp.ivp import OdeResult
import matplotlib.pyplot as plt
class Sdof:
"""
Class for single-degree-of-freedom system
Parameters :
You should provide at least wn or T or (m and k).
Parameters
----------
m: scalar
mass of the system
c: scalar
damping constant
k: scalar
stiffness
xi: scalar
damping ratio
wn: scalar
Natural Frequency (rad/s)
T: scalar
Natural Period
"""
def __init__(self, m=None, c=0.0, k=None, xi=0.0, wn=None, T=None):
if T:
wn = 2 * np.pi / T
m = 1.0
k = m * wn**2
c = 2 * xi * m * wn
elif wn:
T = 2 * np.pi / wn
m = 1.0
k = m * wn**2
c = 2 * xi * m * wn
elif k and m:
wn = np.sqrt(k / m)
T = 2 * np.pi / wn
if xi:
c = 2 * xi * m * wn
elif c:
xi = c / (2 * m * wn)
else:
raise Exception("Incorrect parameters")
self.m, self.c, self.k = m, c, k
self.xi, self.wn, self.T = xi, wn, T
def __repr__(self):
a = ""
for key, val in vars(self).items():
a += "{:10s}:{}\n".format(key, val)
return a
def sdof_grad(self, t, y, tv, f):
m, c, k = self.m, self.c, self.k
ft = np.interp(t, tv, f)
A = np.array([[0, 1], [-k / m, -c / m]])
x = np.array(y)
f = np.array([[0.0], [ft / m]])
dy = np.matmul(A, x) + f
return dy
def get_response(self, ts, tsType="baseExcitation", **kwargs):
"""
Wrapper around solve_ivp module from scipy.integrate. It supports all the arguments supported by solve_ivp.
Parameters
----------
ts: (timeseries object) timeseries defining loading/base excitation
tsType: (string) "baseExcitation" or "force"
**kwargs: arguments acceptable to scipy solve_ivp module
Returns
-------
SdofResponseTimeSeries object
By default the solution will be obtained for duration = 2 * (ts.t duration). This can be changed using t_span argument. Default method : BDF.
"""
if tsType == "baseExcitation":
f = -self.m * ts.y
elif tsType == "force":
f = ts.y
else:
raise Exception("Incorrect timeseries type given")
defaultArgs = {
"t_span": (ts.t[0], ts.t[-1] * 2),
"y0": [0.0, 0.0],
"method": "BDF",
"t_eval": None,
"dense_output": False,
"events": None,
"vectorized": True,
"args": (ts.t, f),
"jac": np.array([[0, 1], [-self.k / self.m, -self.c / self.m]]),
}
kwargs = {**defaultArgs, **kwargs}
# r = solve_ivp(self.sdof_grad, **kwargs)
r = solve_ivp(self.sdof_grad, **kwargs)
m, c, k = self.m, self.c, self.k
fv = np.interp(r.t, ts.t, f)
acc = 1 / m * (fv - c * r.y[1] - k * r.y[0])
return SdofResponseTimeSeries(r, acc)
class SdofResponseTimeSeries(OdeResult):
"""
Class for response object of SDOF system
"""
def __init__(self, ode_result, acc):
self.acc = acc
for key, val in ode_result.items():
self.__setattr__(key, val)
def plot(self, **kwargs):
"""
A quick and dirty way to plot and inspect the output. It accepts all the arguments supported by matplotlib.pyplot.subplots()
"""
y = np.transpose(self.y)
fig, ax = plt.subplots(nrows=1, ncols=len(self.y), **kwargs)
for i in range(len(self.y)):
ax[i].plot(self.t, self.y[i], linewidth=0.5, color="black")
ax[i].set_xlabel("Time (s)")
return fig
Classes
class Sdof (m=None, c=0.0, k=None, xi=0.0, wn=None, T=None)
-
Class for single-degree-of-freedom system Parameters : You should provide at least wn or T or (m and k).
Parameters
m
:scalar
- mass of the system
c
:scalar
- damping constant
k
:scalar
- stiffness
xi
:scalar
- damping ratio
wn
:scalar
- Natural Frequency (rad/s)
T
:scalar
- Natural Period
Expand source code
class Sdof: """ Class for single-degree-of-freedom system Parameters : You should provide at least wn or T or (m and k). Parameters ---------- m: scalar mass of the system c: scalar damping constant k: scalar stiffness xi: scalar damping ratio wn: scalar Natural Frequency (rad/s) T: scalar Natural Period """ def __init__(self, m=None, c=0.0, k=None, xi=0.0, wn=None, T=None): if T: wn = 2 * np.pi / T m = 1.0 k = m * wn**2 c = 2 * xi * m * wn elif wn: T = 2 * np.pi / wn m = 1.0 k = m * wn**2 c = 2 * xi * m * wn elif k and m: wn = np.sqrt(k / m) T = 2 * np.pi / wn if xi: c = 2 * xi * m * wn elif c: xi = c / (2 * m * wn) else: raise Exception("Incorrect parameters") self.m, self.c, self.k = m, c, k self.xi, self.wn, self.T = xi, wn, T def __repr__(self): a = "" for key, val in vars(self).items(): a += "{:10s}:{}\n".format(key, val) return a def sdof_grad(self, t, y, tv, f): m, c, k = self.m, self.c, self.k ft = np.interp(t, tv, f) A = np.array([[0, 1], [-k / m, -c / m]]) x = np.array(y) f = np.array([[0.0], [ft / m]]) dy = np.matmul(A, x) + f return dy def get_response(self, ts, tsType="baseExcitation", **kwargs): """ Wrapper around solve_ivp module from scipy.integrate. It supports all the arguments supported by solve_ivp. Parameters ---------- ts: (timeseries object) timeseries defining loading/base excitation tsType: (string) "baseExcitation" or "force" **kwargs: arguments acceptable to scipy solve_ivp module Returns ------- SdofResponseTimeSeries object By default the solution will be obtained for duration = 2 * (ts.t duration). This can be changed using t_span argument. Default method : BDF. """ if tsType == "baseExcitation": f = -self.m * ts.y elif tsType == "force": f = ts.y else: raise Exception("Incorrect timeseries type given") defaultArgs = { "t_span": (ts.t[0], ts.t[-1] * 2), "y0": [0.0, 0.0], "method": "BDF", "t_eval": None, "dense_output": False, "events": None, "vectorized": True, "args": (ts.t, f), "jac": np.array([[0, 1], [-self.k / self.m, -self.c / self.m]]), } kwargs = {**defaultArgs, **kwargs} # r = solve_ivp(self.sdof_grad, **kwargs) r = solve_ivp(self.sdof_grad, **kwargs) m, c, k = self.m, self.c, self.k fv = np.interp(r.t, ts.t, f) acc = 1 / m * (fv - c * r.y[1] - k * r.y[0]) return SdofResponseTimeSeries(r, acc)
Methods
def get_response(self, ts, tsType='baseExcitation', **kwargs)
-
Wrapper around solve_ivp module from scipy.integrate. It supports all the arguments supported by solve_ivp.
Parameters
ts
:(timeseries object) timeseries defining loading/base excitation
tsType
:(string) "baseExcitation"
or"force"
**kwargs
:arguments acceptable to scipy solve_ivp module
Returns
SdofResponseTimeSeries object
By default the solution will be obtained for duration = 2 * (ts.t duration). This can be changed using t_span argument. Default method : BDF.
Expand source code
def get_response(self, ts, tsType="baseExcitation", **kwargs): """ Wrapper around solve_ivp module from scipy.integrate. It supports all the arguments supported by solve_ivp. Parameters ---------- ts: (timeseries object) timeseries defining loading/base excitation tsType: (string) "baseExcitation" or "force" **kwargs: arguments acceptable to scipy solve_ivp module Returns ------- SdofResponseTimeSeries object By default the solution will be obtained for duration = 2 * (ts.t duration). This can be changed using t_span argument. Default method : BDF. """ if tsType == "baseExcitation": f = -self.m * ts.y elif tsType == "force": f = ts.y else: raise Exception("Incorrect timeseries type given") defaultArgs = { "t_span": (ts.t[0], ts.t[-1] * 2), "y0": [0.0, 0.0], "method": "BDF", "t_eval": None, "dense_output": False, "events": None, "vectorized": True, "args": (ts.t, f), "jac": np.array([[0, 1], [-self.k / self.m, -self.c / self.m]]), } kwargs = {**defaultArgs, **kwargs} # r = solve_ivp(self.sdof_grad, **kwargs) r = solve_ivp(self.sdof_grad, **kwargs) m, c, k = self.m, self.c, self.k fv = np.interp(r.t, ts.t, f) acc = 1 / m * (fv - c * r.y[1] - k * r.y[0]) return SdofResponseTimeSeries(r, acc)
def sdof_grad(self, t, y, tv, f)
-
Expand source code
def sdof_grad(self, t, y, tv, f): m, c, k = self.m, self.c, self.k ft = np.interp(t, tv, f) A = np.array([[0, 1], [-k / m, -c / m]]) x = np.array(y) f = np.array([[0.0], [ft / m]]) dy = np.matmul(A, x) + f return dy
class SdofResponseTimeSeries (ode_result, acc)
-
Class for response object of SDOF system
Expand source code
class SdofResponseTimeSeries(OdeResult): """ Class for response object of SDOF system """ def __init__(self, ode_result, acc): self.acc = acc for key, val in ode_result.items(): self.__setattr__(key, val) def plot(self, **kwargs): """ A quick and dirty way to plot and inspect the output. It accepts all the arguments supported by matplotlib.pyplot.subplots() """ y = np.transpose(self.y) fig, ax = plt.subplots(nrows=1, ncols=len(self.y), **kwargs) for i in range(len(self.y)): ax[i].plot(self.t, self.y[i], linewidth=0.5, color="black") ax[i].set_xlabel("Time (s)") return fig
Ancestors
- scipy.integrate._ivp.ivp.OdeResult
- scipy.optimize._optimize.OptimizeResult
- builtins.dict
Methods
def plot(self, **kwargs)
-
A quick and dirty way to plot and inspect the output. It accepts all the arguments supported by matplotlib.pyplot.subplots()
Expand source code
def plot(self, **kwargs): """ A quick and dirty way to plot and inspect the output. It accepts all the arguments supported by matplotlib.pyplot.subplots() """ y = np.transpose(self.y) fig, ax = plt.subplots(nrows=1, ncols=len(self.y), **kwargs) for i in range(len(self.y)): ax[i].plot(self.t, self.y[i], linewidth=0.5, color="black") ax[i].set_xlabel("Time (s)") return fig