Skip to content

Commit 9e98a62

Browse files
authored
Merge pull request #222 from SURGroup/Development
Development
2 parents 680b267 + 8e4d074 commit 9e98a62

20 files changed

Lines changed: 314 additions & 430 deletions

File tree

docs/code/dimension_reduction/grassmann/plot_grassmann_distances.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,14 @@
1313

1414
# %%
1515

16-
import numpy as np
17-
import matplotlib
1816
import matplotlib.pyplot as plt
19-
from mpl_toolkits.axes_grid1 import make_axes_locatable
20-
from UQpy import SVDProjection
21-
import sys
17+
import numpy as np
2218

19+
from UQpy import SVDProjection
2320
from UQpy.utilities import GrassmannPoint
2421
from UQpy.utilities.distances.baseclass.GrassmannianDistance import GrassmannianDistance
2522
from UQpy.utilities.distances.grassmannian_distances.GeodesicDistance import GeodesicDistance
2623

27-
from UQpy.dimension_reduction import GrassmannOperations
28-
2924
# %% md
3025
#
3126
# Generate four random matrices with reduced rank corresponding to the different samples. The samples are stored in

docs/code/dimension_reduction/grassmann/plot_grassmann_karcher.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,11 @@
1313

1414
#%%
1515

16-
import numpy as np
17-
import matplotlib
1816
import matplotlib.pyplot as plt
19-
from mpl_toolkits.axes_grid1 import make_axes_locatable
20-
import sys
21-
from UQpy.dimension_reduction.grassmann_manifold.projections.SVDProjection import SVDProjection
17+
import numpy as np
18+
2219
from UQpy.dimension_reduction import GrassmannOperations
20+
from UQpy.dimension_reduction.grassmann_manifold.projections.SVDProjection import SVDProjection
2321

2422
#%% md
2523
#

docs/code/dimension_reduction/grassmann/plot_grassmann_log_exp.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,11 @@
1313

1414
#%%
1515

16-
import numpy as np
17-
import matplotlib
1816
import matplotlib.pyplot as plt
19-
from mpl_toolkits.axes_grid1 import make_axes_locatable
20-
from UQpy.dimension_reduction.grassmann_manifold.projections.SVDProjection import SVDProjection
17+
import numpy as np
18+
2119
from UQpy.dimension_reduction import GrassmannOperations
22-
import sys
20+
from UQpy.dimension_reduction.grassmann_manifold.projections.SVDProjection import SVDProjection
2321

2422
#%% md
2523
#

docs/code/reliability/form/FORM_linear function_2d.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,23 @@
1717

1818
#%%
1919

20-
import shutil
21-
22-
from UQpy.run_model.RunModel import RunModel
23-
from UQpy.run_model.model_execution.PythonModel import PythonModel
2420
from UQpy.distributions import Normal
2521
from UQpy.reliability import FORM
22+
from UQpy.run_model.RunModel import RunModel
23+
from UQpy.run_model.model_execution.PythonModel import PythonModel
2624

2725
dist1 = Normal(loc=0., scale=1.)
2826
dist2 = Normal(loc=0., scale=1.)
2927

30-
model = PythonModel(model_script='pfn.py', model_object_name="example2")
28+
model = PythonModel(model_script='local_pfn.py', model_object_name="example2")
3129
RunModelObject2 = RunModel(model=model)
3230

3331
Z = FORM(distributions=[dist1, dist2], runmodel_object=RunModelObject2)
3432
Z.run()
3533

