00001
00002
00003 #ifndef TURBINE_MECHANISM_H
00004 #define TURBINE_MECHANISM_H
00005
00006 #define MAXBLADES 10
00007
00008
00009 #define TURBINE_LOG_ON
00010
00011 #include "Point.h"
00012 #include "Assembly.h"
00013 #include "DH_Chain.h"
00014 #include "Scene.h"
00015
00021 class TurbineControl : public controlable {
00022 public:
00023 TurbineControl() { ontop = 1; }
00024
00025 ~TurbineControl() {}
00026
00027 virtual void register_at(ControlDevice& Ctrl) {}
00028
00029 virtual void register_at(ControlDevice& Ctrl, const std::string& prefix, int num) {
00030 char VariableName[32];
00031
00032 idNum = num;
00033 std::sprintf(VariableName,"Turbine(%02d)",num+1);
00034
00035 #ifdef TURBINE_DEBUG_ON
00036 std::cout << "Registering " << VariableName << std::endl;
00037 #endif
00038
00039 TLocCtrl = Ctrl.getSubDevice(std::string(VariableName));
00040 RegisterAt(TLocCtrl,"Turbine_name",turbine_name);
00041 RegisterAt(TLocCtrl,"Tower_name",tower_name);
00042 RegisterAt(TLocCtrl,"Nacelle_name",nacelle_name);
00043 RegisterAt(TLocCtrl,"Hub_name",hub_name);
00044 RegisterAt(TLocCtrl,"Tower_file",tower_file);
00045 RegisterAt(TLocCtrl,"Nacelle_file",nacelle_file);
00046 RegisterAt(TLocCtrl,"Hub_file",hub_file);
00047 RegisterAt(TLocCtrl,"Tower_filetype",tower_filetype);
00048 RegisterAt(TLocCtrl,"Nacelle_filetype",nacelle_filetype);
00049 RegisterAt(TLocCtrl,"Hub_filetype",hub_filetype);
00050
00051 RegisterAt(TLocCtrl,"offset",part_offset);
00052
00053 RegisterAt(TLocCtrl,"num_blades",num_blades);
00054 for (register int i = 0; i < MAXBLADES; i++) {
00055 std::sprintf(VariableName,"Blade(%02d)_name",i+1);
00056 RegisterAt(TLocCtrl,std::string(VariableName),blade_name[i]);
00057 std::sprintf(VariableName,"Blade(%02d)_file",i+1);
00058 RegisterAt(TLocCtrl,std::string(VariableName),blade_file[i]);
00059 std::sprintf(VariableName,"Blade(%02d)_filetype",i+1);
00060 RegisterAt(TLocCtrl,std::string(VariableName),blade_filetype[i]);
00061 }
00062
00063 towerBase.register_at(TLocCtrl,"towerBase");
00064 tower_nacelle.register_at(TLocCtrl,"tower-nacelle");
00065 nacelleBase.register_at(TLocCtrl,"nacelleBase");
00066 nacelle_tower.register_at(TLocCtrl,"nacelle_tower");
00067 nacelle_rotor.register_at(TLocCtrl,"nacelle_rotor");
00068 for (register int i=0; i < MAXBLADES; i++) {
00069 std::sprintf(VariableName,"BladeJoint(%02d)",i+1);
00070 blades[i].register_at(TLocCtrl,std::string(VariableName));
00071 }
00072
00073 scene_tower.register_at(TLocCtrl,"scene_tower");
00074 RegisterAt(TLocCtrl,"ontop",ontop);
00075 RegisterAt(TLocCtrl,"xpos",xpos);
00076 RegisterAt(TLocCtrl,"ypos",ypos);
00077
00078 RegisterAt(TLocCtrl,"yaw_initial",yaw_initial);
00079 RegisterAt(TLocCtrl,"yaw_rate",yaw_rate);
00080 RegisterAt(TLocCtrl,"rotation_initial",rotation_initial);
00081 RegisterAt(TLocCtrl,"rotation_rate",rotation_rate);
00082 RegisterAt(TLocCtrl,"pitch_control",pitch_control);
00083 RegisterAt(TLocCtrl,"v_minPitch",v_minPitch);
00084 RegisterAt(TLocCtrl,"alpha",alpha);
00085
00086 for (register int i=0; i < MAXBLADES; i++) {
00087 std::sprintf(VariableName,"theta(%02d)",i+1);
00088 RegisterAt(TLocCtrl,std::string(VariableName),theta[i]);
00089 std::sprintf(VariableName,"pitch_initial(%02d)",i+1);
00090 RegisterAt(TLocCtrl,std::string(VariableName),pitch_initial[i]);
00091 std::sprintf(VariableName,"pitch_rate(%02d)",i+1);
00092 RegisterAt(TLocCtrl,std::string(VariableName),pitch_rate[i]);
00093 std::sprintf(VariableName,"pitch_I(%02d)",i+1);
00094 RegisterAt(TLocCtrl,std::string(VariableName),pitch_I[i]);
00095 }
00096
00097
00098 RegisterAt(TLocCtrl,"I_rotor",I_rotor);
00099 RegisterAt(TLocCtrl,"brake_set",brake_set);
00100 RegisterAt(TLocCtrl,"brake_release",brake_release);
00101
00102 RegisterAt(TLocCtrl,"Wind_avg",wind_avg);
00103 RegisterAt(TLocCtrl,"blade_length",blade_length);
00104
00105 }
00106
00107 void print() {
00108 ( mklog() << "TURBINE CONTROL DEVICE\n"
00109 << "\tnum_blades = " << num_blades << " tower_name = " << tower_name << std::endl).flush();
00110 }
00111
00112 public:
00113 double LastTime;
00114 int Outputs, OutputEvery, CheckPointEvery;
00115 int idNum;
00116
00117 std::string turbine_name, tower_name, tower_file, nacelle_name, nacelle_file, hub_name, hub_file;
00118 std::string blade_name[MAXBLADES], blade_file[MAXBLADES];
00119 int num_blades, pitch_control;
00120 int tower_filetype, nacelle_filetype, hub_filetype, blade_filetype[MAXBLADES];
00121
00122 int ontop;
00123 DataType xpos, ypos, part_offset;
00124
00125 DataType yaw_initial, yaw_rate, rotation_initial, rotation_rate, theta[MAXBLADES];
00126 DataType pitch_initial[MAXBLADES], pitch_rate[MAXBLADES], pitch_I[MAXBLADES], v_minPitch, alpha;
00127
00128 JointControl towerBase, tower_nacelle, nacelleBase, nacelle_tower, nacelle_rotor, rotorBase, blades[MAXBLADES];
00129
00130 LinkControl scene_tower;
00131
00132 ControlDevice TLocCtrl;
00133
00134 DataType I_rotor, I_driveTrain, I_nacelleTower, I_rotorTower, I_DriveTower;
00135 DataType brake_set, brake_release, wind_avg, blade_length;
00136
00137 };
00138
00140 class SolidSolverSpecific;
00141
00142 class Turbine {
00143 typedef Assembly<DataType,3> AssemblyType;
00144 typedef Scene<DataType,3> SceneType;
00145 typedef Loft<DataType> LoftType;
00146 typedef Joint<DataType,3> JointType;
00147 typedef DH_Link<DataType,3> LinkType;
00148 typedef DH_Chain<DataType,3> ChainType;
00149
00150 public:
00151 friend class Terrain;
00152
00153 enum pitchType { free, collective, linear, relWind };
00154
00155 Turbine() {
00156 p_rotor = 0.;
00157 p_nacelle = 0.;
00158 v_rotor = 0.;
00159 v_nacelle = 0;
00160
00161 for (register int i = 0; i < MAXBLADES; i++) {
00162 a_blades[i] = 0.;
00163 v_blades[i] = 0.;
00164 p_blades[i] = 0.;
00165 }
00166
00167 }
00168
00169 ~Turbine() {}
00170
00171 bool build(int i, std::string name, std::string file, int type) {
00172 Turbine0pt->GetNthPart(i)->read(type,file);
00173 Turbine0pt->GetNthPart(i)->setName(name);
00174 return 1;
00175 }
00176
00177 bool specificSetup(SceneType& ThisScene, TurbineControl * TurbineCtrl ) {
00178 std::string nameTmp;
00179 ( mklog() << "\n\n*********\t Turbine specificSetup \tBegin\n*********" << std::endl ).flush();
00180
00182 nameTmp = "Turbine_Assembly0";
00183 Turbine0pt = new AssemblyType;
00184 Turbine0pt->setName(TurbineCtrl->turbine_name);
00185
00186 ThisScene.AddAssembly(*Turbine0pt);
00187 ThisScene.GetNthSceneAssembly(TurbineCtrl->idNum).print(0);
00188
00189 Turbine0pt = ThisScene.GetNthAssembly(TurbineCtrl->idNum);
00190
00191 Tower0 = new LoftType;
00192 Turbine0pt->AddPart(Tower0);
00193
00194 Turbine0pt->GetNthPart(0)->read(TurbineCtrl->tower_filetype,TurbineCtrl->tower_file);
00195 Turbine0pt->GetNthPart(0)->setName(TurbineCtrl->tower_name);
00196
00197 Tower0 = (LoftType *) Turbine0pt->GetNthPart(0);
00198 Tower0->measure();
00199
00200 Nacel0 = new LoftType;
00201 Turbine0pt->AddPart(Nacel0);
00202 Turbine0pt->GetNthPart(1)->read(TurbineCtrl->nacelle_filetype,TurbineCtrl->nacelle_file);
00203 nameTmp = "Nacel_Loft0";
00204 Turbine0pt->GetNthPart(1)->setName(TurbineCtrl->nacelle_name);
00205 Nacel0 = (LoftType *) Turbine0pt->GetNthPart(1);
00206
00207 Rotor0 = new AssemblyType;
00208 nameTmp = "Rotor_Assembly0";
00209 char VariableName[16];
00210 std::sprintf(VariableName,"Rotor_%02d",TurbineCtrl->idNum+1);
00211 Rotor0->setName(std::string(VariableName));
00212
00213 Turbine0pt->AddSubAssembly(*Rotor0);
00214 Rotor0 = Turbine0pt->GetNthSubAssembly(0);
00215
00216 for (register int ib = 0; ib < TurbineCtrl->num_blades; ib++) {
00217 Blades[ib] = new LoftType;
00218 Rotor0->AddPart(Blades[ib]);
00219 Rotor0->GetNthPart(ib)->read(TurbineCtrl->blade_filetype[ib],TurbineCtrl->blade_file[ib]);
00220 Rotor0->GetNthPart(ib)->setName(TurbineCtrl->blade_name[ib]);
00221 Blades[ib] = (LoftType *) Rotor0->GetNthPart(ib);
00222 }
00223
00224 Hub0 = new LoftType;
00225 Rotor0->AddPart(Hub0);
00226 Rotor0->GetNthPart(Rotor0->GetNumParts()-1 )->read(TurbineCtrl->hub_filetype,TurbineCtrl->hub_file);
00227 nameTmp = "Hub_Loft0";
00228 Rotor0->GetNthPart(Rotor0->GetNumParts()-1 )->setName(TurbineCtrl->hub_name);
00229 Hub0 = (LoftType *) Rotor0->GetNthPart(Rotor0->GetNumParts()-1);
00230
00231 ( mklog() << "\nparts added\n").flush();
00232
00233
00234 PType o(0.), x(0.), y(0.), z(0.);
00235
00236 o(0) = 0.; o(1) = 0.; o(2) = 0.;
00237 x(0) = 1.; x(1) = 0.; x(2) = 0.;
00238 y(0) = 0.; y(1) = 1.; y(2) = 0.;
00239 z(0) = 0.; z(1) = 0.; z(2) = 1.;
00240
00241 o(0) = 0.; o(1) = 0.; o(2) = 0.;
00242 x(0) = 1.; x(1) = 0.; x(2) = 0.;
00243 z(0) = 0.; z(1) = 0.; z(2) = 1.;
00244 JointType * zero;
00245 zero = new JointType(TurbineCtrl->towerBase.origin,TurbineCtrl->towerBase.zaxis,TurbineCtrl->towerBase.xaxis,
00246 JointType::revolute,Tower0->IdTag());
00247
00248 L0 = new LinkType(*ThisScene.GetCoordFrame(),*zero, TurbineCtrl->scene_tower.r, TurbineCtrl->scene_tower.a, TurbineCtrl->scene_tower.d, TurbineCtrl->scene_tower.t);
00249 L0->setId(-1);
00250
00251 o(0) = 0.; o(1) = 0.; o(2) = 31.5;
00252 z(0) = 0.; z(1) = 0.; z(2) = 1.;
00253 x(0) = 1.; x(1) = 0.; x(2) = 0.;
00254 JointType * one;
00255 one = new JointType(o,z,x,JointType::sphericalWrist,Tower0->IdTag());
00256 LinkType * L1;
00257 L1 = new LinkType(*zero,*one);
00258
00259 o(0) = -0.05; o(1) = 0.; o(2) = 0.;
00260 z(0) = 1.; z(1) = 0.; z(2) = 0.;
00261 x(0) = 0.; x(1) = 0.; x(2) = 1.;
00262 JointType * two;
00263 two = new JointType(o,z,x,JointType::revolute,Nacel0->IdTag());
00264 LinkType * L2;
00265 L2 = new LinkType(*one,*two, 0., 0., 0.2, 0.);
00266
00267 o(0) = 0.; o(1) = 0.; o(2) = 2.;
00268 z(0) = 0.; z(1) = 0.; z(2) = 1.;
00269 x(0) = 1.; x(1) = 0.; x(2) = 0.;
00270 JointType * three;
00271 three = new JointType(o,z,x,JointType::revolute,Nacel0->IdTag());
00272 LinkType * L3;
00273 L3 = new LinkType(*two,*three);
00274
00275 o(0) = 0.; o(1) = 0.; o(2) = 1.6;
00276 z(0) = 0.; z(1) = 0.; z(2) = 1.;
00277 x(0) = 1.; x(1) = 0.; x(2) = 0.;
00278 JointType * four;
00279 four = new JointType(o,z,x,JointType::prismatic,Nacel0->IdTag());
00280 LinkType * L4;
00281 L4 = new LinkType(*three,*four);
00282
00283 o(0) = 0.; o(1) = 0.; o(2) = 0.;
00284 z(0) = 1.; z(1) = 0.; z(2) = 0.;
00285 x(0) = 0.; x(1) = 0.; x(2) = 1.;
00286 JointType * five;
00287 five = new JointType(o,z,x,JointType::revolute,Rotor0->IdTag());
00288 LinkType * L5;
00289 L5 = new LinkType(*three,*five, 0., 0., 2.5, 0.);
00291
00292 o(0) = 0.0; o(1) = 0.; o(2) = 0.2;
00293 z(0) = 0.; z(1) = 0.; z(2) = 1.;
00294 x(0) = 0.; x(1) = 1.; x(2) = 0.;
00295 JointType * six;
00296 six = new JointType(o,z,x,JointType::revolute,Rotor0->GetNthPart(0)->IdTag());
00297 LinkType * L6;
00298 L6 = new LinkType(*five,*six);
00299
00300 o(0) = 0.; o(1) = 0.; o(2) = 0.;
00301 z(0) = 0.; z(1) = 0.; z(2) = 1.;
00302 x(0) = 1.; x(1) = 0.; x(2) = 0.;
00303 JointType * six_n;
00304 six_n = new JointType(o,z,x,JointType::revolute,Rotor0->GetNthPart(0)->IdTag());
00305 LinkType * L6_n;
00306 L6_n = new LinkType(*six,*six_n);
00308
00309 o(0) = 0.0; o(1) = 0.; o(2) = 0.2;
00310 z(0) = 0.; z(1) = 0.; z(2) = 1.;
00311 x(0) = 1.; x(1) = 0.; x(2) = 0.;
00312 JointType * seven;
00313 seven = new JointType(o,z,x,JointType::revolute,Rotor0->GetNthPart(1)->IdTag());
00314 LinkType * L7;
00315 L7 = new LinkType(*five,*seven);
00316
00317 o(0) = 0.; o(1) = 0.; o(2) = 0.;
00318 z(0) = 0.; z(1) = 0.; z(2) = 1.;
00319 x(0) = 1.; x(1) = 0.; x(2) = 0.;
00320 JointType * seven_n;
00321 seven_n = new JointType(o,z,x,JointType::revolute,Rotor0->GetNthPart(1)->IdTag());
00322 LinkType * L7_n;
00323 L7_n = new LinkType(*seven,*seven_n);
00325
00326 o(0) = 0.0; o(1) = 0.; o(2) = 0.2;
00327 z(0) = 0.; z(1) = 0.; z(2) = 1.;
00328 x(0) = 1.; x(1) = 0.; x(2) = 0.;
00329 JointType * eight;
00330 eight = new JointType(o,z,x,JointType::revolute,Rotor0->GetNthPart(2)->IdTag());
00331 LinkType * L8;
00332 L8 = new LinkType(*five,*eight);
00333
00334 o(0) = 0.; o(1) = 0.; o(2) = 0.;
00335 z(0) = 0.; z(1) = 0.; z(2) = 1.;
00336 x(0) = 1.; x(1) = 0.; x(2) = 0.;
00337 JointType * eight_n;
00338 eight_n = new JointType(o,z,x,JointType::revolute,Rotor0->GetNthPart(2)->IdTag());
00339 LinkType * L8_n;
00340 L8_n = new LinkType(*eight,*eight_n);
00342
00343 o(0) = 0.0; o(1) = 0.; o(2) = 0.;
00344 z(0) = 0.; z(1) = 0.; z(2) = 1.;
00345 x(0) = 1.; x(1) = 0.; x(2) = 0.;
00346 JointType * nine;
00347 nine = new JointType(o,z,x,JointType::revolute,Rotor0->GetNthPart(3)->IdTag());
00348 LinkType * L9;
00349 L9 = new LinkType(*five,*nine);
00350
00351 o(0) = 0.; o(1) = 0.; o(2) = -0.25;
00352 z(0) = 0.; z(1) = 0.; z(2) = 1.;
00353 x(0) = 1.; x(1) = 0.; x(2) = 0.;
00354 JointType * nine_n;
00355 nine_n = new JointType(o,z,x,JointType::revolute,Rotor0->GetNthPart(3)->IdTag());
00356 LinkType * L9_n;
00357 L9_n = new LinkType(*nine,*nine_n);
00359
00360 ThisScene.addLink(L0);
00361 L0_index = ThisScene.GetNumLinks();
00362
00363 C1 = new ChainType;
00364 C1->AddJoint(zero);
00365 C1->AddJoint(one);
00366 C1->AddJoint(two);
00367 C1->AddJoint(three);
00368 C1->AddJoint(four);
00369 C1->AddJoint(five);
00370 C1->addLink(L1);
00371 C1->addLink(L2);
00372 C1->addLink(L3);
00373 C1->addLink(L5);
00374 C1->addNativeLink(L4);
00375 C1->addTernLink(2,0);
00376 C1->setParentChain(-L0_index);
00377 C1->GetNthLink(0)->setQ_pre(0.0);
00378
00379 ThisScene.AddChain(C1);
00380 C1_index = ThisScene.GetNumChains()-1;
00381
00382 C2 = new ChainType;
00383 C2->AddJoint(five);
00384 C2->AddJoint(six);
00385 C2->AddJoint(six_n);
00386 C2->addLink(L6);
00387 C2->addNativeLink(L6_n);
00388 C2->addTernLink(0,0);
00389 C2->setParentChain(C1_index);
00390
00391 C3 = new ChainType;
00392 C3->AddJoint(five);
00393 C3->AddJoint(seven);
00394 C3->AddJoint(seven_n);
00395 C3->addLink(L7);
00396 C3->addNativeLink(L7_n);
00397 C3->addTernLink(0,0);
00398 C3->setParentChain(C1_index);
00399
00400 C4 = new ChainType;
00401 C4->AddJoint(five);
00402 C4->AddJoint(eight);
00403 C4->AddJoint(eight_n);
00404 C4->addLink(L8);
00405 C4->addNativeLink(L8_n);
00406 C4->addTernLink(0,0);
00407 C4->setParentChain(C1_index);
00408
00409 C5 = new ChainType;
00410 C5->AddJoint(five);
00411 C5->AddJoint(nine);
00412 C5->AddJoint(nine_n);
00413 C5->addLink(L9);
00414 C5->addNativeLink(L9_n);
00415 C5->addTernLink(0,0);
00416 C5->setParentChain(C1_index);
00417
00418 ThisScene.AddChain(C2);
00419 ThisScene.AddChain(C3);
00420 ThisScene.AddChain(C4);
00421 ThisScene.AddChain(C5);
00422
00424 yaw(TurbineCtrl->yaw_initial);
00425
00427 for ( register int i = 0; i < TurbineCtrl->num_blades; i++ ) {
00428 positionBlade(i,TurbineCtrl->theta[i]);
00429 pitch(i,TurbineCtrl->pitch_initial[i]);
00430 }
00432
00434 ( mklog() << "Turbine "<<TurbineCtrl->turbine_name<<"specific setup end\n" ).flush();
00435 return true;
00436 }
00437
00438
00439 void yaw(DataType val) {
00440 C1->GetNthLink(1)->actuate(val,0.,0.,1.);
00441 }
00442
00443 void ontop(SceneType& ThisScene, TurbineControl * TurbineCtrl, DataType offset ) {
00444 PType o(0.), x(0.), y(0.), z(0.), tmp(0.);
00445
00446 o(0) = 0.; o(1) = 0.; o(2) = 0.;
00447 x(0) = 1.; x(1) = 0.; x(2) = 0.;
00448 z(0) = 0.; z(1) = 0.; z(2) = 1.;
00449 ( mklog() << "=================== Joint at base of" << TurbineCtrl->tower_name << " ===================\n").flush();
00450 PType targ;
00451 targ(0) = TurbineCtrl->xpos; targ(1) = TurbineCtrl->ypos;
00452 targ(2) = 100.;
00453 DataType zmin = 0.;
00454 int flag = 0;
00455
00456 o = ThisScene.GetNthSceneAssembly( ThisScene.GetNumAssemblies()-1 ).surfacePoint(targ,zmin,flag,offset);
00457 L0 = ThisScene.GetNthLink(L0_index-1);
00458 ( mklog() << " PLACING ONTOP " << o << std::endl).flush();
00459 L0->getChild()->setOrigin(o);
00460 y = o - ThisScene.GetCoordFrame()->getOrigin();
00461 y = normalize(y);
00462 L0->update();
00463
00464 }
00465
00466 void positionBlade(int n, DataType val) {
00467 PType norm;
00468 norm(0) = 1.; norm(1) = 0.; norm(2) = 0.;
00469
00470 reflect( Blades[n]->GetCPoints(), Blades[n]->GetCPoints_org(), norm );
00471 std::copy (Blades[n]->GetCPoints_org().begin (), Blades[n]->GetCPoints_org().end (), std::back_inserter(Blades[n]->GetCPoints()) );
00472
00473 switch (n) {
00474 case 0 : {
00475 C2->GetNthLink(0)->actuate(val);
00476 break;
00477 }
00478 case 1 : {
00479 C3->GetNthLink(0)->actuate(val);
00480 break;
00481 }
00482 case 2 : {
00483 C4->GetNthLink(0)->actuate(val);
00484 break;
00485 }
00486 }
00487
00488 }
00489
00490 void rotate(DataType time, DataType period) {
00491 C1->GetNthLink(3)->actuate(-(time*DataType(360.0/period)));
00492 }
00493
00494 void rotate(DataType val) {
00495 C1->GetNthLink(3)->actuate(val);
00496 }
00497
00498
00499 void pitch(int n, DataType val) {
00500 switch (n) {
00501 case 0 : {
00502 C2->GetNthNative(0)->actuate(val);
00503 break;
00504 }
00505 case 1 : {
00506 C3->GetNthNative(0)->actuate(val);
00507 break;
00508 }
00509 case 2 : {
00510 C4->GetNthNative(0)->actuate(val);
00511 break;
00512 }
00513 }
00514
00515 }
00516
00517 AssemblyType * GetRotor() { return Rotor0; }
00518
00519 void response(Turbine * ThisTurbine, TurbineControl * TurbineCtrl, double& t, double& dt, int nsteps, int logevery) {
00520
00521 PType rotorCenter, arm, ftmp, ratmp;
00522 DataType rtmp;
00523 MType mtmp;
00524
00525 if ( (t-TurbineCtrl->brake_release) < dt) {
00526 p_rotor = TurbineCtrl->rotation_initial;
00527 for ( register int i = 0; i < MAXBLADES; i++) {
00528 p_blades[i] = TurbineCtrl->pitch_initial[i];
00529 }
00530 }
00531
00532 if ( (TurbineCtrl->brake_set > 0 && t >= TurbineCtrl->brake_release) || (TurbineCtrl->brake_set <= 0 ) ) {
00533 #ifdef TURBINE_DEBUG_ON
00534 if (nsteps % logevery == 0 )
00535 ( mklog() << "\t" << TurbineCtrl->turbine_name << " FSI response at time = " << t << " , dt = " << dt << std::endl ).flush();
00536 #endif
00537 rotorCenter(0) = 0.; rotorCenter(1) = 0.; rotorCenter(2) = 0.;
00538 for (register int b = 0; b < TurbineCtrl->num_blades; b++) {
00539 rotorCenter += ThisTurbine->Blades[b]->Centroid();
00540 }
00541 rotorCenter *= DataType(1.)/DataType(TurbineCtrl->num_blades);
00542 T_rotor = 0.;
00543 for (register int i = 0; i < TurbineCtrl->num_blades; i++) {
00544 arm = ThisTurbine->Blades[i]->Centroid() - rotorCenter;
00545 ftmp = ThisTurbine->Blades[i]->GetNetP();
00546 T_rotor += cross3D(arm, ftmp);
00547 }
00548 ratmp = ThisTurbine->Blades[0]->Centroid() - rotorCenter;
00549 ratmp = cross3D(arm,ratmp);
00550 T_rotor = project(T_rotor,ratmp);
00551 rtmp = projectScalar(T_rotor,ratmp);
00552 a_rotor = ( rtmp/TurbineCtrl->I_rotor );
00553
00554 if ( std::fabs(a_rotor/d2r) > 2.e3) {
00555 #ifdef TURBINE_LOG_ON
00556 ( mklog() << "\t _ACCELERATION LIMIT " << a_rotor/d2r << " reset to " << sgn(a_rotor)*2.e3 << std::endl ).flush();
00557 #endif
00558 a_rotor = sgn(a_rotor)*2.e3*d2r;
00559 }
00560
00561 v_rotor += a_rotor*dt;
00562 p_rotor += (DataType(0.5)*a_rotor*dt*dt + v_rotor*dt)/d2r;
00563
00565 ThisTurbine->rotate(-p_rotor);
00566
00568 DataType pBlade = 0., vBlade = 0.;
00569
00571 if ( TurbineCtrl->pitch_control == linear ) {
00572 #ifdef TURBINE_DEBUG_ON
00573 if (nsteps % logevery == 0 )
00574 ( mklog() << "\n\t=-linear Pitch Control v_minPitch " << TurbineCtrl->v_minPitch;
00575 #endif
00576 DataType vRtmp = std::fabs(v_rotor/d2r);
00577 for (register int i = 0; i < TurbineCtrl->num_blades; i++) {
00578 if ( vRtmp > TurbineCtrl->v_minPitch ) {
00579 pBlade = TurbineCtrl->pitch_initial[i] + TurbineCtrl->pitch_rate[i]*(vRtmp-TurbineCtrl->v_minPitch);
00580 #ifdef TURBINE_DEBUG_ON
00581 if (nsteps % logevery == 0 )
00582 ( mklog() << "\t\t" << i << " pitching : " << TurbineCtrl->pitch_initial[i] << " + "
00583 << TurbineCtrl->pitch_rate[i] << " * " << (vRtmp-TurbineCtrl->v_minPitch) << " = " << pBlade << std::endl ).flush();
00584 #endif
00585 ThisTurbine->pitch(i,pBlade);
00586 p_blades[i] = pBlade;
00587 }
00588 }
00589 }
00590 if ( TurbineCtrl->pitch_control == relWind ) {
00591 #ifdef TURBINE_DEBUG_ON
00592 if (nsteps % logevery == 0 )
00593 ( mklog() << "\t| Relative Wind Pitch Control\n";
00594 #endif
00595
00596 DataType wind = TurbineCtrl->wind_avg;
00597 DataType blade_length = TurbineCtrl->blade_length;
00598 DataType blade_speed = blade_length*std::fabs(v_rotor);
00599 pBlade = 180. - std::atan(wind/blade_speed)/d2r;
00600
00601 for (register int i = 0; i < TurbineCtrl->num_blades; i++) {
00602 p_blades[i] = DataType(0.5)*(pBlade + p_blades[i]);
00603 ThisTurbine->pitch(i,p_blades[i]);
00604
00605 }
00606
00607 #ifdef TURBINE_DEBUG_ON
00608 if (nsteps % logevery == 0 )
00609 ( mklog() << "\t blade tip speed [m/s] " << blade_speed << "\t tip speed ratio " << blade_speed/wind
00610 << "\t pitch [deg] : " << p_blades[0] << std::endl ).flush();
00611 #endif
00612
00613 }
00614
00616 else if ( TurbineCtrl->pitch_control == free ) {
00617 for (register int i = 0; i < TurbineCtrl->num_blades; i++) {
00618
00619 arm = ThisTurbine->Blades[i]->Centroid() - rotorCenter;
00620 ftmp = ThisTurbine->Blades[i]->GetMomP();
00621 rtmp = projectScalar(ftmp, arm);
00622 a_blades[i] = rtmp / TurbineCtrl->pitch_I[i];
00623 v_blades[i] += a_blades[i]*dt;
00624 p_blades[i] += DataType(0.5)*a_blades[i]*dt*dt + v_blades[i]*dt;
00625 ThisTurbine->pitch(i,p_blades[i]);
00626 #ifdef TURBINE_DEBUG_ON
00627 if (nsteps % logevery == 0 )
00628 ( mklog() << "\t " << i << " ThisTurbine->Blades[i]->GetMomP() " << ThisTurbine->Blades[i]->GetMomP()
00629 << " \t arm " << arm << " rtmp " << rtmp << std::endl
00630 << "\t\t" << i << " pitching : " << p_blades[i] << std::endl ).flush();
00631 #endif
00632 }
00633 }
00635 else if ( TurbineCtrl->pitch_control == collective ) {
00636 pBlade = 0.; vBlade = 0.;
00637 for (register int i = 0; i < TurbineCtrl->num_blades; i++) {
00638
00639
00640 arm = ThisTurbine->Blades[i]->Centroid() - rotorCenter;
00641 ftmp = ThisTurbine->Blades[i]->GetMomP();
00642 rtmp = projectScalar(ftmp, arm);
00643 a_blades[i] = rtmp / TurbineCtrl->pitch_I[i];
00644 v_blades[i] += a_blades[i]*dt;
00645 p_blades[i] += (DataType(0.5)*a_blades[i]*dt*dt + v_blades[i]*dt)/d2r;
00646 vBlade += v_blades[i];
00647 pBlade += p_blades[i];
00648 #ifdef TURBINE_DEBUG_ON
00649 ( mklog() << "\t p_blades["<<i<<"] " << p_blades[i] << " Blades["<<i<<"]->GetMomP() " << ThisTurbine->Blades[i]->GetMomP()
00650 << " \t arm " << arm << " rtmp " << rtmp << std::endl ).flush();
00651 #endif
00652 }
00653 pBlade /= TurbineCtrl->num_blades;
00654 vBlade /= TurbineCtrl->num_blades;
00655
00656 for (register int i = 0; i < TurbineCtrl->num_blades; i++) {
00657 v_blades[i] = vBlade;
00658 p_blades[i] = pBlade;
00659 ThisTurbine->pitch(i,pBlade);
00660 }
00661 #ifdef TURBINE_DEBUG_ON
00662 ( mklog() << "\n\t\t pitching collectively : " << pBlade << std::endl ).flush();
00663 #endif
00664 }
00665
00666 if ( nsteps % logevery == 0 ) {
00667 char fname[256];
00668 sprintf(fname,"motion_Kinetics.dat");
00669 std::ofstream ofs;
00670
00671 if ( ! fexists(fname) ) {
00672 ofs.open(fname, std::ios::out);
00673 ofs << "# 1 NSteps\t2 time\t3 TurbineName\t4 a_rotor\t5 v_rotor\6 tp_rotor";
00674 for (int b=0; b < TurbineCtrl->num_blades; b++) {
00675 ofs << "\t" << 6+b << " pitch[" << b << "]";
00676 }
00677 ofs << std::endl;
00678 }
00679 else {
00680 ofs.open(fname, std::ios::app);
00681 }
00682 ofs << nsteps << "\t" << t << "\t" << TurbineCtrl->turbine_name << "\t"
00683 << a_rotor/d2r << "\t" << v_rotor/d2r << "\t" << p_rotor << "\t";
00684 #ifdef TURBINE_DEBUG_ON
00685 ( mklog() << "\t " << nsteps << "\t time " << t << "\t" << TurbineCtrl->turbine_name << "\t accel. [deg s^-2] "
00686 << a_rotor/d2r << "\t vel. [deg/s] " << v_rotor/d2r << "\t pos. " << p_rotor << "\n";
00687 #endif
00688 for (int b=0; b < TurbineCtrl->num_blades; b++) {
00689 ofs << "\t" << p_blades[b];
00690 }
00691 ofs << std::endl;
00692 ofs.close();
00693 }
00694
00695 if ( nsteps % logevery == 0 ) {
00696
00697 #ifdef TURBINE_DEBUG_ON
00698 ( mklog() << "\t " << nsteps << "\t time " << t << "\t" << TurbineCtrl->turbine_name << "\t accel. [deg s^-2] "
00699 << a_rotor/d2r << "\t vel. [deg/s] " << v_rotor/d2r << "\t pos. " << p_rotor << "\n";
00700 #endif
00701 }
00702 }
00703 }
00704
00705 virtual void logKinetics(Turbine * ThisTurbine, TurbineControl * TurbineCtrl, std::ofstream& ofs, DataType time_, int steps ) {
00706
00707 PType cen, ftmp, axis;
00708
00709 ofs << "\t\t\"" << TurbineCtrl->turbine_name << "\": {\n";
00710 ofs << "\t\t\t\"rotor\": {\n\t\t\t\t\"acc\": " << a_rotor/d2r;
00711 ofs << ", \"vel\": " << v_rotor/d2r;
00712 ofs << ", \"pos\": " << p_rotor/d2r;
00713 ofs << ", \"colPitch\": " << p_blades[0] << ",";
00714 for (int b=0; b < TurbineCtrl->num_blades; b++) {
00715 cen = ThisTurbine->Blades[b]->Centroid();
00716 ftmp = ThisTurbine->Blades[b]->GetNetP();
00717 axis = ThisTurbine->Blades[b]->GetXaxis();
00718 ofs << "\n\t\t\t\t\"blade" << b << "\": {\"lift\": " << projectScalar(ftmp,axis);
00719 axis = ThisTurbine->Blades[b]->GetYaxis();
00720 ofs << ", \"drag\": " << projectScalar(ftmp,axis);
00721 axis = ThisTurbine->Blades[b]->GetZaxis();
00722 ofs << ", \"radial\": " << projectScalar(ftmp,axis);
00723 ofs << ", \"cenX\": " << cen(0);
00724 ofs << ", \"cenY\": " << cen(1);
00725 ofs << ", \"cenZ\": " << cen(2);
00726 ofs << ", \"ZaxiX\": " << axis(0);
00727 ofs << ", \"ZaxiY\": " << axis(1);
00728 ofs << ", \"ZaxiZ\": " << axis(2) << " }";
00729 if (b<TurbineCtrl->num_blades-1) ofs << ",";
00730 }
00731 ofs << "\n\t\t\t},";
00732 cen = ThisTurbine->Hub0->Centroid();
00733 ftmp = ThisTurbine->Hub0->GetNetP();
00734 axis = ThisTurbine->Hub0->GetXaxis();
00735 ofs << "\n\t\t\t\"hub\": { \"lateral\": " << projectScalar(ftmp,axis);
00736 axis = ThisTurbine->Hub0->GetYaxis();
00737 ofs << ", \"drag\": " << projectScalar(ftmp,axis);
00738 axis = ThisTurbine->Hub0->GetZaxis();
00739 ofs << ", \"lift\": " << projectScalar(ftmp,axis);
00740 ofs << ", \"cenX\": " << cen(0);
00741 ofs << ", \"cenY\": " << cen(1);
00742 ofs << ", \"cenZ\": " << cen(2);
00743 ofs << ", \"axiX\": " << axis(0);
00744 ofs << ", \"axiY\": " << axis(1);
00745 ofs << ", \"axiZ\": " << axis(2) << " },";
00746 cen = ThisTurbine->Nacel0->Centroid();
00747 ftmp = ThisTurbine->Nacel0->GetNetP();
00748 axis = ThisTurbine->Nacel0->GetXaxis();
00749 ofs << "\n\t\t\t\"nacelle\": { \"lateral\": " << projectScalar(ftmp,axis);
00750 axis = ThisTurbine->Nacel0->GetYaxis();
00751 ofs << ", \"drag\": " << projectScalar(ftmp,axis);
00752 axis = ThisTurbine->Nacel0->GetZaxis();
00753 ofs << ", \"lift\": " << projectScalar(ftmp,axis);
00754 ofs << ", \"cenX\": " << cen(0);
00755 ofs << ", \"cenY\": " << cen(1);
00756 ofs << ", \"cenZ\": " << cen(2);
00757 ofs << ", \"ZaxiX\": " << axis(0);
00758 ofs << ", \"ZaxiY\": " << axis(1);
00759 ofs << ", \"ZaxiZ\": " << axis(2) << " },";
00760 cen = ThisTurbine->Tower0->Centroid();
00761 ftmp = ThisTurbine->Tower0->GetNetP();
00762 axis = ThisTurbine->Tower0->GetXaxis();
00763 ofs << "\n\t\t\t\"tower\": { \"lateral\": " << projectScalar(ftmp,axis);
00764 axis = ThisTurbine->Tower0->GetYaxis();
00765 ofs << ", \"drag\": " << projectScalar(ftmp,axis);
00766 axis = ThisTurbine->Tower0->GetZaxis();
00767 ofs << ", \"lift\": " << projectScalar(ftmp,axis);
00768 ofs << ", \"cenX\": " << cen(0);
00769 ofs << ", \"cenY\": " << cen(1);
00770 ofs << ", \"cenZ\": " << cen(2);
00771 ofs << ", \"ZaxiX\": " << axis(0);
00772 ofs << ", \"ZaxiY\": " << axis(1);
00773 ofs << ", \"ZaxiZ\": " << axis(2) << " }";
00774 ofs << "\n\t\t}";
00775
00776 }
00777
00778
00779
00780 void movement(Turbine * ThisTurbine, TurbineControl * TurbineCtrl, double& t, double& dt) {
00781
00782 #ifdef TURBINE_DEBUG_ON
00783 ( mklog() << "\n\n*********\tSolidSolverSpecific movement aDVANCE bEGIN\n*********" << std::endl ).flush();
00784 ( mklog() << " time = " << t << " time*DataType(360.0/6.) = " << t*DataType(360.0/6.)
00785 << " time*DataType(360.0/6.)*d2r = " << t*DataType(360.0/6.)*d2r << std::endl
00786 << " dt = " << dt << std::endl ).flush();
00787 #endif
00788
00789 ThisTurbine->yaw(TurbineCtrl->yaw_initial+TurbineCtrl->yaw_rate*t);
00790
00792 ThisTurbine->rotate(TurbineCtrl->rotation_initial+TurbineCtrl->rotation_rate*t);
00793
00795
00796 #ifdef TURBINE_DEBUG_ON
00797 ( mklog() << "\n\n*********\tSolidSolverSpecific movement aDVANCE fINISHED\n*********" << std::endl ).flush();
00798 #endif
00799
00800 }
00801
00802
00803 virtual void Restart(std::ifstream& ifs, int& pos, double& t, double& dt) {
00804 #ifdef CHECKRESTART_DEBUG_ON
00805 ( mklog() << "\nRestarting TURBINEMECHANISM SOLVER t= " << t << " dt = " << dt << " pos = " << pos << std::endl ).flush();
00806 #endif
00807
00808 L0->Restart(ifs,pos,t,dt);
00809 pos = ifs.tellg();
00810 C1->Restart(ifs,pos,t,dt);
00811 pos = ifs.tellg();
00812 C2->Restart(ifs,pos,t,dt);
00813 pos = ifs.tellg();
00814 C3->Restart(ifs,pos,t,dt);
00815 pos = ifs.tellg();
00816 C4->Restart(ifs,pos,t,dt);
00817 pos = ifs.tellg();
00818
00819 ifs.read((char*)&L0_index,sizeof(int));
00820 ifs.read((char*)&C1_index,sizeof(int));
00821
00822 ifs.read((char*)&T_rotor(0),sizeof(DataType));
00823 ifs.read((char*)&T_rotor(1),sizeof(DataType));
00824 ifs.read((char*)&T_rotor(2),sizeof(DataType));
00825
00826 ifs.read((char*)&T_nacelle(0),sizeof(DataType));
00827 ifs.read((char*)&T_nacelle(1),sizeof(DataType));
00828 ifs.read((char*)&T_nacelle(2),sizeof(DataType));
00829
00830 ifs.read((char*)&a_rotor,sizeof(DataType));
00831 ifs.read((char*)&v_rotor,sizeof(DataType));
00832 ifs.read((char*)&p_rotor,sizeof(DataType));
00833
00834 ifs.read((char*)&a_nacelle,sizeof(DataType));
00835 ifs.read((char*)&v_nacelle,sizeof(DataType));
00836 ifs.read((char*)&p_nacelle,sizeof(DataType));
00837
00838 pos = ifs.tellg();
00839 #ifdef CHECKRESTART_DEBUG_ON
00840 ( mklog() << "\nDone Restarting TURBINEMECHANISM t = " << t << " dt = " << dt << " pos = " << pos << std::endl ).flush();
00841 #endif
00842 }
00843
00844 virtual void Checkpointing(std::ofstream& ofs) {
00845 #ifdef CHECKRESTART_DEBUG_ON
00846 ( mklog() << "\nCHECKPOINTING TURBINEMECHANISM SOLVER pos = " << ofs.tellp() << std::endl ).flush();
00847 #endif
00848
00849 L0->Checkpointing(ofs);
00850 C1->Checkpointing(ofs);
00851 C2->Checkpointing(ofs);
00852 C3->Checkpointing(ofs);
00853 C4->Checkpointing(ofs);
00854
00855 ofs.write((char*)&L0_index,sizeof(int));
00856 ofs.write((char*)&C1_index,sizeof(int));
00857
00858 ofs.write((char*)&T_rotor(0),sizeof(DataType));
00859 ofs.write((char*)&T_rotor(1),sizeof(DataType));
00860 ofs.write((char*)&T_rotor(2),sizeof(DataType));
00861
00862 ofs.write((char*)&T_nacelle(0),sizeof(DataType));
00863 ofs.write((char*)&T_nacelle(1),sizeof(DataType));
00864 ofs.write((char*)&T_nacelle(2),sizeof(DataType));
00865
00866 ofs.write((char*)&a_rotor,sizeof(DataType));
00867 ofs.write((char*)&v_rotor,sizeof(DataType));
00868 ofs.write((char*)&p_rotor,sizeof(DataType));
00869
00870 ofs.write((char*)&a_nacelle,sizeof(DataType));
00871 ofs.write((char*)&v_nacelle,sizeof(DataType));
00872 ofs.write((char*)&p_nacelle,sizeof(DataType));
00873
00874 #ifdef CHECKRESTART_DEBUG_ON
00875 ( mklog() << "\n+++ CHECKPOINTING TURBINEMECHANISM COMPLETE pos = " << ofs.tellp() <<std::endl ).flush();
00876 #endif
00877 }
00878
00879 protected:
00880
00881 AssemblyType * Turbine0pt;
00882 AssemblyType * Rotor0;
00883 LoftType * Tower0;
00884 LoftType * Nacel0;
00885 LoftType * Blades[MAXBLADES];
00886 LoftType * Hub0;
00887 LinkType * L0;
00888
00889 ChainType * C1;
00890 ChainType * C2;
00891 ChainType * C3;
00892 ChainType * C4;
00893 ChainType * C5;
00894
00895 int L0_index, C1_index;
00896
00897 PType T_rotor, T_nacelle;
00898
00899 DataType a_rotor, a_nacelle;
00900 DataType v_rotor, v_nacelle;
00901 DataType p_rotor, p_nacelle;
00902
00903 DataType a_blades[MAXBLADES];
00904 DataType v_blades[MAXBLADES];
00905 DataType p_blades[MAXBLADES];
00906
00907 };
00908
00909 #endif