Note
Go to the end to download the full example code or to run this example in your browser via Binder
Mechanical oscillator model (multioutput)
In this example, we consider the mechanical oscillator is governed by the following second-order ODE as demonstrated in [1]:
\[m \ddot{x} + c \dot{x} + k x = 0\]
\[x(0) = \ell, \dot{x}(0) = 0.\]
The parameteres of the oscillator are modeled as follows:
\[m \sim \mathcal{U}(10, 12), c \sim \mathcal{U}(0.4, 0.8), k \sim \mathcal{U}(70, 90), \ell \sim \mathcal{U}(-1, -0.25).\]
Here, we compute the Sobol indices for each point in time and are called pointwise-in-time Sobol indices. These indices describe the sensitivity of the model parameters at each point in time.
import numpy as np
import matplotlib.pyplot as plt
from UQpy.run_model.RunModel import RunModel
from UQpy.run_model.model_execution.PythonModel import PythonModel
from UQpy.distributions import Uniform
from UQpy.distributions.collection.JointIndependent import JointIndependent
from UQpy.sensitivity.SobolSensitivity import SobolSensitivity
Define the model and input distributions
# Create Model object
model = PythonModel(
model_script="local_mechanical_oscillator_ODE.py",
model_object_name="mech_oscillator",
var_names=[r"$m$", "$c$", "$k$", "$\ell$"],
delete_files=True,
)
runmodel_obj = RunModel(model=model)
# Define distribution object
M = Uniform(10, (12 - 10))
C = Uniform(0.4, (0.8 - 0.4))
K = Uniform(70, (90 - 70))
L = Uniform(-1, (-0.25 - -1))
dist_object = JointIndependent([M, C, K, L])
Compute Sobol indices
SA = SobolSensitivity(runmodel_obj, dist_object)
SA.run(n_samples=500)
Plot the Sobol indices
t_0 = 0
t_f = 40
dt = 0.05
n_t = int((t_f - t_0) / dt)
T = np.linspace(t_0, t_f, n_t)
fig, ax = plt.subplots(1, 2, figsize=(16, 8))
ax[0].plot(T, SA.total_order_indices[0, :], "r", label=r"$m$")
ax[0].plot(T, SA.total_order_indices[1, :], "g", label=r"$c$")
ax[0].plot(T, SA.total_order_indices[2, :], label=r"$k$", color="royalblue")
ax[0].plot(T, SA.total_order_indices[3, :], label=r"$\ell$", color="aquamarine")
ax[0].set_title("Total order Sobol indices", fontsize=16)
ax[0].set_xlabel("time (s)", fontsize=16)
ax[0].set_ylabel(r"$S_{T_i}$", fontsize=16)
ax[0].set_xbound(0, t_f)
ax[0].set_ybound(-0.2, 1.2)
ax[0].legend()
ax[1].plot(T, SA.first_order_indices[0, :], "r", label=r"$m$")
ax[1].plot(T, SA.first_order_indices[1, :], "g", label=r"$c$")
ax[1].plot(T, SA.first_order_indices[2, :], label=r"$k$", color="royalblue")
ax[1].plot(T, SA.first_order_indices[3, :], label=r"$\ell$", color="aquamarine")
ax[1].set_title("First order Sobol indices", fontsize=16)
ax[1].set_xlabel("time (s)", fontsize=16)
ax[1].set_ylabel(r"$S_i$", fontsize=16)
ax[1].set_xbound(0, t_f)
ax[1].set_ybound(-0.2, 1.2)
ax[1].legend(fontsize=12)
fig.suptitle("Pointwise-in-time Sobol indices", fontsize=20)
plt.show()
Total running time of the script: ( 0 minutes 0.000 seconds)