3634
# print results
37-
print('Design point in standard normal space: %s' % Z.DesignPoint_U)
38-
print('Design point in original space: %s' % Z.DesignPoint_X)
35+
print('Design point in standard normal space: %s' % Z.design_point_u)
36+
print('Design point in original space: %s' % Z.design_point_x)
3937
print('Hasofer-Lind reliability index: %s' % Z.beta)
4038
print('FORM probability of failure: %s' % Z.failure_probability)
4139

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@
66
"""
77
import numpy as np
88

9+
910
def example1(samples=None):
1011
g = np.zeros(samples.shape[0])
1112
for i in range(samples.shape[0]):
1213
R = samples[i, 0]
1314
S = samples[i, 1]
1415
g[i] = R - S
1516
return g
16-
17+
1718

1819
def example2(samples=None):
19-
import numpy as np
2020
d = 2
2121
beta = 3.0902
2222
g = np.zeros(samples.shape[0])
@@ -30,9 +30,10 @@ def example3(samples=None):
3030
for i in range(samples.shape[0]):
3131
g[i] = 6.2*samples[i, 0] - samples[i, 1]*samples[i, 2]**2
3232
return g
33-
33+
34+
3435
def example4(samples=None):
3536
g = np.zeros(samples.shape[0])
3637
for i in range(samples.shape[0]):
3738
g[i] = samples[i, 0]*samples[i, 1] - 80
38-
return g
39+
return g

docs/code/reliability/form/plot_FORM_linear_function_3d.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@
3434
dist2 = Normal(loc=5., scale=0.8)
3535
dist3 = Normal(loc=4., scale=0.4)
3636

37-
model = PythonModel(model_script='pfn.py', model_object_name="example3",)
37+
model = PythonModel(model_script='local_pfn.py', model_object_name="example3",)
3838
RunModelObject3 = RunModel(model=model)
3939

4040
Z0 = FORM(distributions=[dist1, dist2, dist3], runmodel_object=RunModelObject3)
4141
Z0.run()
4242

43-
print('Design point in standard normal space: %s' % Z0.DesignPoint_U)
44-
print('Design point in original space: %s' % Z0.DesignPoint_X)
43+
print('Design point in standard normal space: %s' % Z0.design_point_u)
44+
print('Design point in original space: %s' % Z0.design_point_x)
4545
print('Hasofer-Lind reliability index: %s' % Z0.beta)
4646
print('FORM probability of failure: %s' % Z0.failure_probability)
4747

docs/code/reliability/form/plot_FORM_structural_reliability.py

Lines changed: 105 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
3. FORM - Structural Reliability
44
==============================================
55
6-
The benchmark problem is a simple structural reliability problem
6+
The benchmark problem is a simple structural reliability problem (example 7.1 in :cite:`FORM_XDu`)
77
defined in a two-dimensional parameter space consisting of a resistance :math:`R` and a stress :math:`S`. The failure
88
happens when the stress is higher than the resistance, leading to the following limit-state function:
99
10-
.. math:: \textbf{X}=\{R, S\}
10+
.. math:: \\textbf{X}=\{R, S\}
1111
12-
.. math:: g(\textbf{X}) = R - S
12+
.. math:: g(\\textbf{X}) = R - S
1313
1414
The two random variables are independent and distributed
1515
according to:
@@ -19,47 +19,77 @@
1919
.. math:: S \sim N(150, 10)
2020
"""
2121

22-
#%% md
22+
# %% md
2323
#
2424
# Initially we have to import the necessary modules.
2525

26-
#%%
27-
import shutil
26+
# %%
2827

2928
import numpy as np
3029
import matplotlib.pyplot as plt
31-
from UQpy.run_model.RunModel import RunModel
32-
from UQpy.run_model.model_execution.PythonModel import PythonModel
30+
plt.style.use('ggplot')
3331
from UQpy.distributions import Normal
3432
from UQpy.reliability import FORM
33+
from UQpy.run_model.RunModel import RunModel
34+
from UQpy.run_model.model_execution.PythonModel import PythonModel
35+
36+
37+
# %% md
38+
#
39+
# Next, we initialize the :code:`RunModel` object.
40+
# The `local_pfn.py <https://github.com/SURGroup/UQpy/tree/master/docs/code/reliability/sorm>`_ file can be found on
41+
# the UQpy GitHub. It contains a simple function :code:`example1` to compute the difference between the resistence and the
42+
# stress.
43+
44+
# %%
45+
46+
model = PythonModel(model_script='local_pfn.py', model_object_name="example1")
47+
runmodel_object = RunModel(model=model)
48+
49+
# %% md
50+
#
51+
# Now we can define the resistence and stress distributions that will be passed into :code:`FORM`.
52+
# Along with the distributions, :code:`FORM` takes in the previously defined :code:`runmodel_object` and tolerances
53+
# for convergences. Since :code:`tolerance_gradient` is not specified in this example, it is not considered.
3554

55+
# %%
3656

37-
model = PythonModel(model_script='pfn.py', model_object_name="example1")
38-
RunModelObject = RunModel(model=model)
57+
distribution_resistance = Normal(loc=200., scale=20.)
58+
distribution_stress = Normal(loc=150., scale=10.)
59+
form = FORM(distributions=[distribution_resistance, distribution_stress], runmodel_object=runmodel_object,
60+
tolerance_u=1e-5, tolerance_beta=1e-5)
61+
# %% md
62+
#
63+
# With everything defined we are ready to run the first-order reliability method and print the results.
64+
# The analytic solution to this problem is :math:`\textbf{u}^*=(-2, 1)` with a reliability index of
65+
# :math:`\beta_{HL}=2.2361` and a probability of failure :math:`P_{f, \text{form}} = \Phi(-\beta_{HL}) = 0.0127`
3966

