1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """The NREL turbine model. Still in heavy development that's why
23 it has an incomplete documentation."""
24 import numpy as N
25 import mbdyn as M
26 import windSimSuite as W
27
28
30 """The wind turbine foundation.
31 """
32
34 self.name = name
35 self.refs = W.List()
36 self.ref = None
37
38 self.phix = W.Angle(0., "deg")
39 self.phiy = W.Angle(0., "deg")
40 self.ground_level = 0.
41
43 """The value is supposed to be entered in degree by default.
44 1. rotate laterally round global X-axis.
45 """
46 self.phix[unit_key] = value
47
49 """The value is supposed to be entered in degree by default.
50 2. rotate longitudinally round the (inclined) Y-axis.
51 """
52 self.phiy[unit_key] = value
53
55 self.ground_level = value
56
58 refx = M.ReferenceFrame("x " + self.name)
59 refx.set_orientation_matrix(one = (1., 0., 0.),
60 three = (0.,
61 -N.sin(self.phix["rad"]),
62 N.cos(self.phix["rad"])))
63 self.refs.add(refx)
64
65 refy = M.ReferenceFrame("y " + self.name)
66 refy.set_relative_from(refx)
67 refy.set_orientation_matrix(two = (0., 1., 0.),
68 three = (N.sin(self.phiy["rad"]),
69 0.,
70 N.cos(self.phiy["rad"])))
71 self.refs.add(refy)
72
73 ref = M.ReferenceFrame(self.name)
74 ref.set_relative_from(refy)
75 ref.set_position(0., 0., self.ground_level)
76 self.ref = ref
77 self.refs.add(ref)
78
82
83
85 """Interface for building the
86 the tower of the wind turbine.
87 The needed parameters are:
88
89 - height
90 - mass
91 - stiffness as a dictionary
92 """
93
95 W.Tower.__init__(self, name)
96 self.foundation = Foundation()
97
98 self.stiffness = {}
99 self.height = 0.
100 self.mass = None
101
102 self.height_substructure = 0.
103
106
108 for ref in self.foundation.refs:
109 self.refs.add(ref)
110
111 base_ref = M.ReferenceFrame(self.name + " base")
112 base_ref.set_relative_from(self.foundation.ref)
113 base_ref.set_position(0., 0., self.height_substructure)
114 self.refs.add(base_ref, "base")
115
116 top_ref = M.ReferenceFrame(self.name + " mid")
117 top_ref.set_relative_from(base_ref)
118 top_ref.set_position(0., 0., 0.5 * self.height)
119 self.refs.add(top_ref, "mid")
120
121 top_ref = M.ReferenceFrame(self.name + " top")
122 top_ref.set_relative_from(base_ref)
123 top_ref.set_position(0., 0., self.height)
124 self.refs.add(top_ref, "top")
125
127 nodes_desc = [
128 ("base", "static", 0.),
129 ("mid", "dynamic", 0.5),
130 ("top", "dynamic", 1.)
131 ]
132 for name, ntype, factor in nodes_desc:
133 node = M.StructuralNode(self.name + " " + name)
134 node.set_relative_from(self.refs.get("base"))
135 com = "Node properties relative to %s" % \
136 self.refs.get("base").name
137 node.set_comment(com)
138 node.set_type(ntype)
139 node.set_position(0., 0., factor * self.height)
140 self.nodes.add(node, name)
141
143 joint = M.Clamp(self.name + " " + "clamp")
144 joint.attach_to_node(self.nodes.get("base"))
145 joint.set_position("node")
146 joint.set_orientation_matrix("node")
147 self.elts.add(joint)
148
150 Jmid = 1./12. * (0.5*self.mass) * (0.5*self.height)**2
151 Jtop = 1./3. * (0.25*self.mass) * (0.25*self.height)**2
152 bodies_desc = [ \
153
154 ("mid", 0.5, 0., Jmid),
155 ("top", 0.25, -0.125, Jtop)
156 ]
157 for key, mass_ratio, offset_ratio, inertia in bodies_desc:
158 body = M.Body(self.name + " body " + key)
159 body.attach_to_node(self.nodes.get(key))
160 body.set_mass(mass_ratio * self.mass)
161 body.set_center_of_mass(0.,
162 0.,
163 offset_ratio * self.height)
164 body.set_inertia_matrix(diag=(inertia,
165 inertia,
166 1.))
167 self.elts.add(body, "body " + key)
168
170 for key1, key2 in [("base", "mid"), ("mid", "top")]:
171 joint = M.Coincidence(self.name + key2)
172 joint.set_relative_from(self.refs.get(key2))
173 joint.set_node1(self.nodes.get(key1))
174 joint.set_node2(self.nodes.get(key2))
175 self.elts.add(joint, key2)
176
178 beam = M.Beam3(self.name + " beam")
179
180 beam.set_node1(self.nodes.get("base"))
181 beam.set_node2(self.nodes.get("mid"))
182 beam.set_node3(self.nodes.get("top"))
183
184 beam.section1.set_orientation_matrix(M.EYE)
185 beam.section2.set_orientation_matrix(M.EYE)
186 self._set_stiffness(beam)
187
188 self.elts.add(beam, "beam")
189
191 """By default, the user will give the same constitutive law
192 for the upper and lower part: values are contained in the
193 'stiffness' dictionary for a 6D diagonal matrix. As a an alternative,
194 he can manipulate the 'tower.beam.section1' instance and set what he
195 wants as a law."""
196 stif = self.stiffness
197 law = M.law.LinearElasticGeneric()
198 law.set_stiffness(diag=(stif["GA"], stif["GA"], stif["EA"],
199 stif["EIx"], stif["EIy"], stif["GIz"]))
200 beam.section1.set_constitutive_law(law)
201 beam.section2.set_constitutive_law(law)
202
215
216
218 """The main bearing of the wind turbine,
219 part of the nacelle.
220 """
221
222 - def __init__(self):
223 self.name = "main bearing"
224 self.refs = W.List()
225 self.nodes = W.List()
226 self.elts = W.List()
227
228 self.distance = 0.
229 self.nacelle = None
230
231 - def set_distance(self, value):
232 """The distance between the nacelle referential
233 and the main bearing center"""
234 self.distance = value
235
236 - def set_nacelle(self, nacelle):
238
240 ref_fix = M.Reference(self.name + " fix")
241 ref_fix.set_relative_from(self.nacelle.refs.get("tilt"))
242 ref_fix.set_position(self.distance, 0., 0.)
243 self.refs.add(ref_fix, "fix")
244
245 - def create_nodes(self):
246
247
248 for name, ntype in [("fix", "dynamic")]:
249 node = M.StructuralNode(self.name + " " + name)
250 node.set_type(ntype)
251 com = "Node properties relative to %s" % \
252 self.refs.get("fix").name
253 node.set_comment(com)
254 node.set_relative_from(self.refs.get("fix"))
255 self.nodes.add(node, name)
256
257
258
259
260
261
262 - def create_joints(self):
263 """Clamp the nacelle node with the fix node
264 of the bearing a Coincidence joint.
265 """
266
267 joint = M.Coincidence("Main bearing coincidence")
268 joint.set_relative_from(self.refs.get("fix"))
269 joint.set_node1(self.nacelle.nodes.get("nacelle"))
270 joint.set_node2(self.nodes.get("fix"))
271 self.elts.add(joint)
272
273
276 W.Nacelle.__init__(self, name)
277 self.main_bearing = MainBearing()
278
279
280 self.main_bearing.set_nacelle(self)
281
282 self.tower = None
283 self.ref = None
284
285 self.distance_to_rotor_axis = 0.
286 self.mass = None
287 self.gravity_center = (0., 0., 0.)
288 self.inertia = {"roll" : None,
289 "node" : None,
290 "yaw" : None}
291 self._yaw = W.Angle(0., "deg")
292 self._tilt = W.Angle(0., "deg")
293
295 self.distance_to_rotor_axis = value
296
298 """Set the mass of the nacelle in kg"""
299 self.mass = value
300
302 """Set the position of the center of gravity
303 relative to the node position, in [m]"""
304 self.gravity_center = (x, y, z)
305
307 """Set the inertia round the axis of nacelle referential
308 referred to center of gravity, in [kg m²]"""
309 self.inertia = {"roll" : Jroll,
310 "node" : Jnode,
311 "yaw" : Jyaw}
312
313 - def set_yaw(self, value, unit_key="deg"):
314 self._yaw[unit_key] = value
315
316 - def set_tilt(self, value, unit_key="deg"):
317 self._tilt[unit_key] = value
318
321
323 yaw_ref = M.Reference(self.name + " yaw")
324 yaw_ref.set_relative_from(self.tower.refs.get("top"))
325
326
327 yaw_ref.set_orientation_matrix(three=(0., 0., 1.),
328 one=(N.cos(self._yaw["rad"] + N.pi),
329 N.sin(self._yaw["rad"] + N.pi),
330 0.))
331 self.refs.add(yaw_ref, "yaw")
332
333 ref = M.Reference(self.name)
334 ref.set_relative_from(yaw_ref)
335 ref.set_position(0., 0., self.distance_to_rotor_axis)
336 self.ref = ref
337 self.refs.add(ref)
338
339 tilt_ref = M.Reference(self.name + " tilt")
340 tilt_ref.set_relative_from(ref)
341
342
343 tilt_ref.set_orientation_matrix(two=(0., 1., 0.),
344 one=(N.cos(-self._tilt["rad"]),
345 0.,
346 -N.sin(-self._tilt["rad"])))
347 self.refs.add(tilt_ref, "tilt")
348
349
351 node = M.StructuralNode(self.name)
352 node.set_type("dynamic")
353 node.set_comment("Node properties relative to %s" % self.ref.name)
354 node.set_relative_from(self.ref)
355 self.nodes.add(node, "nacelle")
356 for node in self.main_bearing.nodes:
357 self.nodes.add(node)
358
363
364 - def _create_body(self):
365 body = M.Body(self.name + " body")
366 body.set_mass(self.mass)
367 body.set_inertia_matrix(diag=(self.inertia["roll"],
368 self.inertia["node"],
369 self.inertia["yaw"]))
370 body.set_center_of_mass(*self.gravity_center)
371 body.attach_to_node(self.nodes.get("nacelle"))
372 self.elts.add(body, "body")
373
375 """Clamp the tower top with the nacelle node"""
376 joint = M.Coincidence("nacelle")
377 joint.set_relative_from(self.ref)
378 joint.set_node1(self.tower.nodes.get("top"))
379 joint.set_node2(self.nodes.get("nacelle"))
380 self.elts.add(joint)
381
392
393
395
397 self._value = N.array([ [self.norm,
398 0.,
399 0.] ])
400
403
406
408 self.mbdyn_inst.set_value(self._value)
409
410
412
417
420
422 ref_tmp = M.ReferenceFrame("Hub tmp")
423 ref_tmp.set_relative_from(self.nacelle.main_bearing.refs.get("fix"))
424 self.refs.add(ref_tmp, "hub tmp")
425
426 ref = M.ReferenceFrame("Hub")
427 ref.set_relative_from(ref_tmp)
428 ref.set_orientation_matrix(one=(-1, 0., 0.),
429 three=(0., 0., 1.))
430 self.refs.add(ref, "hub")
431
433 node = M.StructuralNode("Hub")
434 node.set_relative_from(self.refs.get("hub"))
435 self.nodes.add(node, "hub")
436
438 joint = M.RevoluteHinge("Hub hinge")
439 joint.set_relative_from(self.refs.get("hub"))
440 joint.set_node1(self.nacelle.main_bearing.nodes.get("fix"))
441 joint.set_node2(self.nodes.get("hub"))
442 joint.set_rotation_axis(two=(0., 1., 0.),
443 three=(1., 0., 0.))
444 self.elts.add(joint)
445
450
452 torque = FakeTorque()
453 torque.set_relative_from(self.refs.get("tip"))
454 torque.set_direction(0., -1., 0.)
455 torque.set_node(self.nodes.get("tip"))
456 self.elts.add(torque)
457
461
462
463
465
467 self.force = N.array([ [0.],
468 [-10.],
469 [0.] ])
470
473
475 rot_matrix = N.asmatrix(self.node.mbdyn_inst.get_rotation_matrix())
476 self.mbdyn_inst.set_value(N.asarray(rot_matrix * self.force))
477
478
480 - def __init__(self, idx=0, use_fake_load=False):
481 W.Blade.__init__(self, idx)
482 self.mass = 1.
483 self.stiffness = {}
484 self.flange_distance = 5.
485 self.use_fake_load = use_fake_load
486
489
491 self.use_fake_load = boolean
492
494 ref = M.ReferenceFrame(self.name + "base")
495 ref.set_relative_from(hub.refs.get("hub"))
496
497
498 offset_angle = -self.angle["wing"]["rad"]
499 ref.set_position(0.,
500 N.sin(offset_angle) * self.flange_distance,
501 N.cos(offset_angle) * self.flange_distance)
502 ref.set_orientation_matrix(one=(1., 0., 0.),
503 three=(0.,
504 N.sin(offset_angle),
505 N.cos(offset_angle)))
506 self.refs.add(ref, "base")
507
509 nodes_desc = [
510 ("root", "static", 0.),
511 ("mid", "dynamic", 0.5),
512 ("tip", "dynamic", 1.)
513 ]
514 beam_length = self.radius - self.flange_distance
515 for key, ntype, rfactor in nodes_desc:
516 ref = M.ReferenceFrame(self.name + " " + key)
517 ref.set_relative_from(self.refs.get("base"))
518 ref.set_position(0.,
519 0.,
520 rfactor * beam_length)
521 self.refs.add(ref, key)
522 node = M.StructuralNode(self.name + " " + key)
523 node.set_relative_from(ref)
524 node.set_type(ntype)
525 node.set_comment("Node properties relative to %s" % ref.name)
526 self.nodes.add(node, key)
527
529 joint = M.Coincidence(self.name)
530 joint.set_relative_from(self.refs.get("root"))
531 joint.set_node1(hub.nodes.get("hub"))
532 joint.set_node2(self.nodes.get("root"))
533 self.elts.add(joint)
534
536 for key in ["mid", "tip"]:
537 body = M.Body(self.name + " " + key)
538 body.attach_to_node(self.nodes.get(key))
539 body.set_mass(self.mass)
540
541 self.elts.add(body, key)
542
544 for key1, key2 in [("root", "mid"), ("mid", "tip")]:
545 joint = M.Coincidence(self.name + key2)
546 joint.set_relative_from(self.refs.get(key2))
547 joint.set_node1(self.nodes.get(key1))
548 joint.set_node2(self.nodes.get(key2))
549 self.elts.add(joint, key2)
550
552 beam = M.Beam3(self.name)
553 beam.set_relative_from(self.refs.get("root"))
554 beam.set_node1(self.nodes.get("root"))
555 beam.set_node2(self.nodes.get("mid"))
556 beam.set_node3(self.nodes.get("tip"))
557
558 beam.section1.set_orientation_matrix(M.EYE)
559 beam.section2.set_orientation_matrix(M.EYE)
560 self._set_stiffness(beam)
561
562 self.elts.add(beam, "beam")
563
565 """By default, the user will give the same constitutive law
566 for the upper and lower part: values are contained in the
567 'stifness' dictionary for a 6D diagonal matrix. As a an alternative,
568 he can manipulate the 'blades[i].beam.section1' instance and set what he
569 wants a law."""
570 law = M.law.LinearElasticGeneric()
571 stiff = self.stiffness
572 law.set_stiffness(diag=(stiff["GA"],
573 stiff["GA"],
574 stiff["EA"],
575 stiff["EIx"],
576 stiff["EIy"],
577 stiff["GIz"]))
578 beam.section1.set_constitutive_law(law)
579 beam.section2.set_constitutive_law(law)
580
582 force = FakeLoad()
583 force.set_relative_from(self.refs.get("tip"))
584 force.set_direction(0., -1., 0.)
585 force.set_node(self.nodes.get("tip"))
586 self.elts.add(force)
587
591
592
593
602
604 """The NREL turbine is made of 3 blades
605 """
606
612
615
628
629
630
631
632
633
635 - def __init__(self, name="nrel turbine", use_beams=True,
636 only_mbdyn_rotor=False):
641
667
669 if self.has_tower and self.has_nacelle:
670 self.nacelle.set_tower(self.tower)
671 if self.has_nacelle and self.has_rotor:
672 self.rotor.set_nacelle(self.nacelle)
673
674 for compo_name in ["tower", "nacelle", "rotor"]:
675 if getattr(self, "has_" + compo_name):
676 compo = getattr(self, compo_name)
677 compo.create(self.use_beams)
678