wawi 0.0.1__tar.gz → 0.0.3__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {wawi-0.0.1/wawi.egg-info → wawi-0.0.3}/PKG-INFO +7 -6
- {wawi-0.0.1 → wawi-0.0.3}/README.md +3 -3
- {wawi-0.0.1 → wawi-0.0.3}/pyproject.toml +4 -3
- wawi-0.0.3/tests/test_IABSE_step11a - Copy.py +104 -0
- wawi-0.0.3/tests/test_IABSE_step11a.py +219 -0
- wawi-0.0.3/tests/test_IABSE_step11c.py +284 -0
- wawi-0.0.3/tests/test_IABSE_step2a.py +265 -0
- wawi-0.0.3/tests/test_wind.py +71 -0
- wawi-0.0.3/wawi/__init__.py +10 -0
- wawi-0.0.3/wawi/abq.py +1128 -0
- wawi-0.0.3/wawi/fe.py +134 -0
- wawi-0.0.3/wawi/general.py +473 -0
- wawi-0.0.3/wawi/identification.py +66 -0
- wawi-0.0.3/wawi/io.py +696 -0
- wawi-0.0.3/wawi/modal.py +608 -0
- wawi-0.0.3/wawi/plot.py +569 -0
- wawi-0.0.3/wawi/prob.py +9 -0
- wawi-0.0.3/wawi/random.py +38 -0
- wawi-0.0.3/wawi/signal.py +45 -0
- wawi-0.0.3/wawi/structural.py +278 -0
- wawi-0.0.3/wawi/time_domain.py +126 -0
- wawi-0.0.3/wawi/tools.py +7 -0
- wawi-0.0.3/wawi/wave.py +491 -0
- wawi-0.0.3/wawi/wind.py +1108 -0
- wawi-0.0.3/wawi/wind_code.py +14 -0
- {wawi-0.0.1 → wawi-0.0.3/wawi.egg-info}/PKG-INFO +7 -6
- wawi-0.0.3/wawi.egg-info/SOURCES.txt +30 -0
- {wawi-0.0.1 → wawi-0.0.3}/wawi.egg-info/requires.txt +1 -0
- wawi-0.0.1/wawi/__init__.py +0 -6
- wawi-0.0.1/wawi.egg-info/SOURCES.txt +0 -9
- {wawi-0.0.1 → wawi-0.0.3}/LICENSE +0 -0
- {wawi-0.0.1 → wawi-0.0.3}/setup.cfg +0 -0
- {wawi-0.0.1 → wawi-0.0.3}/wawi.egg-info/dependency_links.txt +0 -0
- {wawi-0.0.1 → wawi-0.0.3}/wawi.egg-info/top_level.txt +0 -0
@@ -1,8 +1,8 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: wawi
|
3
|
-
Version: 0.0.
|
4
|
-
Summary:
|
5
|
-
Author-email: "Knut A.
|
3
|
+
Version: 0.0.3
|
4
|
+
Summary: WAve and WInd response prediction
|
5
|
+
Author-email: "Knut A. Kvåle" <knut.a.kvale@ntnu.no>, Ole Øiseth <ole.oiseth@ntnu.no>, Aksel Fenerci <aksel.fenerci@ntnu.no>, Øivind Wiig Petersen <oyvind.w.petersen@ntnu.no>
|
6
6
|
License: MIT License
|
7
7
|
|
8
8
|
Copyright (c) 2025 Knut Andreas Kvåle
|
@@ -42,13 +42,14 @@ Requires-Dist: scikit-learn
|
|
42
42
|
Requires-Dist: trame
|
43
43
|
Requires-Dist: ipywidgets
|
44
44
|
Requires-Dist: pyvistaqt
|
45
|
+
Requires-Dist: beefpy
|
45
46
|
|
46
47
|

