1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
|
"""
Use the FORM - SORM algorithms
==============================
"""
# %%
# In this example we estimate a failure probability with the `FORM` algorithm on the :ref:`cantilever beam <use-case-cantilever-beam>` example.
# More precisely, we show how to use the associated results:
#
# - the design point in both physical and standard space,
# - the probability estimation according to the FORM approximation, and the following SORM ones: Tvedt, Hohenbichler and Breitung,
# - the Hasofer reliability index and the generalized ones evaluated from the Breitung, Tvedt and Hohenbichler approximations,
# - the importance factors defined as the normalized director factors of the design point in the :math:`U`-space
# - the sensitivity factors of the Hasofer reliability index and the FORM probability,
# - the coordinates of the mean point in the standard event space.
#
# See :ref:`FORM <form_approximation>` and :ref:`SORM <sorm_approximation>` for theoretical details.
# %%
# Model definition
# ----------------
# %%
from openturns.usecases import cantilever_beam
import openturns as ot
import openturns.viewer as otv
# %%
# We load the model from the usecases module :
cb = cantilever_beam.CantileverBeam()
# %%
# We use the input parameters distribution from the data class :
distribution = cb.distribution
distribution.setDescription(["E", "F", "L", "I"])
# %%
# We define the model
model = cb.model
# %%
# Create the event whose probability we want to estimate.
# %%
vect = ot.RandomVector(distribution)
G = ot.CompositeRandomVector(model, vect)
event = ot.ThresholdEvent(G, ot.Greater(), 0.3)
event.setName("deviation")
# %%
# FORM Analysis
# -------------
# %%
# Define a solver, here we use a :class:`~openturns.MultiStart` optimization based on :class:`~openturns.Cobyla`
startingSample = distribution.getSample(10)
optimAlgo = ot.MultiStart(ot.Cobyla(), startingSample)
optimAlgo.setMaximumCallsNumber(1000)
optimAlgo.setMaximumAbsoluteError(1.0e-4)
optimAlgo.setMaximumRelativeError(1.0e-4)
optimAlgo.setMaximumResidualError(1.0e-4)
optimAlgo.setMaximumConstraintError(1.0e-4)
# %%
# Run FORM
algo = ot.FORM(optimAlgo, event)
algo.run()
result = algo.getResult()
# %%
# Analysis of the results
# -----------------------
# %%
# Probability
result.getEventProbability()
# %%
# Hasofer reliability index
result.getHasoferReliabilityIndex()
# %%
# Design point in the standard U* space.
# %%
print(result.getStandardSpaceDesignPoint())
# %%
# Design point in the physical X space.
# %%
print(result.getPhysicalSpaceDesignPoint())
# %%
# Importance factors
graph = result.drawImportanceFactors()
view = otv.View(graph)
# %%
marginalSensitivity, otherSensitivity = result.drawHasoferReliabilityIndexSensitivity()
marginalSensitivity.setLegends(["E", "F", "L", "I"])
marginalSensitivity.setLegendPosition("bottom")
view = otv.View(marginalSensitivity)
# %%
marginalSensitivity, otherSensitivity = result.drawEventProbabilitySensitivity()
marginalSensitivity.setLegends(["E", "F", "L", "I"])
marginalSensitivity.setLegendPosition("bottom")
view = otv.View(marginalSensitivity)
# %%
# Error history
optimResult = result.getOptimizationResult()
graphErrors = optimResult.drawErrorHistory()
graphErrors.setLegendPosition("bottom")
graphErrors.setYMargin(0.0)
view = otv.View(graphErrors)
# %%
# Get additional results with SORM
algo = ot.SORM(optimAlgo, event)
algo.run()
sorm_result = algo.getResult()
# %%
# Reliability index with Breitung approximation
sorm_result.getGeneralisedReliabilityIndexBreitung()
# %%
# ... with Hohenbichler approximation
sorm_result.getGeneralisedReliabilityIndexHohenbichler()
# %%
# .. with Tvedt approximation
sorm_result.getGeneralisedReliabilityIndexTvedt()
# %%
# SORM probability of the event with Breitung approximation
sorm_result.getEventProbabilityBreitung()
# %%
# ... with Hohenbichler approximation
sorm_result.getEventProbabilityHohenbichler()
# %%
# ... with Tvedt approximation
sorm_result.getEventProbabilityTvedt()
# %%
# FORM analysis with finite difference gradient
# ---------------------------------------------
# %%
# When the considered function has no analytical expression, the gradient may not be known.
# In this case, a constant step finite difference gradient definition may be used.
# %%
def cantilever_beam_python(X):
E, F, L, II = X
return [F * L**3 / (3 * E * II)]
cbPythonFunction = ot.PythonFunction(4, 1, func=cantilever_beam_python)
epsilon = [1e-8] * 4 # Here, a constant step of 1e-8 is used for every dimension
gradStep = ot.ConstantStep(epsilon)
cbPythonFunction.setGradient(
ot.CenteredFiniteDifferenceGradient(gradStep, cbPythonFunction.getEvaluation())
)
G = ot.CompositeRandomVector(cbPythonFunction, vect)
event = ot.ThresholdEvent(G, ot.Greater(), 0.3)
event.setName("deviation")
# %%
# However, given the different nature of the model variables, a blended (variable)
# finite difference step may be preferable:
# The step depends on the location in the input space
gradStep = ot.BlendedStep(epsilon)
cbPythonFunction.setGradient(
ot.CenteredFiniteDifferenceGradient(gradStep, cbPythonFunction.getEvaluation())
)
G = ot.CompositeRandomVector(cbPythonFunction, vect)
event = ot.ThresholdEvent(G, ot.Greater(), 0.3)
event.setName("deviation")
# %%
# We can then run the FORM analysis in the same way as before:
algo = ot.FORM(optimAlgo, event)
algo.run()
result = algo.getResult()
# %%
otv.View.ShowAll()
|