00001
00009 #include <stdlib.h>
00010 #include <stdio.h>
00011 #include <errno.h>
00012 #include <math.h>
00013 #include <complex.h>
00014
00015 #include "windturb_dg.h"
00016
00017 CLASS *windturb_dg::oclass = NULL;
00018 windturb_dg *windturb_dg::defaults = NULL;
00019
00020 windturb_dg::windturb_dg(MODULE *module)
00021 {
00022 if (oclass==NULL)
00023 {
00024
00025 oclass = gl_register_class(module,"windturb_dg",sizeof(windturb_dg),PC_PRETOPDOWN|PC_BOTTOMUP|PC_POSTTOPDOWN);
00026
00027 if (gl_publish_variable(oclass,
00028
00029 PT_enumeration,"Gen_status",PADDR(Gen_status),
00030 PT_KEYWORD,"OFFLINE",OFFLINE,
00031 PT_KEYWORD,"ONLINE",ONLINE,
00032 PT_enumeration,"Gen_type",PADDR(Gen_type),
00033 PT_KEYWORD,"INDUCTION",INDUCTION,
00034 PT_KEYWORD,"SYNCHRONOUS",SYNCHRONOUS,
00035 PT_enumeration,"Gen_mode",PADDR(Gen_mode),
00036 PT_KEYWORD,"CONSTANTE",CONSTANTE,
00037 PT_KEYWORD,"CONSTANTP",CONSTANTP,
00038 PT_KEYWORD,"CONSTANTPQ",CONSTANTPQ,
00039 PT_enumeration,"Turbine_Model",PADDR(Turbine_Model),
00040 PT_KEYWORD,"GENERIC_SYNCH",GENERIC_SYNCH,
00041 PT_KEYWORD,"GENERIC_IND",GENERIC_IND,
00042 PT_KEYWORD,"VESTAS_V82",VESTAS_V82,
00043 PT_KEYWORD,"GE_25MW",GE_25MW,
00044 PT_double, "Rated_VA[VA]", PADDR(Rated_VA),
00045 PT_double, "Rated_V[V]", PADDR(Rated_V),
00046 PT_double, "Pconv[W]", PADDR(Pconv),
00047 PT_double, "WSadj[m/s]", PADDR(WSadj),
00048 PT_double, "Wind_Speed[m/s]", PADDR(Wind_Speed),
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 PT_double, "pf", PADDR(pf),
00065
00066 PT_double, "GenElecEff", PADDR(GenElecEff),
00067 PT_double, "TotalRealPow[W]", PADDR(TotalRealPow),
00068 PT_double, "TotalReacPow", PADDR(TotalReacPow),
00069
00070 PT_complex, "voltage_A[V]", PADDR(voltage_A),
00071 PT_complex, "voltage_B[V]", PADDR(voltage_B),
00072 PT_complex, "voltage_C[V]", PADDR(voltage_C),
00073 PT_complex, "current_A[A]", PADDR(current_A),
00074 PT_complex, "current_B[A]", PADDR(current_B),
00075 PT_complex, "current_C[A]", PADDR(current_C),
00076 PT_complex, "EfA[V]", PADDR(EfA),
00077 PT_complex, "EfB[V]", PADDR(EfB),
00078 PT_complex, "EfC[V]", PADDR(EfC),
00079 PT_complex, "Vrotor_A[V]", PADDR(Vrotor_A),
00080 PT_complex, "Vrotor_B[V]", PADDR(Vrotor_B),
00081 PT_complex, "Vrotor_C[V]", PADDR(Vrotor_C),
00082 PT_complex, "Irotor_A[V]", PADDR(Irotor_A),
00083 PT_complex, "Irotor_B[V]", PADDR(Irotor_B),
00084 PT_complex, "Irotor_C[V]", PADDR(Irotor_C),
00085
00086 PT_set, "phases", PADDR(phases),
00087 PT_KEYWORD, "A",(set)PHASE_A,
00088 PT_KEYWORD, "B",(set)PHASE_B,
00089 PT_KEYWORD, "C",(set)PHASE_C,
00090 PT_KEYWORD, "N",(set)PHASE_N,
00091 PT_KEYWORD, "S",(set)PHASE_S,
00092 NULL)<1) GL_THROW("unable to publish properties in %s",__FILE__);
00093
00094 defaults = this;
00095 roughness_l = .055;
00096 ref_height = 10;
00097 Max_Vrotor = 1.2;
00098 Min_Vrotor = 0.8;
00099 Max_Ef = 1.2;
00100 Min_Ef = 0.8;
00101 avg_ws = 8;
00102
00103 time_advance = 3600;
00104
00105
00106 Ridealgas = 8.31447;
00107 Molar = 0.0289644;
00108 std_air_dens = 1.2754;
00109 std_air_temp = 0;
00110 std_air_press = 100000;
00111 }
00112 }
00113
00114
00115 int windturb_dg::create(void)
00116 {
00117 memcpy(this,defaults,sizeof(*this));
00118
00119 return 1;
00120 }
00121
00125 int windturb_dg::init_climate()
00126 {
00127 OBJECT *hdr = OBJECTHDR(this);
00128
00129
00130 static FINDLIST *climates = NULL;
00131 int not_found = 0;
00132 if (climates==NULL && not_found==0)
00133 {
00134 climates = gl_find_objects(FL_NEW,FT_CLASS,SAME,"climate",FT_END);
00135 if (climates==NULL)
00136 {
00137 not_found = 1;
00138 gl_warning("windturb_dg: no climate data found, using static data");
00139
00140
00141 static double air_dens = std_air_dens, avgWS = avg_ws, Press = std_air_press, Temp = std_air_temp;
00142 pPress = &Press;
00143 pTemp = &Temp;
00144 pWS = &avgWS;
00145
00146 }
00147 else if (climates->hit_count>1)
00148 {
00149 gl_warning("windturb_dg: %d climates found, using first one defined", climates->hit_count);
00150 }
00151 }
00152 if (climates!=NULL)
00153 {
00154 if (climates->hit_count==0)
00155 {
00156
00157 gl_warning("windturb_dg: no climate data found, using mock data");
00158 static double air_dens = std_air_dens, avgWS = avg_ws, Press = std_air_press, Temp = std_air_temp;
00159 pPress = &Press;
00160 pTemp = &Temp;
00161 pWS = &avgWS;
00162 }
00163 else
00164 {
00165
00166 gl_warning("windturb_dg: using climate data");
00167 OBJECT *obj = gl_find_next(climates,NULL);
00168 if (obj->rank<=hdr->rank)
00169 gl_set_dependent(obj,hdr);
00170 pTemp = (double*)GETADDR(obj,gl_get_property(obj,"temperature_raw"));
00171 pWS = (double*)GETADDR(obj,gl_get_property(obj,"wind_speed"));
00172
00173 static double Press = std_air_press;
00174 pPress = &Press;
00175 }
00176 }
00177
00178 return 1;
00179 }
00180
00181 int windturb_dg::init(OBJECT *parent)
00182 {
00183 double ZB, SB, EB;
00184 complex tst, tst2, tst3, tst4;
00185
00186 switch (Turbine_Model) {
00187 case GENERIC_IND:
00188 case GENERIC_SYNCH:
00189 blade_diam = 82.5;
00190 turbine_height = 90;
00191 q = 3;
00192 Rated_VA = 1635000;
00193 Max_P = 1500000;
00194 Max_Q = 650000;
00195 Rated_V = 600;
00196 pf = 0.95;
00197 CP_Data = GENERAL;
00198 cut_in_ws = 4;
00199 cut_out_ws = 25;
00200 Cp_max = 0.302;
00201 ws_maxcp = 7;
00202 Cp_rated = Cp_max-.05;
00203 ws_rated = 12.5;
00204 if (Turbine_Model == GENERIC_IND) {
00205 Gen_type = INDUCTION;
00206 Rst = 0.12;
00207 Xst = 0.17;
00208 Rr = 0.12;
00209 Xr = 0.15;
00210 Rc = 999999;
00211 Xm = 9.0;
00212 }
00213 else if (Turbine_Model == GENERIC_SYNCH) {
00214 Gen_type = SYNCHRONOUS;
00215 Rs = 0.05;
00216 Xs = 0.200;
00217 Rg = 0.000;
00218 Xg = 0.000;
00219 }
00220 break;
00221 case VESTAS_V82:
00222 turbine_height = 78;
00223 blade_diam = 82;
00224 Rated_VA = 1808000;
00225 Rated_V = 600;
00226 Max_P = 1650000;
00227 Max_Q = 740000;
00228 pf = 0.91;
00229 CP_Data = MANUF_TABLE;
00230 cut_in_ws = 3.5;
00231 cut_out_ws = 20;
00232 q = 2;
00233 Gen_type = SYNCHRONOUS;
00234 Rs = 0.025;
00235 Xs = 0.200;
00236 Rg = 0.000;
00237 Xg = 0.000;
00238 break;
00239 case GE_25MW:
00240 turbine_height = 100;
00241 blade_diam = 100;
00242 Rated_VA = 2727000;
00243 Rated_V = 690;
00244 Max_P = 2500000;
00245 Max_Q = 1090000;
00246 pf = 0.95;
00247 q = 3;
00248 CP_Data = GENERAL;
00249 cut_in_ws = 3.5;
00250 cut_out_ws = 25;
00251 Cp_max = 0.28;
00252 Cp_rated = 0.275;
00253 ws_maxcp = 8.2;
00254 ws_rated = 12.5;
00255 Gen_type = SYNCHRONOUS;
00256 Rs = 0.035;
00257 Xs = 0.200;
00258 Rg = 0.000;
00259 Xg = 0.000;
00260 break;
00261 }
00262
00263
00264 struct {
00265 complex **var;
00266 char *varname;
00267 } map[] = {
00268
00269 {&pCircuit_V, "voltage_A"},
00270 {&pLine_I, "current_A"},
00272 };
00273
00274 static complex default_line123_voltage[3], default_line1_current[3];
00275 int i;
00276
00277
00278 if (parent!=NULL && strcmp(parent->oclass->name,"meter")==0)
00279 {
00280
00281 for (i=0; i<sizeof(map)/sizeof(map[0]); i++)
00282 *(map[i].var) = get_complex(parent,map[i].varname);
00283 }
00284 else
00285 {
00286 OBJECT *obj = OBJECTHDR(this);
00287 gl_warning("house:%d %s", obj->id, parent==NULL?"has no parent meter defined":"parent is not a meter");
00288
00289
00290 *(map[0].var) = &default_line123_voltage[0];
00291 *(map[1].var) = &default_line1_current[0];
00292
00293
00294 default_line123_voltage[0] = complex(Rated_V/sqrt(3.0),0);
00295 default_line123_voltage[1] = complex(Rated_V/sqrt(3.0)*cos(2*PI/3),Rated_V/sqrt(3.0)*sin(2*PI/3));
00296 default_line123_voltage[2] = complex(Rated_V/sqrt(3.0)*cos(-2*PI/3),Rated_V/sqrt(3.0)*sin(-2*PI/3));
00297
00298 }
00299
00300 if (Gen_mode==UNKNOWN)
00301 {
00302 OBJECT *obj = OBJECTHDR(this);
00303 throw("Generator control mode is not specified");
00304 }
00305
00306 if (Gen_status==0)
00307 {
00308 throw("Generator is out of service!"); }
00309
00310 else
00311 {
00312 if (Rated_VA!=0.0) SB = Rated_VA/3;
00313 if (Rated_V!=0.0) EB = Rated_V/sqrt(3.0);
00314 if (SB!=0.0) ZB = EB*EB/SB;
00315 else throw("Generator power capacity not specified!");
00316 }
00317
00318 if (Gen_type == INDUCTION)
00319 {
00320 complex Zrotor(Rr,Xr);
00321 complex Zmag = complex(Rc*Xm*Xm/(Rc*Rc + Xm*Xm),Rc*Rc*Xm/(Rc*Rc + Xm*Xm));
00322 complex Zstator(Rst,Xst);
00323
00324
00325 IndTPMat[0][0] = (Zmag + Zstator)/Zmag;
00326 IndTPMat[0][1] = Zrotor + Zstator + Zrotor*Zstator/Zmag;
00327 IndTPMat[1][0] = complex(1,0) / Zmag;
00328 IndTPMat[1][1] = (Zmag + Zrotor) / Zmag;
00329 }
00330
00331 else if (Gen_type == SYNCHRONOUS)
00332 {
00333 double Real_Rs = Rs * ZB;
00334 double Real_Xs = Xs * ZB;
00335 double Real_Rg = Rg * ZB;
00336 double Real_Xg = Xg * ZB;
00337 tst = complex(Real_Rg,Real_Xg);
00338 tst2 = complex(Real_Rs,Real_Xs);
00339 AMx[0][0] = tst2 + tst;
00340 AMx[1][1] = tst2 + tst;
00341 AMx[2][2] = tst2 + tst;
00342 AMx[0][1] = AMx[0][2] = AMx[1][0] = AMx[1][2] = AMx[2][0] = AMx[2][1] = tst;
00343 tst3 = (complex(1,0) + complex(2,0)*tst/tst2)/(tst2 + complex(3,0)*tst);
00344 tst4 = (-tst/tst2)/(tst2 + tst);
00345 invAMx[0][0] = tst3;
00346 invAMx[1][1] = tst3;
00347 invAMx[2][2] = tst3;
00348 invAMx[0][1] = AMx[0][2] = AMx[1][0] = AMx[1][2] = AMx[2][0] = AMx[2][1] = tst4;
00349 }
00350
00351 init_climate();
00352
00353 return 1;
00354 }
00355
00356
00357 TIMESTAMP windturb_dg::presync(TIMESTAMP t0, TIMESTAMP t1)
00358 {
00359 double Pwind, Pmech, Cp, detCp, F, G, gearbox_eff;
00360 double matCp[2][3];
00361
00362 double air_dens = std_air_dens;
00363 pair_density = &air_dens;
00364
00365
00366 WSadj = *pWS * log(turbine_height/roughness_l)/log(ref_height/roughness_l);
00367
00368
00369
00370
00371
00372
00373
00374 Pwind = 0.5 * (*pair_density) * PI * pow(blade_diam/2,2) * pow(WSadj,3);
00375
00376 if (CP_Data == GENERAL)
00377 {
00378 if (WSadj <= cut_in_ws)
00379 {
00380 Cp = 0; }
00381
00382 else if (WSadj > cut_out_ws)
00383 {
00384 Cp = 0; }
00385
00386 else
00387 {
00388 if (WSadj > ws_rated)
00389 {
00390 Cp = Cp_rated * pow(ws_rated,3) / pow(WSadj,3); }
00391
00392 else
00393 {
00394 matCp[0][0] = pow((ws_maxcp/cut_in_ws - 1),2);
00395 matCp[0][1] = pow((ws_maxcp/cut_in_ws - 1),3);
00396 matCp[0][2] = 1;
00397 matCp[1][0] = pow((ws_maxcp/ws_rated - 1),2);
00398 matCp[1][1] = pow((ws_maxcp/ws_rated - 1),3);
00399 matCp[1][2] = 1 - Cp_rated/Cp_max;
00400 detCp = matCp[0][0]*matCp[1][1] - matCp[0][1]*matCp[1][0];
00401
00402 F = (matCp[0][2]*matCp[1][1] - matCp[0][1]*matCp[1][2])/detCp;
00403 G = (matCp[0][0]*matCp[1][2] - matCp[0][2]*matCp[1][0])/detCp;
00404
00405 Cp = Cp_max*(1 - F*pow((ws_maxcp/WSadj - 1),2) - G*pow((ws_maxcp/WSadj - 1),3));
00406 }
00407 }
00408 }
00409
00410 else if (CP_Data == MANUF_TABLE)
00411 {
00412 switch (Turbine_Model) {
00413 case VESTAS_V82:
00414 if (WSadj <= cut_in_ws || WSadj >= cut_out_ws)
00415 {
00416 Cp = 0; }
00417 else
00418 {
00419
00420 double z = (WSadj - 10.5)/5.9161;
00421
00422
00423 Cp = -0.08609*pow(z,10) + 0.078599*pow(z,9) + 0.50509*pow(z,8) - 0.45466*pow(z,7) - 0.94154*pow(z,6) + 0.77922*pow(z,5) + 0.59082*pow(z,4) - 0.23196*pow(z,3) - 0.25009*pow(z,2) - 0.24282*z + 0.37502;
00424 }
00425 break;
00426 default:
00427 throw("Coefficient of Performance model not determined.");
00428 }
00429 }
00430
00431 Pmech = Pwind * Cp;
00432
00433 if (Pmech != 0)
00434 {
00435 gearbox_eff = 1 - (q*.01*Rated_VA / Pmech);
00436
00437 if (gearbox_eff < .1)
00438 {
00439 gearbox_eff = .1;
00440 }
00441
00442 Pmech = Pwind * Cp * gearbox_eff;
00443 }
00444
00445 Pconv = 1 * Pmech;
00446 current_A = current_B = current_C = 0.0;
00447
00448 return TS_NEVER;
00449 }
00450
00451
00452 TIMESTAMP windturb_dg::sync(TIMESTAMP t0, TIMESTAMP t1)
00453 {
00454 int k;
00455 voltage_A = pCircuit_V[0];
00456 voltage_B = pCircuit_V[1];
00457 voltage_C = pCircuit_V[2];
00458
00459 double Pconva = (voltage_A.Mag() / (voltage_A.Mag() + voltage_B.Mag() + voltage_C.Mag()))*Pconv;
00460 double Pconvb = (voltage_B.Mag() / (voltage_A.Mag() + voltage_B.Mag() + voltage_C.Mag()))*Pconv;
00461 double Pconvc = (voltage_C.Mag() / (voltage_A.Mag() + voltage_B.Mag() + voltage_C.Mag()))*Pconv;
00462
00463 if (Gen_type == INDUCTION)
00464 {
00465 Pconva = Pconva/Rated_VA;
00466 Pconvb = Pconvb/Rated_VA;
00467 Pconvc = Pconvc/Rated_VA;
00468
00469 Vapu = voltage_A/(Rated_V/sqrt(3.0));
00470 Vbpu = voltage_B/(Rated_V/sqrt(3.0));
00471 Vcpu = voltage_C/(Rated_V/sqrt(3.0));
00472
00473 Vrotor_A = Vapu;
00474 Vrotor_B = Vbpu;
00475 Vrotor_C = Vcpu;
00476
00477 complex detTPMat = IndTPMat[1][1]*IndTPMat[0][0] - IndTPMat[1][0]*IndTPMat[0][1];
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 switch (Gen_mode) {
00490 case CONSTANTE:
00491 for(k = 0; k < 6; k++)
00492 {
00493 Irotor_A = (~((complex(Pconva,0)/Vrotor_A)));
00494 Irotor_B = (~((complex(Pconvb,0)/Vrotor_B)));
00495 Irotor_C = (~((complex(Pconvc,0)/Vrotor_C)));
00496
00497 Iapu = IndTPMat[1][0]*Vrotor_A + IndTPMat[1][1]*Irotor_A;
00498 Ibpu = IndTPMat[1][0]*Vrotor_B + IndTPMat[1][1]*Irotor_B;
00499 Icpu = IndTPMat[1][0]*Vrotor_C + IndTPMat[1][1]*Irotor_C;
00500
00501 Vrotor_A = complex(1,0)/detTPMat * (IndTPMat[1][1]*Vapu - IndTPMat[0][1]*Iapu);
00502 Vrotor_B = complex(1,0)/detTPMat * (IndTPMat[1][1]*Vbpu - IndTPMat[0][1]*Ibpu);
00503 Vrotor_C = complex(1,0)/detTPMat * (IndTPMat[1][1]*Vcpu - IndTPMat[0][1]*Icpu);
00504
00505 Vrotor_A = Vrotor_A * Max_Vrotor / Vrotor_A.Mag();
00506 Vrotor_B = Vrotor_B * Max_Vrotor / Vrotor_B.Mag();
00507 Vrotor_C = Vrotor_C * Max_Vrotor / Vrotor_C.Mag();
00508 }
00509 break;
00510 case CONSTANTPQ:
00511 for(k = 0; k < 6; k++)
00512 {
00513 Irotor_A = -(~complex(-Pconva/Vrotor_A.Mag()*cos(Vrotor_A.Arg()),Pconva/Vrotor_A.Mag()*sin(Vrotor_A.Arg())));
00514 Irotor_B = -(~complex(-Pconvb/Vrotor_B.Mag()*cos(Vrotor_B.Arg()),Pconvb/Vrotor_B.Mag()*sin(Vrotor_B.Arg())));
00515 Irotor_C = -(~complex(-Pconvc/Vrotor_C.Mag()*cos(Vrotor_C.Arg()),Pconvc/Vrotor_C.Mag()*sin(Vrotor_C.Arg())));
00516
00517 Iapu = IndTPMat[1][0]*Vrotor_A - IndTPMat[1][1]*Irotor_A;
00518 Ibpu = IndTPMat[1][0]*Vrotor_B - IndTPMat[1][1]*Irotor_B;
00519 Icpu = IndTPMat[1][0]*Vrotor_C - IndTPMat[1][1]*Irotor_C;
00520
00521 Vrotor_A = complex(1,0)/detTPMat * (IndTPMat[1][1]*Vapu - IndTPMat[0][1]*Iapu);
00522 Vrotor_B = complex(1,0)/detTPMat * (IndTPMat[1][1]*Vbpu - IndTPMat[0][1]*Ibpu);
00523 Vrotor_C = complex(1,0)/detTPMat * (IndTPMat[1][1]*Vcpu - IndTPMat[0][1]*Icpu);
00524 }
00525 break;
00526 }
00527
00528 current_A = Iapu * Rated_VA/(Rated_V/sqrt(3.0));
00529 current_B = Ibpu * Rated_VA/(Rated_V/sqrt(3.0));
00530 current_C = Icpu * Rated_VA/(Rated_V/sqrt(3.0));
00531 }
00532
00533 else if (Gen_type == SYNCHRONOUS)
00534 {
00535 double Mxef, Mnef, PoutA, PoutB, PoutC, QoutA, QoutB, QoutC;
00536 complex SoutA, SoutB, SoutC;
00537 complex lossesA, lossesB, lossesC;
00538
00539 Mxef = Max_Ef * Rated_V/sqrt(3.0);
00540 Mnef = Min_Ef * Rated_V/sqrt(3.0);
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564 if (Gen_mode == CONSTANTE)
00565 {
00566 current_A = invAMx[0][0]*(voltage_A - EfA) + invAMx[0][1]*(voltage_B - EfB) + invAMx[0][2]*(voltage_C - EfC);
00567 current_B = invAMx[1][0]*(voltage_A - EfA) + invAMx[1][1]*(voltage_B - EfB) + invAMx[1][2]*(voltage_C - EfC);
00568 current_C = invAMx[2][0]*(voltage_A - EfA) + invAMx[2][1]*(voltage_B - EfB) + invAMx[2][2]*(voltage_C - EfC);
00569
00570 SoutA = -voltage_A * (~(current_A));
00571 SoutB = -voltage_B * (~(current_B));
00572 SoutC = -voltage_C * (~(current_C));
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583 }
00584
00585 else if (Gen_mode == CONSTANTP)
00586 {
00587 if (Pconva > 1.05*Max_P/3) {
00588 Pconva = 1.05*Max_P/3;
00589 }
00590 if (Pconvb > 1.05*Max_P/3) {
00591 Pconvb = 1.05*Max_P/3;
00592 }
00593 if (Pconvc > 1.05*Max_P/3) {
00594 Pconvc = 1.05*Max_P/3;
00595 }
00596
00597 current_A = -(~(complex(Pconva,(Pconva/pf)*sin(acos(pf)))/voltage_A));
00598 current_B = -(~(complex(Pconvb,(Pconvb/pf)*sin(acos(pf)))/voltage_B));
00599 current_C = -(~(complex(Pconvc,(Pconvc/pf)*sin(acos(pf)))/voltage_C));
00600
00601 for (k = 0; k < 6; k++)
00602 {
00603 PoutA = Pconva - current_A.Mag()*current_A.Mag()*(AMx[0][0] - AMx[0][1]).Re();
00604 PoutB = Pconvb - current_B.Mag()*current_B.Mag()*(AMx[1][1] - AMx[0][1]).Re();
00605 PoutC = Pconvc - current_C.Mag()*current_C.Mag()*(AMx[2][2] - AMx[0][1]).Re();
00606
00607 QoutA = pf/abs(pf)*PoutA*sin(acos(pf));
00608 QoutB = pf/abs(pf)*PoutB*sin(acos(pf));
00609 QoutC = pf/abs(pf)*PoutC*sin(acos(pf));
00610
00611 current_A = -(~(complex(PoutA,QoutA)/voltage_A));
00612 current_B = -(~(complex(PoutB,QoutB)/voltage_B));
00613 current_C = -(~(complex(PoutC,QoutC)/voltage_C));
00614 }
00615
00616 EfA = voltage_A - (AMx[0][0] - AMx[0][1])*current_A - AMx[0][2]*(current_A + current_B + current_C);
00617 EfB = voltage_B - (AMx[1][1] - AMx[1][0])*current_A - AMx[1][2]*(current_A + current_B + current_C);
00618 EfC = voltage_C - (AMx[2][2] - AMx[2][0])*current_A - AMx[2][1]*(current_A + current_B + current_C);
00619
00620
00621
00622
00623
00624 }
00625 }
00626
00627
00628 double PowerA, PowerB, PowerC, QA, QB, QC;
00629
00630 PowerA = -voltage_A.Mag()*current_A.Mag()*cos(voltage_A.Arg() - current_A.Arg());
00631 PowerB = -voltage_B.Mag()*current_B.Mag()*cos(voltage_B.Arg() - current_B.Arg());
00632 PowerC = -voltage_C.Mag()*current_C.Mag()*cos(voltage_C.Arg() - current_C.Arg());
00633
00634 QA = -voltage_A.Mag()*current_A.Mag()*sin(voltage_A.Arg() - current_A.Arg());
00635 QB = -voltage_B.Mag()*current_B.Mag()*sin(voltage_B.Arg() - current_B.Arg());
00636 QC = -voltage_C.Mag()*current_C.Mag()*sin(voltage_C.Arg() - current_C.Arg());
00637
00638
00639 TotalRealPow = PowerA + PowerB + PowerC;
00640 TotalReacPow = QA + QB + QC;
00641
00642 GenElecEff = TotalRealPow/Pconv * 100;
00643
00644 Wind_Speed = WSadj;
00645
00646 pLine_I[0] = current_A;
00647 pLine_I[1] = current_B;
00648 pLine_I[2] = current_C;
00649
00650 TIMESTAMP t2 = TS_NEVER;
00651 return t2;
00652 }
00653
00654 TIMESTAMP windturb_dg::postsync(TIMESTAMP t0, TIMESTAMP t1)
00655 {
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672 TIMESTAMP t2 = t1 + time_advance;
00673
00674
00675
00676 return t2;
00677 }
00678
00679 complex *windturb_dg::get_complex(OBJECT *obj, char *name)
00680 {
00681 PROPERTY *p = gl_get_property(obj,name);
00682 if (p==NULL || p->ptype!=PT_complex)
00683 return NULL;
00684 return (complex*)GETADDR(obj,p);
00685 }
00686
00688
00690
00691 EXPORT int create_windturb_dg(OBJECT **obj, OBJECT *parent)
00692 {
00693 try
00694 {
00695 *obj = gl_create_object(windturb_dg::oclass);
00696 if (*obj!=NULL)
00697 {
00698 windturb_dg *my = OBJECTDATA(*obj,windturb_dg);
00699 gl_set_parent(*obj,parent);
00700 return my->create();
00701 }
00702 }
00703 catch (char *msg)
00704 {
00705 gl_error("create_windturb_dg: %s", msg);
00706 }
00707 return 1;
00708 }
00709
00710
00711
00712 EXPORT int init_windturb_dg(OBJECT *obj, OBJECT *parent)
00713 {
00714 try
00715 {
00716 if (obj!=NULL)
00717 return OBJECTDATA(obj,windturb_dg)->init(parent);
00718 }
00719 catch (char *msg)
00720 {
00721 gl_error("init_windturb_dg(obj=%d;%s): %s", obj->id, obj->name?obj->name:"unnamed", msg);
00722 }
00723 return 0;
00724 }
00725
00726 EXPORT TIMESTAMP sync_windturb_dg(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
00727 {
00728 TIMESTAMP t1 = TS_NEVER;
00729 windturb_dg *my = OBJECTDATA(obj,windturb_dg);
00730 try
00731 {
00732 switch (pass) {
00733 case PC_PRETOPDOWN:
00734 t1 = my->presync(obj->clock,t0);
00735 break;
00736 case PC_BOTTOMUP:
00737 t1 = my->sync(obj->clock,t0);
00738 break;
00739 case PC_POSTTOPDOWN:
00740 t1 = my->postsync(obj->clock,t0);
00741 break;
00742 default:
00743 GL_THROW("invalid pass request (%d)", pass);
00744 break;
00745 }
00746 }
00747
00748 catch (char *msg)
00749 {
00750 gl_error("sync_windturb_dg(obj=%d;%s): %s", obj->id, obj->name?obj->name:"unnamed", msg);
00751 }
00752 return t1;
00753 }
00754
00755
00756
00757
00758
00759
00760
00761
00762