40-
dist1 = Normal(loc=200., scale=20.)
41-
dist2 = Normal(loc=150, scale=10.)
42-
Q = FORM(distributions=[dist1, dist2], runmodel_object=RunModelObject, tol1=1e-5, tol2=1e-5)
43-
Q.run()
67+
# %%
4468

69+
form.run()
70+
print('Design point in standard normal space:', form.design_point_u)
71+
print('Design point in original space:', form.design_point_x)
72+
print('Hasofer-Lind reliability index:', form.beta)
73+
print('FORM probability of failure:', form.failure_probability)
74+
print('FORM record of the function gradient:', form.state_function_gradient_record)
4575

46-
# print results
47-
print('Design point in standard normal space: %s' % Q.DesignPoint_U)
48-
print('Design point in original space: %s' % Q.DesignPoint_X)
49-
print('Hasofer-Lind reliability index: %s' % Q.beta)
50-
print('FORM probability of failure: %s' % Q.failure_probability)
51-
print(Q.dg_u_record)
76+
# %% md
77+
#
78+
# This problem can be visualized in the following plots that show the FORM results in both :math:`\textbf{X}` and
79+
# :math:`\textbf{U}` space.
5280

81+
# %%
5382

54-
# Supporting function
55-
def multivariate_gaussian(pos, mu, Sigma):
83+
def multivariate_gaussian(pos, mu, sigma):
84+
"""Supporting function"""
5685
n = mu.shape[0]
57-
Sigma_det = np.linalg.det(Sigma)
58-
Sigma_inv = np.linalg.inv(Sigma)
59-
N = np.sqrt((2 * np.pi) ** n * Sigma_det)
60-
fac = np.einsum('...k,kl,...l->...', pos - mu, Sigma_inv, pos - mu)
86+
sigma_det = np.linalg.det(sigma)
87+
sigma_inv = np.linalg.inv(sigma)
88+
N = np.sqrt((2 * np.pi) ** n * sigma_det)
89+
fac = np.einsum('...k,kl,...l->...', pos - mu, sigma_inv, pos - mu)
6190
return np.exp(-fac / 2) / N
6291

92+
6393
N = 60
6494
XX = np.linspace(150, 250, N)
6595
YX = np.linspace(120, 180, N)
@@ -69,85 +99,65 @@ def multivariate_gaussian(pos, mu, Sigma):
6999
YU = np.linspace(-3, 3, N)
70100
XU, YU = np.meshgrid(XU, YU)
71101

72-
# Mean vector and covariance matrix in the original space
73-
parameters = [[200, 20], [150, 10]]
74-
mu_X = np.array([parameters[0][0], parameters[1][0]])
75-
Sigma_X = np.array([[parameters[0][1] ** 2, 0.0], [0.0, parameters[1][1] ** 2]])
76102

77-
# Mean vector and covariance matrix in the standard normal space
78-
mu_U = np.array([0., 0.])
79-
Sigma_U = np.array([[1., 0.0], [0.0, 1]])
103+
# %% md
104+
#
105+
# Define the mean vector and covariance matrix in the original :math:`\textbf{X}` space and the standard normal
106+
# :math:`\textbf{U}` space.
107+
108+
# %%
109+
mu_X = np.array([distribution_resistance.parameters['loc'], distribution_stress.parameters['loc']])
110+
sigma_X = np.array([[distribution_resistance.parameters['scale']**2, 0],
111+
[0, distribution_stress.parameters['scale']**2]])
112+
113+
mu_U = np.array([0, 0])
114+
sigma_U = np.array([[1, 0],
115+
[0, 1]])
80116

81117
# Pack X and Y into a single 3-dimensional array for the original space
82118
posX = np.empty(XX.shape + (2,))
83119
posX[:, :, 0] = XX
84120
posX[:, :, 1] = YX
85-
ZX = multivariate_gaussian(posX, mu_X, Sigma_X)
121+
ZX = multivariate_gaussian(posX, mu_X, sigma_X)
86122

