68 #define USE_SINGLE_PRECISION
73 :
virtual public Elem,
118 mutable std::ofstream
out;
189 std::ostream&
Restart(std::ostream&
out)
const;
239 "Module: AeroDyn" << std::endl
241 <<
"Author: Fanzhong Meng, Pierangelo Masarati" << 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
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
272 if (::module_aerodyn != 0) {
273 silent_cerr(
"AeroDynModule::AeroDynModule(" << uLabel <<
"): "
274 "AeroDyn already in use" << std::endl);
281 silent_cerr(
"AeroDynModule(" <<
GetLabel() <<
"): "
282 "nacelle node not defined "
290 silent_cerr(
"AeroDynModule(" <<
GetLabel() <<
"): "
291 "hub node not defined "
307 char Version[26 + 1];
308 snprintf(Version,
sizeof(Version),
"(%s)", VERSION);
309 for (
unsigned i = strlen(Version); i <
sizeof(Version); i++) {
312 Version[
sizeof(Version) - 1] =
'\0';
317 silent_cerr(
"AeroDynModule(" <<
GetLabel() <<
"): "
318 "invalid number of blades " << NBlades
327 silent_cerr(
"AeroDynModule(" <<
GetLabel() <<
"): "
328 "invalid number of elements per blade " << NElems
339 nodes.resize(NBlades*NElems);
343 if ((
elem % NElems) == 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;
382 if (HP.
IsKeyWord(
"force" "scale" "factor")) {
389 if (HP.
IsKeyWord(
"output" "file" "name")) {
392 silent_cerr(
"AeroDynModule(" <<
GetLabel() <<
"): "
393 "unable to get file name "
401 silent_cerr(
"AeroDynModule(" <<
GetLabel() <<
"): "
402 "unable to open file \"" << ofname <<
"\" "
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"
418 std::string input_file_name;
419 std::string elem_file_name;
421 if (HP.
IsKeyWord(
"input" "file" "name")) {
424 silent_cerr(
"unable to get input file name "
428 input_file_name = fname;
431 if (HP.
IsKeyWord(
"element" "file" "name")) {
434 silent_cerr(
"unable to get element file name "
438 elem_file_name = fname;
441 F_INTEGER input_file_name_len = input_file_name.size();
442 F_INTEGER elem_file_name_len = elem_file_name.size();
444 (
F_CHAR *)elem_file_name.c_str(), &elem_file_name_len);
446 silent_cerr(
"AeroDynModule(" <<
GetLabel() <<
"): "
447 "initialization failed "
448 "(err=" << rc <<
")" << std::endl);
459 Vec3 d = R_nacelle.
MulTV(X_node - X_hub);
495 out << std::scientific
497 << std::setw(16) <<
Thrust/1000.0
498 << std::setw(16) <<
Torque/1000.0
508 return out <<
"not implemented yet;" << std::endl;
566 BladeAxis = BladeR.
GetVec(1);
572 F_REAL DFN, DFT, PMA;
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
612 #ifdef MODULE_AERODYN_DEBUG
616 #endif // MODULE_AERODYN_DEBUG
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
631 #ifdef MODULE_AERODYN_DEBUG
632 silent_cerr(std::endl);
633 #endif // MODULE_AERODYN_DEBUG
646 for (
int i = 1; i <= 6; i++) {
792 return nodes.size() + 2;
801 connectedNodes.resize(
nodes.size() + 2);
804 for (n = 0; n <
nodes.size(); n++) {
805 connectedNodes[n] =
nodes[n].pNode;
809 connectedNodes[n++] =
pHub;
971 *Omega = std::abs(hub_Omega*rotation_axis);
981 *gamma =
std::atan2(-rotation_axis(2), -rotation_axis(1));
991 std::sqrt(rotation_axis(1)*rotation_axis(1) + rotation_axis(2)*rotation_axis(2)));
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
1032 Mat3x3 R = (R_hub*R_blade_root).MulTM(R_nacelle);
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
1084 Vec3 d = R_nacelle.
MulTV(X_node - X_hub);
1096 Mat3x3 R = (R_hub*R_blade_root).MulTM(R_node);
1145 Vec3 vw_G =
Vec3(-(*VX), -(*VY), *VZ);
1175 doublereal vt_wind = -vw_El(2)*CPitchNow - vw_El(3)*SPitchNow;
1176 doublereal vt_element = ve_El(2)*CPitchNow + ve_El(3)*SPitchNow;
1178 *VT = vt_wind + vt_element;
1179 *VNW = -vw_El(2)*SPitchNow + vw_El(3)*CPitchNow;
1184 *VNE = -(-ve_El(2)*SPitchNow + ve_El(3)*CPitchNow);
1207 silent_cerr(
"module-aerodyn: msg=\"" <<
msg <<
"\" "
1209 <<
" level=" << level
1212 silent_cerr(
"module-aerodyn: diagnostics from AeroDyn, "
1213 "code=" << *code << std::endl);
1223 if (!
SetUDE(
"aerodyn", rf)) {
1226 silent_cerr(
"module-aerodyn: "
1227 "module_init(" << module_name <<
") "
1228 "failed" << std::endl);
Mat3x3 GetRotRel(const ReferenceFrame &rf)
int __FC_DECL__() aerofrcintrface(F_LOGICAL *FirstLoop, F_INTEGER *JElem, F_REAL *DFN, F_REAL *DFT, F_REAL *PMA)
doublereal dGetCurrBladeNodePITNOW(void) const
const Vec3 Zero3(0., 0., 0.)
VariableSubMatrixHandler & InitialAssJac(VariableSubMatrixHandler &WorkMat, const VectorHandler &XCurr)
doublereal dGetCurrBladeNodeBuiltinTwist(void) const
SubVectorHandler & InitialAssRes(SubVectorHandler &WorkVec, const VectorHandler &XCurr)
void AfterConvergence(const VectorHandler &X, const VectorHandler &XP)
#define MBDYN_EXCEPT_ARGS
GradientExpression< UnaryExpr< FuncSin, Expr > > sin(const GradientExpression< Expr > &u)
int __FC_DECL__() mbdyn_true(F_LOGICAL *val)
std::vector< Mat3x3 > bladeR
#define DEBUGCOUTFNAME(fname)
virtual void ResizeReset(integer)
virtual integer GetInt(integer iDefval=0)
virtual const Mat3x3 & GetRCurr(void) const
int __FC_DECL__() getelemparams(F_INTEGER *MulTabLoc, F_REAL *phi, F_REAL *radius, F_REAL *XGRND, F_REAL *YGRND, F_REAL *ZGRND)
doublereal Norm(void) const
unsigned int iGetNumPrivData(void) const
void WorkSpaceDim(integer *piNumRows, integer *piNumCols) const
virtual unsigned int iGetPrivDataIdx(const char *s) const
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)
const DriveHandler * pGetDrvHdl(void) const
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
std::vector< Hint * > Hints
Vec3 GetVec(unsigned short int i) const
void Output(OutputHandler &OH) const
Vec3 VecRot(const Mat3x3 &Phi)
DofOrder::Order GetDofType(unsigned int i) const
Vec3 MulTV(const Vec3 &v) const
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)
const Mat3x3 & GetCurrBladeNodeRa(void) const
int __FC_DECL__() mbdyn_sim_time(doublereal *c_time)
Vec3 GetPosRel(const ReferenceFrame &rf)
const Mat3x3 & GetCurrBladeR(void) const
void SetCurrBladeNodePITNOW(doublereal PITNOW)
virtual bool IsKeyWord(const char *sKeyWord)
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)
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
unsigned int iGetNumDof(void) const
F_INTEGER iGetCurrBlade(void) const
#define ASSERT(expression)
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)
VectorExpression< VectorCrossExpr< VectorLhsExpr, VectorRhsExpr >, 3 > Cross(const VectorExpression< VectorLhsExpr, 3 > &u, const VectorExpression< VectorRhsExpr, 3 > &v)
virtual const Vec3 & GetXCurr(void) const
virtual void Add(integer iRow, const Vec3 &v)
int __FC_DECL__() getbladeparams(F_REAL *psi)
void InitialWorkSpaceDim(integer *piNumRows, integer *piNumCols) const
virtual doublereal dGetPrivData(unsigned int i) const
unsigned int iGetInitialNumDof(void) const
int __FC_DECL__() mbdyn_get_tl_const(F_REAL *RLOCAL, F_INTEGER *Cur_elem)
static std::stack< cleanup * > c
Mat3x3 Transpose(void) const
int __FC_DECL__() usrmes(F_LOGICAL *Logical, F_CHAR msg[], F_INTEGER *code, F_CHAR level[])
int __FC_DECL__() elemout(void)
void AfterPredict(VectorHandler &X, VectorHandler &XP)
std::ostream & Restart(std::ostream &out) const
void SetRotorSpeed(doublereal Omega)
bool SetUDE(const std::string &s, UserDefinedElemRead *rude)
void Set(const DriveCaller *pDC)
doublereal dGet(const doublereal &dVar) const
F_INTEGER iGetNumBladeElems(void) const
virtual const Vec3 & GetVCurr(void) const
GradientExpression< UnaryExpr< FuncCos, Expr > > cos(const GradientExpression< Expr > &u)
DriveCaller * GetDriveCaller(bool bDeferred=false)
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)
virtual HighParser::ErrOut GetLineData(void) const
unsigned int GetLabel(void) const
Node * ReadNode(MBDynParser &HP, Node::Type type) const
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)
doublereal Hub_Tower_xy_distance
virtual doublereal GetReal(const doublereal &dDefval=0.0)