h2lib-tests 13.2.702__py3-none-any.whl → 13.2.901__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- h2lib_tests/conftest.py +212 -7
- h2lib_tests/test_distributed_sections.py +337 -43
- h2lib_tests/test_h2lib.py +0 -7
- h2lib_tests/test_h2rotor.py +17 -1
- h2lib_tests/test_topology_h2lib.py +422 -32
- {h2lib_tests-13.2.702.dist-info → h2lib_tests-13.2.901.dist-info}/METADATA +3 -2
- {h2lib_tests-13.2.702.dist-info → h2lib_tests-13.2.901.dist-info}/RECORD +9 -9
- {h2lib_tests-13.2.702.dist-info → h2lib_tests-13.2.901.dist-info}/WHEEL +0 -0
- {h2lib_tests-13.2.702.dist-info → h2lib_tests-13.2.901.dist-info}/top_level.txt +0 -0
@@ -1,11 +1,48 @@
|
|
1
|
+
from pathlib import Path
|
2
|
+
|
1
3
|
from h2lib_tests import tfp
|
4
|
+
from numpy import testing as npt
|
2
5
|
import pytest
|
6
|
+
from scipy.spatial.transform import Rotation as R
|
7
|
+
from wetb.hawc2.htc_file import HTCFile
|
8
|
+
from wetb.hawc2.st_file import StFile
|
3
9
|
|
4
|
-
from h2lib
|
5
|
-
from h2lib.distributed_sections import
|
6
|
-
|
7
|
-
from numpy import testing as npt
|
10
|
+
from h2lib import H2Lib
|
11
|
+
from h2lib.distributed_sections import LinkType
|
12
|
+
from h2lib_tests.dtu10mw import DTU10MWSimple
|
8
13
|
import matplotlib.pyplot as plt
|
14
|
+
import numpy as np
|
15
|
+
|
16
|
+
|
17
|
+
class Plot():
|
18
|
+
def __init__(self, h2, ds_lst, ax=None):
|
19
|
+
self.h2 = h2
|
20
|
+
self.ds_lst = ds_lst
|
21
|
+
self.ax = ax or plt.figure().add_subplot(projection='3d')
|
22
|
+
|
23
|
+
def __call__(self, label, coo_index=[], h2=None, ds_lst=None, mainbody_coo=0):
|
24
|
+
self.h2 = h2 or self.h2
|
25
|
+
self.ds_lst = ds_lst or self.ds_lst
|
26
|
+
for ds in self.ds_lst:
|
27
|
+
sec_pos, sec_tsg = self.h2.get_distributed_section_position_orientation(ds, mainbody_coo_nr=mainbody_coo)
|
28
|
+
x, y, z = sec_pos.T
|
29
|
+
self.ax.plot(y, x, z, label=f'{label}, {ds.name}')
|
30
|
+
|
31
|
+
for (x, y, z), tsg in zip(sec_pos[coo_index], sec_tsg[coo_index]):
|
32
|
+
for (ex, ey, ez), c in zip(tsg.T * 10, 'rgb'):
|
33
|
+
plt.plot([y, y + ey], [x, x + ex], [z, z + ez], c)
|
34
|
+
|
35
|
+
def show(self, show):
|
36
|
+
if show:
|
37
|
+
plt.axis('equal')
|
38
|
+
self.ax.set_zlim([10, -220])
|
39
|
+
plt.legend()
|
40
|
+
self.ax.set_xlabel('x')
|
41
|
+
self.ax.set_ylabel('y')
|
42
|
+
self.ax.set_zlabel('z')
|
43
|
+
plt.show()
|
44
|
+
else:
|
45
|
+
plt.close('all')
|
9
46
|
|
10
47
|
|
11
48
|
def test_distributed_sections():
|
@@ -14,22 +51,11 @@ def test_distributed_sections():
|
|
14
51
|
model_path = f"{tfp}DTU_10_MW/"
|
15
52
|
htc_path = f"{tfp}DTU_10_MW/htc/DTU_10MW_RWT.htc"
|
16
53
|
h2.init(htc_path=htc_path, model_path=model_path)
|
54
|
+
ds_lst = [h2.get_distributed_sections(LinkType.BLADE, link_id=i) for i in [1, 2, 3]]
|
55
|
+
plot = Plot(h2, ds_lst)
|
56
|
+
plot('', slice(None))
|
57
|
+
plot.show(0)
|
17
58
|
|
18
|
-
ax = plt.figure().add_subplot(projection='3d')
|
19
|
-
for i in [1, 2, 3]:
|
20
|
-
# ds = DistributedSections(name='', link_type=1, link_id=i, nsec=50)
|
21
|
-
ds = h2.get_distributed_sections(LinkType.BLADE, link_id=i)
|
22
|
-
|
23
|
-
sec_pos, sec_tsg = h2.get_distributed_section_position_orientation(ds, mainbody_coo_nr=0)
|
24
|
-
x, y, z = sec_pos.T
|
25
|
-
ax.plot(y, x, -z, label=ds.name)
|
26
|
-
for (x, y, z), tsg in zip(sec_pos, sec_tsg):
|
27
|
-
for (ex, ey, ez), c in zip(tsg.T * 10, 'rgb'):
|
28
|
-
plt.plot([y, y + ey], [x, x + ex], [-z, -z - ez], c)
|
29
|
-
plt.legend()
|
30
|
-
plt.axis('equal')
|
31
|
-
if 0:
|
32
|
-
plt.show()
|
33
59
|
ds = h2.get_distributed_sections(LinkType.BLADE, link_id=2)
|
34
60
|
sec_pos, sec_tsg = h2.get_distributed_section_position_orientation(ds, mainbody_coo_nr=0)
|
35
61
|
npt.assert_array_almost_equal(sec_pos[40], [70.58938502, -16.98280589, -77.95555399], 6)
|
@@ -45,21 +71,9 @@ def test_distributed_sections():
|
|
45
71
|
for mbdy_name in mbdy_name_lst}
|
46
72
|
h2.initialize_distributed_sections()
|
47
73
|
ds_dict['blade1_aero'] = h2.get_distributed_sections(LinkType.BLADE, 1)
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
sec_pos, sec_tsg = h2.get_distributed_section_position_orientation(ds, mbdy_name_dict['hub2'])
|
52
|
-
x, y, z = sec_pos.T
|
53
|
-
ax.plot(y, x, -z, label=name)
|
54
|
-
for (x, y, z), tsg in zip(sec_pos, sec_tsg):
|
55
|
-
for (ex, ey, ez), c in zip(tsg.T * 10, 'rgb'):
|
56
|
-
|
57
|
-
plt.plot([y, y + ey], [x, x + ex], [-z, -z - ez], c)
|
58
|
-
|
59
|
-
plt.axis('equal')
|
60
|
-
if 0:
|
61
|
-
plt.show()
|
62
|
-
|
74
|
+
plot = Plot(h2, ds_dict.values())
|
75
|
+
plot('test', slice(None), mainbody_coo=mbdy_name_dict['hub2'])
|
76
|
+
plot.show(0)
|
63
77
|
# print(ds_lst[6].name, ds_lst[3].name)
|
64
78
|
# mb_pos, b1_mb_tbg, b1_sec_pos, sec_tsb = h2.get_distributed_section_position_orientation(ds_lst[6])
|
65
79
|
# hub_id = h2.get_mainbody_name_dict()['hub1']
|
@@ -91,16 +105,11 @@ def test_distributed_sections():
|
|
91
105
|
frc[:, 1] = 100000
|
92
106
|
h2.set_distributed_section_force_and_moment(ds_dict['tower'], sec_frc=frc, sec_mom=np.zeros((4, 3)))
|
93
107
|
|
108
|
+
plot = Plot(h2, ds_dict.values())
|
109
|
+
plot('t=0')
|
94
110
|
h2.run(2)
|
95
|
-
|
96
|
-
|
97
|
-
x, y, z = sec_pos.T
|
98
|
-
ax.plot(y, x, -z, '--', label=ds.name)
|
99
|
-
plt.legend()
|
100
|
-
plt.axis('scaled')
|
101
|
-
if 0:
|
102
|
-
plt.show()
|
103
|
-
plt.close('all')
|
111
|
+
plot('t=2')
|
112
|
+
plot.show(0)
|
104
113
|
np.set_printoptions(linewidth=200)
|
105
114
|
sec_pos, sec_tsb = h2.get_distributed_section_position_orientation(ds_dict['tower'])
|
106
115
|
# print(np.round(mb_pos + [mb_tbg@sp for sp in sec_pos], 1).tolist())
|
@@ -109,3 +118,288 @@ def test_distributed_sections():
|
|
109
118
|
[-0.0, 0.7, -46.2],
|
110
119
|
[-0.0, 2.4, -92.5],
|
111
120
|
[0.0, 3.5, -115.6]], 1)
|
121
|
+
|
122
|
+
|
123
|
+
def test_distributed_section_positions():
|
124
|
+
|
125
|
+
mp = Path(tfp) / 'DTU_10_MW/'
|
126
|
+
htc_path = mp / 'htc/DTU_10MW_RWT_only_tower.htc'
|
127
|
+
st = StFile(mp / 'data/DTU_10MW_RWT_Tower_st.dat')
|
128
|
+
st_new = st.main_data_sets[1][1].copy()
|
129
|
+
st_new[:, -2] = .4
|
130
|
+
st_new[:, -1] = .3
|
131
|
+
st.main_data_sets[1][1] = st_new
|
132
|
+
st.save(mp / 'data/DTU_10MW_RWT_Tower_st_tmp.dat')
|
133
|
+
htc = HTCFile(htc_path)
|
134
|
+
htc.new_htc_structure.main_body.timoschenko_input.filename = str(mp / 'data/DTU_10MW_RWT_Tower_st_tmp.dat')
|
135
|
+
htc.set_name('DTU_10MW_RWT_only_tower_tmp.htc')
|
136
|
+
htc.save()
|
137
|
+
|
138
|
+
with H2Lib() as h2:
|
139
|
+
h2.init(htc_path=htc.filename, model_path=htc.modelpath)
|
140
|
+
ds = h2.add_distributed_sections(mainbody_name='tower', section_relative_position=[0, .1, .5, 1])
|
141
|
+
h2.initialize_distributed_sections()
|
142
|
+
|
143
|
+
ax = plt.figure().add_subplot(projection='3d')
|
144
|
+
pos = h2.get_mainbody_nodes_state(1, 'pos')
|
145
|
+
npt.assert_array_equal(pos[:, :2].T, [[-0.4, -0.4, -0.4, -0.4, -0.4, -0.4, -0.4, -0.4, -0.4, -0.4, -0.4],
|
146
|
+
[0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3]])
|
147
|
+
ax.plot(*pos.T, '.-', label='initial nodes position')
|
148
|
+
|
149
|
+
sec_pos, sec_tsg = h2.get_distributed_section_position_orientation(ds)
|
150
|
+
npt.assert_array_almost_equal(sec_pos[:, :2], 0, 10)
|
151
|
+
ax.plot(*sec_pos.T, '.-', label='initial distributed sections, c2def')
|
152
|
+
|
153
|
+
st_new[:, -2] = 0.8
|
154
|
+
st_new[:, -1] = 0.9
|
155
|
+
|
156
|
+
h2.set_st(main_body_nr=1, st=st_new)
|
157
|
+
|
158
|
+
pos = h2.get_mainbody_nodes_state(1, 'pos')
|
159
|
+
npt.assert_array_equal(pos[:, :2].T, [[-0.8, -0.8, -0.8, -0.8, -0.8, -0.8, -0.8, -0.8, -0.8, -0.8, -0.8],
|
160
|
+
[0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9]])
|
161
|
+
ax.plot(*pos.T, '.-', label='exy=1, nodes position')
|
162
|
+
|
163
|
+
sec_pos, sec_tsg = h2.get_distributed_section_position_orientation(ds)
|
164
|
+
ax.plot(*sec_pos.T, '.-', label='exy=1 distributed sections, c2def')
|
165
|
+
|
166
|
+
plt.legend()
|
167
|
+
ax.set_xlabel('x')
|
168
|
+
ax.set_ylabel('y')
|
169
|
+
ax.set_zlabel('z')
|
170
|
+
ax.set_zlim([0, -120])
|
171
|
+
if 0:
|
172
|
+
plt.show()
|
173
|
+
plt.close('all')
|
174
|
+
|
175
|
+
npt.assert_array_equal(sec_pos[:, :2], 0, 10)
|
176
|
+
|
177
|
+
|
178
|
+
def test_distributed_sections_static_solver():
|
179
|
+
with H2Lib() as h2:
|
180
|
+
model_path = f"{tfp}DTU_10_MW/"
|
181
|
+
htc_path = f"{tfp}DTU_10_MW/htc/DTU_10MW_RWT_only_tower.htc"
|
182
|
+
h2.init(htc_path=htc_path, model_path=model_path)
|
183
|
+
ds = h2.add_distributed_sections(mainbody_name='tower', section_relative_position=[0, .5, 1])
|
184
|
+
h2.initialize_distributed_sections()
|
185
|
+
|
186
|
+
ax = plt.figure().add_subplot(projection='3d')
|
187
|
+
|
188
|
+
def draw(label, ref):
|
189
|
+
pos = h2.get_mainbody_nodes_state(mainbody_nr=1, state='pos')
|
190
|
+
# print(label, np.round(pos[-1], 4).tolist())
|
191
|
+
npt.assert_array_almost_equal(pos[-1], ref, 4)
|
192
|
+
ax.plot(*pos.T, marker='.', label=label)
|
193
|
+
ax.set_zlim([0, -120])
|
194
|
+
|
195
|
+
pos = h2.get_mainbody_nodes_state(mainbody_nr=1, state='pos')
|
196
|
+
|
197
|
+
draw('initial', [0.0, 0.0, -115.63])
|
198
|
+
|
199
|
+
frc = np.zeros((3, 3))
|
200
|
+
frc[:, 1] = 100000
|
201
|
+
h2.set_distributed_section_force_and_moment(ds, sec_frc=frc, sec_mom=frc * 0)
|
202
|
+
h2.solver_static_run(reset_structure=True)
|
203
|
+
draw('set frc + static solver', [0.0, 1.8293, -115.6123])
|
204
|
+
c2_def = np.concatenate([pos, pos[:, :1]], 1)
|
205
|
+
c2_def[:, 0] = np.r_[np.arange(0, 60, 10), np.arange(50, 0, -10)]
|
206
|
+
tower_id = h2.get_mainbody_name_dict()["tower"]
|
207
|
+
h2.set_c2_def(tower_id, c2_def)
|
208
|
+
draw('set_c2_def', [10.0, 0.1184, -115.6296])
|
209
|
+
h2.solver_static_run(reset_structure=True)
|
210
|
+
draw('static solver', [10.2695, 2.8081, -115.5122])
|
211
|
+
h2.set_distributed_section_force_and_moment(ds, sec_frc=-frc, sec_mom=frc * 0)
|
212
|
+
h2.solver_static_run(reset_structure=True)
|
213
|
+
draw('set -frc + static solver', [10.2695, -2.8081, -115.5122])
|
214
|
+
if 0:
|
215
|
+
plt.legend()
|
216
|
+
plt.show()
|
217
|
+
else:
|
218
|
+
plt.close('all')
|
219
|
+
|
220
|
+
|
221
|
+
def test_set_distributed_section_force_and_moment_coo():
|
222
|
+
with H2Lib() as h2:
|
223
|
+
model_path = f"{tfp}DTU_10_MW/"
|
224
|
+
htc = HTCFile(model_path + "htc/DTU_10MW_RWT_only_tower.htc")
|
225
|
+
htc.new_htc_structure.orientation.base.body_eulerang = 0, 0, 90
|
226
|
+
htc.save(model_path + "htc/DTU_10MW_RWT_only_tower_rot90.htc")
|
227
|
+
h2.init(htc_path=htc.filename, model_path=model_path)
|
228
|
+
ds = h2.add_distributed_sections(mainbody_name='tower', section_relative_position=[0, .5, 1])
|
229
|
+
with pytest.raises(AssertionError, match='Call initialize_distributed_sections before get_distributed_section_force_and_moment'):
|
230
|
+
h2.get_distributed_section_force_and_moment(ds)
|
231
|
+
|
232
|
+
h2.initialize_distributed_sections()
|
233
|
+
|
234
|
+
ax = plt.figure().add_subplot(projection='3d')
|
235
|
+
|
236
|
+
def draw(label, ref):
|
237
|
+
h2.solver_static_run()
|
238
|
+
pos = h2.get_mainbody_nodes_state(mainbody_nr=1, state='pos')
|
239
|
+
# print(label, np.round(pos[-1], 4).tolist())
|
240
|
+
ax.plot(*pos.T, marker='.', label=label)
|
241
|
+
npt.assert_array_almost_equal(pos[-1], ref, 4)
|
242
|
+
|
243
|
+
draw('init', [0.0, 0.0, -115.6281])
|
244
|
+
frc = np.zeros((3, 3))
|
245
|
+
frc[:, 1] = 2e6
|
246
|
+
h2.set_distributed_section_force_and_moment(ds, sec_frc=frc, sec_mom=frc * 0)
|
247
|
+
draw('frc_y_global', [0.0, 33.8576, -110.0939])
|
248
|
+
|
249
|
+
h2.set_distributed_section_force_and_moment(ds, sec_frc=frc, sec_mom=frc * 0, mainbody_coo_nr=1)
|
250
|
+
draw('frc_y_tower', [-33.8576, -0.0, -110.0939])
|
251
|
+
|
252
|
+
if 0:
|
253
|
+
ax.axis('equal')
|
254
|
+
ax.set_zlim([0, -120])
|
255
|
+
ax.set_xlabel('x')
|
256
|
+
ax.set_ylabel('y')
|
257
|
+
ax.set_zlabel('z')
|
258
|
+
ax.plot([0, 0], [0, 10], label='global y')
|
259
|
+
ax.plot([0, -10], [0, 0], label='tower y')
|
260
|
+
ax.legend()
|
261
|
+
plt.show()
|
262
|
+
else:
|
263
|
+
plt.close('all')
|
264
|
+
|
265
|
+
|
266
|
+
def test_set_frc_blade():
|
267
|
+
with H2Lib(suppress_output=0) as h2:
|
268
|
+
htc = DTU10MWSimple(rotor_speed=.6, pitch=0, nbodies=1)
|
269
|
+
htc.set_name('DTU_10MW_RWT_fixed_rotspeed')
|
270
|
+
htc.aero.aerocalc_method = 0
|
271
|
+
htc.save()
|
272
|
+
h2.init(htc_path=htc.filename, model_path=htc.modelpath)
|
273
|
+
|
274
|
+
ds_lst = [h2.get_distributed_sections(LinkType.BLADE, link_id=i) for i in [1, 2, 3]]
|
275
|
+
h2.solver_static_run()
|
276
|
+
plot = Plot(h2, ds_lst)
|
277
|
+
plot('initial', [-1])
|
278
|
+
ini_tip_pos = [h2.get_distributed_section_position_orientation(ds, mainbody_coo_nr=0)[0][-1] for ds in ds_lst]
|
279
|
+
ini_tip3_tsg = h2.get_distributed_section_position_orientation(ds_lst[2], mainbody_coo_nr=9)[1][-1]
|
280
|
+
zeros = np.zeros((50, 3))
|
281
|
+
h2.set_distributed_section_force_and_moment(ds=ds_lst[0], sec_frc=zeros + [10000, 0, 0], sec_mom=zeros)
|
282
|
+
h2.set_distributed_section_force_and_moment(ds=ds_lst[1], sec_frc=zeros + [0, 10000, 0], sec_mom=zeros)
|
283
|
+
h2.set_distributed_section_force_and_moment(ds=ds_lst[2], sec_frc=zeros, sec_mom=zeros + [0, 0, 100000])
|
284
|
+
h2.solver_static_run()
|
285
|
+
|
286
|
+
plot('deflected', [-1])
|
287
|
+
def_tip_pos = [h2.get_distributed_section_position_orientation(ds, mainbody_coo_nr=0)[0][-1] for ds in ds_lst]
|
288
|
+
def_tip3_tsg = h2.get_distributed_section_position_orientation(ds_lst[2], mainbody_coo_nr=9)[1][-1]
|
289
|
+
npt.assert_array_almost_equal(np.array(def_tip_pos) - ini_tip_pos,
|
290
|
+
[[7.545511, -0.270957, 0.189638], # mainly x
|
291
|
+
[0.942178, 11.676871, 2.980586], # mainly y
|
292
|
+
[0.596675, -6.677523, -2.850951]], # complex due to bend-twist coupling
|
293
|
+
6)
|
294
|
+
|
295
|
+
npt.assert_array_almost_equal(R.from_matrix(ini_tip3_tsg @ def_tip3_tsg).as_euler('xyz', 1),
|
296
|
+
[30.762956, 0.310381, 44.774262], 6) # rotation around z (but also x due to bend-twist coupling
|
297
|
+
plot.show(0)
|
298
|
+
|
299
|
+
|
300
|
+
@pytest.mark.parametrize('coo_nr', [-1, 0, 1])
|
301
|
+
def test_get_set_frc_blade(coo_nr):
|
302
|
+
'''
|
303
|
+
1 Run static solver with aerodynamic and extract position, frc and mom of distributed sections
|
304
|
+
2 New simulation, set frc and mom and run static solver without aerocalc
|
305
|
+
3 compare position of distributed sections
|
306
|
+
'''
|
307
|
+
with H2Lib(suppress_output=0) as h2:
|
308
|
+
htc = DTU10MWSimple(rotor_speed=.6, pitch=0, nbodies=1)
|
309
|
+
htc.set_name('DTU_10MW_RWT_fixed_rotspeed')
|
310
|
+
htc.simulation.convergence_limits.delete()
|
311
|
+
htc.wind.wsp = 10
|
312
|
+
htc.aero.tiploss_method = 0 # tiploss makes the static solver unstable
|
313
|
+
htc.save()
|
314
|
+
h2.init(htc_path=htc.filename, model_path=htc.modelpath)
|
315
|
+
|
316
|
+
aero_ds_lst = [h2.get_distributed_sections(LinkType.BLADE, link_id=i) for i in [1, 2, 3]]
|
317
|
+
|
318
|
+
mb_dict = h2.get_mainbody_name_dict()
|
319
|
+
p = h2.get_distributed_section_position_orientation(aero_ds_lst[0], mb_dict['blade1'])[0]
|
320
|
+
r = np.r_[0, np.cumsum(np.sqrt((np.diff(p, 1, 0)**2).sum(1)))] # curve-length radius
|
321
|
+
rR = r / r[-1]
|
322
|
+
for ds in aero_ds_lst:
|
323
|
+
h2.add_distributed_sections(ds.name, rR)
|
324
|
+
h2.initialize_distributed_sections()
|
325
|
+
|
326
|
+
body_ds_lst = [h2.get_distributed_sections(link_type=LinkType.BODY, link_id=i) for i in [1, 2, 3]]
|
327
|
+
|
328
|
+
plot = Plot(h2, aero_ds_lst)
|
329
|
+
h2.solver_static_run()
|
330
|
+
plot('aerosections after static solver')
|
331
|
+
# plot('bodysections after static solver', ds_lst=body_ds_lst)
|
332
|
+
pos_coo = np.maximum(coo_nr, 0)
|
333
|
+
ref_pos = [h2.get_distributed_section_position_orientation(ds, pos_coo)[0] for ds in aero_ds_lst]
|
334
|
+
aero2body = [np.array(h2.get_distributed_section_position_orientation(aero_ds, pos_coo)[0]) -
|
335
|
+
h2.get_distributed_section_position_orientation(body_ds, pos_coo)[0]
|
336
|
+
for aero_ds, body_ds in zip(aero_ds_lst, body_ds_lst)]
|
337
|
+
frc, mom = zip(*[h2.get_distributed_section_force_and_moment(ds, mainbody_coo_nr=coo_nr)
|
338
|
+
for ds in aero_ds_lst])
|
339
|
+
if coo_nr == 0:
|
340
|
+
aero_frc = h2.get_aerosections_forces()
|
341
|
+
aero_mom = h2.get_aerosections_moments()
|
342
|
+
aero_pos = h2.get_aerosections_position()
|
343
|
+
npt.assert_array_equal(aero_frc, frc)
|
344
|
+
npt.assert_array_almost_equal(aero_mom, mom)
|
345
|
+
|
346
|
+
npt.assert_array_equal(ref_pos, aero_pos)
|
347
|
+
|
348
|
+
with H2Lib(suppress_output=0) as h2:
|
349
|
+
htc = DTU10MWSimple(rotor_speed=.6, pitch=0, nbodies=1)
|
350
|
+
htc.simulation.convergence_limits.delete()
|
351
|
+
htc.set_name('DTU_10MW_RWT_fixed_rotspeed')
|
352
|
+
htc.aero.aerocalc_method = 0
|
353
|
+
htc.save()
|
354
|
+
h2.init(htc_path=htc.filename, model_path=htc.modelpath)
|
355
|
+
|
356
|
+
aero_ds_lst = [h2.get_distributed_sections(LinkType.BLADE, link_id=i) for i in [1, 2, 3]]
|
357
|
+
|
358
|
+
# set_distributed_section_force_and_moment maps the moment from section moments to moments around
|
359
|
+
# elastic axis. This mapping depends on the deflection, so we need to run a couple of times to
|
360
|
+
# get the right deflection and thereby the right mapping
|
361
|
+
for _ in range(5):
|
362
|
+
for sec_frc, sec_mom, ds in zip(frc, mom, aero_ds_lst):
|
363
|
+
h2.set_distributed_section_force_and_moment(ds, sec_frc, sec_mom, mainbody_coo_nr=coo_nr)
|
364
|
+
h2.solver_static_run()
|
365
|
+
|
366
|
+
pos = [h2.get_distributed_section_position_orientation(ds, np.maximum(coo_nr, 0))[0] for ds in aero_ds_lst]
|
367
|
+
plot = Plot(h2, aero_ds_lst, ax=plot.ax)
|
368
|
+
plot('set frc')
|
369
|
+
plot.show(0)
|
370
|
+
npt.assert_array_almost_equal(ref_pos, pos)
|
371
|
+
|
372
|
+
if coo_nr >= 0:
|
373
|
+
# for global and blade1 coordinates:
|
374
|
+
# apply forces and moments (mapped to c2df) to distributed sections (at c2def)
|
375
|
+
# and compare position of aerodynamic sections
|
376
|
+
with H2Lib(suppress_output=0) as h2:
|
377
|
+
htc = DTU10MWSimple(rotor_speed=.6, pitch=0, nbodies=1)
|
378
|
+
htc.simulation.convergence_limits.delete()
|
379
|
+
htc.set_name('DTU_10MW_RWT_fixed_rotspeed')
|
380
|
+
htc.aero.aerocalc_method = 0
|
381
|
+
htc.save()
|
382
|
+
h2.init(htc_path=htc.filename, model_path=htc.modelpath)
|
383
|
+
|
384
|
+
aero_ds_lst = [h2.get_distributed_sections(LinkType.BLADE, link_id=i) for i in [1, 2, 3]]
|
385
|
+
|
386
|
+
for ds in aero_ds_lst:
|
387
|
+
h2.add_distributed_sections(ds.name, rR)
|
388
|
+
h2.initialize_distributed_sections()
|
389
|
+
|
390
|
+
body_ds_lst = [h2.get_distributed_sections(link_type=LinkType.BODY, link_id=i) for i in [1, 2, 3]]
|
391
|
+
|
392
|
+
# set_distributed_section_force_and_moment maps the moment from section moments to moments around
|
393
|
+
# elastic axis. This mapping depends on the deflection, so we need to run a couple of times to
|
394
|
+
# get the right deflection and thereby the right mapping
|
395
|
+
for _ in range(5):
|
396
|
+
for sec_frc, sec_mom, ds, a2b in zip(frc, mom, body_ds_lst, aero2body):
|
397
|
+
body_mom = sec_mom + np.cross(sec_frc, -a2b)
|
398
|
+
h2.set_distributed_section_force_and_moment(ds, sec_frc, body_mom, mainbody_coo_nr=coo_nr)
|
399
|
+
h2.solver_static_run()
|
400
|
+
pos = [h2.get_distributed_section_position_orientation(ds, np.maximum(coo_nr, 0))[0] for ds in aero_ds_lst]
|
401
|
+
plot = Plot(h2, aero_ds_lst, ax=plot.ax)
|
402
|
+
plot('set frc')
|
403
|
+
plot.show(0)
|
404
|
+
# not sure why the accuracy is much worse. Maybe the distributed
|
405
|
+
npt.assert_array_almost_equal(ref_pos, pos, 2)
|
h2lib_tests/test_h2lib.py
CHANGED
@@ -335,13 +335,6 @@ def test_fail():
|
|
335
335
|
assert h2.get_version() == version # hawc2 still alive
|
336
336
|
stop_code = 0
|
337
337
|
|
338
|
-
# cover get_stop_code, get_stop_message and reset_stop_code_and_message, but
|
339
|
-
# reset_stop_code_and_message is already called, so stop_code and stop_message are 0 and ""
|
340
|
-
assert h2.get_stop_code(stop_code)[0][0] == 0
|
341
|
-
stop_msg = " " * 1024
|
342
|
-
assert h2.get_stop_message(stop_msg)[0][0].strip() == ''
|
343
|
-
h2.reset_stop_code_and_message()
|
344
|
-
|
345
338
|
with MultiH2Lib(2) as h2:
|
346
339
|
# , match=re.escape('H2LibThread process died before or while executing fail(...)')):
|
347
340
|
with pytest.raises(Exception, match='MyError'):
|
h2lib_tests/test_h2rotor.py
CHANGED
@@ -55,11 +55,14 @@ def test_get_mainbody_position_orientation(h2: H2LibThread):
|
|
55
55
|
ax = plt.figure().add_subplot(projection='3d')
|
56
56
|
for name, mainbody_nr in mb_dict.items():
|
57
57
|
pos, ori = h2.get_mainbody_position_orientation(mainbody_nr, mainbody_coo_nr)
|
58
|
-
ax.plot(*pos, 'o', label=name)
|
58
|
+
c = ax.plot(*pos, 'o', label=name)[0].get_color()
|
59
|
+
nodes_pos = h2.get_mainbody_nodes_state(mainbody_nr, state='pos')
|
60
|
+
ax.plot(*nodes_pos.T, '.-', color=c)
|
59
61
|
for (exyz), c in zip(ori, 'rgb'):
|
60
62
|
ax.plot(*np.array([pos, pos + exyz * 10]).T, color=c)
|
61
63
|
plt.axis('equal')
|
62
64
|
plt.legend()
|
65
|
+
plt.gca().set_zlim([0, -200])
|
63
66
|
plt.show()
|
64
67
|
|
65
68
|
pos, ori = h2.get_mainbody_position_orientation(mb_dict['blade2'], 0)
|
@@ -73,6 +76,19 @@ def test_get_mainbody_position_orientation(h2: H2LibThread):
|
|
73
76
|
npt.assert_array_almost_equal(ori, [[0.49826698, 0.03781904, 0.86619844],
|
74
77
|
[0.07556557, 0.99335236, -0.0868386],
|
75
78
|
[-0.86372441, 0.10872359, 0.49209687]], 6)
|
79
|
+
npt.assert_array_almost_equal(
|
80
|
+
h2.get_mainbody_nodes_state(mainbody_nr=mb_dict['blade1'], state='pos', mainbody_coo_nr=0)[-1],
|
81
|
+
[-0.113689, -6.504988, -208.222845], 6)
|
82
|
+
npt.assert_array_almost_equal(
|
83
|
+
h2.get_mainbody_nodes_state(mainbody_nr=mb_dict['blade1'], state='pos', mainbody_coo_nr=mb_dict['blade1'])[-1],
|
84
|
+
[-0.069654, -3.326239, 86.364205], 6)
|
85
|
+
|
86
|
+
npt.assert_array_almost_equal(
|
87
|
+
h2.get_mainbody_nodes_state(mainbody_nr=mb_dict['blade1'], state='vel', mainbody_coo_nr=0)[-1],
|
88
|
+
[-17.787036, 1.8e-05, 0.061966], 6)
|
89
|
+
npt.assert_array_almost_equal(
|
90
|
+
h2.get_mainbody_nodes_state(mainbody_nr=mb_dict['blade1'], state='acc', mainbody_coo_nr=0)[-1],
|
91
|
+
[-0.032976, 0.08213, 11.252719], 6)
|
76
92
|
|
77
93
|
|
78
94
|
def test_induction(h2):
|