87123
# Pack X and Y into a single 3-dimensional array for the standard normal space
88124
posU = np.empty(XU.shape + (2,))
89125
posU[:, :, 0] = XU
90126
posU[:, :, 1] = YU
91-
ZU = multivariate_gaussian(posU, mu_U, Sigma_U)
92-
93-
# Figure 4a
94-
plt.figure()
95-
plt.rcParams["figure.figsize"] = (12, 12)
96-
plt.rcParams.update({'font.size': 22})
97-
plt.plot(parameters[0][0], parameters[1][0], 'r.')
98-
plt.plot([0, 200], [0, 200], 'k', linewidth=5)
99-
plt.plot(Q.DesignPoint_X[0][0], Q.DesignPoint_X[0][1], 'bo', markersize=12)
100-
plt.contour(XX, YX, ZX, levels=20)
101-
plt.xlabel(r'$X_1$')
102-
plt.ylabel(r'$X_2$')
103-
plt.text(170, 182, '$X_1 - X_2=0$',
104-
rotation=45,
105-
horizontalalignment='center',
106-
verticalalignment='top',
107-
multialignment='center')
108-
plt.ylim([120, 200])
109-
plt.xlim([130, 240])
110-
plt.grid()
111-
plt.title('Original space')
112-
plt.axes().set_aspect('equal', 'box')
113-
plt.show()
127+
ZU = multivariate_gaussian(posU, mu_U, sigma_U)
128+
129+
# %% md
130+
#
131+
# Plot the :code:`FORM` solution in the original :math:`\textbf{X}` space and the standard normal :math:`\text{U}`
132+
# space.
133+
134+
# %%
135+
fig, ax = plt.subplots()
136+
ax.contour(XX, YX, ZX,
137+
levels=20)
138+
ax.plot([0, 200], [0, 200],
139+
color='black', linewidth=2, label='$G(R,S)=R-S=0$', zorder=1)
140+
ax.scatter(mu_X[0], mu_X[1],
141+
color='black', s=64, label='Mean $(\mu_R, \mu_S)$')
142+
ax.scatter(form.design_point_x[0][0], form.design_point_x[0][1],
143+
color='tab:orange', marker='*', s=100, label='Design Point', zorder=2)
144+
ax.set(xlabel='Resistence $R$', ylabel='Stress $S$', xlim=(145, 255), ylim=(115, 185))
145+
ax.set_title('Original $X$ Space ')
146+
ax.set_aspect('equal')
147+
ax.legend(loc='lower right')
148+
149+
fig, ax = plt.subplots()
150+
ax.contour(XU, YU, ZU,
151+
levels=20, zorder=1)
152+
ax.plot([0, -3], [5, -1],
153+
color='black', linewidth=2, label='$G(U_1, U_2)=0$', zorder=2)
154+
ax.arrow(0, 0, form.design_point_u[0][0], form.design_point_u[0][1],
155+
color='tab:blue', length_includes_head=True, width=0.05, label='$\\beta=||u^*||$', zorder=2)
156+
ax.scatter(form.design_point_u[0][0], form.design_point_u[0][1],
157+
color='tab:orange', marker='*', s=100, label='Design Point $u^*$', zorder=2)
158+
ax.set(xlabel='$U_1$', ylabel='$U_2$', xlim=(-3, 3), ylim=(-3, 3))
159+
ax.set_aspect('equal')
160+
ax.set_title('Standard Normal $U$ Space')
161+
ax.legend(loc='lower right')
114162

115-
# Figure 4b
116-
plt.figure()
117-
plt.rcParams["figure.figsize"] = (12, 12)
118-
plt.rcParams.update({'font.size': 22})
119-
plt.plot([0, Q.DesignPoint_U[0][0]], [0, Q.DesignPoint_U[0][1]], 'b', linewidth=2)
120-
plt.plot([0, -3], [5, -1], 'k', linewidth=5)
121-
plt.plot(Q.DesignPoint_U[0][0], Q.DesignPoint_U[0][1], 'bo', markersize=12)
122-
plt.contour(XU, YU, ZU, levels=20)
123-
plt.axhline(0, color='black')
124-
plt.axvline(0, color='black')
125-
plt.plot(0, 0, 'r.')
126-
127-
plt.xlabel(r'$U_1$')
128-
plt.ylabel(r'$U_2$')
129-
plt.text(-1.0, 1.1, '$U^\star$=({:1.2f}, {:1.2f})'.format(-2.0, 1.0),
130-
rotation=0,
131-
horizontalalignment='center',
132-
verticalalignment='top',
133-
multialignment='center')
134-
135-
plt.text(-2.1, 2.05, '$20U_1 - 10U_2 + 50=0$',
136-
rotation=63,
137-
horizontalalignment='center',
138-
verticalalignment='top',
139-
multialignment='center')
140-
141-
plt.text(-1.5, 0.7, r'$\overrightarrow{\beta}$',
142-
rotation=0,
143-
horizontalalignment='center',
144-
verticalalignment='top',
145-
multialignment='center')
146-
147-
plt.text(0.02, -0.2, '({:1.1f}, {:1.1f})'.format(0.0, 0.0))
148-
plt.ylim([-1, 3])
149-
plt.xlim([-3.5, 2])
150-
plt.grid()
151-
plt.title('Standard Normal space')
152-
plt.axes().set_aspect('equal', 'box')
153163
plt.show()

0 commit comments

Comments
 (0)