|
47
48
|
=======================
|
48
49
|
|
49
50
|
What is wawi?
|
50
51
|
=======================
|
51
|
-
|
52
|
+
WAWI is a Python toolbox for prediction of response of structures exposed to wind and wave excitation. The package is still under development in its alpha stage, and documentation and testing will be completed along the way.
|
52
53
|
|
53
54
|
|
54
55
|
Installation
|
@@ -62,7 +63,7 @@ pip install wawi
|
|
62
63
|
or install directly from github:
|
63
64
|
|
64
65
|
```
|
65
|
-
pip install git+https://www.github.com/knutankv/wawi.git@
|
66
|
+
pip install git+https://www.github.com/knutankv/wawi.git@main
|
66
67
|
```
|
67
68
|
|
68
69
|
|
@@ -71,7 +72,7 @@ Quick start
|
|
71
72
|
|
72
73
|
Examples
|
73
74
|
=======================
|
74
|
-
Examples are provided as Jupyter Notebooks in the [examples folder](https://github.com/knutankv/wawi/tree/
|
75
|
+
Examples are provided as Jupyter Notebooks in the [examples folder](https://github.com/knutankv/wawi/tree/main/examples).
|
75
76
|
|
76
77
|
References
|
77
78
|
=======================
|
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
What is wawi?
|
5
5
|
=======================
|
6
|
-
|
6
|
+
WAWI is a Python toolbox for prediction of response of structures exposed to wind and wave excitation. The package is still under development in its alpha stage, and documentation and testing will be completed along the way.
|
7
7
|
|
8
8
|
|
9
9
|
Installation
|
@@ -17,7 +17,7 @@ pip install wawi
|
|
17
17
|
or install directly from github:
|
18
18
|
|
19
19
|
```
|
20
|
-
pip install git+https://www.github.com/knutankv/wawi.git@
|
20
|
+
pip install git+https://www.github.com/knutankv/wawi.git@main
|
21
21
|
```
|
22
22
|
|
23
23
|
|
@@ -26,7 +26,7 @@ Quick start
|
|
26
26
|
|
27
27
|
Examples
|
28
28
|
=======================
|
29
|
-
Examples are provided as Jupyter Notebooks in the [examples folder](https://github.com/knutankv/wawi/tree/
|
29
|
+
Examples are provided as Jupyter Notebooks in the [examples folder](https://github.com/knutankv/wawi/tree/main/examples).
|
30
30
|
|
31
31
|
References
|
32
32
|
=======================
|
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "wawi"
|
7
|
-
description = "
|
7
|
+
description = "WAve and WInd response prediction"
|
8
8
|
requires-python = ">= 3.6"
|
9
9
|
|
10
10
|
readme = "README.md"
|
11
11
|
license = {file = "LICENSE"}
|
12
12
|
authors = [
|
13
|
-
{name = "Knut A.
|
13
|
+
{name = "Knut A. Kvåle", email = "knut.a.kvale@ntnu.no"},
|
14
14
|
{name = "Ole Øiseth", email = "ole.oiseth@ntnu.no"},
|
15
15
|
{name = "Aksel Fenerci", email = "aksel.fenerci@ntnu.no"},
|
16
16
|
{name = "Øivind Wiig Petersen", email = "oyvind.w.petersen@ntnu.no"},
|
@@ -23,7 +23,8 @@ classifiers = [
|
|
23
23
|
]
|
24
24
|
dynamic = ["version"]
|
25
25
|
dependencies = ["plotly", "pandas", "numpy", "pyvista[jupyter]>=0.38.1",
|
26
|
-
"scikit-learn", "trame", "ipywidgets", "pyvistaqt"
|
26
|
+
"scikit-learn", "trame", "ipywidgets", "pyvistaqt",
|
27
|
+
"beefpy"]
|
27
28
|
|
28
29
|
|
29
30
|
[tool.setuptools]
|
@@ -0,0 +1,104 @@
|
|
1
|
+
|
2
|
+
import pytest
|
3
|
+
import numpy as np
|
4
|
+
from math import isclose
|
5
|
+
import dill
|
6
|
+
|
7
|
+
# use the local wawi (Github folder) instead of the installed version (remove this when using the installed version)
|
8
|
+
import sys
|
9
|
+
import os
|
10
|
+
sys.path.insert(0, os.path.abspath('C:\\Users\\aksef\\Documents\\GitHub\\wawi'))
|
11
|
+
|
12
|
+
# import functions
|
13
|
+
from wawi.io import import_folder
|
14
|
+
from wawi.model import Windstate
|
15
|
+
from wawi.wind import ADs, flatplate_ads
|
16
|
+
from wawi.wind import itflutter_cont_naive
|
17
|
+
from wawi.general import eval_3d_fun
|
18
|
+
|
19
|
+
model_folder = './tests/models/model_2a'
|
20
|
+
|
21
|
+
def AD_dict(AD_funs):
|
22
|
+
AD_s = dict(
|
23
|
+
A1 = lambda v: -AD_funs['a_fun'][0](v), # sign convention
|
24
|
+
A2 = AD_funs['a_fun'][1],
|
25
|
+
A3 = AD_funs['a_fun'][2],
|
26
|
+
A4 = lambda v: -AD_funs['a_fun'][3](v),
|
27
|
+
A5 = lambda v: -AD_funs['a_fun'][4](v),
|
28
|
+
A6 = lambda v: -AD_funs['a_fun'][5](v),
|
29
|
+
|
30
|
+
H1 = AD_funs['h_fun'][0],
|
31
|
+
H2 = lambda v: -AD_funs['h_fun'][1](v),
|
32
|
+
H3 = lambda v: -AD_funs['h_fun'][2](v),
|
33
|
+
H4 = AD_funs['h_fun'][3],
|
34
|
+
H5 = AD_funs['h_fun'][4],
|
35
|
+
H6 = AD_funs['h_fun'][5],
|
36
|
+
|
37
|
+
P1 = AD_funs['p_fun'][0],
|
38
|
+
P2 = lambda v: -AD_funs['p_fun'][1](v),
|
39
|
+
P3 = lambda v: -AD_funs['p_fun'][2](v),
|
40
|
+
P4 = AD_funs['p_fun'][3],
|
41
|
+
P5 = AD_funs['p_fun'][4],
|
42
|
+
P6 = AD_funs['p_fun'][5],
|
43
|
+
)
|
44
|
+
return AD_s
|
45
|
+
|
46
|
+
def iabse_2a_windstate(mean_v):
|
47
|
+
windstate = Windstate(mean_v,
|
48
|
+
90,
|
49
|
+
Iu=0.1,
|
50
|
+
Iw=0.05,
|
51
|
+
Au=6.8, Aw=9.4, # not used in von Karman
|
52
|
+
Cuy=10.0, Cwy=6.5,
|
53
|
+
Cuz=10.0, Cwz=3.0,
|
54
|
+
Lux=200.0, Lwx=20.0,
|
55
|
+
x_ref=[0,0,0], rho=1.22,
|
56
|
+
options = {
|
57
|
+
'spectra_type': 'vonKarman'
|
58
|
+
}
|
59
|
+
)
|
60
|
+
|
61
|
+
return windstate
|
62
|
+
|
63
|
+
davenport = lambda fred: 2*(7*fred-1+np.exp(-7*fred))/(7*fred)**2
|
64
|
+
|
65
|
+
omega = np.linspace(0.001, 6, 1000)
|
66
|
+
|
67
|
+
# import the model and assign properties
|
68
|
+
model = import_folder(model_folder)
|
69
|
+
model.modal_dry.xi0 = .3e-2
|
70
|
+
|
71
|
+
# assign ADs (BB3 ADs)
|
72
|
+
with open( model_folder + '/AD_funs_BB3_scanlan.pkl', 'rb') as file:
|
73
|
+
AD_funs = dill.load(file)
|
74
|
+
AD_s = AD_dict(AD_funs)
|
75
|
+
for key in model.aero.sections:
|
76
|
+
model.aero.sections[key].ADs = ADs(**AD_s)
|
77
|
+
|
78
|
+
V = 30
|
79
|
+
# assign windstate
|
80
|
+
model.aero.windstate = iabse_2a_windstate(30)
|
81
|
+
# admittance
|
82
|
+
for key in model.aero.sections:
|
83
|
+
model.aero.sections[key].Admittance = lambda fred: np.full((4, 3), davenport(fred))
|
84
|
+
|
85
|
+
model.run_eig(w_initial=model.modal_dry.omega_n.tolist(), freq_kind=True, itmax=100)
|
86
|
+
|
87
|
+
# run analysis
|
88
|
+
model.run_freqsim(omega,
|
89
|
+
include_selfexcited=['aero'],
|
90
|
+
include_action=['aero'],
|
91
|
+
print_progress=False, merge_aero_sections=True)
|
92
|
+
# RMS responses
|
93
|
+
stds = model.get_result_std(key = 'full')
|
94
|
+
# global dofs
|
95
|
+
global_dof_ix1 = model.eldef.node_dof_lookup(36)[1:4]
|
96
|
+
global_dof_ix2 = model.eldef.node_dof_lookup(26)[1:4]
|
97
|
+
|
98
|
+
assert isclose(stds[global_dof_ix1][0], RMS_horz_exp1, rel_tol = 10e-2) # midspan horizontal
|
99
|
+
assert isclose(stds[global_dof_ix1][1], RMS_vert_exp1, rel_tol = 10e-2) # midspan vertical
|
100
|
+
assert isclose(stds[global_dof_ix1][2]*31/2, RMS_tors_exp1, rel_tol = 10e-2) # midspan torsional
|
101
|
+
|
102
|
+
assert isclose(stds[global_dof_ix2][0], RMS_horz_exp2, rel_tol = 15e-2) # q-span horizontal
|
103
|
+
assert isclose(stds[global_dof_ix2][1], RMS_vert_exp2, rel_tol = 15e-2) # q-span vertical
|
104
|
+
assert isclose(stds[global_dof_ix2][2]*31/2, RMS_tors_exp2, rel_tol = 20e-2) # q-span torsional
|
@@ -0,0 +1,219 @@
|
|
1
|
+
|
2
|
+
import pytest
|
3
|
+
import numpy as np
|
4
|
+
from math import isclose
|
5
|
+
|
6
|
+
# use the local wawi (Github folder) instead of the installed version (remove this when using the installed version)
|
7
|
+
import sys
|
8
|
+
import os
|
9
|
+
sys.path.insert(0, os.path.abspath('C:\\Users\\aksef\\Documents\\GitHub\\wawi'))
|
10
|
+
|
11
|
+
# import functions
|
12
|
+
from wawi.io import import_folder
|
13
|
+
from wawi.model import Windstate
|
14
|
+
from wawi.wind import ADs, flatplate_ads
|
15
|
+
from wawi.wind import itflutter_cont_naive
|
16
|
+
from wawi.general import eval_3d_fun
|
17
|
+
|
18
|
+
model_folder = './tests/models/model_11a'
|
19
|
+
|
20
|
+
def iabse_11a_windstate(mean_v):
|
21
|
+
windstate = Windstate(mean_v,
|
22
|
+
90,
|
23
|
+
Iu=0.0,
|
24
|
+
Iw=0.05,
|
25
|
+
Au=6.8, Aw=9.4,
|
26
|
+
Cuy=0.0, Cwy=0.0,
|
27
|
+
Cuz=0.0, Cwz=0.0,
|
28
|
+
Lux=0.0, Lwx=20.0,
|
29
|
+
x_ref=[0,0,0], rho=1.22,
|
30
|
+
options = {
|
31
|
+
'spectra_type': 'vonKarman'
|
32
|
+
}
|
33
|
+
)
|
34
|
+
return windstate
|
35
|
+
|
36
|
+
davenport = lambda fred: 2*(7*fred-1+np.exp(-7*fred))/(7*fred)**2
|
37
|
+
|
38
|
+
|
39
|
+
# in-wind frequencies and damping ratio
|
40
|
+
|
41
|
+
@pytest.mark.parametrize(
|
42
|
+
'V, expected_f, expected_zeta, tol',
|
43
|
+
[(15, np.array([0.0987, 0.279]), np.array([0.0399, 0.0096]), 0.05),
|
44
|
+
(30, np.array([0.0999, 0.2691]), np.array([0.0921, 0.0189]), 0.1),
|
45
|
+
(45, np.array([0.1014, 0.2561]), np.array([0.1689, 0.0309]), 0.1),
|
46
|
+
(60, np.array([0.1027, 0.2340]), np.array([0.3034, 0.0418]), 0.15),
|
47
|
+
(75, np.array([0.0829, 0.1994]), np.array([0.5349, 0.0148]), 0.25)],
|
48
|
+
)
|
49
|
+
|
50
|
+
|
51
|
+
# aerodynamic stability
|
52
|
+
|
53
|
+
# input - wind velocities / output - frequencies, damping ratios ( test only the unstable mode)
|
54
|
+
|
55
|
+
def test_in_wind_frequencies_and_damping( V, expected_f, expected_zeta, tol):
|
56
|
+
|
57
|
+
# importing the relevant model
|
58
|
+
model = import_folder('./tests/models/model_11a')
|
59
|
+
model.modal_dry.xi0 = .3e-2
|
60
|
+
|
61
|
+
# assign flat plate ADs (Theodorsen)
|
62
|
+
model.aero.sections['girder0'].ADs = ADs(**flatplate_ads())
|
63
|
+
|
64
|
+
model.aero.windstate = iabse_11a_windstate(V)
|
65
|
+
model.run_eig(w_initial=[0.5, 1.25], freq_kind=True, itmax=50)
|
66
|
+
lambd = model.results.lambd
|
67
|
+
|
68
|
+
f2 = np.abs(lambd[1].imag) / (2*np.pi)
|
69
|
+
zeta2 = -lambd[1].real/ np.abs(lambd[1])
|
70
|
+
|
71
|
+
assert isclose(f2, expected_f[1], rel_tol = tol)
|
72
|
+
assert isclose(zeta2, expected_zeta[1], rel_tol = tol)
|
73
|
+
|
74
|
+
|
75
|
+
# flutter speed
|
76
|
+
def test_flutter():
|
77
|
+
|
78
|
+
expected_flutter_speed = 77.45
|
79
|
+
tol = 0.01
|
80
|
+
ad_dict = flatplate_ads()
|
81
|
+
|
82
|
+
# importing the relevant model
|
83
|
+
model = import_folder(model_folder)
|
84
|
+
model.modal_dry.xi0 = .3e-2
|
85
|
+
B = model.aero.sections['girder0'].B
|
86
|
+
|
87
|
+
Ms = model.dry_M
|
88
|
+
Cs = model.dry_C
|
89
|
+
Ks = model.dry_K
|
90
|
+
phi = model.get_dry_phi('full')
|
91
|
+
|
92
|
+
# calculate the flutter speed
|
93
|
+
res = itflutter_cont_naive(Ms, Cs, Ks, phi, np.array([0,1]), ad_dict, B, V=0.1, rho=1.22, dV=5,
|
94
|
+
overshoot_factor=0.5, itmax={}, tol={}, print_progress=True)
|
95
|
+
|
96
|
+
assert isclose(res['V'][-1], expected_flutter_speed, rel_tol = tol)
|
97
|
+
|
98
|
+
|
99
|
+
# buffeting at 45 m/s (compare with analytical)
|
100
|
+
def test_mean_speed_45():
|
101
|
+
|
102
|
+
# at 45 m/s & f = 0.278 Hz
|
103
|
+
V = 45
|
104
|
+
f = 0.278
|
105
|
+
|
106
|
+
# expected values (IABSE report)
|
107
|
+
sww = 5.26 # wind spectrum
|
108
|
+
# impedance matrix
|
109
|
+
h_exp = np.array( [[-0.0619+0.0056j, -(-0.1492-0.0811j)], [-(0.01+0.0419j), -1.1559+0.5382j]] )*1e6
|
110
|
+
# PSD response
|
111
|
+
S_exp = np.transpose(np.array( [ [0.0167, -0.007j], [0.007j, 0.00293] ] ))
|
112
|
+
|
113
|
+
|
114
|
+
model = import_folder(model_folder)
|
115
|
+
model.aero.windstate = iabse_11a_windstate(V)
|
116
|
+
|
117
|
+
wind_spectrum_func = model.aero.get_generic_kaimal(nodes = model.eldef.nodes)
|
118
|
+
wind_spectrum_ww = 2*np.pi*wind_spectrum_func(f*2*np.pi)[2,2]
|
119
|
+
|
120
|
+
model.modal_dry.xi0 = .3e-2
|
121
|
+
model.aero.sections['girder0'].ADs = ADs(**flatplate_ads())
|
122
|
+
model.aero.prepare_aero_matrices()
|
123
|
+
omega = np.array([0.001, f])*np.pi*2
|
124
|
+
HH = eval_3d_fun(model.get_frf_fun(opt = 1), omega)
|
125
|
+
|
126
|
+
model.aero.sections['girder0'].Admittance = lambda fred: np.full((4, 3), davenport(fred))
|
127
|
+
model.run_freqsim(omega,
|
128
|
+
include_selfexcited=['aero'],
|
129
|
+
include_action=['aero'],
|
130
|
+
print_progress=False, merge_aero_sections=True)
|
131
|
+
|
132
|
+
global_dof_ix = np.array([2,3])
|
133
|
+
S = model.get_result_psd(key='full',
|
134
|
+
index=global_dof_ix)
|
135
|
+
|
136
|
+
assert isclose(wind_spectrum_ww, sww, rel_tol = 0.01)
|
137
|
+
assert np.allclose(HH[:,:,1], h_exp, rtol=1e-2)
|
138
|
+
assert np.allclose((2*np.pi)*S[:,:,-1], S_exp, rtol=5e-2)
|
139
|
+
|
140
|
+
|
141
|
+
# buffeting responses (spectra)
|
142
|
+
|
143
|
+
@pytest.mark.parametrize(
|
144
|
+
'Vbuff, RS_vert_exp, RS_tors_exp',
|
145
|
+
[
|
146
|
+
(15, np.array([1.24E-01, 1.19E-01, 1.37E-01, 4.09E+00, 5.66E-04, 1.75E-04, 2.15E-04, 2.18E-05, 7.02E-06,]),
|
147
|
+
np.array([2.53E-03, 2.39E-03, 1.56E-03, 1.85E-04, 4.94E-04, 9.05E-04, 7.07E-02, 1.02E-03, 5.71E-05]) ),
|
148
|
+
|
149
|
+
(30, np.array([1.19E+00, 1.15E+00, 1.75E+00, 2.06E+01, 3.02E-02, 1.27E-02, 4.61E-03, 9.67E-04, 3.75E-04,]),
|
150
|
+
np.array([2.43E-02, 2.31E-02, 1.98E-02, 9.30E-04, 2.59E-02, 6.16E-02, 4.23E-01, 3.46E-02, 2.94E-03,]) ),
|
151
|
+
|
152
|
+
(45, np.array([5.60E+00 , 5.40E+00 , 7.45E+00 , 3.43E+01 , 3.41E-01 , 2.50E-01 , 1.67E-02 , 5.85E-03 , 2.78E-03]),
|
153
|
+
np.array([1.15E-01 , 1.08E-01 , 8.46E-02 , 1.55E-03 , 2.85E-01 , 1.11E+00 , 7.06E-01 , 1.52E-01 , 2.07E-02]) ),
|
154
|
+
|
155
|
+
(60, np.array([2.39E+01 , 2.25E+01 , 2.36E+01 , 4.45E+01 , 3.44E+00 , 6.03E+00 , 3.41E-02 , 1.62E-02 , 9.21E-03,]),
|
156
|
+
np.array([4.89E-01 , 4.51E-01 , 2.67E-01 , 2.00E-03 , 2.77E+00 , 2.38E+01 , 8.28E-01 , 3.06E-01 , 6.37E-02,]) ),
|
157
|
+
|
158
|
+
(75, np.array([1.47E+02 , 1.24E+02 , 6.17E+01 , 5.32E+01 , 9.48E+02 , 1.79E+00 , 5.34E-02 , 3.04E-02 , 1.98E-02,]),
|
159
|
+
np.array([3.02E+00 , 2.50E+00 , 6.99E-01 , 2.38E-03 , 7.29E+02 , 6.17E+00 , 8.39E-01 , 4.26E-01 , 1.26E-01,]) ),
|
160
|
+
|
161
|
+
]
|
162
|
+
)
|
163
|
+
|
164
|
+
|
165
|
+
|
166
|
+
# buffeting responses (spectra)
|
167
|
+
def test_response_spectra(Vbuff, RS_vert_exp, RS_tors_exp):
|
168
|
+
|
169
|
+
omega_axis = np.array( [0.001, 0.01, 0.052, 0.1, 0.2, 0.234, 0.278, 0.3, 0.35] )*np.pi*2
|
170
|
+
|
171
|
+
model = import_folder(model_folder)
|
172
|
+
model.aero.windstate = iabse_11a_windstate(Vbuff)
|
173
|
+
model.modal_dry.xi0 = .3e-2
|
174
|
+
model.aero.sections['girder0'].ADs = ADs(**flatplate_ads())
|
175
|
+
model.aero.sections['girder0'].Admittance = lambda fred: np.full((4, 3), davenport(fred))
|
176
|
+
|
177
|
+
model.run_freqsim(omega_axis,
|
178
|
+
include_selfexcited=['aero'],
|
179
|
+
include_action=['aero'],
|
180
|
+
print_progress=False, merge_aero_sections=True)
|
181
|
+
|
182
|
+
global_dof_ix = np.array([2,3])
|
183
|
+
S = model.get_result_psd(key='full',
|
184
|
+
index=global_dof_ix)
|
185
|
+
|
186
|
+
assert np.allclose((2*np.pi)*S[0,0,:], RS_vert_exp, rtol=5e-2)
|
187
|
+
assert np.allclose((31/2)**2*(2*np.pi)*S[1,1,:], RS_tors_exp, rtol=5e-2)
|
188
|
+
|
189
|
+
|
190
|
+
|
191
|
+
@pytest.mark.parametrize(
|
192
|
+
'Vbuff, RMS_vert_exp, RMS_tors_exp',
|
193
|
+
[(15, 0.2603, 0.0419 ),
|
194
|
+
(30, 0.778 , 0.2027 ),
|
195
|
+
(45, 1.3404, 0.4792 ),
|
196
|
+
(60, 2.1601, 0.9306 ),
|
197
|
+
(75, 4.4848, 2.8414 )],
|
198
|
+
)
|
199
|
+
|
200
|
+
# buffeting responses (RMS values) - for integration we use a finer frequency axis
|
201
|
+
def test_RMS_response(Vbuff, RMS_vert_exp, RMS_tors_exp):
|
202
|
+
|
203
|
+
omega_axis = np.linspace(0.001, 6, 1000)
|
204
|
+
|
205
|
+
model = import_folder(model_folder)
|
206
|
+
model.aero.windstate = iabse_11a_windstate(Vbuff)
|
207
|
+
model.modal_dry.xi0 = .3e-2
|
208
|
+
model.aero.sections['girder0'].ADs = ADs(**flatplate_ads())
|
209
|
+
model.aero.sections['girder0'].Admittance = lambda fred: np.full((4, 3), davenport(fred))
|
210
|
+
|
211
|
+
model.run_freqsim(omega_axis,
|
212
|
+
include_selfexcited=['aero'],
|
213
|
+
include_action=['aero'],
|
214
|
+
print_progress=False, merge_aero_sections=True)
|
215
|
+
|
216
|
+
stds = model.get_result_std(key = 'full')
|
217
|
+
|
218
|
+
assert isclose(stds[2], RMS_vert_exp, rel_tol = 10e-2) # vertical # 5-10% std reported in the paper
|
219
|
+
assert isclose(stds[3]*31/2, RMS_tors_exp, rel_tol = 20e-2) # torsional # 10-25% std reported in the paper
|