diff --git a/CHANGELOG.md b/CHANGELOG.md index dc1520d..b243636 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- The 6-dimensional undamped non-linear oscillator function for reliability + analysis exercises. - The M-dimension Sobol'-Levitan function from Sobol' and Levitan (1999) for sensitivity analysis exercises. - The M-dimensional test function from Morris et al. (2006) for sensitivity diff --git a/docs/_toc.yml b/docs/_toc.yml index 4a924d2..addd350 100644 --- a/docs/_toc.yml +++ b/docs/_toc.yml @@ -135,6 +135,8 @@ parts: title: Speed Reducer Shaft - file: test-functions/sulfur title: Sulfur + - file: test-functions/undamped-oscillator + title: Undamped Oscillator - file: test-functions/webster-2d title: Webster et al. (1996) 2D - file: test-functions/welch1992 diff --git a/docs/fundamentals/metamodeling.md b/docs/fundamentals/metamodeling.md index 642c604..94a5889 100644 --- a/docs/fundamentals/metamodeling.md +++ b/docs/fundamentals/metamodeling.md @@ -17,40 +17,41 @@ kernelspec: The table below listed the available test functions typically used in the comparison of metamodeling approaches. -| Name | Input Dimension | Constructor | -|:----------------------------------------------------------------------:|:---------------:|:--------------------:| -| {ref}`Ackley ` | M | `Ackley()` | -| {ref}`Alemazkoor & Meidani (2018) 2D ` | 2 | `Alemazkoor2D()` | -| {ref}`Alemazkoor & Meidani (2018) 20D ` | 20 | `Alemazkoor20D()` | -| {ref}`Borehole ` | 8 | `Borehole()` | -| {ref}`Cheng and Sandu (2010) 2D ` | 2 | `Cheng2D` | -| {ref}`Damped Cosine ` | 1 | `DampedCosine()` | -| {ref}`Damped Oscillator ` | 7 | `DampedOscillator()` | -| {ref}`Flood ` | 8 | `Flood()` | -| {ref}`Forrester et al. (2008) ` | 1 | `Forrester2008()` | -| {ref}`(1st) Franke ` | 2 | `Franke1()` | -| {ref}`(2nd) Franke ` | 2 | `Franke2()` | -| {ref}`(3rd) Franke ` | 2 | `Franke3()` | -| {ref}`(4th) Franke ` | 2 | `Franke4()` | -| {ref}`(5th) Franke ` | 2 | `Franke5()` | -| {ref}`(6th) Franke ` | 2 | `Franke6()` | -| {ref}`Friedman (6D) ` | 6 | `Friedman6D()` | -| {ref}`Friedman (10D) ` | 10 | `Friedman10D()` | -| {ref}`Gramacy (2007) 1D Sine ` | 1 | `Gramacy1DSine()` | -| {ref}`Lim et al. (2002) Non-Polynomial ` | 2 | `LimNonPoly()` | -| {ref}`Lim et al. (2002) Polynomial ` | 2 | `LimPoly()` | -| {ref}`McLain S1 ` | 2 | `McLainS1()` | -| {ref}`McLain S2 ` | 2 | `McLainS2()` | -| {ref}`McLain S3 ` | 2 | `McLainS3()` | -| {ref}`McLain S4 ` | 2 | `McLainS4()` | -| {ref}`McLain S5 ` | 2 | `McLainS5()` | -| {ref}`Oakley & O'Hagan (2002) 1D ` | 1 | `Oakley1D()` | -| {ref}`OTL Circuit ` | 6 / 20 | `OTLCircuit()` | -| {ref}`Piston Simulation ` | 7 / 20 | `Piston()` | -| {ref}`Webster et al. (1996) 2D ` | 2 | `Webster2D()` | -| {ref}`Sulfur ` | 9 | `Sulfur()` | -| {ref}`Welch et al. (1992) ` | 20 | `Welch1992()` | -| {ref}`Wing Weight ` | 10 | `WingWeight()` | +| Name | Input Dimension | Constructor | +|:----------------------------------------------------------------------:|:---------------:|:-----------------------:| +| {ref}`Ackley ` | M | `Ackley()` | +| {ref}`Alemazkoor & Meidani (2018) 2D ` | 2 | `Alemazkoor2D()` | +| {ref}`Alemazkoor & Meidani (2018) 20D ` | 20 | `Alemazkoor20D()` | +| {ref}`Borehole ` | 8 | `Borehole()` | +| {ref}`Cheng and Sandu (2010) 2D ` | 2 | `Cheng2D` | +| {ref}`Damped Cosine ` | 1 | `DampedCosine()` | +| {ref}`Damped Oscillator ` | 7 | `DampedOscillator()` | +| {ref}`Flood ` | 8 | `Flood()` | +| {ref}`Forrester et al. (2008) ` | 1 | `Forrester2008()` | +| {ref}`(1st) Franke ` | 2 | `Franke1()` | +| {ref}`(2nd) Franke ` | 2 | `Franke2()` | +| {ref}`(3rd) Franke ` | 2 | `Franke3()` | +| {ref}`(4th) Franke ` | 2 | `Franke4()` | +| {ref}`(5th) Franke ` | 2 | `Franke5()` | +| {ref}`(6th) Franke ` | 2 | `Franke6()` | +| {ref}`Friedman (6D) ` | 6 | `Friedman6D()` | +| {ref}`Friedman (10D) ` | 10 | `Friedman10D()` | +| {ref}`Gramacy (2007) 1D Sine ` | 1 | `Gramacy1DSine()` | +| {ref}`Lim et al. (2002) Non-Polynomial ` | 2 | `LimNonPoly()` | +| {ref}`Lim et al. (2002) Polynomial ` | 2 | `LimPoly()` | +| {ref}`McLain S1 ` | 2 | `McLainS1()` | +| {ref}`McLain S2 ` | 2 | `McLainS2()` | +| {ref}`McLain S3 ` | 2 | `McLainS3()` | +| {ref}`McLain S4 ` | 2 | `McLainS4()` | +| {ref}`McLain S5 ` | 2 | `McLainS5()` | +| {ref}`Oakley & O'Hagan (2002) 1D ` | 1 | `Oakley1D()` | +| {ref}`OTL Circuit ` | 6 / 20 | `OTLCircuit()` | +| {ref}`Piston Simulation ` | 7 / 20 | `Piston()` | +| {ref}`Webster et al. (1996) 2D ` | 2 | `Webster2D()` | +| {ref}`Sulfur ` | 9 | `Sulfur()` | +| {ref}`Undamped Oscillator ` | 6 | `UndampedOscillator()` | +| {ref}`Welch et al. (1992) ` | 20 | `Welch1992()` | +| {ref}`Wing Weight ` | 10 | `WingWeight()` | In a Python terminal, you can list all the available functions relevant for metamodeling applications using ``list_functions()`` and filter the results diff --git a/docs/fundamentals/reliability.md b/docs/fundamentals/reliability.md index 269fe60..73af9e5 100644 --- a/docs/fundamentals/reliability.md +++ b/docs/fundamentals/reliability.md @@ -29,6 +29,7 @@ in the comparison of reliability analysis methods. | {ref}`RS - Circular Bar ` | 2 | `RSCircularBar()` | | {ref}`RS - Quadratic ` | 2 | `RSQuadratic()` | | {ref}`Speed Reducer Shaft ` | 5 | `SpeedReducerShaft()` | +| {ref}`Undamped Oscillator ` | 6 | `UndampedOscillator()` | In a Python terminal, you can list all the available functions relevant for metamodeling applications using ``list_functions()`` and filter the results diff --git a/docs/glossary.md b/docs/glossary.md index f0012f2..b3d1641 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -6,6 +6,9 @@ CDF Cumulative distribution function, denoted by $F_X(x; \circ)$ where $\circ$ is a placeholder for the distribution parameter(s). +DS + Directional sampling + FORM First-order reliability method diff --git a/docs/references.bib b/docs/references.bib index 95c3c0e..99829ed 100644 --- a/docs/references.bib +++ b/docs/references.bib @@ -867,4 +867,37 @@ @Article{Moon2012 doi = {10.1080/00401706.2012.725994}, } +@Article{Bucher1990, + author = {Bucher, C. G. and Bourgund, U.}, + journal = {Structural Safety}, + title = {A fast and efficient response surface approach for structural reliability problems}, + year = {1990}, + number = {1}, + pages = {57--66}, + volume = {7}, + doi = {10.1016/0167-4730(90)90012-e}, +} + +@Article{Luethen2021, + author = {Lüthen, Nora and Marelli, Stefano and Sudret, Bruno}, + journal = {SIAM/ASA Journal on Uncertainty Quantification}, + title = {Sparse polynomial chaos expansions: literature survey and benchmark}, + year = {2021}, + number = {2}, + pages = {593--649}, + volume = {9}, + doi = {10.1137/20m1315774}, +} + +@Article{Gayton2003, + author = {Gayton, N. and Bourinet, J. M. and Lemaire, M.}, + journal = {Structural Safety}, + title = {{CQ2RS}: a new statistical approach to the response surface method for reliability analysis}, + year = {2003}, + number = {1}, + pages = {99--121}, + volume = {25}, + doi = {10.1016/s0167-4730(02)00045-0}, +} + @Comment{jabref-meta: databaseType:bibtex;} diff --git a/docs/test-functions/available.md b/docs/test-functions/available.md index 0a7d967..fe7c2e4 100644 --- a/docs/test-functions/available.md +++ b/docs/test-functions/available.md @@ -72,6 +72,7 @@ regardless of their typical applications. | {ref}`Sobol'-Levitan ` | M | `SobolLevitan()` | | {ref}`Speed Reducer Shaft ` | 5 | `SpeedReducerShaft()` | | {ref}`Sulfur ` | 9 | `Sulfur()` | +| {ref}`Undamped Oscillator ` | 6 | `UndampedOscillator()` | | {ref}`Webster et al. (1996) 2D ` | 2 | `Webster2D()` | | {ref}`Welch et al. (1992) ` | 20 | `Welch1992()` | | {ref}`Wing Weight ` | 10 | `WingWeight()` | diff --git a/docs/test-functions/undamped-oscillator.md b/docs/test-functions/undamped-oscillator.md new file mode 100644 index 0000000..6fcdc04 --- /dev/null +++ b/docs/test-functions/undamped-oscillator.md @@ -0,0 +1,179 @@ +--- +jupytext: + formats: ipynb,md:myst + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.1 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +(test-functions:undamped-oscillator)= +# Undamped Oscillator + +```{code-cell} ipython3 +import numpy as np +import matplotlib.pyplot as plt +import uqtestfuns as uqtf +``` + +The undamped oscillator function (`UndampedOscillator`) is a six-dimensional, +scalar-valued test function that models a non-linear, undamped, +single-degree-of-freedom, forced oscillating mechanical system. + +This function is frequently used as a test function for reliability analysis +methods (see {cite}`Bucher1990, Rajashekhar1993, Gayton2003, Schueremans2005, Echard2011, Echard2013`). +Additionally, in {cite}`Luethen2021`, the function is employed +as a test function for metamodeling exercises. + +## Test function instance + +To create a default instance of the test function: + +```{code-cell} ipython3 +my_testfun = uqtf.UndampedOscillator() +``` + +Check if it has been correctly instantiated: + +```{code-cell} ipython3 +print(my_testfun) +``` + +## Description + +The system under consideration is a single-degree-of-freedom mechanical system +that undergoes undamped forced oscillation. +The performance function is analytically defined as follows[^location]: + +$$ +g(\boldsymbol{x}) = 3 r - \lvert z_{\text{max}} \rvert, +$$ + +where $z_{\text{max}}$ is the maximum displacement response of the system +given by + +$$ +z_{\text{max}} (\boldsymbol{x}) = \frac{2 F_1}{m \omega_0^2} \sin{\left( \frac{\omega_0 t_1}{2} \right)} +$$ + +and + +$$ +\omega_0 = \sqrt{\frac{c_1 + c2}{m}}. +$$ + + +$\boldsymbol{x} = \{ m, c_1, c_2, r, F_1, t_1 \}$ is the six-dimensional vector +of input variables probabilistically defined further below. + +The failure state and the failure probability are defined as +$g(\boldsymbol{x}; \boldsymbol{p}) \leq 0$ +and $\mathbb{P}[g(\boldsymbol{X}; \boldsymbol{p}) \leq 0]$, respectively. + +## Probabilistic input + +The available probabilistic input models are shown in the table below. +The different specifications alter the failure probability of the system +(as expected). + +```{table} Available probabilistic input of the undamped oscillator function +:name: undamped-oscillator-inputs +| No. | Remark | Keyword | Source | +|:---:|:------------------:|:----------------------:|:----------------------------:| +| 1. | $\mu_{F_1} = 1.00$ | `Gayton2003` (default) | {cite}`Gayton2003` (Table 9) | +| 2. | $\mu_{F_1} = 0.60$ | `Echard2013-1` | {cite}`Echard2013` (Table 4) | +| 3. | $\mu_{F_1} = 0.45} | `Echard2013-2` | {cite}`Echard2013` (Table 4) | +``` + +The default input is shown below. + +```{code-cell} ipython3 +:tags: [hide-input] + +print(my_testfun.prob_input) +``` + +## Reference results + +This section provides several reference results of typical UQ analyses involving +the test function. + +### Sample histogram + +Shown below is the histogram of the output based on $10^6$ random points: + +```{code-cell} ipython3 +:tags: [hide-input] + +xx_test = my_testfun.prob_input.get_sample(1000000) +yy_test = my_testfun(xx_test) +idx_pos = yy_test > 0 +idx_neg = yy_test <= 0 + +hist_pos = plt.hist(yy_test, bins="auto", color="#0571b0") +plt.hist(yy_test[idx_neg], bins=hist_pos[1], color="#ca0020") +plt.axvline(0, linewidth=1.0, color="#ca0020") + +plt.grid() +plt.ylabel("Counts [-]") +plt.xlabel("$g(\mathbf{X})$") +plt.gcf().set_dpi(150); +``` + +### Failure probability ($P_f$) + +Some reference values for the failure probability $P_f$ from the literature +are summarized in the tables below according to the chosen input specification. + +::::{tab-set} + +:::{tab-item} Gayton2003 +| Method | $N$ | $\hat{P}_f$ | $\mathrm{CoV}[\hat{P}_f]$ | Source | +|:--------------------------------------:|:-----------------:|:----------------------:|:-------------------------:|:---------------------------------:| +| {term}`DS` | $1281$ | $3.5 \times 10^{-2}$ | — | {cite}`Schueremans2005` (Table 5) | +| {term}`DS` + Polynomial | $62$ | $3.4 \times 10^{-2}$ | — | {cite}`Schueremans2005` (Table 5) | +| {term}`DS` + Splines | $76$ | $3.4 \times 10^{-2}$ | — | {cite}`Schueremans2005` (Table 5) | +| {term}`DS` + Neural network (NN) | $86$ | $2.8 \times 10^{-2}$ | — | {cite}`Schueremans2005` (Table 5) | +| {term}`MCS` + {term}`IS` | $6144$ | $2.7 \times 10^{-2}$ | — | {cite}`Schueremans2005` (Table 5) | +| {term}`MCS` + {term}`IS` + Polynomials | $109$ | $2.5 \times 10^{-2}$ | — | {cite}`Schueremans2005` (Table 5) | +| {term}`MCS` + {term}`IS` + Splines | $67$ | $2.7 \times 10^{-2}$ | — | {cite}`Schueremans2005` (Table 5) | +| {term}`MCS` + {term}`IS` + NN | $68$ | $3.1 \times 10^{-2}$ | — | {cite}`Schueremans2005` (Table 5) | +| {term}`MCS` | $7 \times 10^{4}$ | $2.834 \times 10^{-2}$ | $2.2\%$ | {cite}`Echard2011` (Table 6) | +| Adaptive Kriging + {term}`MCS` + EFF | $58$ | $2.834 \times 10^{-2}$ | — | {cite}`Echard2011` (Table 6) | +| Adaptive Kriging + {term}`MCS` + U | $45$ | $2.851 \times 10^{-2}$ | — | {cite}`Echard2011` (Table 6) | +::: + +:::{tab-item} Sobol1999-2 +| Method | $N$ | $\hat{P}_f$ | $\mathrm{CoV}[\hat{P}_f]$ | Source | +|:-----------------------------:|:--------------------:|:---------------------:|:-------------------------:|:----------------------------:| +| {term}`MCS` | $1.8 \times 10^{8}$ | $9.09 \times 10^{-6}$ | $2.47\%$ | {cite}`Echard2013` (Table 5) | +| {term}`FORM` | $29$ | $9.76 \times 10^{-6}$ | — | {cite}`Echard2013` (Table 5) | +| {term}`IS` | $20 + \times 10^{4}$ | $9.13 \times 10^{-6}$ | $2.29\%$ | {cite}`Echard2013` (Table 5) | +| Adaptive Kriging + {term}`IS` | $29 + 38$ | $9.13 \times 10^{-6}$ | $2.29\%$ | {cite}`Echard2013` (Table 5) | +::: + +:::{tab-item} Moon2012-1 +| Method | $N$ | $\hat{P}_f$ | $\mathrm{CoV}[\hat{P}_f]$ | Source | +|:-----------------------------:|:--------------------:|:---------------------:|:-------------------------:|:----------------------------:| +| {term}`MCS` | $9 \times 10^{8}$ | $1.55 \times 10^{-8}$ | $2.68\%$ | {cite}`Echard2013` (Table 5) | +| {term}`FORM` | $29$ | $1.56 \times 10^{-8}$ | — | {cite}`Echard2013` (Table 5) | +| {term}`IS` | $29 + \times 10^{4}$ | $1.53 \times 10^{-8}$ | $2.70\%$ | {cite}`Echard2013` (Table 5) | +| Adaptive Kriging + {term}`IS` | $29 + 38$ | $1.54 \times 10^{-8}$ | $2.70\%$ | {cite}`Echard2013` (Table 5) | +::: + +:::: + + +## References + +```{bibliography} +:style: unsrtalpha +:filter: docname in docnames +``` + +[^location]: see Section 6.4.1 in {cite}`Gayton2003`. \ No newline at end of file diff --git a/src/uqtestfuns/test_functions/__init__.py b/src/uqtestfuns/test_functions/__init__.py index 197f65e..5df474b 100644 --- a/src/uqtestfuns/test_functions/__init__.py +++ b/src/uqtestfuns/test_functions/__init__.py @@ -37,6 +37,7 @@ from .sobol_levitan import SobolLevitan from .speed_reducer_shaft import SpeedReducerShaft from .sulfur import Sulfur +from .undamped_oscillator import UndampedOscillator from .webster import Webster2D from .welch1992 import Welch1992 from .wing_weight import WingWeight @@ -96,6 +97,7 @@ "SobolLevitan", "SpeedReducerShaft", "Sulfur", + "UndampedOscillator", "Webster2D", "Welch1992", "WingWeight", diff --git a/src/uqtestfuns/test_functions/undamped_oscillator.py b/src/uqtestfuns/test_functions/undamped_oscillator.py new file mode 100644 index 0000000..e7f5649 --- /dev/null +++ b/src/uqtestfuns/test_functions/undamped_oscillator.py @@ -0,0 +1,229 @@ +""" +Module with an implementation of undamped oscillator test function. + +The undamped oscillator function is a six-dimensional, scalar-valued test +function that models a non-linear, undamped, single-degree-of-freedom, forced +oscillating mechanical system. +This function is frequently used as a test function for reliability analysis +methods (see [1] through [6]). Additionally, in [7], the function is employed +as a test function for metamodeling exercises. + + +1. C. G. Bucher and U. Bourgund, “A fast and efficient response surface + approach for structural reliability problems,” Structural Safety, vol. 7, + no. 1, pp. 57–66, 1990. + DOI: 10.1016/0167-4730(90)90012-E +2. M. R. Rajashekhar and B. R. Ellingwood, “A new look at the response surface + approach for reliability analysis,” Structural Safety, vol. 12, no. 3, + pp. 205–220, 1993. + DOI: 10.1016/0167-4730(93)90003-J +3. N. Gayton, J. M. Bourinet, and M. Lemaire, “CQ2RS: a new statistical + approach to the response surface method for reliability analysis,” + Structural Safety, vol. 25, no. 1, pp. 99–121, 2003. + DOI: 10.1016/S0167-4730(02)00045-0 +4. L. Schueremans and D. Van Gemert, “Benefit of splines and neural networks + in simulation based structural reliability analysis,” Structural Safety, + vol. 27, no. 3, pp. 246–261, 2005. + DOI: 10.1016/j.strusafe.2004.11.001 +5. B. Echard, N. Gayton, and M. Lemaire, “AK-MCS: An active learning + reliability method combining Kriging and Monte Carlo Simulation,” + Structural Safety, vol. 33, no. 2, pp. 145–154, 2011. + DOI: 10.1016/j.strusafe.2011.01.002. +6. B. Echard, N. Gayton, M. Lemaire, and N. Relun, “A combined Importance + Sampling and Kriging reliability method for small failure probabilities + with time-demanding numerical models,” Reliability Engineering & + System Safety, vol. 111, pp. 232–240, 2013. + DOI: 10.1016/j.ress.2012.10.008. +8. N. Lüthen, S. Marelli, and B. Sudret, “Sparse Polynomial Chaos Expansions: + Literature Survey and Benchmark,” SIAM/ASA Journal of Uncertainty + Quantification, vol. 9, no. 2, pp. 593–649, 2021. + DOI: 10.1137/20M1315774 +""" + +import numpy as np + +from uqtestfuns.core.custom_typing import ProbInputSpecs +from uqtestfuns.core.uqtestfun_abc import UQTestFunFixDimABC + + +__all__ = ["UndampedOscillator"] + + +AVAILABLE_INPUTS: ProbInputSpecs = { + "Gayton2003": { + "function_id": "UndampedOscillator", + "description": ( + "Input model for the undamped non-linear oscillator " + "from Gayton et al. (2003) (Table 9)" + ), + "marginals": [ + { + "name": "m", + "distribution": "normal", + "parameters": [1.0, 0.05], + "description": "Mass", + }, + { + "name": "c1", + "distribution": "normal", + "parameters": [1.0, 0.10], + "description": "Spring (1) constant", + }, + { + "name": "c2", + "distribution": "normal", + "parameters": [0.1, 0.01], + "description": "Spring (2) constant", + }, + { + "name": "r", + "distribution": "normal", + "parameters": [0.5, 0.05], + "description": "Length of restoring force", + }, + { + "name": "F1", + "distribution": "normal", + "parameters": [1.0, 0.2], + "description": "Pulse load", + }, + { + "name": "t1", + "distribution": "normal", + "parameters": [1.0, 0.2], + "description": "Duration of the pulse load", + }, + ], + "copulas": None, + }, + "Echard2013-1": { + "function_id": "UndampedOscillator", + "description": ( + "Input model for the undamped non-linear oscillator " + "from Echard et al. (2013) (Table 4, F1 = 0.6)" + ), + "marginals": [ + { + "name": "m", + "distribution": "normal", + "parameters": [1.0, 0.05], + "description": "Mass", + }, + { + "name": "c1", + "distribution": "normal", + "parameters": [1.0, 0.10], + "description": "Spring (1) constant", + }, + { + "name": "c2", + "distribution": "normal", + "parameters": [0.1, 0.01], + "description": "Spring (2) constant", + }, + { + "name": "r", + "distribution": "normal", + "parameters": [0.5, 0.05], + "description": "Length of restoring force", + }, + { + "name": "F1", + "distribution": "normal", + "parameters": [0.6, 0.1], + "description": "Pulse load", + }, + { + "name": "t1", + "distribution": "normal", + "parameters": [1.0, 0.2], + "description": "Duration of the pulse load", + }, + ], + "copulas": None, + }, + "Echard2013-2": { + "function_id": "UndampedOscillator", + "description": ( + "Input model for the undamped non-linear oscillator " + "from Echard et al. (2013) (Table 4, F1 = 0.45)" + ), + "marginals": [ + { + "name": "m", + "distribution": "normal", + "parameters": [1.0, 0.05], + "description": "Mass", + }, + { + "name": "c1", + "distribution": "normal", + "parameters": [1.0, 0.10], + "description": "Spring (1) constant", + }, + { + "name": "c2", + "distribution": "normal", + "parameters": [0.1, 0.01], + "description": "Spring (2) constant", + }, + { + "name": "r", + "distribution": "normal", + "parameters": [0.5, 0.05], + "description": "Length of restoring force", + }, + { + "name": "F1", + "distribution": "normal", + "parameters": [0.45, 0.45 / 6], + "description": "Pulse load", + }, + { + "name": "t1", + "distribution": "normal", + "parameters": [1.0, 0.2], + "description": "Duration of the pulse load", + }, + ], + "copulas": None, + }, +} + + +def evaluate(xx: np.ndarray) -> np.ndarray: + """Evaluate the undamped oscillator test function on a set of input values. + + Parameters + ---------- + xx : np.ndarray + A two-dimensional input values given by N-by-6 arrays + where N is the number of input values. + + Returns + ------- + np.ndarray + The output of the test function evaluated on the input values. + If negative, then the system is in failed state. + The output is a 1-dimensional array of length N. + """ + omega_0 = np.sqrt((xx[:, 1] + xx[:, 2]) / xx[:, 0]) + term_1 = 3 * xx[:, 3] + term_2 = 2 * xx[:, 4] / xx[:, 0] / omega_0**2 + term_3 = np.sin(omega_0 * xx[:, 5] / 2) + + yy = term_1 - np.abs(term_2 * term_3) + + return yy + + +class UndampedOscillator(UQTestFunFixDimABC): + """A concrete implementation of the undamped oscillator test function.""" + + _tags = ["reliability", "metamodeling"] + _description = "Undamped, non-linear, single DOF oscillator" + _available_inputs = AVAILABLE_INPUTS + _available_parameters = None + _default_input_id = "Gayton2003" + + evaluate = staticmethod(evaluate) # type: ignore