Очень неточный результат в модели надежности OpenTURNS при использовании подмножества RandomVector - PullRequest
0 голосов
/ 13 апреля 2020

У меня есть модель надежности, встроенная в OpenTURNS с несколькими функциями предельного состояния, которые принимают от двух до восьми случайных величин (RV). Моя первоначальная попытка состояла в том, чтобы определить один RandomVector со всеми восемью переменными и использовать этот RandomVector для всех вычислений событий. Для функции предельного состояния с двумя переменными результаты приемлемы для Монте-Карло, но совершенно неточны при использовании FORM или SORM. Однако, когда я применяю FORM или SORM с RandomVector, содержащим только два RV для функции предельного состояния с двумя переменными, это работает хорошо.

Правильная вероятность равна 0,000427, тогда как FORM и SORM с моделью из восьми переменных возвращают значения порядка 1e-29. В модели с двумя переменными FORM возвращает правильное значение 0,00427.

Компоненты векторов расчетной точки аналогичны при использовании RandomVectors с двумя или восемью переменными:

  • Расчетная точка для модели с восемью переменными (см. Сначала и третьи элементы): [-0.445716,0.0305458,3.30454,-0.119868,0.0317001,-0.0382662,-0.0233416,7.59606,7.5671]

  • Расчетная точка для двухвариантной модели: [-0.438289,3.30553]

Пожалуйста, см. рисунок ниже. Я использую OpenTURNS 1.14 на Windows 10.

# Define marginal distributions for wall thickness and depth
wt_dist = ot.Normal(0.156, 0.003666)
od_dist = ot.Normal(8.625, 0.0146625)
d_dist = ot.Normal(0.063, 0.0276486)
lg_dist = ot.Normal(2.36, 0.143478)
ys_dist = ot.Normal(57000, 2700)
ts_dist = ot.Normal(80565, 3868)
cv_dist = ot.TruncatedDistribution(ot.Normal(37, 5), 4)
mdlerr_dist = ot.Dirac(1)
press_dist = ot.Dirac(1140.3)

# Setup FORM optimizer
optimizer = ot.Cobyla()
eps = 1e-10
optimizer.setMaximumIterationNumber(5000)
optimizer.setMaximumAbsoluteError(eps)
optimizer.setMaximumRelativeError(eps)
optimizer.setMaximumResidualError(eps)
optimizer.setMaximumConstraintError(eps)

# === Full model ===
marginals = [
    wt_dist,
    od_dist,
    d_dist,
    lg_dist,
    ys_dist,
    ts_dist,
    cv_dist,
    mdlerr_dist,
    press_dist
    ]
n_vars = len(marginals)

# Define correlations between variables (using the normal copula)
cor_mat = ot.CorrelationMatrix(n_vars)
cor_mat[4, 5] = cor_mat[5, 4] = 0.98675
copula = ot.NormalCopula(cor_mat)
composed_dist = ot.ComposedDistribution(marginals, copula)
composed_dist.setName("Distributions")
composed_dist.setDescription(['WT', 'OD', 'D', 'L', 'YS', 'TS', 'CV', 'e', 'P'])
rv_vect = ot.RandomVector(composed_dist)  # vector of random variables

model = ot.SymbolicFunction(['WT', 'OD', 'D', 'L', 'YS', 'TS', 'CV', 'e', 'P'], ['WT-D'])
g = ot.CompositeRandomVector(model, rv_vect)
event = ot.ThresholdEvent(g, ot.Less(), 0.0)

# FORM test 1
algo = ot.FORM(optimizer, event, rv_vect.getMean())
algo.run()
result = algo.getResult()
prob_form1 = result.getEventProbability()
design_pt1 = result.getStandardSpaceDesignPoint()

# MC test 1
experiment = ot.MonteCarloExperiment()
algo = ot.ProbabilitySimulationAlgorithm(event, experiment)
algo.setMaximumCoefficientOfVariation(0.05)
algo.setMaximumOuterSampling(int(1e6))
algo.run()
result = algo.getResult()
prob_MC1 = result.getProbabilityEstimate()


# === Reduced model ===
marginals = [
    wt_dist,
    d_dist
    ]
n_vars = len(marginals)

# Define correlations between variables (using the normal copula)
cor_mat = ot.CorrelationMatrix(n_vars)
copula = ot.NormalCopula(cor_mat)
composed_dist = ot.ComposedDistribution(marginals, copula)
composed_dist.setName("Distributions")
composed_dist.setDescription(['WT', 'D'])
rv_vect = ot.RandomVector(composed_dist)  # vector of random variables

model = ot.SymbolicFunction(['WT', 'D'], ['WT-D'])
g = ot.CompositeRandomVector(model, rv_vect)
event = ot.ThresholdEvent(g, ot.Less(), 0.0)

# FORM test 2
algo = ot.FORM(optimizer, event, rv_vect.getMean())
algo.run()
result = algo.getResult()
prob_form2 = result.getEventProbability()
design_pt2 = result.getStandardSpaceDesignPoint()

# MC test 2
experiment = ot.MonteCarloExperiment()
algo = ot.ProbabilitySimulationAlgorithm(event, experiment)
algo.setMaximumCoefficientOfVariation(0.05)
algo.setMaximumOuterSampling(int(1e6))
algo.run()
result = algo.getResult()
prob_MC2 = result.getProbabilityEstimate()

print(prob_form1)
print(design_pt1)
print(prob_MC1)
print(prob_form2)
print(design_pt2)
print(prob_MC2)

1 Ответ

2 голосов
/ 13 апреля 2020

Вы используете алгоритм оптимизации Cobyla, который является достаточно надежным, но требовательным с точки зрения обращений к модели. Каждая итерация Cobyla имеет стоимость, пропорциональную измерению вашего входного случайного вектора с точки зрения оценки модели, поскольку алгоритм строит и обновляет ее линейное приближение. Когда вы используете его с 8 входами, алгоритм останавливается, потому что вы достигли максимально допустимого количества оценок (по умолчанию 100) и получаете следующее предупреждение:

WRN - Предупреждение! Алгоритм Кобила не смог сходиться. Сообщение об ошибке: Максимальное число достигнутых оценок функций

1.4631933217717485e-29

[- 0.445716,0.0305458,3.30454, -0.119868,0.0317001, -0.0382662, - 0.0233416,7.59606,7.5671]

0.0004238055834266587

0.0004273278619031894

[- 0.438289,3.30553]

0.0004415498399381834

Если вы увеличите ограничение с использованием числа оценок, :

optimizer.setMaximumEvaluationNumber (100000)

Тогда вы получите:

WRN - Внимание! Алгоритм Cobyla не может применять критерии сходимости

0.0004273278619032821

[- 0.438289, -3.05982e-08,3.30553, -2.76053e-08, -4.41471e-08, -4.71149e- 08, -4,95428e-08, -5,77001e-09,1.00438e-07]

0,0004238055834266587

0,00042732786190326374

[- 0,438289,3,30553]

1034 * 0.0004415498399381834

Предупреждение здесь, потому что вы вряд ли сможете достичь точности 1e-10 для решения с использованием Cobyla.

Спасибо за использование OpenTURNS!

Régis LEBRUN

...