h2lib-tests 13.1.3110__py3-none-any.whl → 13.2.701__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 +252 -37
- h2lib_tests/test_distributed_sections.py +111 -0
- h2lib_tests/test_ellipsys_couplings.py +3 -2
- h2lib_tests/test_files/DTU_10_MW/htc/DTU_10MW_RWT_only_tower.htc +68 -0
- h2lib_tests/test_h2rotor.py +34 -2
- h2lib_tests/test_lin.py +7 -21
- h2lib_tests/test_static_solver.py +42 -62
- h2lib_tests/test_topology_h2lib.py +305 -12
- {h2lib_tests-13.1.3110.dist-info → h2lib_tests-13.2.701.dist-info}/METADATA +2 -2
- {h2lib_tests-13.1.3110.dist-info → h2lib_tests-13.2.701.dist-info}/RECORD +12 -10
- {h2lib_tests-13.1.3110.dist-info → h2lib_tests-13.2.701.dist-info}/WHEEL +0 -0
- {h2lib_tests-13.1.3110.dist-info → h2lib_tests-13.2.701.dist-info}/top_level.txt +0 -0
h2lib_tests/conftest.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
import pytest
|
2
1
|
import numpy as np
|
2
|
+
import pytest
|
3
3
|
from wetb.hawc2.htc_file import HTCFile
|
4
|
+
from wetb.hawc2.mainbody import MainBody
|
4
5
|
from h2lib_tests.test_files import tfp
|
5
6
|
from h2lib._h2lib import H2Lib
|
6
7
|
|
@@ -59,7 +60,9 @@ def write_dtu10mw_only_tower_encrypted(write_dtu10mw_only_tower):
|
|
59
60
|
htc = write_dtu10mw_only_tower.copy()
|
60
61
|
htc.set_name("DTU_10MW_RWT_only_tower_encrypted")
|
61
62
|
# Only the tower is left.
|
62
|
-
htc.new_htc_structure.main_body.timoschenko_input.filename =
|
63
|
+
htc.new_htc_structure.main_body.timoschenko_input.filename = (
|
64
|
+
"./data/DTU_10MW_RWT_Tower_st.dat.v3.enc"
|
65
|
+
)
|
63
66
|
htc.save()
|
64
67
|
|
65
68
|
|
@@ -88,7 +91,9 @@ def write_dtu10mw_only_blade():
|
|
88
91
|
htc.new_htc_structure.orientation.base.mbdy = "blade1"
|
89
92
|
htc.new_htc_structure.orientation.base.inipos = [0.0, 0.0, 0.0]
|
90
93
|
htc.new_htc_structure.orientation.base["mbdy_eulerang"] = [90.0, 0.0, 0.0]
|
91
|
-
htc.new_htc_structure.orientation.base.mbdy_eulerang.comments =
|
94
|
+
htc.new_htc_structure.orientation.base.mbdy_eulerang.comments = (
|
95
|
+
"Blade span is horizontal."
|
96
|
+
)
|
92
97
|
|
93
98
|
# Clamp the blade.
|
94
99
|
htc.new_htc_structure.add_section("constraint")
|
@@ -128,6 +133,20 @@ def write_dtu10mw_only_blade_low_max_iter(write_dtu10mw_only_blade):
|
|
128
133
|
return htc
|
129
134
|
|
130
135
|
|
136
|
+
@pytest.fixture(scope="session")
|
137
|
+
def write_dtu10mw_only_blade_1_body(write_dtu10mw_only_blade):
|
138
|
+
# Start from the write_dtu10mw_only_blade and then set the number of bodies to 1.
|
139
|
+
# This is to compute its mass properties.
|
140
|
+
htc = write_dtu10mw_only_blade.copy()
|
141
|
+
htc.set_name("DTU_10MW_RWT_only_blade_1_body")
|
142
|
+
htc.new_htc_structure.main_body__7.nbodies = 1
|
143
|
+
htc["wind"].delete()
|
144
|
+
htc["output"].delete()
|
145
|
+
htc.save()
|
146
|
+
|
147
|
+
return htc
|
148
|
+
|
149
|
+
|
131
150
|
@pytest.fixture(scope="session")
|
132
151
|
def write_dtu10mw_only_blade_rotate_base(write_dtu10mw_only_blade):
|
133
152
|
# Start from the write_dtu10mw_only_blade and then make it rotate by using the base command.
|
@@ -137,12 +156,20 @@ def write_dtu10mw_only_blade_rotate_base(write_dtu10mw_only_blade):
|
|
137
156
|
htc = write_dtu10mw_only_blade.copy()
|
138
157
|
htc.set_name("DTU_10MW_RWT_only_blade_rotate_base")
|
139
158
|
speed = 1.0 # [rad/s]
|
140
|
-
htc.new_htc_structure.orientation.base["mbdy_ini_rotvec_d1"] = [
|
141
|
-
|
159
|
+
htc.new_htc_structure.orientation.base["mbdy_ini_rotvec_d1"] = [
|
160
|
+
0.0,
|
161
|
+
1.0,
|
162
|
+
0.0,
|
163
|
+
speed,
|
164
|
+
]
|
165
|
+
htc.new_htc_structure.orientation.base.mbdy_ini_rotvec_d1.comments = (
|
166
|
+
f"= {speed * 30.0 / np.pi:.2f} rpm"
|
167
|
+
)
|
142
168
|
htc.new_htc_structure.main_body__7.gravity = 0.0
|
143
169
|
htc["wind"].delete()
|
144
170
|
htc["output"].delete()
|
145
171
|
htc.save()
|
172
|
+
return htc
|
146
173
|
|
147
174
|
|
148
175
|
@pytest.fixture(scope="session")
|
@@ -152,16 +179,17 @@ def write_dtu10mw_only_blade_rotate_relative():
|
|
152
179
|
# Because of the fix1 constraint, the blade will not rotate after time 0.
|
153
180
|
htc = HTCFile(tfp + "DTU_10_MW/htc/DTU_10MW_RWT.htc")
|
154
181
|
htc.set_name("DTU_10MW_RWT_only_blade_rotate_relative")
|
155
|
-
for key1 in (
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
182
|
+
for key1 in (
|
183
|
+
"main_body", # tower
|
184
|
+
"main_body__2", # towertop
|
185
|
+
"main_body__3", # shaft
|
186
|
+
"main_body__5", # hub2
|
187
|
+
"main_body__6", # hub3
|
188
|
+
"main_body__8", # blade2
|
189
|
+
"main_body__9", # blade3
|
190
|
+
"orientation",
|
191
|
+
"constraint",
|
192
|
+
):
|
165
193
|
htc["new_htc_structure"][key1].delete()
|
166
194
|
htc["wind"].delete()
|
167
195
|
htc["aerodrag"].delete()
|
@@ -175,17 +203,32 @@ def write_dtu10mw_only_blade_rotate_relative():
|
|
175
203
|
htc.new_htc_structure.orientation.base.mbdy = "hub1"
|
176
204
|
htc.new_htc_structure.orientation.base.inipos = [0.0, 0.0, 0.0]
|
177
205
|
htc.new_htc_structure.orientation.base["mbdy_eulerang"] = [180.0, 0.0, 0.0]
|
178
|
-
htc.new_htc_structure.orientation.base.mbdy_eulerang.comments =
|
206
|
+
htc.new_htc_structure.orientation.base.mbdy_eulerang.comments = (
|
207
|
+
"Hub axis is up."
|
208
|
+
)
|
179
209
|
|
180
210
|
# Set the blade horizontal.
|
181
211
|
htc.new_htc_structure.orientation.add_section("relative")
|
182
212
|
htc.new_htc_structure.orientation.relative.mbdy1 = "hub1 last"
|
183
213
|
htc.new_htc_structure.orientation.relative.mbdy2 = "blade1 1"
|
184
|
-
htc.new_htc_structure.orientation.relative["mbdy2_eulerang"] = [
|
185
|
-
|
214
|
+
htc.new_htc_structure.orientation.relative["mbdy2_eulerang"] = [
|
215
|
+
-90.0,
|
216
|
+
0.0,
|
217
|
+
0.0,
|
218
|
+
]
|
219
|
+
htc.new_htc_structure.orientation.relative.mbdy2_eulerang.comments = (
|
220
|
+
"Blade span is horizontal."
|
221
|
+
)
|
186
222
|
speed = 1.0 # [rad/s]
|
187
|
-
htc.new_htc_structure.orientation.relative["mbdy2_ini_rotvec_d1"] = [
|
188
|
-
|
223
|
+
htc.new_htc_structure.orientation.relative["mbdy2_ini_rotvec_d1"] = [
|
224
|
+
0.0,
|
225
|
+
1.0,
|
226
|
+
0.0,
|
227
|
+
speed,
|
228
|
+
]
|
229
|
+
htc.new_htc_structure.orientation.relative.mbdy2_ini_rotvec_d1.comments = (
|
230
|
+
f"= {speed * 30.0 / np.pi:.2f} rpm"
|
231
|
+
)
|
189
232
|
|
190
233
|
# Disable gravity.
|
191
234
|
htc.new_htc_structure.main_body__7.gravity = 0.0
|
@@ -224,16 +267,17 @@ def write_dtu10mw_only_blade_rotate_bearing3():
|
|
224
267
|
# The blade now rotates because of the bearing3 between the blade and hub.
|
225
268
|
htc = HTCFile(tfp + "DTU_10_MW/htc/DTU_10MW_RWT.htc")
|
226
269
|
htc.set_name("DTU_10MW_RWT_only_blade_rotate_bearing3")
|
227
|
-
for key1 in (
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
270
|
+
for key1 in (
|
271
|
+
"main_body", # tower
|
272
|
+
"main_body__2", # towertop
|
273
|
+
"main_body__3", # shaft
|
274
|
+
"main_body__5", # hub2
|
275
|
+
"main_body__6", # hub3
|
276
|
+
"main_body__8", # blade2
|
277
|
+
"main_body__9", # blade3
|
278
|
+
"orientation",
|
279
|
+
"constraint",
|
280
|
+
):
|
237
281
|
htc["new_htc_structure"][key1].delete()
|
238
282
|
htc["wind"].delete()
|
239
283
|
htc["aerodrag"].delete()
|
@@ -247,14 +291,22 @@ def write_dtu10mw_only_blade_rotate_bearing3():
|
|
247
291
|
htc.new_htc_structure.orientation.base.mbdy = "hub1"
|
248
292
|
htc.new_htc_structure.orientation.base.inipos = [0.0, 0.0, 0.0]
|
249
293
|
htc.new_htc_structure.orientation.base["mbdy_eulerang"] = [180.0, 0.0, 0.0]
|
250
|
-
htc.new_htc_structure.orientation.base.mbdy_eulerang.comments =
|
294
|
+
htc.new_htc_structure.orientation.base.mbdy_eulerang.comments = (
|
295
|
+
"Hub axis is up."
|
296
|
+
)
|
251
297
|
|
252
298
|
# Set the blade horizontal.
|
253
299
|
htc.new_htc_structure.orientation.add_section("relative")
|
254
300
|
htc.new_htc_structure.orientation.relative.mbdy1 = "hub1 last"
|
255
301
|
htc.new_htc_structure.orientation.relative.mbdy2 = "blade1 1"
|
256
|
-
htc.new_htc_structure.orientation.relative["mbdy2_eulerang"] = [
|
257
|
-
|
302
|
+
htc.new_htc_structure.orientation.relative["mbdy2_eulerang"] = [
|
303
|
+
-90.0,
|
304
|
+
0.0,
|
305
|
+
0.0,
|
306
|
+
]
|
307
|
+
htc.new_htc_structure.orientation.relative.mbdy2_eulerang.comments = (
|
308
|
+
"Blade span is horizontal."
|
309
|
+
)
|
258
310
|
|
259
311
|
# Disable gravity.
|
260
312
|
htc.new_htc_structure.main_body__7.gravity = 0.0
|
@@ -270,10 +322,17 @@ def write_dtu10mw_only_blade_rotate_bearing3():
|
|
270
322
|
htc.new_htc_structure.constraint.bearing3.name = "bearing"
|
271
323
|
htc.new_htc_structure.constraint.bearing3.mbdy1 = "hub1 last"
|
272
324
|
htc.new_htc_structure.constraint.bearing3.mbdy2 = "blade1 1"
|
273
|
-
htc.new_htc_structure.constraint.bearing3.bearing_vector = [
|
325
|
+
htc.new_htc_structure.constraint.bearing3.bearing_vector = [
|
326
|
+
1,
|
327
|
+
0.0,
|
328
|
+
0.0,
|
329
|
+
1.0,
|
330
|
+
]
|
274
331
|
speed = 1.0 # [rad/s]
|
275
332
|
htc.new_htc_structure.constraint.bearing3.omegas = speed
|
276
|
-
htc.new_htc_structure.constraint.bearing3.omegas.comments =
|
333
|
+
htc.new_htc_structure.constraint.bearing3.omegas.comments = (
|
334
|
+
f"= {speed * 30.0 / np.pi:.2f} rpm"
|
335
|
+
)
|
277
336
|
|
278
337
|
# Set as many bodies as elements.
|
279
338
|
htc.new_htc_structure.main_body__7.nbodies = 26
|
@@ -291,6 +350,85 @@ def write_dtu10mw_only_blade_rotate_bearing3():
|
|
291
350
|
return htc
|
292
351
|
|
293
352
|
|
353
|
+
@pytest.fixture(scope="session")
|
354
|
+
def write_dtu10mw_only_blade_uniform_node_distribution(
|
355
|
+
write_dtu10mw_only_blade,
|
356
|
+
):
|
357
|
+
# Start from the write_dtu10mw_only_blade and then change the nodes distribution to uniform.
|
358
|
+
htc = write_dtu10mw_only_blade.copy()
|
359
|
+
htc.set_name("DTU_10MW_RWT_only_blade_uniform_node_distribution")
|
360
|
+
htc.new_htc_structure.main_body__7.nbodies = 10
|
361
|
+
htc.new_htc_structure.main_body__7.node_distribution = ["uniform", 11]
|
362
|
+
# Somehow the wind and output blocks are back.
|
363
|
+
htc["wind"].delete()
|
364
|
+
htc["output"].delete()
|
365
|
+
htc.save()
|
366
|
+
return htc
|
367
|
+
|
368
|
+
|
369
|
+
@pytest.fixture(scope="session")
|
370
|
+
def write_dtu10mw_only_blade_high_gravity(
|
371
|
+
write_dtu10mw_only_blade,
|
372
|
+
):
|
373
|
+
# Start from the write_dtu10mw_only_blade and then increase the gravity loading.
|
374
|
+
htc = write_dtu10mw_only_blade.copy()
|
375
|
+
htc.set_name("DTU_10MW_RWT_only_blade_high_gravity")
|
376
|
+
htc.new_htc_structure.main_body__7.gravity = 100.0
|
377
|
+
mb = MainBody(htc, "blade1")
|
378
|
+
blade_c2def = mb.c2def
|
379
|
+
# Somehow the wind and output blocks are back.
|
380
|
+
htc["wind"].delete()
|
381
|
+
htc["output"].delete()
|
382
|
+
htc.save()
|
383
|
+
return htc, blade_c2def
|
384
|
+
|
385
|
+
|
386
|
+
@pytest.fixture(scope="session")
|
387
|
+
def write_dtu10mw_only_blade_high_gravity_1_body(
|
388
|
+
write_dtu10mw_only_blade_high_gravity,
|
389
|
+
):
|
390
|
+
# Start from the write_dtu10mw_only_blade_high_gravity and then set 1 body.
|
391
|
+
htc_ori, _ = write_dtu10mw_only_blade_high_gravity
|
392
|
+
htc = htc_ori.copy()
|
393
|
+
htc.set_name("DTU_10MW_RWT_only_blade_high_gravity_1_body")
|
394
|
+
htc.new_htc_structure.main_body__7.nbodies = 1
|
395
|
+
mb = MainBody(htc, "blade1")
|
396
|
+
blade_c2def = mb.c2def
|
397
|
+
# Somehow the wind and output blocks are back.
|
398
|
+
htc["wind"].delete()
|
399
|
+
htc["output"].delete()
|
400
|
+
htc.save()
|
401
|
+
return htc, blade_c2def
|
402
|
+
|
403
|
+
|
404
|
+
@pytest.fixture(scope="session")
|
405
|
+
def write_dtu10mw_only_blade_high_gravity_deformed(
|
406
|
+
write_dtu10mw_only_blade,
|
407
|
+
):
|
408
|
+
# Start from the write_dtu10mw_only_blade and then increase the gravity loading.
|
409
|
+
htc = write_dtu10mw_only_blade.copy()
|
410
|
+
htc.set_name("DTU_10MW_RWT_only_blade_high_gravity_deformed")
|
411
|
+
htc.new_htc_structure.main_body__7.gravity = 100.0
|
412
|
+
# Deform c2_def.
|
413
|
+
mb = MainBody(htc, "blade1")
|
414
|
+
blade_c2def = mb.c2def
|
415
|
+
blade_c2def[:, 0] *= 1.3
|
416
|
+
blade_c2def[:, 1] *= 0.8
|
417
|
+
blade_c2def[:, 2] *= 1.2
|
418
|
+
blade_c2def[:, 3] -= 3.42796
|
419
|
+
# Loop over the sec and set c2def.
|
420
|
+
i = 0
|
421
|
+
htc.new_htc_structure.main_body__7.c2_def.sec = f"{i + 1} {blade_c2def[i, 0]:.14f} {blade_c2def[i, 1]:.14f} {blade_c2def[i, 2]:.14f} {blade_c2def[i, 3]:.14f}"
|
422
|
+
for i in range(1, blade_c2def.shape[0]):
|
423
|
+
setattr(htc.new_htc_structure.main_body__7.c2_def, f"sec__{i + 1}", f"{i + 1} {blade_c2def[i, 0]:.14f} {blade_c2def[i, 1]:.14f} {blade_c2def[i, 2]:.14f} {blade_c2def[i, 3]:.14f}")
|
424
|
+
|
425
|
+
# Somehow the wind and output blocks are back.
|
426
|
+
htc["wind"].delete()
|
427
|
+
htc["output"].delete()
|
428
|
+
htc.save()
|
429
|
+
return htc, blade_c2def
|
430
|
+
|
431
|
+
|
294
432
|
@pytest.fixture(scope="session")
|
295
433
|
def h2_dtu_10mw_only_tower(write_dtu10mw_only_tower):
|
296
434
|
h2 = H2Lib(suppress_output=True)
|
@@ -329,6 +467,9 @@ def h2_dtu_10mw_only_blade(write_dtu10mw_only_blade):
|
|
329
467
|
h2 = H2Lib(suppress_output=True)
|
330
468
|
model_path = f"{tfp}DTU_10_MW/"
|
331
469
|
htc_path = "htc/DTU_10MW_RWT_only_blade.htc"
|
470
|
+
h2.add_sensor("mbdy forcevec blade1 1 1 blade1") # 1, 2, 3
|
471
|
+
h2.add_sensor("mbdy momentvec blade1 1 1 blade1") # 4, 5, 6
|
472
|
+
h2.add_sensor("mbdy statevec_new blade1 c2def global absolute 85.0 1.0 0.0 0.0") # 7, 8, 9
|
332
473
|
h2.init(htc_path=htc_path, model_path=model_path)
|
333
474
|
h2.stop_on_error(False)
|
334
475
|
yield h2
|
@@ -346,11 +487,24 @@ def h2_dtu10mw_only_blade_low_max_iter(write_dtu10mw_only_blade_low_max_iter):
|
|
346
487
|
h2.close()
|
347
488
|
|
348
489
|
|
490
|
+
@pytest.fixture(scope="session")
|
491
|
+
def h2_dtu10mw_only_blade_1_body(write_dtu10mw_only_blade_1_body):
|
492
|
+
h2 = H2Lib(suppress_output=True)
|
493
|
+
model_path = f"{tfp}DTU_10_MW/"
|
494
|
+
htc_path = "htc/DTU_10MW_RWT_only_blade_1_body.htc"
|
495
|
+
h2.init(htc_path=htc_path, model_path=model_path)
|
496
|
+
h2.stop_on_error(False)
|
497
|
+
yield h2
|
498
|
+
h2.close()
|
499
|
+
|
500
|
+
|
349
501
|
@pytest.fixture(scope="session")
|
350
502
|
def h2_dtu_10mw_only_blade_rotate_base(write_dtu10mw_only_blade_rotate_base):
|
351
503
|
h2 = H2Lib(suppress_output=True)
|
352
504
|
model_path = f"{tfp}DTU_10_MW/"
|
353
505
|
htc_path = "htc/DTU_10MW_RWT_only_blade_rotate_base.htc"
|
506
|
+
h2.add_sensor("mbdy forcevec blade1 1 1 blade1") # 1, 2, 3
|
507
|
+
h2.add_sensor("mbdy momentvec blade1 1 1 blade1") # 4, 5, 6
|
354
508
|
h2.init(htc_path=htc_path, model_path=model_path)
|
355
509
|
h2.stop_on_error(False)
|
356
510
|
yield h2
|
@@ -358,10 +512,14 @@ def h2_dtu_10mw_only_blade_rotate_base(write_dtu10mw_only_blade_rotate_base):
|
|
358
512
|
|
359
513
|
|
360
514
|
@pytest.fixture(scope="session")
|
361
|
-
def h2_dtu_10mw_only_blade_rotate_relative(
|
515
|
+
def h2_dtu_10mw_only_blade_rotate_relative(
|
516
|
+
write_dtu10mw_only_blade_rotate_relative,
|
517
|
+
):
|
362
518
|
h2 = H2Lib(suppress_output=True)
|
363
519
|
model_path = f"{tfp}DTU_10_MW/"
|
364
520
|
htc_path = "htc/DTU_10MW_RWT_only_blade_rotate_relative.htc"
|
521
|
+
h2.add_sensor("mbdy forcevec blade1 1 1 blade1") # 1, 2, 3
|
522
|
+
h2.add_sensor("mbdy momentvec blade1 1 1 blade1") # 4, 5, 6
|
365
523
|
h2.init(htc_path=htc_path, model_path=model_path)
|
366
524
|
h2.stop_on_error(False)
|
367
525
|
yield h2
|
@@ -369,10 +527,67 @@ def h2_dtu_10mw_only_blade_rotate_relative(write_dtu10mw_only_blade_rotate_relat
|
|
369
527
|
|
370
528
|
|
371
529
|
@pytest.fixture(scope="session")
|
372
|
-
def h2_dtu_10mw_only_blade_rotate_bearing3(
|
530
|
+
def h2_dtu_10mw_only_blade_rotate_bearing3(
|
531
|
+
write_dtu10mw_only_blade_rotate_bearing3,
|
532
|
+
):
|
373
533
|
h2 = H2Lib(suppress_output=True)
|
374
534
|
model_path = f"{tfp}DTU_10_MW/"
|
375
535
|
htc_path = "htc/DTU_10MW_RWT_only_blade_rotate_bearing3.htc"
|
536
|
+
h2.add_sensor("mbdy forcevec blade1 1 1 blade1") # 1, 2, 3
|
537
|
+
h2.add_sensor("mbdy momentvec blade1 1 1 blade1") # 4, 5, 6
|
538
|
+
h2.init(htc_path=htc_path, model_path=model_path)
|
539
|
+
h2.stop_on_error(False)
|
540
|
+
yield h2
|
541
|
+
h2.close()
|
542
|
+
|
543
|
+
|
544
|
+
@pytest.fixture(scope="session")
|
545
|
+
def h2_dtu_10mw_only_blade_uniform_node_distribution(
|
546
|
+
write_dtu10mw_only_blade_uniform_node_distribution,
|
547
|
+
):
|
548
|
+
h2 = H2Lib(suppress_output=True)
|
549
|
+
model_path = f"{tfp}DTU_10_MW/"
|
550
|
+
htc_path = "htc/DTU_10MW_RWT_only_blade_uniform_node_distribution.htc"
|
551
|
+
h2.init(htc_path=htc_path, model_path=model_path)
|
552
|
+
h2.stop_on_error(False)
|
553
|
+
yield h2
|
554
|
+
h2.close()
|
555
|
+
|
556
|
+
|
557
|
+
@pytest.fixture(scope="session")
|
558
|
+
def h2_dtu10mw_only_blade_high_gravity(write_dtu10mw_only_blade_high_gravity):
|
559
|
+
h2 = H2Lib(suppress_output=True)
|
560
|
+
model_path = f"{tfp}DTU_10_MW/"
|
561
|
+
htc_path = "htc/DTU_10MW_RWT_only_blade_high_gravity.htc"
|
562
|
+
h2.add_sensor("mbdy statevec_new blade1 c2def global absolute 90.0 1.0 0.0 0.0") # 1-6
|
563
|
+
h2.add_sensor("mbdy forcevec blade1 1 1 blade1") # 7, 8, 9
|
564
|
+
h2.add_sensor("mbdy momentvec blade1 1 1 blade1") # 10, 11, 12
|
565
|
+
h2.init(htc_path=htc_path, model_path=model_path)
|
566
|
+
h2.stop_on_error(False)
|
567
|
+
yield h2
|
568
|
+
h2.close()
|
569
|
+
|
570
|
+
|
571
|
+
@pytest.fixture(scope="session")
|
572
|
+
def h2_dtu10mw_only_blade_high_gravity_deformed(write_dtu10mw_only_blade_high_gravity_deformed):
|
573
|
+
h2 = H2Lib(suppress_output=True)
|
574
|
+
model_path = f"{tfp}DTU_10_MW/"
|
575
|
+
htc_path = "htc/DTU_10MW_RWT_only_blade_high_gravity_deformed.htc"
|
576
|
+
h2.add_sensor("mbdy statevec_new blade1 c2def global absolute 90.0 1.0 0.0 0.0") # 1-6
|
577
|
+
h2.add_sensor("mbdy forcevec blade1 1 1 blade1") # 7, 8, 9
|
578
|
+
h2.add_sensor("mbdy momentvec blade1 1 1 blade1") # 10, 11, 12
|
579
|
+
h2.init(htc_path=htc_path, model_path=model_path)
|
580
|
+
h2.stop_on_error(False)
|
581
|
+
yield h2
|
582
|
+
h2.close()
|
583
|
+
|
584
|
+
|
585
|
+
@pytest.fixture(scope="session")
|
586
|
+
def h2_dtu10mw_only_blade_high_gravity_1_body(write_dtu10mw_only_blade_high_gravity_1_body):
|
587
|
+
h2 = H2Lib(suppress_output=True)
|
588
|
+
model_path = f"{tfp}DTU_10_MW/"
|
589
|
+
htc_path = "htc/DTU_10MW_RWT_only_blade_high_gravity_1_body.htc"
|
590
|
+
h2.add_sensor("mbdy statevec_new blade1 c2def global absolute 90.0 1.0 0.0 0.0")
|
376
591
|
h2.init(htc_path=htc_path, model_path=model_path)
|
377
592
|
h2.stop_on_error(False)
|
378
593
|
yield h2
|
@@ -0,0 +1,111 @@
|
|
1
|
+
from h2lib_tests import tfp
|
2
|
+
import pytest
|
3
|
+
|
4
|
+
from h2lib._h2lib import H2LibThread, H2Lib
|
5
|
+
from h2lib.distributed_sections import DistributedSections, LinkType
|
6
|
+
import numpy as np
|
7
|
+
from numpy import testing as npt
|
8
|
+
import matplotlib.pyplot as plt
|
9
|
+
|
10
|
+
|
11
|
+
def test_distributed_sections():
|
12
|
+
# apply force on tower and check deflected tower position
|
13
|
+
with H2Lib(suppress_output=0) as h2:
|
14
|
+
model_path = f"{tfp}DTU_10_MW/"
|
15
|
+
htc_path = f"{tfp}DTU_10_MW/htc/DTU_10MW_RWT.htc"
|
16
|
+
h2.init(htc_path=htc_path, model_path=model_path)
|
17
|
+
|
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
|
+
ds = h2.get_distributed_sections(LinkType.BLADE, link_id=2)
|
34
|
+
sec_pos, sec_tsg = h2.get_distributed_section_position_orientation(ds, mainbody_coo_nr=0)
|
35
|
+
npt.assert_array_almost_equal(sec_pos[40], [70.58938502, -16.98280589, -77.95555399], 6)
|
36
|
+
npt.assert_array_almost_equal(sec_tsg[40], [[0.49371347, 0.09098716, 0.86485163],
|
37
|
+
[0.12164175, 0.97750846, -0.17228029],
|
38
|
+
[-0.86107508, 0.19025917, 0.47154125]], 6)
|
39
|
+
|
40
|
+
with pytest.raises(AssertionError, match=r"'missing' does not exist. Valid names are \['tower',"):
|
41
|
+
h2.add_distributed_sections('missing', [0, .4, .8, 1])
|
42
|
+
mbdy_name_dict = h2.get_mainbody_name_dict()
|
43
|
+
mbdy_name_lst = list(mbdy_name_dict.keys())
|
44
|
+
ds_dict = {mbdy_name: h2.add_distributed_sections(mbdy_name, [0, .4, .8, 1])
|
45
|
+
for mbdy_name in mbdy_name_lst}
|
46
|
+
h2.initialize_distributed_sections()
|
47
|
+
ds_dict['blade1_aero'] = h2.get_distributed_sections(LinkType.BLADE, 1)
|
48
|
+
|
49
|
+
ax = plt.figure().add_subplot(projection='3d')
|
50
|
+
for name, ds in ds_dict.items():
|
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
|
+
|
63
|
+
# print(ds_lst[6].name, ds_lst[3].name)
|
64
|
+
# mb_pos, b1_mb_tbg, b1_sec_pos, sec_tsb = h2.get_distributed_section_position_orientation(ds_lst[6])
|
65
|
+
# hub_id = h2.get_mainbody_name_dict()['hub1']
|
66
|
+
# print(hub_id)
|
67
|
+
# print(h2.get_mainbody_position_orientation(hub_id))
|
68
|
+
# print(b1_sec_pos[[0, -1]])
|
69
|
+
|
70
|
+
sec_pos, sec_tsb = h2.get_distributed_section_position_orientation(ds_dict['blade1'])
|
71
|
+
# print(np.round(mb_pos + [mb_tbg@sp for sp in sec_pos], 1).tolist())
|
72
|
+
|
73
|
+
print(np.round(sec_pos, 1).tolist())
|
74
|
+
npt.assert_array_almost_equal(sec_pos, [[-0.0, -6.9, -121.8],
|
75
|
+
[0.8, -5.7, -156.4],
|
76
|
+
[0.4, -5.8, -190.9],
|
77
|
+
[0.1, -6.5, -208.2]], 1)
|
78
|
+
|
79
|
+
sec_pos, sec_tsb = h2.get_distributed_section_position_orientation(ds_dict['blade1_aero'])
|
80
|
+
|
81
|
+
idx = [0, 10, 20, 30, 40, 49]
|
82
|
+
print(np.round(sec_pos[idx], 2).tolist())
|
83
|
+
npt.assert_array_almost_equal(sec_pos[idx], [[1.3, -6.61, -121.78],
|
84
|
+
[1.37, -6.27, -130.32],
|
85
|
+
[2.33, -5.65, -152.69],
|
86
|
+
[1.51, -5.61, -179.95],
|
87
|
+
[0.86, -6.2, -201.24],
|
88
|
+
[0.29, -6.53, -208.25]], 2)
|
89
|
+
|
90
|
+
frc = np.zeros((4, 3))
|
91
|
+
frc[:, 1] = 100000
|
92
|
+
h2.set_distributed_section_force_and_moment(ds_dict['tower'], sec_frc=frc, sec_mom=np.zeros((4, 3)))
|
93
|
+
|
94
|
+
h2.run(2)
|
95
|
+
for ds in ds_dict.values():
|
96
|
+
sec_pos, sec_tsb = h2.get_distributed_section_position_orientation(ds)
|
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')
|
104
|
+
np.set_printoptions(linewidth=200)
|
105
|
+
sec_pos, sec_tsb = h2.get_distributed_section_position_orientation(ds_dict['tower'])
|
106
|
+
# print(np.round(mb_pos + [mb_tbg@sp for sp in sec_pos], 1).tolist())
|
107
|
+
|
108
|
+
npt.assert_array_almost_equal(sec_pos, [[0.0, 0.0, 0.0],
|
109
|
+
[-0.0, 0.7, -46.2],
|
110
|
+
[-0.0, 2.4, -92.5],
|
111
|
+
[0.0, 3.5, -115.6]], 1)
|
@@ -55,7 +55,7 @@ def test_ellipsys_dummy_workflow_1wt():
|
|
55
55
|
htc.set_name(f'wt{i}')
|
56
56
|
htc.save()
|
57
57
|
|
58
|
-
h2.init_AD(htc_path=f'htc/wt0.htc', model_path=tfp + 'DTU_10_MW',
|
58
|
+
h2.init_AD(htc_path=f'htc/wt0.htc', model_path=tfp + 'DTU_10_MW', tiploss2_shen_c2=28)
|
59
59
|
wt_pos = np.array([0, 0, 0])
|
60
60
|
|
61
61
|
while True:
|
@@ -80,7 +80,8 @@ def test_ellipsys_dummy_workflow():
|
|
80
80
|
htc.set_name(f'wt{i}')
|
81
81
|
htc.save()
|
82
82
|
|
83
|
-
h2.init_AD(htc_path=[f'htc/wt{i}.htc' for i in range(N)], model_path=tfp + 'DTU_10_MW',
|
83
|
+
h2.init_AD(htc_path=[f'htc/wt{i}.htc' for i in range(N)], model_path=tfp + 'DTU_10_MW',
|
84
|
+
tiploss2_shen_c2=28, tiploss2_shen_h=0.5)
|
84
85
|
wt_pos = np.array([[0, 0, 0], [0, 500, 0], [0, 1000, 0], [0, 1500, 0]])
|
85
86
|
|
86
87
|
while True:
|
@@ -0,0 +1,68 @@
|
|
1
|
+
;DTU_10MW_RWT, version 9, 25-09-2017, mhha
|
2
|
+
;
|
3
|
+
begin simulation;
|
4
|
+
time_stop 10.0;
|
5
|
+
solvertype 1; (newmark)
|
6
|
+
on_no_convergence continue;
|
7
|
+
convergence_limits 1000 1 1e-07;
|
8
|
+
;logfile ./log/DTU_10MW_RWT_ver09.log ;
|
9
|
+
log_deltat 1;
|
10
|
+
begin newmark;
|
11
|
+
deltat 0.01;
|
12
|
+
end newmark;
|
13
|
+
end simulation;
|
14
|
+
;
|
15
|
+
;----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
16
|
+
begin new_htc_structure;
|
17
|
+
; beam_output_file_name ./log/DTU_10MW_RWT_beam.dat; Optional - Calculated beam properties of the bodies are written to file
|
18
|
+
; body_output_file_name ./log/DTU_10MW_RWT_body.dat; Optional - Body initial position and orientation are written to file
|
19
|
+
; body_eigenanalysis_file_name ./eig/DTU_10MW_RWT_body_eigen.dat;
|
20
|
+
; structure_eigenanalysis_file_name ./eig/DTU_10MW_RWT_strc_eigen.dat ;
|
21
|
+
;-------------------------------------------------------------------------------------------------------------------------------
|
22
|
+
;-------------------------------------------------------------------------------------------------------------------------------
|
23
|
+
begin main_body; tower 115m
|
24
|
+
name tower;
|
25
|
+
type timoschenko;
|
26
|
+
nbodies 3;
|
27
|
+
node_distribution c2_def;
|
28
|
+
damping_posdef 0 0 0 0.00412 0.00412 0.00045; Mx My Mz Kx Ky Kz , M´s raises overall level, K´s raises high freguency level "tuned by Larh"
|
29
|
+
begin timoschenko_input;
|
30
|
+
filename ./data/DTU_10MW_RWT_Tower_st.dat;
|
31
|
+
set 1 1;
|
32
|
+
end timoschenko_input;
|
33
|
+
begin c2_def; Definition of centerline (main_body coordinates)
|
34
|
+
nsec 11;
|
35
|
+
sec 1 0 0 0 0; x,y,z,twist
|
36
|
+
sec 2 0 0 -11.5 0;
|
37
|
+
sec 3 0 0 -23 0;
|
38
|
+
sec 4 0 0 -34.5 0;
|
39
|
+
sec 5 0 0 -46 0;
|
40
|
+
sec 6 0 0 -57.5 0;
|
41
|
+
sec 7 0 0 -69 0;
|
42
|
+
sec 8 0 0 -80.5 0;
|
43
|
+
sec 9 0 0 -92 0;
|
44
|
+
sec 10 0 0 -103.5 0;
|
45
|
+
sec 11 0 0 -115.63 0;
|
46
|
+
end c2_def;
|
47
|
+
end main_body;
|
48
|
+
;
|
49
|
+
begin orientation;
|
50
|
+
begin base;
|
51
|
+
body tower;
|
52
|
+
inipos 0 0 0; initial position of node 1
|
53
|
+
body_eulerang 0 0 0;
|
54
|
+
end base;
|
55
|
+
;
|
56
|
+
end orientation;
|
57
|
+
;-------------------------------------------------------------------------------------------------------------------------------
|
58
|
+
begin constraint;
|
59
|
+
;
|
60
|
+
begin fix0; fixed to ground in translation and rotation of node 1
|
61
|
+
body tower;
|
62
|
+
end fix0;
|
63
|
+
;
|
64
|
+
end constraint;
|
65
|
+
;
|
66
|
+
end new_htc_structure;
|
67
|
+
;----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
68
|
+
exit;
|
h2lib_tests/test_h2rotor.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import os
|
2
|
-
from h2lib._h2lib import H2Lib, MultiH2Lib
|
2
|
+
from h2lib._h2lib import H2Lib, MultiH2Lib, H2LibThread
|
3
3
|
|
4
4
|
from numpy import testing as npt
|
5
5
|
import pytest
|
@@ -40,7 +40,39 @@ def test_get_bem_grid(h2):
|
|
40
40
|
azi, rad = h2.get_bem_grid()
|
41
41
|
|
42
42
|
npt.assert_array_almost_equal(np.roll(np.linspace(-np.pi, np.pi, 17)[1:], 9), azi)
|
43
|
-
npt.assert_array_almost_equal([3.09929662, 11.4350243, 33.76886193, 60.8641887, 82.01217305], rad[::10])
|
43
|
+
npt.assert_array_almost_equal([3.09929662, 11.4350243, 33.76886193, 60.8641887, 82.01217305], rad[::10], 4)
|
44
|
+
|
45
|
+
|
46
|
+
def test_mainbody_names(h2: H2LibThread):
|
47
|
+
assert h2.get_mainbody_name_dict() == {'tower': 1, 'towertop': 2, 'shaft': 3, 'hub1': 4, 'hub2': 5, 'hub3': 6,
|
48
|
+
'blade1': 7, 'blade2': 8, 'blade3': 9}
|
49
|
+
|
50
|
+
|
51
|
+
def test_get_mainbody_position_orientation(h2: H2LibThread):
|
52
|
+
mainbody_coo_nr = 0
|
53
|
+
mb_dict = h2.get_mainbody_name_dict()
|
54
|
+
if 0:
|
55
|
+
ax = plt.figure().add_subplot(projection='3d')
|
56
|
+
for name, mainbody_nr in mb_dict.items():
|
57
|
+
pos, ori = h2.get_mainbody_position_orientation(mainbody_nr, mainbody_coo_nr)
|
58
|
+
ax.plot(*pos, 'o', label=name)
|
59
|
+
for (exyz), c in zip(ori, 'rgb'):
|
60
|
+
ax.plot(*np.array([pos, pos + exyz * 10]).T, color=c)
|
61
|
+
plt.axis('equal')
|
62
|
+
plt.legend()
|
63
|
+
plt.show()
|
64
|
+
|
65
|
+
pos, ori = h2.get_mainbody_position_orientation(mb_dict['blade2'], 0)
|
66
|
+
npt.assert_array_almost_equal(pos, [2.42817657, -7.31388712, -117.62523996], 6)
|
67
|
+
npt.assert_array_almost_equal(ori, [[0.49826649, 0.03782549, 0.86619844],
|
68
|
+
[0.07555272, 0.99335333, -0.08683861],
|
69
|
+
[-0.86372582, 0.10871241, 0.49209686]], 6)
|
70
|
+
|
71
|
+
pos, ori = h2.get_mainbody_position_orientation(mb_dict['hub2'], 0)
|
72
|
+
npt.assert_array_almost_equal(pos, [-2.42631565e-09, -7.07298239e+00, -1.18998544e+02], 6)
|
73
|
+
npt.assert_array_almost_equal(ori, [[0.49826698, 0.03781904, 0.86619844],
|
74
|
+
[0.07556557, 0.99335236, -0.0868386],
|
75
|
+
[-0.86372441, 0.10872359, 0.49209687]], 6)
|
44
76
|
|
45
77
|
|
46
78
|
def test_induction(h2):
|
h2lib_tests/test_lin.py
CHANGED
@@ -83,10 +83,7 @@ def test_sys_eig_no_damping_eigv(h2_dtu_10mw_only_blade):
|
|
83
83
|
assert eig_vec.shape == (n_modes, n_rdofs)
|
84
84
|
assert eig_val.dtype == np.float64
|
85
85
|
assert eig_vec.dtype == np.float64
|
86
|
-
npt.assert_allclose(
|
87
|
-
eig_val,
|
88
|
-
np.array([3.835311, 5.846144, 10.92697, 17.353821]),
|
89
|
-
)
|
86
|
+
npt.assert_allclose(eig_val, [3.835311, 5.846144, 10.92697, 17.353821], atol=2e-6)
|
90
87
|
|
91
88
|
|
92
89
|
def test_sys_eig_with_damping(h2_dtu_10mw_only_blade):
|
@@ -156,29 +153,18 @@ def test_sys_eig_encrypted(h2_dtu_10mw_only_tower_encrypted):
|
|
156
153
|
eig_val = h2_dtu_10mw_only_tower_encrypted.get_system_eigenvalues_and_eigenvectors(
|
157
154
|
n_modes=n_modes, n_rdofs=n_rdofs, include_damping=True
|
158
155
|
)
|
159
|
-
npt.assert_allclose(
|
160
|
-
freq,
|
161
|
-
np.array([0.770592, 0.770592, 3.449993, 3.449993]),
|
162
|
-
rtol=1e-6,
|
163
|
-
)
|
156
|
+
npt.assert_allclose(freq, [0.770592, 0.770592, 3.449993, 3.449993], atol=1e-5)
|
164
157
|
|
165
158
|
npt.assert_allclose(
|
166
159
|
damp,
|
167
160
|
np.array([0.010006, 0.010006, 0.044675, 0.044675]),
|
168
161
|
atol=1e-6,
|
169
162
|
)
|
170
|
-
npt.assert_allclose(
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
-0.048444 - 4.84153j,
|
176
|
-
-0.968409 - 21.6553j,
|
177
|
-
-0.968409 - 21.6553j,
|
178
|
-
]
|
179
|
-
),
|
180
|
-
atol=1e-6,
|
181
|
-
)
|
163
|
+
npt.assert_allclose(eig_val, [-0.048444 - 4.84153j,
|
164
|
+
-0.048444 - 4.84153j,
|
165
|
+
-0.968409 - 21.6553j,
|
166
|
+
-0.968409 - 21.6553j], atol=1e-5,
|
167
|
+
)
|
182
168
|
|
183
169
|
|
184
170
|
def test_get_system_matrices_encrypted(h2_dtu_10mw_only_tower_encrypted):
|
@@ -59,70 +59,59 @@ def test_static_solver_run_fail(h2_dtu10mw_only_blade_low_max_iter):
|
|
59
59
|
|
60
60
|
def test_static_solver_run_1(h2_dtu_10mw_only_blade):
|
61
61
|
# Use gravity to deflect the clamped blade.
|
62
|
-
# Add a sensor for the blade root moment, in this case only due to gravity.
|
63
|
-
id = h2_dtu_10mw_only_blade.add_sensor("mbdy momentvec blade1 1 1 blade1")
|
64
62
|
|
65
63
|
# Run the static solver.
|
66
64
|
h2_dtu_10mw_only_blade.solver_static_run(reset_structure=True)
|
67
65
|
|
68
|
-
#
|
69
|
-
h2_dtu_10mw_only_blade.
|
70
|
-
val = h2_dtu_10mw_only_blade.get_sensor_values(id)
|
71
|
-
# Test against: initial_condition 2; followed by time simulaiton.
|
66
|
+
# Test against: initial_condition 2; followed by time simulation.
|
67
|
+
val = h2_dtu_10mw_only_blade.get_sensor_values((4, 5, 6))
|
72
68
|
npt.assert_allclose(
|
73
|
-
val, np.array([-1.
|
69
|
+
val, np.array([-1.071480e+04, -3.974322e-02, -4.064080e+01]), rtol=1e-6
|
74
70
|
)
|
75
71
|
|
76
72
|
|
77
73
|
def test_static_solver_run_2(h2_dtu_10mw_only_blade_rotate_base):
|
78
74
|
# Apply centrifugal loading with the base command.
|
79
|
-
# Add a sensor for the blade root force, in this case only due to centrifugal force.
|
80
|
-
id = h2_dtu_10mw_only_blade_rotate_base.add_sensor(
|
81
|
-
"mbdy forcevec blade1 1 1 blade1"
|
82
|
-
)
|
83
75
|
|
84
76
|
# Run the static solver.
|
85
77
|
h2_dtu_10mw_only_blade_rotate_base.solver_static_run(reset_structure=True)
|
86
78
|
|
87
|
-
# Do 1 step to get the output.
|
88
|
-
h2_dtu_10mw_only_blade_rotate_base.step()
|
89
|
-
val = h2_dtu_10mw_only_blade_rotate_base.get_sensor_values(id)
|
90
79
|
# Test against: result at the time of writing.
|
91
|
-
|
80
|
+
val = h2_dtu_10mw_only_blade_rotate_base.get_sensor_values((1, 2, 3))
|
81
|
+
npt.assert_allclose(val, np.array([-5.02001147e+00, 1.87207970e-01, 1.09028022e+03]))
|
92
82
|
|
93
83
|
|
94
84
|
def test_static_solver_run_3(h2_dtu_10mw_only_blade_rotate_relative):
|
95
85
|
# Apply centrifugal loading with the relative command.
|
96
|
-
# Add a sensor for the blade root force, in this case only due to centrifugal force.
|
97
|
-
id = h2_dtu_10mw_only_blade_rotate_relative.add_sensor(
|
98
|
-
"mbdy forcevec blade1 1 1 blade1"
|
99
|
-
)
|
100
86
|
|
101
87
|
# Run the static solver.
|
102
88
|
h2_dtu_10mw_only_blade_rotate_relative.solver_static_run(reset_structure=True)
|
103
89
|
|
104
|
-
# Do 1 step to get the output.
|
105
|
-
h2_dtu_10mw_only_blade_rotate_relative.step()
|
106
|
-
val = h2_dtu_10mw_only_blade_rotate_relative.get_sensor_values(id)
|
107
90
|
# Test against: result at the time of writing.
|
108
|
-
|
91
|
+
val = h2_dtu_10mw_only_blade_rotate_relative.get_sensor_values((1, 2, 3))
|
92
|
+
npt.assert_allclose(val, np.array([-5.02001146e+00, 1.87207914e-01, 1.09028022e+03]))
|
109
93
|
|
110
94
|
|
111
95
|
def test_static_solver_run_4(h2_dtu_10mw_only_blade_rotate_bearing3):
|
112
96
|
# Apply centrifugal loading with the bearing3 command.
|
113
|
-
# Add a sensor for the blade root moment, in this case only due to centrifugal force.
|
114
|
-
id = h2_dtu_10mw_only_blade_rotate_bearing3.add_sensor(
|
115
|
-
"mbdy momentvec blade1 1 1 blade1"
|
116
|
-
)
|
117
97
|
|
118
98
|
# Run the static solver.
|
119
99
|
h2_dtu_10mw_only_blade_rotate_bearing3.solver_static_run(reset_structure=True)
|
120
100
|
|
121
|
-
# Do 1 step to get the output.
|
122
|
-
h2_dtu_10mw_only_blade_rotate_bearing3.step()
|
123
|
-
val = h2_dtu_10mw_only_blade_rotate_bearing3.get_sensor_values(id)
|
124
101
|
# Test against: result at the time of writing.
|
125
|
-
|
102
|
+
# The static solver does not work with bearing3 and we get 0 load.
|
103
|
+
val = h2_dtu_10mw_only_blade_rotate_bearing3.get_sensor_values((4, 5, 6))
|
104
|
+
npt.assert_allclose(val, np.array([0., 0., 0.]))
|
105
|
+
|
106
|
+
# This is what happens by simulating for a long time.
|
107
|
+
# The simulation must be long because the rotor speed is applied impulsively
|
108
|
+
# and we get a very long initial transient.
|
109
|
+
# h2_dtu_10mw_only_blade_rotate_bearing3.run(500.0)
|
110
|
+
# npt.assert_allclose(h2_dtu_10mw_only_blade_rotate_bearing3.get_sensor_values(id),
|
111
|
+
# np.array([-757.65278331, 4.16512026, 6.05878323]))
|
112
|
+
# h2_dtu_10mw_only_blade_rotate_bearing3.run(1000.0)
|
113
|
+
# npt.assert_allclose(h2_dtu_10mw_only_blade_rotate_bearing3.get_sensor_values(id),
|
114
|
+
# np.array([-758.77170923, 4.31107218, 6.05914454]))
|
126
115
|
|
127
116
|
|
128
117
|
def test_static_solver_run_no_reset(h2_dtu_10mw_only_blade):
|
@@ -160,34 +149,25 @@ def test_static_solver_run_with_reset(h2_dtu_10mw_only_blade):
|
|
160
149
|
)
|
161
150
|
|
162
151
|
|
163
|
-
def test_structure_reset():
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
h2.step()
|
186
|
-
val_actual = h2.get_sensor_values(id)
|
187
|
-
npt.assert_raises(AssertionError, npt.assert_allclose, val_actual, val_desired)
|
188
|
-
|
189
|
-
# Reset the structure and check that we match the reference.
|
190
|
-
h2.structure_reset()
|
191
|
-
h2.step()
|
192
|
-
val_actual = h2.get_sensor_values(id)
|
193
|
-
npt.assert_allclose(val_actual, val_desired)
|
152
|
+
def test_structure_reset(h2_dtu10mw_only_blade_high_gravity):
|
153
|
+
h2 = h2_dtu10mw_only_blade_high_gravity
|
154
|
+
|
155
|
+
id = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
|
156
|
+
h2.step()
|
157
|
+
val_1 = h2.get_sensor_values(id)
|
158
|
+
h2.solver_static_run(reset_structure=True)
|
159
|
+
val_2 = h2.get_sensor_values(id)
|
160
|
+
h2.structure_reset()
|
161
|
+
h2.step()
|
162
|
+
val_3 = h2.get_sensor_values(id)
|
163
|
+
|
164
|
+
with npt.assert_raises(AssertionError):
|
165
|
+
npt.assert_allclose(val_1, val_2)
|
166
|
+
npt.assert_allclose(val_1, val_3)
|
167
|
+
|
168
|
+
|
169
|
+
# %% Main.
|
170
|
+
|
171
|
+
if __name__ == "__main__":
|
172
|
+
# pytest.main([__file__])
|
173
|
+
pytest.main([__file__, "-k test_structure_reset"])
|
@@ -108,6 +108,63 @@ def test_get_body_rotation_tensor_encrypted(h2_dtu_10mw_only_tower_encrypted):
|
|
108
108
|
h2_dtu_10mw_only_tower_encrypted.get_body_rotation_tensor(ibdy=0)
|
109
109
|
|
110
110
|
|
111
|
+
def test_body_output_mass_body_does_not_exist(h2_dtu_10mw_only_tower):
|
112
|
+
with pytest.raises(IndexError, match="BODY_DOES_NOT_EXIST"):
|
113
|
+
h2_dtu_10mw_only_tower.get_body_rotation_tensor(ibdy=1000)
|
114
|
+
|
115
|
+
|
116
|
+
def test_body_output_mass_encrypted(h2_dtu_10mw_only_tower_encrypted):
|
117
|
+
with pytest.raises(RuntimeError, match="STRUCTURE_IS_CONFIDENTIAL"):
|
118
|
+
h2_dtu_10mw_only_tower_encrypted.body_output_mass(ibdy=0)
|
119
|
+
|
120
|
+
|
121
|
+
def test_body_output_mass(h2_dtu10mw_only_blade_1_body):
|
122
|
+
body_mass, body_inertia, cog_global_frame, cog_body_frame = h2_dtu10mw_only_blade_1_body.body_output_mass(ibdy=0)
|
123
|
+
|
124
|
+
npt.assert_allclose(body_mass, 41715.74898702217)
|
125
|
+
npt.assert_allclose(
|
126
|
+
body_inertia,
|
127
|
+
np.array(
|
128
|
+
[
|
129
|
+
4.59166245e07,
|
130
|
+
4.59258429e07,
|
131
|
+
1.68059539e05,
|
132
|
+
-5.46069861e03,
|
133
|
+
-1.63069037e05,
|
134
|
+
-8.35539506e05,
|
135
|
+
]
|
136
|
+
),
|
137
|
+
)
|
138
|
+
npt.assert_allclose(
|
139
|
+
cog_global_frame, np.array([-0.12113986, -26.17867389, -0.3688314])
|
140
|
+
)
|
141
|
+
npt.assert_allclose(
|
142
|
+
cog_body_frame, np.array([-0.12113986, -0.3688314, 26.17867389])
|
143
|
+
)
|
144
|
+
|
145
|
+
|
146
|
+
def test_body_output_element_body_does_not_exist(h2_dtu_10mw_only_tower):
|
147
|
+
with pytest.raises(IndexError, match="BODY_DOES_NOT_EXIST"):
|
148
|
+
h2_dtu_10mw_only_tower.body_output_element(ibdy=1000, ielem=0)
|
149
|
+
|
150
|
+
|
151
|
+
def test_body_output_element_element_does_not_exist(h2_dtu_10mw_only_tower):
|
152
|
+
with pytest.raises(IndexError, match="ELEMENT_DOES_NOT_EXIST"):
|
153
|
+
h2_dtu_10mw_only_tower.body_output_element(ibdy=0, ielem=1000)
|
154
|
+
|
155
|
+
|
156
|
+
def test_body_output_element_encrypted(h2_dtu_10mw_only_tower_encrypted):
|
157
|
+
with pytest.raises(RuntimeError, match="STRUCTURE_IS_CONFIDENTIAL"):
|
158
|
+
h2_dtu_10mw_only_tower_encrypted.body_output_element(ibdy=0, ielem=0)
|
159
|
+
|
160
|
+
|
161
|
+
def test_body_output_element(h2_dtu10mw_only_blade_1_body):
|
162
|
+
mass, stiffness, damping = h2_dtu10mw_only_blade_1_body.body_output_element(ibdy=0, ielem=0)
|
163
|
+
assert mass.shape == (12, 12)
|
164
|
+
assert stiffness.shape == (12, 12)
|
165
|
+
assert damping.shape == (12, 12)
|
166
|
+
|
167
|
+
|
111
168
|
def test_set_orientation_base_not_found(h2_dtu_10mw_only_tower):
|
112
169
|
with pytest.raises(ValueError, match="MAIN_BODY_NOT_FOUND"):
|
113
170
|
h2_dtu_10mw_only_tower.set_orientation_base(main_body="blade")
|
@@ -157,9 +214,6 @@ def test_set_orientation_base_without_reset_orientation(
|
|
157
214
|
|
158
215
|
|
159
216
|
def test_set_orientation_base_speed(h2_dtu_10mw_only_blade):
|
160
|
-
# Add a sensor for the blade root force, in this case only due to centrifugal force.
|
161
|
-
id = h2_dtu_10mw_only_blade.add_sensor("mbdy forcevec blade1 1 1 blade1")
|
162
|
-
|
163
217
|
# Set speed.
|
164
218
|
h2_dtu_10mw_only_blade.set_orientation_base(
|
165
219
|
main_body="blade1",
|
@@ -171,11 +225,11 @@ def test_set_orientation_base_speed(h2_dtu_10mw_only_blade):
|
|
171
225
|
|
172
226
|
# Do 1 step to get the output.
|
173
227
|
h2_dtu_10mw_only_blade.step()
|
174
|
-
val = h2_dtu_10mw_only_blade.get_sensor_values(
|
228
|
+
val = h2_dtu_10mw_only_blade.get_sensor_values((1, 2, 3))
|
175
229
|
|
176
230
|
# Test against: result at the time of writing.
|
177
231
|
# The result is close, but not identical, to test_static_solver_run_2.
|
178
|
-
npt.assert_allclose(val,
|
232
|
+
npt.assert_allclose(val, [10879.363449, 793.564425, 1034.896613])
|
179
233
|
|
180
234
|
# Reset speed.
|
181
235
|
h2_dtu_10mw_only_blade.set_orientation_base(
|
@@ -184,6 +238,241 @@ def test_set_orientation_base_speed(h2_dtu_10mw_only_blade):
|
|
184
238
|
)
|
185
239
|
|
186
240
|
|
241
|
+
def test_set_c2_def_main_body_not_found(h2_dtu_10mw_only_blade):
|
242
|
+
with pytest.raises(ValueError, match="MAIN_BODY_NOT_FOUND"):
|
243
|
+
h2_dtu_10mw_only_blade.set_c2_def(
|
244
|
+
"tower",
|
245
|
+
np.array([[0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0]]),
|
246
|
+
)
|
247
|
+
|
248
|
+
|
249
|
+
def test_set_c2_def_too_few_sections(h2_dtu_10mw_only_blade):
|
250
|
+
with pytest.raises(ValueError, match="TOO_FEW_SECTIONS_IN_C2DEF"):
|
251
|
+
h2_dtu_10mw_only_blade.set_c2_def("blade1", np.zeros((1, 4)))
|
252
|
+
|
253
|
+
|
254
|
+
def test_set_c2_def_different_nsec(h2_dtu_10mw_only_blade):
|
255
|
+
with pytest.raises(ValueError, match="DIFFERENT_NSEC"):
|
256
|
+
h2_dtu_10mw_only_blade.set_c2_def(
|
257
|
+
"blade1",
|
258
|
+
np.array([[0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0]]),
|
259
|
+
)
|
260
|
+
|
261
|
+
|
262
|
+
def test_set_c2_def_uniform_node_distribution(
|
263
|
+
h2_dtu_10mw_only_blade_uniform_node_distribution,
|
264
|
+
):
|
265
|
+
with pytest.raises(
|
266
|
+
NotImplementedError,
|
267
|
+
):
|
268
|
+
h2_dtu_10mw_only_blade_uniform_node_distribution.set_c2_def(
|
269
|
+
"blade1", np.ones((27, 4), dtype=np.float64, order="F")
|
270
|
+
)
|
271
|
+
|
272
|
+
|
273
|
+
def test_set_c2_def_beam_too_short(h2_dtu_10mw_only_blade):
|
274
|
+
c2def = np.zeros((27, 4), dtype=np.float64, order="F")
|
275
|
+
c2def[:, 2] = np.linspace(0.0, 1e-9, c2def.shape[0])
|
276
|
+
with pytest.raises(ValueError, match="BEAM_TOO_SHORT"):
|
277
|
+
h2_dtu_10mw_only_blade.set_c2_def("blade1", c2def)
|
278
|
+
|
279
|
+
|
280
|
+
def test_set_c2_def_blade_static_back_to_original(
|
281
|
+
write_dtu10mw_only_blade_high_gravity,
|
282
|
+
h2_dtu10mw_only_blade_high_gravity,
|
283
|
+
):
|
284
|
+
# This test will:
|
285
|
+
# 1. Take the DTU 10 MW blade subjected to high gravity loading.
|
286
|
+
# 2. Compute the static solution.
|
287
|
+
# 3. Change c2_def a few times and re-compute the static solution.
|
288
|
+
# 4. Revert it to the original one and check that the static solution matches the one from step 2.
|
289
|
+
|
290
|
+
# Get the clamped DTU 10 MW blade subjected to high gravity loading.
|
291
|
+
_, blade_c2def = write_dtu10mw_only_blade_high_gravity
|
292
|
+
h2 = h2_dtu10mw_only_blade_high_gravity
|
293
|
+
|
294
|
+
# Sensors 1 to 6 are the displacement and rotation of the blade tip.
|
295
|
+
# h2.get_sensor_info(1)
|
296
|
+
|
297
|
+
# Run the static solver and get the blade tip position and rotation.
|
298
|
+
h2.solver_static_run(reset_structure=True)
|
299
|
+
blade_tip_desired = h2.get_sensor_values((1, 2, 3, 4, 5, 6))
|
300
|
+
|
301
|
+
# Change blade length and run the static solver.
|
302
|
+
c2def_new = blade_c2def.copy()
|
303
|
+
for factor in (0.6, 0.7, 0.8, 0.9, 1.1, 1.2, 1.3, 1.4):
|
304
|
+
c2def_new[:, 2] = factor * blade_c2def[:, 2]
|
305
|
+
h2.set_c2_def("blade1", c2def_new)
|
306
|
+
# Since we are smoothly changing c2_def, it makes sense to start the static solver from the last converged solution.
|
307
|
+
h2.solver_static_run(reset_structure=False)
|
308
|
+
|
309
|
+
# Get new blade displacement.
|
310
|
+
blade_tip_actual = h2.get_sensor_values((1, 2, 3, 4, 5, 6))
|
311
|
+
|
312
|
+
# Must differ from blade_tip_desired.
|
313
|
+
with npt.assert_raises(AssertionError):
|
314
|
+
npt.assert_allclose(blade_tip_actual, blade_tip_desired)
|
315
|
+
|
316
|
+
# Restore blade c2_def.
|
317
|
+
h2.set_c2_def("blade1", blade_c2def)
|
318
|
+
h2.solver_static_run(reset_structure=True)
|
319
|
+
blade_tip_actual = h2.get_sensor_values((1, 2, 3, 4, 5, 6))
|
320
|
+
npt.assert_allclose(blade_tip_actual, blade_tip_desired)
|
321
|
+
|
322
|
+
|
323
|
+
def test_set_c2_def_blade_static_deformed(
|
324
|
+
write_dtu10mw_only_blade_high_gravity,
|
325
|
+
write_dtu10mw_only_blade_high_gravity_deformed,
|
326
|
+
h2_dtu10mw_only_blade_high_gravity,
|
327
|
+
h2_dtu10mw_only_blade_high_gravity_deformed,
|
328
|
+
):
|
329
|
+
# Solve the static problem with the deformed blade loaded directly by HAWC2.
|
330
|
+
h2_dtu10mw_only_blade_high_gravity_deformed.solver_static_run(reset_structure=True)
|
331
|
+
blade_tip_desired = h2_dtu10mw_only_blade_high_gravity_deformed.get_sensor_values((1, 2, 3, 4, 5, 6))
|
332
|
+
|
333
|
+
# Set c2_def in the original blade, thus making it equivalent to the deformed one.
|
334
|
+
# Then, solve again the static problem.
|
335
|
+
_, c2def_deformed = write_dtu10mw_only_blade_high_gravity_deformed
|
336
|
+
h2_dtu10mw_only_blade_high_gravity.set_c2_def("blade1", c2def_deformed)
|
337
|
+
h2_dtu10mw_only_blade_high_gravity.solver_static_run(reset_structure=True)
|
338
|
+
blade_tip_actual = h2_dtu10mw_only_blade_high_gravity_deformed.get_sensor_values((1, 2, 3, 4, 5, 6))
|
339
|
+
|
340
|
+
npt.assert_allclose(blade_tip_actual, blade_tip_desired)
|
341
|
+
|
342
|
+
# Restore c2_def.
|
343
|
+
_, c2def_original = write_dtu10mw_only_blade_high_gravity
|
344
|
+
h2_dtu10mw_only_blade_high_gravity.set_c2_def("blade1", c2def_original)
|
345
|
+
|
346
|
+
|
347
|
+
@pytest.mark.skip(reason="The system eigenanalysis cannot be called more than once.")
|
348
|
+
def test_set_c2_def_blade_eig_back_to_original(
|
349
|
+
write_dtu10mw_only_blade_high_gravity,
|
350
|
+
h2_dtu10mw_only_blade_high_gravity,
|
351
|
+
):
|
352
|
+
# Get the clamped DTU 10 MW blade.
|
353
|
+
# We use the fixture with high gravity because it also returns c2_def.
|
354
|
+
_, blade_c2def = write_dtu10mw_only_blade_high_gravity
|
355
|
+
h2 = h2_dtu10mw_only_blade_high_gravity
|
356
|
+
|
357
|
+
# Solve the eigenvalue problem.
|
358
|
+
h2.structure_reset()
|
359
|
+
h2.linearize()
|
360
|
+
natural_frequencies_desired, damping_ratios_desired = h2.do_system_eigenanalysis(n_modes=6, include_damping=True)
|
361
|
+
|
362
|
+
# Change blade length and solve again the eigenvalue problem
|
363
|
+
c2def_new = blade_c2def.copy()
|
364
|
+
for factor in (0.6, 0.7, 0.8, 0.9, 1.1, 1.2, 1.3, 1.4):
|
365
|
+
c2def_new[:, 2] = factor * blade_c2def[:, 2]
|
366
|
+
h2.set_c2_def("blade1", c2def_new)
|
367
|
+
h2.structure_reset()
|
368
|
+
h2.linearize()
|
369
|
+
natural_frequencies_actual, damping_ratios_actual = h2.do_system_eigenanalysis(n_modes=6, include_damping=True)
|
370
|
+
|
371
|
+
# Must differ from the desired ones.
|
372
|
+
with npt.assert_raises(AssertionError):
|
373
|
+
npt.assert_allclose(natural_frequencies_actual, natural_frequencies_desired)
|
374
|
+
with npt.assert_raises(AssertionError):
|
375
|
+
npt.assert_allclose(damping_ratios_actual, damping_ratios_desired)
|
376
|
+
|
377
|
+
# Restore blade c2_def.
|
378
|
+
h2.set_c2_def("blade1", blade_c2def)
|
379
|
+
h2.structure_reset()
|
380
|
+
h2.linearize()
|
381
|
+
natural_frequencies_actual, damping_ratios_actual = h2.do_system_eigenanalysis(n_modes=6, include_damping=True)
|
382
|
+
npt.assert_allclose(natural_frequencies_actual, natural_frequencies_desired)
|
383
|
+
npt.assert_allclose(damping_ratios_actual, damping_ratios_desired)
|
384
|
+
|
385
|
+
|
386
|
+
def test_set_c2_def_blade_mass_back_to_original(
|
387
|
+
write_dtu10mw_only_blade_high_gravity_1_body,
|
388
|
+
h2_dtu10mw_only_blade_high_gravity_1_body,
|
389
|
+
):
|
390
|
+
# Get the clamped DTU 10 MW blade.
|
391
|
+
# We use the fixture with high gravity because it also returns c2_def.
|
392
|
+
_, blade_c2def = write_dtu10mw_only_blade_high_gravity_1_body
|
393
|
+
h2 = h2_dtu10mw_only_blade_high_gravity_1_body
|
394
|
+
|
395
|
+
# Get the inertia properties.
|
396
|
+
h2.structure_reset()
|
397
|
+
inertia_desired = h2.body_output_mass(0)
|
398
|
+
|
399
|
+
# Change blade length and compute inertia properties.
|
400
|
+
c2def_new = blade_c2def.copy()
|
401
|
+
for factor in (0.6, 0.7, 0.8, 0.9, 1.1, 1.2, 1.3, 1.4):
|
402
|
+
c2def_new[:, 2] = factor * blade_c2def[:, 2]
|
403
|
+
h2.set_c2_def("blade1", c2def_new)
|
404
|
+
inertia_actual = h2.body_output_mass(0)
|
405
|
+
|
406
|
+
# Must differ from the desired ones.
|
407
|
+
for i in range(4): # Loop over tuple of arrays.
|
408
|
+
with npt.assert_raises(AssertionError):
|
409
|
+
npt.assert_allclose(inertia_actual[i], inertia_desired[i])
|
410
|
+
|
411
|
+
# Restore blade c2_def.
|
412
|
+
h2.set_c2_def("blade1", blade_c2def)
|
413
|
+
inertia_actual = h2.body_output_mass(0)
|
414
|
+
for i in range(4): # Loop over tuple of arrays.
|
415
|
+
npt.assert_allclose(inertia_actual[i], inertia_desired[i])
|
416
|
+
|
417
|
+
|
418
|
+
def test_set_c2_def_blade_mass_deformed(
|
419
|
+
write_dtu10mw_only_blade_high_gravity,
|
420
|
+
write_dtu10mw_only_blade_high_gravity_deformed,
|
421
|
+
h2_dtu10mw_only_blade_high_gravity,
|
422
|
+
h2_dtu10mw_only_blade_high_gravity_deformed,
|
423
|
+
):
|
424
|
+
# Revert blades to the undeflected configuration.
|
425
|
+
h2_dtu10mw_only_blade_high_gravity.structure_reset()
|
426
|
+
h2_dtu10mw_only_blade_high_gravity_deformed.structure_reset()
|
427
|
+
|
428
|
+
# Set c2_def in the original blade, thus making it equivalent to the deformed one.
|
429
|
+
_, c2def_deformed = write_dtu10mw_only_blade_high_gravity_deformed
|
430
|
+
h2_dtu10mw_only_blade_high_gravity.set_c2_def("blade1", c2def_deformed)
|
431
|
+
|
432
|
+
# Compare inertia properties for all bodies.
|
433
|
+
nbdy, _ = h2_dtu10mw_only_blade_high_gravity_deformed.get_number_of_bodies_and_constraints()
|
434
|
+
for i in range(nbdy):
|
435
|
+
inertia_desired = h2_dtu10mw_only_blade_high_gravity_deformed.body_output_mass(i)
|
436
|
+
inertia_actual = h2_dtu10mw_only_blade_high_gravity.body_output_mass(i)
|
437
|
+
|
438
|
+
for i in range(4): # Loop over tuple of arrays.
|
439
|
+
npt.assert_allclose(inertia_actual[i], inertia_desired[i], rtol=1e-6)
|
440
|
+
|
441
|
+
# Restore c2_def.
|
442
|
+
_, c2def_original = write_dtu10mw_only_blade_high_gravity
|
443
|
+
h2_dtu10mw_only_blade_high_gravity.set_c2_def("blade1", c2def_original)
|
444
|
+
|
445
|
+
|
446
|
+
def test_set_c2_def_blade_element_deformed(
|
447
|
+
write_dtu10mw_only_blade_high_gravity,
|
448
|
+
write_dtu10mw_only_blade_high_gravity_deformed,
|
449
|
+
h2_dtu10mw_only_blade_high_gravity,
|
450
|
+
h2_dtu10mw_only_blade_high_gravity_deformed,
|
451
|
+
):
|
452
|
+
# Revert blades to the undeflected configuration.
|
453
|
+
h2_dtu10mw_only_blade_high_gravity.structure_reset()
|
454
|
+
h2_dtu10mw_only_blade_high_gravity_deformed.structure_reset()
|
455
|
+
|
456
|
+
# Set c2_def in the original blade, thus making it equivalent to the deformed one.
|
457
|
+
_, c2def_deformed = write_dtu10mw_only_blade_high_gravity_deformed
|
458
|
+
h2_dtu10mw_only_blade_high_gravity.set_c2_def("blade1", c2def_deformed)
|
459
|
+
|
460
|
+
# Compare element matrices for all bodies.
|
461
|
+
nelem = h2_dtu10mw_only_blade_high_gravity_deformed.get_number_of_elements()
|
462
|
+
for ibdy in range(nelem.size):
|
463
|
+
for ielem in range(nelem[ibdy]):
|
464
|
+
mat_desired = h2_dtu10mw_only_blade_high_gravity_deformed.body_output_element(ibdy, ielem)
|
465
|
+
mat_actual = h2_dtu10mw_only_blade_high_gravity.body_output_element(ibdy, ielem)
|
466
|
+
|
467
|
+
npt.assert_allclose(mat_actual[0], mat_desired[0], rtol=1e-10) # mass
|
468
|
+
npt.assert_allclose(mat_actual[1], mat_desired[1], rtol=1e-10) # stiffness
|
469
|
+
npt.assert_allclose(mat_actual[2], mat_desired[2], rtol=1e-10) # damping
|
470
|
+
|
471
|
+
# Restore c2_def.
|
472
|
+
_, c2def_original = write_dtu10mw_only_blade_high_gravity
|
473
|
+
h2_dtu10mw_only_blade_high_gravity.set_c2_def("blade1", c2def_original)
|
474
|
+
|
475
|
+
|
187
476
|
def test_set_orientation_relative_main_body_not_found(
|
188
477
|
h2_dtu_10mw_only_blade_rotate_relative,
|
189
478
|
):
|
@@ -279,11 +568,6 @@ def test_set_orientation_relative_2(
|
|
279
568
|
def test_set_orientation_relative_static(
|
280
569
|
h2_dtu_10mw_only_blade_rotate_relative,
|
281
570
|
):
|
282
|
-
# Add a sensor for the blade root force.
|
283
|
-
id = h2_dtu_10mw_only_blade_rotate_relative.add_sensor(
|
284
|
-
"mbdy forcevec blade1 1 1 blade1"
|
285
|
-
)
|
286
|
-
|
287
571
|
# Set arbitrary orientation and speed.
|
288
572
|
h2_dtu_10mw_only_blade_rotate_relative.set_orientation_relative(
|
289
573
|
main_body_1="hub1",
|
@@ -295,11 +579,13 @@ def test_set_orientation_relative_static(
|
|
295
579
|
mbdy2_ini_rotvec_d1=[0.0, 1.0, 0.0, 0.8],
|
296
580
|
)
|
297
581
|
# Run static solver.
|
298
|
-
h2_dtu_10mw_only_blade_rotate_relative.solver_static_run(
|
582
|
+
h2_dtu_10mw_only_blade_rotate_relative.solver_static_run(
|
583
|
+
reset_structure=True
|
584
|
+
)
|
299
585
|
|
300
586
|
# Do 1 step to get the output.
|
301
587
|
h2_dtu_10mw_only_blade_rotate_relative.step()
|
302
|
-
val = h2_dtu_10mw_only_blade_rotate_relative.get_sensor_values(
|
588
|
+
val = h2_dtu_10mw_only_blade_rotate_relative.get_sensor_values((1, 2, 3))
|
303
589
|
|
304
590
|
# Test against: result at the time of writing.
|
305
591
|
npt.assert_allclose(val, np.array([8702.206018, 306.728782, 640.051269]))
|
@@ -314,3 +600,10 @@ def test_set_orientation_relative_static(
|
|
314
600
|
reset_orientation=True,
|
315
601
|
mbdy2_ini_rotvec_d1=np.array([0.0, 1.0, 0.0, 1.0]),
|
316
602
|
)
|
603
|
+
|
604
|
+
|
605
|
+
# %% Main.
|
606
|
+
|
607
|
+
if __name__ == "__main__":
|
608
|
+
# pytest.main([__file__])
|
609
|
+
pytest.main([__file__, "-k test_set_c2_def_blade_element_deformed"])
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: h2lib-tests
|
3
|
-
Version: 13.
|
4
|
-
Summary: Tests and test_files for test h2lib (13.
|
3
|
+
Version: 13.2.701
|
4
|
+
Summary: Tests and test_files for test h2lib (13.2.7+4-gb779ee7)
|
5
5
|
Download-URL:
|
6
6
|
Author: Mads M Pedersen
|
7
7
|
Author-email:
|
@@ -1,15 +1,16 @@
|
|
1
1
|
h2lib_tests/__init__.py,sha256=VjSqfGg8BzdmSjfSFhJh4hZbYZ_cME7xp9EWFKHQphA,61
|
2
|
-
h2lib_tests/conftest.py,sha256=
|
2
|
+
h2lib_tests/conftest.py,sha256=o9bkMEaB40rr_KSGovy1nuvq2Y09rKfQWxTcTGZ0MfY,21607
|
3
3
|
h2lib_tests/dtu10mw.py,sha256=a7SXfyDwDQPastYKb5CgghOQcYfgO1eTwGrd-H3Enok,4374
|
4
4
|
h2lib_tests/test_calc.py,sha256=VNLfr2J9R2Jy9xTbdZ9dfbQ4dCwr7H7nbZRI3yP69fQ,2152
|
5
|
-
h2lib_tests/
|
5
|
+
h2lib_tests/test_distributed_sections.py,sha256=JtguIddd2nmRyNsy2jqjPFB8E5cGpH2_IVErP1wGPPg,5432
|
6
|
+
h2lib_tests/test_ellipsys_couplings.py,sha256=mfSTk1IamaKETU6Be8p8W9vA-yostWJl17m5sFlEK3Q,3345
|
6
7
|
h2lib_tests/test_h2lib.py,sha256=LEV1n0Fwa1llQwIM06Mcqr07Y6WOn-j8mNxjzlCEOl0,14219
|
7
|
-
h2lib_tests/test_h2rotor.py,sha256=
|
8
|
-
h2lib_tests/test_lin.py,sha256=
|
8
|
+
h2lib_tests/test_h2rotor.py,sha256=yAcG9RDD3uO4g4w8LJnJ3Md_bC-_mBn1--4KHwvlTRc,12963
|
9
|
+
h2lib_tests/test_lin.py,sha256=yydbsMX44ym_MSqR1cbQkqil8qC4icSW_JccPSElGac,6292
|
9
10
|
h2lib_tests/test_mpi.py,sha256=CTT160yc6uZFRr_QNFWxyOwJ-y0qHiIp8jPYs1MQpyg,7111
|
10
11
|
h2lib_tests/test_multiprocessinterface.py,sha256=h2o4havtK6IuMXsplNjGUa3VxOnbpEYGxdrrAKQilj0,1470
|
11
|
-
h2lib_tests/test_static_solver.py,sha256=
|
12
|
-
h2lib_tests/test_topology_h2lib.py,sha256=
|
12
|
+
h2lib_tests/test_static_solver.py,sha256=IuUkKrEoz_EKLCmGQ94CLFgjKPvO20iVx4773JTKO-8,6503
|
13
|
+
h2lib_tests/test_topology_h2lib.py,sha256=7ZfVjEUYBJacPcFCDi_Qb0LqW6W-0no_zTBUKbNcKQw,23858
|
13
14
|
h2lib_tests/test_files/__init__.py,sha256=9e6ZUPb42e0wf2E1rutdcTM8hROcWFRVPXtZriU3ySw,50
|
14
15
|
h2lib_tests/test_files/my_test_cls.py,sha256=7ZDsFkxrLfOY6q00U5Y-daxfuhATK-K5H04RP-VmQdE,850
|
15
16
|
h2lib_tests/test_files/DTU_10_MW/control/dtu_we_controller.dll,sha256=C5T_CuAFtIuDgCXSYAoNu24yKPwj2nWOeORacJbLN9s,1134592
|
@@ -44,6 +45,7 @@ h2lib_tests/test_files/DTU_10_MW/htc/DTU_10MW_RWT.htc,sha256=gBDcGmlmm9UWpYE1fvq
|
|
44
45
|
h2lib_tests/test_files/DTU_10_MW/htc/DTU_10MW_RWT_mann_turb.htc,sha256=-jFK-ra64GeY3fQrP8FxeZ25DkQMdS8yQ9sO78SS9G8,32006
|
45
46
|
h2lib_tests/test_files/DTU_10_MW/htc/DTU_10MW_RWT_no_aerodrag.htc,sha256=ELZNcQWlUdOsfSFq9iryvolbYgu5sd241lTfnyD8cS4,31705
|
46
47
|
h2lib_tests/test_files/DTU_10_MW/htc/DTU_10MW_RWT_no_output.htc,sha256=PxkaacH8iVp0ewk6x8fIjkITPUkiVar5bxZCWqZSoP4,25887
|
48
|
+
h2lib_tests/test_files/DTU_10_MW/htc/DTU_10MW_RWT_only_tower.htc,sha256=xUOj-miknjkFyUz7plPaVqbU9RtYsI-BMLqQi7peV7Y,2744
|
47
49
|
h2lib_tests/test_files/DTU_10_MW/htc/DTU_10MW_RWT_yaw_acturator.htc,sha256=WMxUTE_EJo39AjPfNm3zhjNkSyGli-qwcc0GRauTkw4,33790
|
48
50
|
h2lib_tests/test_files/IEA-15-240-RWT/IEA_15MW_RWT_Blade_st_FPM.st,sha256=ytwFSx1cFSF25vZ8WZpYFiV2aL3DTvetPrR7oEqFYpc,16605
|
49
51
|
h2lib_tests/test_files/IEA-15-240-RWT/IEA_15MW_RWT_Blade_st_noFPM.st,sha256=Pdb8rfJoV7zOAmbPn_xUyGgQk-xIjQ5fCZPRzsu9Q-M,20945
|
@@ -89,7 +91,7 @@ h2lib_tests/test_files/minimal/res/minimal_mann_turb.hdf5,sha256=Q3cs3bZyplZjBpo
|
|
89
91
|
h2lib_tests/test_files/minimal/turb/hawc2_mann_l33.6_ae0.1000_g3.9_h0_512xd32xd16_2.000x3.00x4.00_s0001_u,sha256=byiorJmXDL6uKFbyfXthHTjJdm6ELvLR2lS202KrhRI,1048576
|
90
92
|
h2lib_tests/test_files/minimal/turb/hawc2_mann_l33.6_ae0.1000_g3.9_h0_512xd32xd16_2.000x3.00x4.00_s0001_v,sha256=cxK5Rfgfm3gyJsEYi_KlmYY8DIIl_G0aizN2jt18Glc,1048576
|
91
93
|
h2lib_tests/test_files/minimal/turb/hawc2_mann_l33.6_ae0.1000_g3.9_h0_512xd32xd16_2.000x3.00x4.00_s0001_w,sha256=xs61jAwhP3fIR1P5Oa8ovEt2baLoF8uCNs6pKIT8L4o,1048576
|
92
|
-
h2lib_tests-13.
|
93
|
-
h2lib_tests-13.
|
94
|
-
h2lib_tests-13.
|
95
|
-
h2lib_tests-13.
|
94
|
+
h2lib_tests-13.2.701.dist-info/METADATA,sha256=-mXXeU5VEAY9tlTcDTGdIrr3YjPISLCZsZpFATvR-cg,417
|
95
|
+
h2lib_tests-13.2.701.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
96
|
+
h2lib_tests-13.2.701.dist-info/top_level.txt,sha256=WufAL3LO35YJBhWg1AfgTjSld-6l_WuRkXAkNKczUrM,12
|
97
|
+
h2lib_tests-13.2.701.dist-info/RECORD,,
|
File without changes
|
File without changes
|