MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
module-aerodyn.cc
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/modules/module-aerodyn/module-aerodyn.cc,v 1.46 2017/01/12 14:47:15 masarati Exp $ */
2 /*
3  * MBDyn (C) is a multibody analysis code.
4  * http://www.mbdyn.org
5  *
6  * Copyright (C) 1996-2017
7  *
8  * Pierangelo Masarati <masarati@aero.polimi.it>
9  *
10  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
11  * via La Masa, 34 - 20156 Milano, Italy
12  * http://www.aero.polimi.it
13  *
14  * Changing this copyright notice is forbidden.
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation (version 2 of the License).
19  *
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29  */
30 /* module-aerodyn
31  * Authors: Fanzhong Meng, Pierangelo Masarati
32  *
33  * Copyright (C) 2008-2017
34  *
35  * Fanzhong Meng <f.meng@tudelft.nl>
36  *
37  * Faculty of Aerospace Engineering - Delft University of Technology
38  * Kluyverweg 1, 2629HS Delft, the Netherlands
39  * http://www.tudelft.nl
40  *
41  */
42 /*
43  * AeroDynModule: interface between MBDyn and NREL's AeroDyn.
44  *
45  * Author: Pierangelo Masarati
46  *
47  * Copyright (C) 2008-2017 All rights reserved
48  *
49  * Refactoring of module-aerodyn using the UserDefinedElem interface.
50  * Based on module-aerodyn.cc by Fanzhong Meng and Pierangelo Masarati.
51  */
52 
53 #include "mbconfig.h" /* This goes first in every *.c,*.cc file */
54 
55 #include "Rot.hh"
56 
57 #include "dataman.h"
58 #include "userelem.h"
59 //#include "loadable.h"
60 #include "drive_.h"
61 //#include "module-aerodyn.h"
62 
63 // uncomment to enable debug output
64 // #define MODULE_AERODYN_DEBUG
65 
66 // keep this consistent with AeroDyn build
67 // #define USE_DOUBLE_PRECISION
68 #define USE_SINGLE_PRECISION
69 
70 #include "NREL_AeroDyn.h"
71 
73 : virtual public Elem,
74 public UserDefinedElem
75 {
76 private:
77 
78  struct AeroNode {
80  Vec3 f; // offset of the aero point wrt./ the node,
81  // constant in the node's reference frame
82  Mat3x3 Ra; // aerodynamic orientation of the aero point
83  // wrt./ the node
84 
86 
87  Vec3 F; // Force acting on Node
88  Vec3 M; // Moment acting on Node, with respect
89  // to node's position
90 
91  doublereal FN; // Normal Force on each blade element (Not being used now!).
92  doublereal FT; // Tangental force on each blade element.(Not being used now!)
93  doublereal AM; // Aerodynamic moment on each blade element.(Not being used now!)
94 
95  doublereal PITNOW; // Node pitch angle
96  };
97 
105 
106  integer nblades; // the number of blades.
107  integer nelems; // the number of elements per blade.
108 
110 
111  /*
112  * node data
113  */
114  std::vector<AeroNode> nodes; // nodes
115  std::vector<Mat3x3> bladeR; // orientation matrix of each blade root in the hub reference frame
116 
117  std::string ofname;
118  mutable std::ofstream out;
119 
120  /*
121  * Total aerodynamic data
122  */
123  Vec3 TF; // Total Force on the rotor in the absolute frame
124  Vec3 TM; // Total Moment on the rotor in the absolute frame.
125  Vec3 TF_h; // Total Force on the rotor in the hub frame
126  Vec3 TM_h; // Total Moment on the rotor in the hub frame.
127  doublereal Thrust; // Rotor Thrust.
128  doublereal Torque; // Rotor Torque.
129  doublereal Rotor_speed; // Rotor angular velocity.
130  /*
131  * internal states to access the Variables which is defined in the
132  * common MODULEs of AeroDyn
133  */
135  F_INTEGER elem; // use to identify the current element in the interface module!
136  F_INTEGER c_elem; // use to identify the current element in AeroDyn!
137  F_INTEGER c_blade; // use to identify the current blade in AeroDyn!
138  F_REAL rlocal; // use to identify the current element position
139  F_REAL r_hub; // use to identify the hub radius.
140  F_REAL r_rotor; // use to identify the rotor radius.
141 
142  bool bFirst;
143  DriveOwner Time; // time drive
144  doublereal dOldTime; // old time
145  doublereal dCurTime; // current time
146  F_REAL dDT; // time step
147 
149 
150 public:
151  // interface for AeroDyn callbacks
152 
153  // module_aerodyn->pNacelle
154  const StructNode *pGetNacelleNode(void) const;
155  // module_aerodyn->pHub
156  const StructNode *pGetHubNode(void) const;
157  // module_aerodyn->Rotor_speed
158  void SetRotorSpeed(doublereal Omega);
159  // module_aerodyn->Hub_Tower_xy_distance;
161  // module_aerodyn->nblades
162  F_INTEGER iGetNumBlades(void) const;
163  // module_aerodyn->c_blade
164  F_INTEGER iGetCurrBlade(void) const;
165  // module_aerodyn->bladeR
166  const Mat3x3& GetCurrBladeR(void) const;
167  // module_aerodyn->nelems
168  F_INTEGER iGetNumBladeElems(void) const;
169  // module_aerodyn->elem
170  F_INTEGER iGetCurrBladeElem(void) const;
171  // module_aerodyn->nodes
172  const StructNode *pGetCurrBladeNode(void) const;
173  // module_aerodyn->nodes[::module_aerodyn->elem].dBuiltInTwist
175  // module_aerodyn->nodes[::module_aerodyn->elem].PITNOW
176  void SetCurrBladeNodePITNOW(doublereal PITNOW);
178  // module_aerodyn->nodes[::module_aerodyn->elem].Ra
179  const Mat3x3& GetCurrBladeNodeRa(void) const;
180 
181 public:
182  AeroDynModule(unsigned uLabel, const DofOwner *pDO,
183  DataManager* pDM, MBDynParser& HP);
184  ~AeroDynModule(void);
185 
186  unsigned int iGetNumDof(void) const;
187  DofOrder::Order GetDofType(unsigned int i) const;
188  void Output(OutputHandler& OH) const;
189  std::ostream& Restart(std::ostream& out) const;
190  void WorkSpaceDim(integer* piNumRows, integer* piNumCols) const;
193  doublereal dCoef,
194  const VectorHandler& XCurr,
195  const VectorHandler& XPrimeCurr);
197  AssRes(SubVectorHandler& WorkVec,
198  doublereal dCoef,
199  const VectorHandler& XCurr,
200  const VectorHandler& XPrimeCurr);
202  void AfterConvergence(const VectorHandler& X,
203  const VectorHandler& XP);
204  unsigned int iGetInitialNumDof(void) const;
205  void InitialWorkSpaceDim(integer* piNumRows, integer* piNumCols) const;
208  const VectorHandler& XCurr);
210  InitialAssRes(SubVectorHandler& WorkVec, const VectorHandler& XCurr);
211  void SetValue(DataManager *pDM,
213  SimulationEntity::Hints* h = 0);
214  unsigned int iGetNumPrivData(void) const;
215 #if 0
216  unsigned int iGetPrivDataIdx(const char *s) const;
217  doublereal dGetPrivData(unsigned int i) const;
218 #endif
219  int GetNumConnectedNodes(void) const;
220  void GetConnectedNodes(std::vector<const Node *>& connectedNodes) const;
221 };
222 
223 // static handler for AeroDyn callbacks
224 // only one element per simulation can be active (AeroDyn limitation)
226 
228  unsigned uLabel,
229  const DofOwner *pDO,
230  DataManager* pDM,
231  MBDynParser& HP)
232 : Elem(uLabel, 0),
233 UserDefinedElem(uLabel, pDO),
234 bFirst(true)
235 {
236  if (HP.IsKeyWord("help")) {
237  /* NOTE: add help message */
238  silent_cout(
239  "Module: AeroDyn" << std::endl
240  << std::endl
241  << "Author: Fanzhong Meng, Pierangelo Masarati" << std::endl
242  << std::endl
243  << "This is the MBDyn interface to AeroDyn, the aerodynamic routines" << std::endl
244  << "developed by NREL <http://www.nrel.gov/> to model the aerodynamic" << std::endl
245  << "forces acting on wind turbines" << std::endl
246  << std::endl
247  << "usage:" << std::endl
248  << "#Nacelle node; requirements:" << std::endl
249  << "#\t\t- axis 3 is the shaft axis, pointing downstream the wind" << std::endl
250  << "\t<nacelle node label> ," << std::endl
251  << "\t<hub node label> ," << std::endl
252  << "\t<pylon top-hub xy distance> ," << std::endl
253  << "\t<hub radius> ," << std::endl
254  << "\t<rotor radius> ," << std::endl
255  << "\t<number of blades> ," << std::endl
256  << "\t<number of elements per blade> ," << std::endl
257  << "\t# for each blade..." << std::endl
258  << "\t#\t- axis 1 in the blade spanwise direction, towards blade tip" << std::endl
259  << "\t#\t- axis 2 in coord direction, towards leading edge" << std::endl
260  << "\t#\t- axis 3 in thickness direction, towards low pressure side" << std::endl
261  << "\t\t<i-th blade root orientation matrix> ," << std::endl
262  << "\t\t# for each blade element..." << std::endl
263  << "\t\t\t<i-th blade j-th node label>" << std::endl
264  << "\t\t\t[ , orientation , <i-th blade j-th node orientation> ]" << std::endl
265  << "\t[ , force scale factor , (DriveCaller)<factor> ]" << std::endl
266  << "\t[ , output file name , \"<file name>\" ]" << std::endl
267  << "\t[ , AeroDyn input file name , \"<file name>\" ]" << std::endl
268  << "\t[ , element file name , \"<file name>\" ]" << std::endl
269  );
270  }
271 
272  if (::module_aerodyn != 0) {
273  silent_cerr("AeroDynModule::AeroDynModule(" << uLabel << "): "
274  "AeroDyn already in use" << std::endl);
276  }
277 
278  /* read nacelle node */
279  pNacelle = dynamic_cast<StructNode *>(pDM->ReadNode(HP, Node::STRUCTURAL));
280  if (pNacelle == 0) {
281  silent_cerr("AeroDynModule(" << GetLabel() << "): "
282  "nacelle node not defined "
283  "at line " << HP.GetLineData() << std::endl);
285  }
286 
287  /* read hub node */
288  pHub = dynamic_cast<StructNode *>(pDM->ReadNode(HP, Node::STRUCTURAL));
289  if (pHub == 0) {
290  silent_cerr("AeroDynModule(" << GetLabel() << "): "
291  "hub node not defined "
292  "at line " << HP.GetLineData() << std::endl);
294  }
295 
297 
298  r_hub = HP.GetReal();
299 
300  r_rotor = HP.GetReal();
301 
302  /*
303  * Initialize AeroDyn package
304  *
305  * FIXME: does it return an error code?
306  */
307  char Version[26 + 1];
308  snprintf(Version, sizeof(Version), "(%s)", VERSION);
309  for (unsigned i = strlen(Version); i < sizeof(Version); i++) {
310  Version[i] = ' ';
311  }
312  Version[sizeof(Version) - 1] = '\0';
313 
314  // number of blades
315  F_INTEGER NBlades = HP.GetInt();
316  if (NBlades <= 0) {
317  silent_cerr("AeroDynModule(" << GetLabel() << "): "
318  "invalid number of blades " << NBlades
319  << " at line " << HP.GetLineData()
320  << std::endl);
322  }
323 
324  // number of elements per blade
325  F_INTEGER NElems = HP.GetInt();
326  if (NElems <= 0) {
327  silent_cerr("AeroDynModule(" << GetLabel() << "): "
328  "invalid number of elements per blade " << NElems
329  << " at line " << HP.GetLineData()
330  << std::endl);
332  }
333 
334  nblades = NBlades;
335  nelems = NElems;
336 
337  // get blade root orientation(without pitch angle).
338 
339  nodes.resize(NBlades*NElems);
340  bladeR.resize(NBlades);
341  ReferenceFrame rf(pHub);
342  for (elem = 0; elem < NBlades*NElems; elem++) {
343  if ((elem % NElems) == 0) {
344  /*
345  * Get the orientation matrix of blade root with respect to hub reference frame
346  */
347  bladeR[elem/NElems] = HP.GetRotRel(rf);
348 #if 0
349  std::cerr << "Root[" << elem/NElems << "] Rotation Matrix:" << bladeR[elem/NElems] << std::endl;
350  std::cerr << "Hub Rotation Matrix:" << pHub->GetRCurr() << std::endl;
351  std::cerr << "Nacelle Rotation Matrix:" << pNacelle->GetRCurr() << std::endl<< std::endl;
352 #endif
353  }
354 
355  nodes[elem].pNode = dynamic_cast<StructNode *>(pDM->ReadNode(HP, Node::STRUCTURAL));
356 
357  // (optional) aerodynamics offset with respect to the node,
358  // constant in the reference frame of the node
359  if (HP.IsKeyWord("position")) {
360  nodes[elem].f = HP.GetPosRel(ReferenceFrame(nodes[elem].pNode));
361 
362  } else {
363  nodes[elem].f = Zero3;
364  }
365 
366  // (optional) relative orientation between the aerodynamics
367  // and the node
368  if (HP.IsKeyWord("orientation")) {
369  nodes[elem].Ra = HP.GetRotRel(ReferenceFrame(nodes[elem].pNode));
370  // built-in twist: the component about blade axis 1
371  // (x) of the relative orientation between
372  // the aerodynamics and the node
373  Vec3 Twist(RotManip::VecRot(nodes[elem].Ra));
374  nodes[elem].dBuiltInTwist = -Twist(1);
375 
376  } else {
377  nodes[elem].Ra = Eye3;
378  nodes[elem].dBuiltInTwist = 0.;
379  }
380  }
381 
382  if (HP.IsKeyWord("force" "scale" "factor")) {
383  FSF.Set(HP.GetDriveCaller());
384 
385  } else {
386  FSF.Set(new OneDriveCaller);
387  }
388 
389  if (HP.IsKeyWord("output" "file" "name")) {
390  const char *ofname = HP.GetFileName();
391  if (ofname == 0) {
392  silent_cerr("AeroDynModule(" << GetLabel() << "): "
393  "unable to get file name "
394  "at line " << HP.GetLineData()
395  << std::endl);
397  }
398  ofname = ofname;
399  out.open(ofname);
400  if (!out) {
401  silent_cerr("AeroDynModule(" << GetLabel() << "): "
402  "unable to open file \"" << ofname << "\" "
403  "at line " << HP.GetLineData()
404  << std::endl);
406  } else {
407  out << std::setw(16) << "Time s"
408  << std::setw(16) << "Thrust kN"
409  << std::setw(16) << "Torque kNm"
410  << std::setw(16) << "R.Speed Rad/s"
411  << std::setw(16) << "Power kW"
412  << std::endl;
413  }
414  }
415 
416  __FC_DECL__(mbdyn_init)(Version, &NBlades, &r_rotor);
417 
418  std::string input_file_name;
419  std::string elem_file_name;
420 
421  if (HP.IsKeyWord("input" "file" "name")) {
422  const char *fname = HP.GetStringWithDelims();
423  if (fname == 0) {
424  silent_cerr("unable to get input file name "
425  "at line " << HP.GetLineData() << std::endl);
427  }
428  input_file_name = fname;
429  }
430 
431  if (HP.IsKeyWord("element" "file" "name")) {
432  const char *fname = HP.GetStringWithDelims();
433  if (fname == 0) {
434  silent_cerr("unable to get element file name "
435  "at line " << HP.GetLineData() << std::endl);
437  }
438  elem_file_name = fname;
439  }
440 
441  F_INTEGER input_file_name_len = input_file_name.size();
442  F_INTEGER elem_file_name_len = elem_file_name.size();
443  int rc = __FC_DECL__(mbdyn_ad_inputgate)((F_CHAR *)input_file_name.c_str(), &input_file_name_len,
444  (F_CHAR *)elem_file_name.c_str(), &elem_file_name_len);
445  if (rc != 0) {
446  silent_cerr("AeroDynModule(" << GetLabel() << "): "
447  "initialization failed "
448  "(err=" << rc << ")" << std::endl);
450  }
451 
452  (void)__FC_DECL__(mbdyn_true)(&FirstLoop);
453 
454  // Calculate the Tip and Hub loss constants for AeroDyn.
455  for (elem = 0; elem < nelems; elem++) {
456  const Vec3& X_node = nodes[elem].pNode->GetXCurr();
457  const Vec3& X_hub = pHub->GetXCurr();
458  const Mat3x3& R_nacelle = pNacelle->GetRCurr();
459  Vec3 d = R_nacelle.MulTV(X_node - X_hub);
460  rlocal = (F_REAL)d.Norm();
461  c_elem = elem + 1;
462  __FC_DECL__(mbdyn_get_tl_const)(&rlocal, &c_elem);
463  __FC_DECL__(mbdyn_get_hl_const)(&rlocal, &c_elem, &r_hub);
464  }
465 
466  // FIXME: only needed when Beddoes and also Dynamic Inflow model are enabled
467  Time.Set(new TimeDriveCaller(pDM->pGetDrvHdl()));
468  dCurTime = Time.dGet();
469  (void)__FC_DECL__(mbdyn_sim_time)(&dCurTime);
470 
471  ::module_aerodyn = this;
472 }
473 
475 {
476  NO_OP;
477 }
478 
479 unsigned int
481 {
482  return 0;
483 }
484 
486 AeroDynModule::GetDofType(unsigned int i) const
487 {
488  return DofOrder::UNKNOWN;
489 }
490 
491 void
493 {
494  if (out) {
495  out << std::scientific
496  << std::setw(16) << dCurTime
497  << std::setw(16) << Thrust/1000.0
498  << std::setw(16) << Torque/1000.0
499  << std::setw(16) << Rotor_speed
500  << std::setw(16) << Torque*Rotor_speed/1000.0
501  << std::endl;
502  }
503 }
504 
505 std::ostream&
506 AeroDynModule::Restart(std::ostream& out) const
507 {
508  return out << "not implemented yet;" << std::endl;
509 }
510 
511 void
512 AeroDynModule::WorkSpaceDim(integer* piNumRows, integer* piNumCols) const
513 {
514  *piNumRows = 6*nblades*nelems;
515  *piNumCols = 1;
516 }
517 
520  doublereal dCoef,
521  const VectorHandler& XCurr,
522  const VectorHandler& XPrimeCurr)
523 {
524  // should do something useful
525  WorkMat.SetNullMatrix();
526 
527  return WorkMat;
528 }
529 
532  SubVectorHandler& WorkVec,
533  doublereal dCoef,
534  const VectorHandler& XCurr,
535  const VectorHandler& XPrimeCurr)
536 {
537  integer iNumRows = 0;
538  integer iNumCols = 0;
539  WorkSpaceDim(&iNumRows, &iNumCols);
540 
541  WorkVec.ResizeReset(iNumRows);
542 
543  /*
544  * set sub-vector indices and coefs
545  */
546 
547  if (bFirst) {
548  c_blade = 0;
549  Mat3x3 BladeR;
550  Vec3 BladeAxis;
551 
552  // force scale factor to "ramp up" loads
553  doublereal dFSF = FSF.dGet();
554 
555  // sanity check
556  ASSERT(dFSF >= 0.);
557  ASSERT(dFSF <= 1.);
558 
559  for (elem = 0; elem < nelems*nblades; elem++) {
560  /*
561  * get the current blade number.
562  */
563  if ((elem % nelems) == 0) {
564  c_blade++;
565  BladeR = pHub->GetRCurr()*bladeR[c_blade];
566  BladeAxis = BladeR.GetVec(1);
567  }
568 
569  /*
570  * get force/moment
571  */
572  F_REAL DFN, DFT, PMA;
573 
574  c_elem = elem%nelems + 1;
575  (void)__FC_DECL__(mbdyn_com_data)(&c_blade, &c_elem);
576 
577  /*
578  * Get blade elements radius. It is the perpendicular distance
579  * from the rotor axis to the element aerodynamic reference point.
580  */
581 
582  /*
583  * forces and moments are in the blade reference frame,
584  * not in the element's.
585  */
586  __FC_DECL__(aerofrcintrface)(&FirstLoop, &c_elem, &DFN, &DFT, &PMA);
587 
588  // ramp forces in the very first second up to ease convergence
589  DFN *= dFSF;
590  DFT *= dFSF;
591  PMA *= dFSF;
592 
593  nodes[elem].FN = DFN;
594  nodes[elem].FT = DFT;
595  nodes[elem].AM = PMA;
596 
597 #ifdef MODULE_AERODYN_DEBUG
598  silent_cerr("aerodyn[" << elem << "] in rotation plane: DFN=" << DFN << " DFT=" << DFT << " PMA=" << PMA << std::endl);
599 #endif // MODULE_AERODYN_DEBUG
600  /*
601  * turn force/moment into the node frame (blade element frame used by Aerodyn to calculation forces)
602  * (passing thru local element frame),
603  * including offset
604  */
605 
606  doublereal c = std::cos(nodes[elem].PITNOW);
607  doublereal s = std::sin(nodes[elem].PITNOW);
608  nodes[elem].F = Vec3(0., DFT*c - DFN*s, DFT*s + DFN*c);
609  nodes[elem].M = nodes[elem].Ra.GetVec(1)*PMA + nodes[elem].f.Cross(nodes[elem].F);
610 
611 
612 #ifdef MODULE_AERODYN_DEBUG
613 
614  silent_cerr("Moment on Node[" << elem << "]: " << nodes[elem].f.Cross(nodes[elem].F) << std::endl);
615 
616 #endif // MODULE_AERODYN_DEBUG
617 
618 #ifdef MODULE_AERODYN_DEBUG
619  silent_cerr(std::setprecision(3) << std::fixed
620  << " aerodyn[" << elem << "]"
621  << " F = " << nodes[elem].F
622  << " M = " << nodes[elem].M
623  << " FN = " << nodes[elem].FN
624  << " FN = " << nodes[elem].FT
625  << " AM = " << nodes[elem].AM
626  << std::endl << std::endl);
627 #endif // MODULE_AERODYN_DEBUG
628 
629  }
630 
631 #ifdef MODULE_AERODYN_DEBUG
632  silent_cerr(std::endl);
633 #endif // MODULE_AERODYN_DEBUG
634 
635  bFirst = false;
636  }
637 
638 
639  TF = Vec3(Zero3);
640  TM = Vec3(Zero3);
641  for (elem = 0; elem < nblades*nelems; elem++) {
642  /*
643  * set indices where force/moment need to be put
644  */
645  integer iFirstIndex = nodes[elem].pNode->iGetFirstMomentumIndex();
646  for (int i = 1; i <= 6; i++) {
647  WorkVec.PutRowIndex(6*elem + i, iFirstIndex + i);
648  }
649 
650  /*
651  * add force/moment to residual, after rotating them
652  * into the global frame
653  */
654  /*
655  * Transfer the force/moment to global frame.
656  */
657  WorkVec.Add(6*elem + 1, nodes[elem].pNode->GetRCurr()*(nodes[elem].Ra*nodes[elem].F));
658  WorkVec.Add(6*elem + 4, nodes[elem].pNode->GetRCurr()*(nodes[elem].Ra*nodes[elem].M));
659 
660  /*
661  * calculate the force and moment contributions on the rotor in absolute frame.
662  */
663  const Vec3& Xp = nodes[elem].pNode->GetXCurr();
664  const Vec3& Xh = pHub->GetXCurr();
665 
666  TF = TF + nodes[elem].pNode->GetRCurr()*nodes[elem].Ra*nodes[elem].F;
667  TM = TM + nodes[elem].pNode->GetRCurr()*nodes[elem].Ra*nodes[elem].M
668  + (Xp-Xh).Cross(nodes[elem].pNode->GetRCurr()*nodes[elem].Ra*nodes[elem].F);
669  }
670 
671  /*
672  * Transfer the force/moment to hub reference frame.
673  */
674  const Mat3x3& Rh = pHub->GetRCurr();
675  TF_h = Rh.MulTV(TF);
676  TM_h = Rh.MulTV(TM);
677 
678  /*
679  * The 3rd component of TF_h and TM_h are the rotor Thrust and rotor Torque.
680  */
681  Thrust = TF_h(3);
682  Torque = TM_h(3);
683 
684  /*
685  * make sure next time FirstLoop will be false
686  */
687  if (FirstLoop) {
688  (void)__FC_DECL__(mbdyn_false)(&FirstLoop);
689  }
690 
691  return WorkVec;
692 }
693 
694 #if 0
695 void
696 module_aerodyn_before_predict(const LoadableElem* pEl,
698  VectorHandler& XPrev, VectorHandler& XPPrev)
699 {
700  DEBUGCOUTFNAME("module_aerodyn_before_predict");
701 }
702 #endif
703 
704 void
706 {
707  bFirst = true;
708 
709  /*
710  * Get the current simulation time and time step!
711  * MENG: 19 June 2008.
712  */
713  dDT = Time.dGet() - dOldTime;
714  dCurTime = Time.dGet();
715  (void)__FC_DECL__(mbdyn_sim_time)(&dCurTime);
716  (void)__FC_DECL__(mbdyn_time_step)(&dDT);
717 }
718 
719 #if 0
720 void
721 module_aerodyn_update(LoadableElem* pEl,
722  const VectorHandler& X, const VectorHandler& XP)
723 {
724  DEBUGCOUTFNAME("module_aerodyn_update");
725 }
726 #endif
727 
728 void
730  const VectorHandler& X,
731  const VectorHandler& XP)
732 {
733  dOldTime = Time.dGet();
734 }
735 
736 unsigned int
738 {
739  return 0;
740 }
741 
742 void
744 {
745  *piNumRows = 6*nblades*nelems;
746  *piNumCols = 1;
747 }
748 
751  VariableSubMatrixHandler& WorkMat,
752  const VectorHandler& XCurr)
753 {
754  // should not be called, since initial workspace is empty
755  ASSERT(0);
756 
757  WorkMat.SetNullMatrix();
758 
759  return WorkMat;
760 }
761 
764  SubVectorHandler& WorkVec,
765  const VectorHandler& XCurr)
766 {
767  // should not be called, since initial workspace is empty
768  ASSERT(0);
769 
770  WorkVec.ResizeReset(0);
771 
772  return WorkVec;
773 }
774 
775 void
779 {
780  bFirst = true;
781 }
782 
783 unsigned int
785 {
786  return 0;
787 }
788 
789 int
791 {
792  return nodes.size() + 2;
793 }
794 
795 void
796 AeroDynModule::GetConnectedNodes(std::vector<const Node *>& connectedNodes) const
797 {
798  /*
799  * set args according to element connections
800  */
801  connectedNodes.resize(nodes.size() + 2);
802 
803  unsigned n;
804  for (n = 0; n < nodes.size(); n++) {
805  connectedNodes[n] = nodes[n].pNode;
806  }
807 
808  connectedNodes[n++] = pNacelle;
809  connectedNodes[n++] = pHub;
810 }
811 
812 // module_aerodyn->pNacelle
813 const StructNode *
815 {
816  return pNacelle;
817 }
818 
819 // module_aerodyn->pHub
820 const StructNode *
822 {
823  return pHub;
824 }
825 
826 // module_aerodyn->Rotor_speed
827 void
829 {
830  Rotor_speed = Omega;
831 }
832 
833 // module_aerodyn->Hub_Tower_xy_distance;
836 {
837  return Hub_Tower_xy_distance;
838 }
839 
840 // module_aerodyn->nblades
841 F_INTEGER
843 {
844  return nblades;
845 }
846 
847 // module_aerodyn->c_blade
848 F_INTEGER
850 {
851  ASSERT(c_blade >= 0);
853 
854  return c_blade;
855 }
856 
857 // module_aerodyn->bladeR
858 const Mat3x3&
860 {
861  ASSERT(c_blade >= 0);
863 
864  return bladeR[c_blade - 1];
865 }
866 
867 // module_aerodyn->nelems
868 F_INTEGER
870 {
871  return nelems;
872 }
873 
874 // module_aerodyn->elem
875 F_INTEGER
877 {
878  ASSERT(elem >= 0);
880 
881  return elem;
882 }
883 
884 // module_aerodyn->nodes
885 const StructNode *
887 {
888  ASSERT(elem >= 0);
890 
891  return nodes[elem].pNode;
892 }
893 
894 // module_aerodyn->nodes[::module_aerodyn->elem].dBuiltInTwist
897 {
898  ASSERT(elem >= 0);
900 
901  return nodes[elem].dBuiltInTwist;
902 }
903 
904 // module_aerodyn->nodes[::module_aerodyn->elem].PITNOW
905 void
907 {
908  ASSERT(elem >= 0);
910 
911  nodes[elem].PITNOW = PITNOW;
912 }
913 
916 {
917  ASSERT(elem >= 0);
919 
920  return nodes[elem].PITNOW;
921 }
922 
923 // module_aerodyn->nodes[::module_aerodyn->elem].Ra
924 const Mat3x3&
926 {
927  ASSERT(elem >= 0);
929 
930  return nodes[elem].Ra;
931 }
932 
933 // Functions called by AeroDyn
934 
935 /*
936  * Rotor parameters - called once per time step.
937  */
938 
939 /* This comment is added by Fanzhong MENG 9th.Feb.2008
940  *
941  * I think in these three functions we should add the codes
942  * that can deal with the communication with MBDyn to get
943  * the structure information which is need for the
944  * Aerodynamic calculation from libAeroDyn.a.
945  */
946 
947 
948 int
949 __FC_DECL__(getrotorparams)(
950  F_REAL *Omega,
951  F_REAL *gamma,
952  F_REAL *VHUB,
953  F_REAL *tau)
954 {
955  /*
956  * This comment is added by Fanzhong MENG 10th.Feb.2008
957  * NOTE: Add code here to get rotorspeed from MBDyn.
958  * Rotor can be running clockwise or ccw. But the
959  * value of *Omega must be positive [rad/s]
960  */
961  /*
962  * PM 2008-09-06:
963  * nacelle & rotor axis is node axis 3, positive opposite
964  * to wind direction
965  */
966 
967  const Mat3x3& nacelle_R = ::module_aerodyn->pGetNacelleNode()->GetRCurr();
968  const Vec3& hub_Omega = ::module_aerodyn->pGetHubNode()->GetWCurr();
969  Vec3 rotation_axis = nacelle_R.GetVec(3);
970 
971  *Omega = std::abs(hub_Omega*rotation_axis);
972  module_aerodyn->SetRotorSpeed(*Omega);
973 
974  /*
975  * This comment is added by Fanzhong MENG 10th.Feb.2008
976  * NOTE: Add code here to get Yawangle from MBDyn.
977  * Yaw angle of the shaft relative to the ground reference.
978  * Positive value is clockwise when viewed from above of nacelle.
979  * Variable name is *gamma. [rad].
980  */
981  *gamma = std::atan2(-rotation_axis(2), -rotation_axis(1));
982 
983  /*
984  * This comment is added by Fanzhong MENG 10th.Feb.2008
985  * NOTE: Add code here to get tilt angle from MBDyn.
986  * Tilt angle of the shaft relative to the ground reference.
987  * Positive value is Tilt UP
988  * Variable name is *tau. [rad].
989  */
990  *tau = std::atan2(rotation_axis(3),
991  std::sqrt(rotation_axis(1)*rotation_axis(1) + rotation_axis(2)*rotation_axis(2)));
992 
993  /*
994  * This comment is added by Fanzhong MENG 10th.Feb.2008
995  * NOTE: Add code here to get Hub Tangential velocity from MBDyn.
996  * Positive value is in the same direction with Yaw Angle.
997  * Variable name is *VHUB.[m/s or feet/s]
998  */
999  // *VHUB = hub_Omega(3)*::module_aerodyn->dGetHubTowerXYDistance();
1000  /* See Emails by Fanzhong Meng August 27, 2010 */
1001  const Vec3& nacelle_Omega = ::module_aerodyn->pGetNacelleNode()->GetWCurr();
1002  *VHUB = nacelle_Omega(3)*::module_aerodyn->dGetHubTowerXYDistance();
1003 
1004  __FC_DECL__(elemout)();
1005 
1006 #ifdef MODULE_AERODYN_DEBUG
1007  silent_cerr("getrotorparams: "
1008  "Omega=" << *Omega << " "
1009  "gamma=" << (*gamma)*180/M_PI << " "
1010  "tau=" << (*tau)*180/M_PI << " "
1011  "VHUB=" << *VHUB << std::endl);
1012 #endif // MODULE_AERODYN_DEBUG
1013 
1014  return 0;
1015 }
1016 
1017 /*
1018  * Blade parameters - called once for each blade at each time step.
1019  */
1020 int
1021 __FC_DECL__(getbladeparams)(F_REAL *psi)
1022 {
1023  /*
1024  * This comment is added by Fanzhong MENG 10th.Feb.2008
1025  * NOTE: Add code here too get blade Azimuth angle.
1026  * The 6 o'clock position is positive value
1027  * Variable name is *psi. [rad].
1028  */
1029  const Mat3x3& R_nacelle = ::module_aerodyn->pGetNacelleNode()->GetRCurr();
1030  const Mat3x3& R_hub = ::module_aerodyn->pGetHubNode()->GetRCurr();
1031  const Mat3x3& R_blade_root = ::module_aerodyn->GetCurrBladeR();
1032  Mat3x3 R = (R_hub*R_blade_root).MulTM(R_nacelle);
1033  Vec3 Phi(RotManip::VecRot(R));
1034  *psi = -Phi(3);
1035 
1036  // unwrap psi (0 <= psi <= 360)
1037  while (*psi < 0) {
1038  *psi += 2*M_PI;
1039  }
1040 
1041 #ifdef MODULE_AERODYN_DEBUG
1042  silent_cerr("getbladeparams: blade=" << ::module_aerodyn->iGetCurrBlade()
1043  << " psi=" << (*psi)*180/M_PI << std::endl);
1044 #endif // MODULE_AERODYN_DEBUG
1045 
1046  return 0;
1047 }
1048 
1049 /*
1050  * Element parameters - called once for each element at each time step.
1051  */
1052 int
1053 __FC_DECL__(getelemparams)(
1054  F_INTEGER *MulTabLoc,
1055  F_REAL *phi,
1056  F_REAL *radius,
1057  F_REAL *XGRND,
1058  F_REAL *YGRND,
1059  F_REAL *ZGRND)
1060 {
1061  /*
1062  * This comment is added by Fanzhong MENG 10th.Feb.2008
1063  * Get coordinates of blade element relative to the undeflected
1064  * tower top reference frame. At the Hub height.
1065  * The variable name is *XGRND *YGRND *ZGRND
1066  */
1067  /*
1068  * Get blade elements coordinates X,Y,Z.
1069  */
1072  // Maybe we have to modified here. Here we need
1073  // hub height coordinates.
1074  *XGRND = x(1);
1075  *YGRND = x(2);
1076  *ZGRND = x(3);
1077  /*
1078  * Get blade elements radius. It is the perpendicular distance
1079  * from the rotor axis to the element aerodynamic reference point.
1080  */
1081  const Vec3& X_node = ::module_aerodyn->pGetCurrBladeNode()->GetXCurr();
1082  const Vec3& X_hub = ::module_aerodyn->pGetHubNode()->GetXCurr();
1083  const Mat3x3& R_nacelle = ::module_aerodyn->pGetNacelleNode()->GetRCurr();
1084  Vec3 d = R_nacelle.MulTV(X_node - X_hub);
1085  d(3) = 0.;
1086  *radius = d.Norm();
1087 
1088  /*
1089  * Get the blade elements local pitch angle. Here X-axis is in the blade
1090  * spanwise direction.
1091  */
1092  // unsigned blade = ::module_aerodyn->iGetCurrBlade();
1093  const Mat3x3& R_node = ::module_aerodyn->pGetCurrBladeNode()->GetRCurr();
1094  const Mat3x3& R_hub = ::module_aerodyn->pGetHubNode()->GetRCurr();
1095  const Mat3x3& R_blade_root = ::module_aerodyn->GetCurrBladeR();
1096  Mat3x3 R = (R_hub*R_blade_root).MulTM(R_node);
1097  Vec3 Phi(RotManip::VecRot(R.Transpose()));
1098 
1099  // Pitch Now = Pitch + Twist
1102 
1103  /*
1104  * This comment is added by Fanzhong MENG 10th.Feb.2008
1105  * When the Multi-airfoil table option is open, we should also
1106  * switch on this option. By default, this value should be set to ZERO.
1107  * I don't know how this Multi-airfoil table work,yet.
1108  */
1109  *MulTabLoc = 0;
1110 
1111  return 0;
1112 }
1113 
1114 /*
1115  * Compute VT, VN{W,E} based on VX, VY, VZ of the wind.
1116  */
1117 int
1118 __FC_DECL__(getvnvt)(
1119  F_REAL *VX,
1120  F_REAL *VY,
1121  F_REAL *VZ,
1122  F_REAL *VT,
1123  F_REAL *VNW,
1124  F_REAL *VNE)
1125 {
1126  /*
1127  * Fanzhong MENG 18th.Feb.2008.
1128  * This function returns velocities of the wind
1129  * and the element in the ground reference frame.
1130  * VX,VY,VZ are provided by AeroDyn for MBDyn.
1131  */
1132  /*
1133  * This "getvnvt" function is correct now!
1134  */
1135  /*
1136  * velocity of the element related to Ground reference frame.
1137  */
1138  const Vec3& ve_G = ::module_aerodyn->pGetCurrBladeNode()->GetVCurr();
1139 
1140  /*
1141  * velocity of the wind related to Ground reference frame.
1142  * The "-" sign change the wind velocity from Aerodyn reference frame to MBDyn
1143  * Global reference frame. AeroDyn global reference frame can be found on page 35 of Aerodyn user's guide--Figure C1
1144  */
1145  Vec3 vw_G = Vec3(-(*VX), -(*VY), *VZ);
1146 
1147  /*
1148  * Transform wind vector from ground coordinate system (vw_G) to
1149  * blade Node reference frame (vw_El)
1150  */
1151  const Mat3x3& R_node = ::module_aerodyn->pGetCurrBladeNode()->GetRCurr();
1152  /*
1153  * 10th of June. Modified by fanzhong meng.
1154  * get orientation matrix of node twist with respect to node without pitch.
1155  */
1156  const Mat3x3& R_node_twist = ::module_aerodyn->GetCurrBladeNodeRa();
1157 
1158 
1159  Vec3 vw_El = R_node_twist.MulTV( R_node.MulTV(vw_G) );
1160  Vec3 ve_El = R_node_twist.MulTV( R_node.MulTV(ve_G) );
1161 
1162  /*
1163  * Calculate SIN and COS value of current pitch angle.
1164  */
1165 
1167  doublereal CPitchNow = std::cos(PitchNow);
1168  doublereal SPitchNow = std::sin(PitchNow);
1169 
1170  /*
1171  * Play around with these SIN and COS value to get
1172  * *VT,*VNW and *VNE.
1173  */
1174 
1175  doublereal vt_wind = -vw_El(2)*CPitchNow - vw_El(3)*SPitchNow;
1176  doublereal vt_element = ve_El(2)*CPitchNow + ve_El(3)*SPitchNow;
1177 
1178  *VT = vt_wind + vt_element;
1179  *VNW = -vw_El(2)*SPitchNow + vw_El(3)*CPitchNow;
1180  /*
1181  * Element Normal velocity opposites to the Wind Normal velocity.
1182  * You can find is on page 35 of Aerodyn user's guide--Figure C2.
1183  */
1184  *VNE = -(-ve_El(2)*SPitchNow + ve_El(3)*CPitchNow);
1185 
1186  return 0;
1187 }
1188 
1189 /*
1190  * Write an error message to the appropriate stream
1191  * By Fanzhong Meng: usrmes is an Adams built in function.
1192  * We have to rewrite this function. Because libAeroDyn.a library-GenSub.f90 will call this function,
1193  * so we can not simply remove this function.
1194  *
1195  * FIXME: the "msg" and "level" arrays should be reset by the caller
1196  * before writing the message, otherwise they're not '\0' terminated
1197  */
1198 int
1199 __FC_DECL__(usrmes)(
1200  F_LOGICAL *Logical,
1201  F_CHAR msg[],
1202  F_INTEGER *code,
1203  F_CHAR level[])
1204 {
1205 #if 0
1206  // can't work, unless we know the size of the arrays!
1207  silent_cerr("module-aerodyn: msg=\"" << msg << "\" "
1208  "code=" << *code
1209  << " level=" << level
1210  << std::endl);
1211 #endif
1212  silent_cerr("module-aerodyn: diagnostics from AeroDyn, "
1213  "code=" << *code << std::endl);
1214 
1215  return 0;
1216 }
1217 
1218 extern "C" int
1219 module_init(const char *module_name, void *pdm, void *php)
1220 {
1222 
1223  if (!SetUDE("aerodyn", rf)) {
1224  delete rf;
1225 
1226  silent_cerr("module-aerodyn: "
1227  "module_init(" << module_name << ") "
1228  "failed" << std::endl);
1229 
1230  return -1;
1231  }
1232 
1233  return 0;
1234 }
1235 
F_LOGICAL FirstLoop
Mat3x3 GetRotRel(const ReferenceFrame &rf)
Definition: mbpar.cc:1795
int __FC_DECL__() aerofrcintrface(F_LOGICAL *FirstLoop, F_INTEGER *JElem, F_REAL *DFN, F_REAL *DFT, F_REAL *PMA)
doublereal dGetCurrBladeNodePITNOW(void) const
#define M_PI
Definition: gradienttest.cc:67
const Vec3 Zero3(0., 0., 0.)
VariableSubMatrixHandler & InitialAssJac(VariableSubMatrixHandler &WorkMat, const VectorHandler &XCurr)
doublereal dGetCurrBladeNodeBuiltinTwist(void) const
SubVectorHandler & InitialAssRes(SubVectorHandler &WorkVec, const VectorHandler &XCurr)
doublereal Thrust
std::ofstream out
void AfterConvergence(const VectorHandler &X, const VectorHandler &XP)
#define MBDYN_EXCEPT_ARGS
Definition: except.h:63
Definition: matvec3.h:98
GradientExpression< UnaryExpr< FuncSin, Expr > > sin(const GradientExpression< Expr > &u)
Definition: gradient.h:2977
int __FC_DECL__() mbdyn_true(F_LOGICAL *val)
std::vector< Mat3x3 > bladeR
#define DEBUGCOUTFNAME(fname)
Definition: myassert.h:256
virtual void ResizeReset(integer)
Definition: vh.cc:55
virtual integer GetInt(integer iDefval=0)
Definition: parser.cc:1050
virtual const Mat3x3 & GetRCurr(void) const
Definition: strnode.h:1012
int __FC_DECL__() getelemparams(F_INTEGER *MulTabLoc, F_REAL *phi, F_REAL *radius, F_REAL *XGRND, F_REAL *YGRND, F_REAL *ZGRND)
std::string ofname
doublereal Norm(void) const
Definition: matvec3.h:263
StructNode * pHub
doublereal Rotor_speed
doublereal dCurTime
unsigned int iGetNumPrivData(void) const
void WorkSpaceDim(integer *piNumRows, integer *piNumCols) const
virtual unsigned int iGetPrivDataIdx(const char *s) const
Definition: simentity.cc:142
static AeroDynModule * module_aerodyn
int __FC_DECL__() mbdyn_init(F_CHAR *Version, F_INTEGER *nblades, F_REAL *rotradius)
AeroDynModule(unsigned uLabel, const DofOwner *pDO, DataManager *pDM, MBDynParser &HP)
const Mat3x3 Eye3(1., 0., 0., 0., 1., 0., 0., 0., 1.)
virtual const char * GetFileName(enum Delims Del=DEFAULTDELIM)
Definition: parsinc.cc:673
const DriveHandler * pGetDrvHdl(void) const
Definition: dataman.h:340
int __FC_DECL__() getvnvt(F_REAL *VX, F_REAL *VY, F_REAL *VZ, F_REAL *VT, F_REAL *VNW, F_REAL *VNE)
std::vector< AeroNode > nodes
#define NO_OP
Definition: myassert.h:74
std::vector< Hint * > Hints
Definition: simentity.h:89
doublereal dOldTime
Vec3 GetVec(unsigned short int i) const
Definition: matvec3.h:893
void Output(OutputHandler &OH) const
Vec3 VecRot(const Mat3x3 &Phi)
Definition: Rot.cc:136
DofOrder::Order GetDofType(unsigned int i) const
Vec3 MulTV(const Vec3 &v) const
Definition: matvec3.cc:482
doublereal dGetHubTowerXYDistance(void) const
void GetConnectedNodes(std::vector< const Node * > &connectedNodes) const
virtual void PutRowIndex(integer iSubRow, integer iRow)=0
int __FC_DECL__() mbdyn_false(F_LOGICAL *val)
int __FC_DECL__() getrotorparams(F_REAL *Omega, F_REAL *gamma, F_REAL *VHUB, F_REAL *tau)
F_INTEGER c_blade
const Mat3x3 & GetCurrBladeNodeRa(void) const
int __FC_DECL__() mbdyn_sim_time(doublereal *c_time)
doublereal Torque
Vec3 GetPosRel(const ReferenceFrame &rf)
Definition: mbpar.cc:1331
const Mat3x3 & GetCurrBladeR(void) const
void SetNullMatrix(void)
Definition: submat.h:1159
void SetCurrBladeNodePITNOW(doublereal PITNOW)
virtual bool IsKeyWord(const char *sKeyWord)
Definition: parser.cc:910
int module_init(const char *module_name, void *pdm, void *php)
VariableSubMatrixHandler & AssJac(VariableSubMatrixHandler &WorkMat, doublereal dCoef, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
const StructNode * pGetHubNode(void) const
virtual const char * GetStringWithDelims(enum Delims Del=DEFAULTDELIM, bool escape=true)
Definition: parser.cc:1228
Definition: mbdyn.h:77
StructNode * pNacelle
const StructNode * pGetCurrBladeNode(void) const
int __FC_DECL__() mbdyn_com_data(F_INTEGER *c_blade, F_INTEGER *c_elem)
int GetNumConnectedNodes(void) const
virtual const Vec3 & GetWCurr(void) const
Definition: strnode.h:1030
unsigned int uLabel
Definition: withlab.h:44
unsigned int iGetNumDof(void) const
F_INTEGER iGetCurrBlade(void) const
#define ASSERT(expression)
Definition: colamd.c:977
char F_CHAR
Definition: NREL_AeroDyn.h:64
void SetValue(DataManager *pDM, VectorHandler &X, VectorHandler &XP, SimulationEntity::Hints *h=0)
const StructNode * pGetNacelleNode(void) const
F_INTEGER iGetNumBlades(void) const
GradientExpression< UnaryExpr< FuncSqrt, Expr > > sqrt(const GradientExpression< Expr > &u)
Definition: gradient.h:2974
VectorExpression< VectorCrossExpr< VectorLhsExpr, VectorRhsExpr >, 3 > Cross(const VectorExpression< VectorLhsExpr, 3 > &u, const VectorExpression< VectorRhsExpr, 3 > &v)
Definition: matvec.h:3248
virtual const Vec3 & GetXCurr(void) const
Definition: strnode.h:310
F_INTEGER c_elem
virtual void Add(integer iRow, const Vec3 &v)
Definition: vh.cc:63
int __FC_DECL__() getbladeparams(F_REAL *psi)
void InitialWorkSpaceDim(integer *piNumRows, integer *piNumCols) const
virtual doublereal dGetPrivData(unsigned int i) const
Definition: simentity.cc:149
unsigned int iGetInitialNumDof(void) const
int __FC_DECL__() mbdyn_get_tl_const(F_REAL *RLOCAL, F_INTEGER *Cur_elem)
static std::stack< cleanup * > c
Definition: cleanup.cc:59
Mat3x3 Transpose(void) const
Definition: matvec3.h:816
int __FC_DECL__() usrmes(F_LOGICAL *Logical, F_CHAR msg[], F_INTEGER *code, F_CHAR level[])
int __FC_DECL__() elemout(void)
Definition: elem.h:75
void AfterPredict(VectorHandler &X, VectorHandler &XP)
struct mbrtai_msg_t msg
std::ostream & Restart(std::ostream &out) const
long int F_INTEGER
Definition: NREL_AeroDyn.h:65
long int F_LOGICAL
Definition: NREL_AeroDyn.h:63
void SetRotorSpeed(doublereal Omega)
bool SetUDE(const std::string &s, UserDefinedElemRead *rude)
Definition: userelem.cc:97
void Set(const DriveCaller *pDC)
Definition: drive.cc:647
doublereal dGet(const doublereal &dVar) const
Definition: drive.cc:664
F_INTEGER iGetNumBladeElems(void) const
DriveOwner FSF
virtual const Vec3 & GetVCurr(void) const
Definition: strnode.h:322
GradientExpression< UnaryExpr< FuncCos, Expr > > cos(const GradientExpression< Expr > &u)
Definition: gradient.h:2978
DriveCaller * GetDriveCaller(bool bDeferred=false)
Definition: mbpar.cc:2033
SubVectorHandler & AssRes(SubVectorHandler &WorkVec, doublereal dCoef, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
int __FC_DECL__() mbdyn_ad_inputgate(F_CHAR *ifname, F_INTEGER *ifnamelen, F_CHAR *efname, F_INTEGER *efnamelen)
GradientExpression< BinaryExpr< FuncAtan2, LhsExpr, RhsExpr > > atan2(const GradientExpression< LhsExpr > &u, const GradientExpression< RhsExpr > &v)
Definition: gradient.h:2962
double doublereal
Definition: colamd.c:52
long int integer
Definition: colamd.c:51
virtual HighParser::ErrOut GetLineData(void) const
Definition: parsinc.cc:697
unsigned int GetLabel(void) const
Definition: withlab.cc:62
Node * ReadNode(MBDynParser &HP, Node::Type type) const
Definition: dataman3.cc:2309
DriveOwner Time
F_INTEGER iGetCurrBladeElem(void) const
int __FC_DECL__() mbdyn_time_step(F_REAL *dt)
int __FC_DECL__() mbdyn_get_hl_const(F_REAL *RLOCAL, F_INTEGER *Cur_elem, F_REAL *RHub)
Mat3x3 R
doublereal Hub_Tower_xy_distance
virtual doublereal GetReal(const doublereal &dDefval=0.0)
Definition: parser.cc:1056