00001
00010 #include <stdlib.h>
00011 #include <stdio.h>
00012 #include <errno.h>
00013 #include <math.h>
00014
00015 #include "diesel_dg.h"
00016
00017 CLASS *diesel_dg::oclass = NULL;
00018 diesel_dg *diesel_dg::defaults = NULL;
00019
00020 static PASSCONFIG passconfig = PC_BOTTOMUP|PC_POSTTOPDOWN;
00021 static PASSCONFIG clockpass = PC_BOTTOMUP;
00022
00023
00024 diesel_dg::diesel_dg(MODULE *module)
00025 {
00026 if (oclass==NULL)
00027 {
00028 oclass = gl_register_class(module,"diesel_dg",sizeof(diesel_dg),passconfig|PC_AUTOLOCK);
00029 if (oclass==NULL)
00030 throw "unable to register class diesel_dg";
00031 else
00032 oclass->trl = TRL_PROOF;
00033
00034 if (gl_publish_variable(oclass,
00035
00036 PT_enumeration,"Gen_type",PADDR(Gen_type),
00037 PT_KEYWORD,"CONSTANT_PQ",(enumeration)NON_DYN_CONSTANT_PQ,PT_DESCRIPTION,"Non-dynamic mode of diesel generator with constant PQ output as defined",
00038 PT_KEYWORD,"DYN_SYNCHRONOUS",(enumeration)DYNAMIC,PT_DESCRIPTION,"Dynamics-capable implementation of synchronous diesel generator",
00039
00040 PT_double, "pf", PADDR(power_factor),PT_DESCRIPTION,"desired power factor",
00041
00042
00043 PT_double, "Rated_V[V]", PADDR(Rated_V_LL),PT_DESCRIPTION,"nominal line-line voltage in Volts",
00044 PT_double, "Rated_VA[VA]", PADDR(Rated_VA),PT_DESCRIPTION,"nominal capacity in VA",
00045 PT_double, "overload_limit[pu]", PADDR(Overload_Limit_Pub),PT_DESCRIPTION,"per-unit value of the maximum power the generator can provide",
00046
00047 PT_complex, "current_out_A[A]", PADDR(current_val[0]),PT_DESCRIPTION,"Output current of phase A",
00048 PT_complex, "current_out_B[A]", PADDR(current_val[1]),PT_DESCRIPTION,"Output current of phase B",
00049 PT_complex, "current_out_C[A]", PADDR(current_val[2]),PT_DESCRIPTION,"Output current of phase C",
00050 PT_complex, "power_out_A[VA]", PADDR(power_val[0]),PT_DESCRIPTION,"Output power of phase A",
00051 PT_complex, "power_out_B[VA]", PADDR(power_val[1]),PT_DESCRIPTION,"Output power of phase B",
00052 PT_complex, "power_out_C[VA]", PADDR(power_val[2]),PT_DESCRIPTION,"Output power of phase C",
00053
00054
00055 PT_double,"omega_ref[rad/s]",PADDR(omega_ref),PT_DESCRIPTION,"Reference frequency of generator (rad/s)",
00056 PT_double,"inertia",PADDR(inertia),PT_DESCRIPTION,"Inertial constant (H) of generator",
00057 PT_double,"damping",PADDR(damping),PT_DESCRIPTION,"Damping constant (D) of generator",
00058 PT_double,"number_poles",PADDR(number_poles),PT_DESCRIPTION,"Number of poles in the generator",
00059 PT_double,"Ra[pu]",PADDR(Ra),PT_DESCRIPTION,"Stator resistance (p.u.)",
00060 PT_double,"Xd[pu]",PADDR(Xd),PT_DESCRIPTION,"d-axis reactance (p.u.)",
00061 PT_double,"Xq[pu]",PADDR(Xq),PT_DESCRIPTION,"q-axis reactance (p.u.)",
00062 PT_double,"Xdp[pu]",PADDR(Xdp),PT_DESCRIPTION,"d-axis transient reactance (p.u.)",
00063 PT_double,"Xqp[pu]",PADDR(Xqp),PT_DESCRIPTION,"q-axis transient reactance (p.u.)",
00064 PT_double,"Xdpp[pu]",PADDR(Xdpp),PT_DESCRIPTION,"d-axis subtransient reactance (p.u.)",
00065 PT_double,"Xqpp[pu]",PADDR(Xqpp),PT_DESCRIPTION,"q-axis subtransient reactance (p.u.)",
00066 PT_double,"Xl[pu]",PADDR(Xl),PT_DESCRIPTION,"Leakage reactance (p.u.)",
00067 PT_double,"Tdp[s]",PADDR(Tdp),PT_DESCRIPTION,"d-axis short circuit time constant (s)",
00068 PT_double,"Tdop[s]",PADDR(Tdop),PT_DESCRIPTION,"d-axis open circuit time constant (s)",
00069 PT_double,"Tqop[s]",PADDR(Tqop),PT_DESCRIPTION,"q-axis open circuit time constant (s)",
00070 PT_double,"Tdopp[s]",PADDR(Tdopp),PT_DESCRIPTION,"d-axis open circuit subtransient time constant (s)",
00071 PT_double,"Tqopp[s]",PADDR(Tqopp),PT_DESCRIPTION,"q-axis open circuit subtransient time constant (s)",
00072 PT_double,"Ta[s]",PADDR(Ta),PT_DESCRIPTION,"Armature short-circuit time constant (s)",
00073 PT_complex,"X0[pu]",PADDR(X0),PT_DESCRIPTION,"Zero sequence impedance (p.u.)",
00074 PT_complex,"X2[pu]",PADDR(X2),PT_DESCRIPTION,"Negative sequence impedance (p.u.)",
00075
00076
00077 PT_double,"rotor_speed_convergence[rad]",PADDR(rotor_speed_convergence_criterion),PT_DESCRIPTION,"Convergence criterion on rotor speed used to determine when to exit deltamode",
00078 PT_double,"voltage_convergence[V]",PADDR(voltage_convergence_criterion),PT_DESCRIPTION,"Convergence criterion for voltage changes (if exciter present) to determine when to exit deltamode",
00079
00080
00081 PT_bool,"rotor_speed_convergence_enabled",PADDR(apply_rotor_speed_convergence),PT_DESCRIPTION,"Uses rotor_speed_convergence to determine if an exit of deltamode is needed",
00082 PT_bool,"voltage_magnitude_convergence_enabled",PADDR(apply_voltage_mag_convergence),PT_DESCRIPTION,"Uses voltage_convergence to determine if an exit of deltamode is needed - only works if an exciter is present",
00083
00084
00085 PT_double,"rotor_angle[rad]",PADDR(curr_state.rotor_angle),PT_DESCRIPTION,"rotor angle state variable",
00086 PT_double,"rotor_speed[rad/s]",PADDR(curr_state.omega),PT_DESCRIPTION,"machine speed state variable",
00087 PT_double,"field_voltage[pu]",PADDR(curr_state.Vfd),PT_DESCRIPTION,"machine field voltage state variable",
00088 PT_double,"flux1d[pu]",PADDR(curr_state.Flux1d),PT_DESCRIPTION,"machine transient flux on d-axis state variable",
00089 PT_double,"flux2q[pu]",PADDR(curr_state.Flux2q),PT_DESCRIPTION,"machine subtransient flux on q-axis state variable",
00090 PT_complex,"EpRotated[pu]",PADDR(curr_state.EpRotated),PT_DESCRIPTION,"d-q rotated E-prime internal voltage state variable",
00091 PT_complex,"VintRotated[pu]",PADDR(curr_state.VintRotated),PT_DESCRIPTION,"d-q rotated Vint voltage state variable",
00092 PT_complex,"Eint_A[V]",PADDR(curr_state.EintVal[0]),PT_DESCRIPTION,"Unrotated, unsequenced phase A internal voltage",
00093 PT_complex,"Eint_B[V]",PADDR(curr_state.EintVal[1]),PT_DESCRIPTION,"Unrotated, unsequenced phase B internal voltage",
00094 PT_complex,"Eint_C[V]",PADDR(curr_state.EintVal[2]),PT_DESCRIPTION,"Unrotated, unsequenced phase C internal voltage",
00095 PT_complex,"Irotated[pu]",PADDR(curr_state.Irotated),PT_DESCRIPTION,"d-q rotated sequence current state variable",
00096 PT_complex,"pwr_electric[VA]",PADDR(curr_state.pwr_electric),PT_DESCRIPTION,"Current electrical output of machine",
00097 PT_double,"pwr_mech[W]",PADDR(curr_state.pwr_mech),PT_DESCRIPTION,"Current mechanical output of machine",
00098 PT_double,"torque_mech[N*m]",PADDR(curr_state.torque_mech),PT_DESCRIPTION,"Current mechanical torque of machine",
00099 PT_double,"torque_elec[N*m]",PADDR(curr_state.torque_elec),PT_DESCRIPTION,"Current electrical torque output of machine",
00100
00101
00102 PT_double,"wref[pu]", PADDR(gen_base_set_vals.wref), PT_DESCRIPTION, "wref input to governor controls (per-unit)",
00103 PT_double,"vset[pu]", PADDR(gen_base_set_vals.vset), PT_DESCRIPTION, "vset input to AVR controls (per-unit)",
00104 PT_double,"Pref[pu]", PADDR(gen_base_set_vals.Pref), PT_DESCRIPTION, "Pref input to governor controls (per-unit), if supported",
00105 PT_double,"Qref[pu]", PADDR(gen_base_set_vals.Qref), PT_DESCRIPTION, "Qref input to govornor or AVR controls (per-unit), if supported",
00106
00107
00108 PT_enumeration,"Exciter_type",PADDR(Exciter_type),PT_DESCRIPTION,"Exciter model for dynamics-capable implementation",
00109 PT_KEYWORD,"NO_EXC",(enumeration)NO_EXC,PT_DESCRIPTION,"No exciter",
00110 PT_KEYWORD,"SEXS",(enumeration)SEXS,PT_DESCRIPTION,"Simplified Excitation System",
00111
00112 PT_double,"KA[pu]",PADDR(exc_KA),PT_DESCRIPTION,"Exciter gain (p.u.)",
00113 PT_double,"TA[s]",PADDR(exc_TA),PT_DESCRIPTION,"Exciter time constant (seconds)",
00114 PT_double,"TB[s]",PADDR(exc_TB),PT_DESCRIPTION,"Exciter transient gain reduction time constant (seconds)",
00115 PT_double,"TC[s]",PADDR(exc_TC),PT_DESCRIPTION,"Exciter transient gain reduction time constant (seconds)",
00116 PT_double,"EMAX[pu]",PADDR(exc_EMAX),PT_DESCRIPTION,"Exciter upper limit (p.u.)",
00117 PT_double,"EMIN[pu]",PADDR(exc_EMIN),PT_DESCRIPTION,"Exciter lower limit (p.u.)",
00118 PT_double,"Vterm_max[pu]",PADDR(Max_Ef),PT_DESCRIPTION,"Upper voltage limit for super-second (p.u.)",
00119 PT_double,"Vterm_min[pu]",PADDR(Min_Ef),PT_DESCRIPTION,"Lower voltage limit for super-second (p.u.)",
00120
00121
00122 PT_double,"bias",PADDR(curr_state.avr.bias),PT_DESCRIPTION,"Exciter bias state variable",
00123 PT_double,"xe",PADDR(curr_state.avr.xe),PT_DESCRIPTION,"Exciter state variable",
00124 PT_double,"xb",PADDR(curr_state.avr.xb),PT_DESCRIPTION,"Exciter state variable",
00125
00126 PT_double,"x_cvr1",PADDR(curr_state.avr.x_cvr1),PT_DESCRIPTION,"Exciter state variable",
00127 PT_double,"x_cvr2",PADDR(curr_state.avr.x_cvr2),PT_DESCRIPTION,"Exciter state variable",
00128 PT_double,"Vref",PADDR(Vref),PT_DESCRIPTION,"Exciter CVR control voltage reference value",
00129
00130 PT_enumeration,"CVR_mode",PADDR(CVRmode),PT_DESCRIPTION,"CVR mode in Exciter model",
00131 PT_KEYWORD,"HighOrder",(enumeration)HighOrder,PT_DESCRIPTION,"High order control mode",
00132 PT_KEYWORD,"Feedback",(enumeration)Feedback,PT_DESCRIPTION,"First order control mode with feedback loop",
00133
00134
00135 PT_double,"P_CONSTANT_ki", PADDR(ki_Pconstant), PT_DESCRIPTION, "parameter of the integration control for constant P mode",
00136 PT_double,"P_CONSTANT_kp", PADDR(kp_Pconstant), PT_DESCRIPTION, "parameter of the proportional control for constant P mode",
00137
00138
00139 PT_bool, "Exciter_Q_constant_mode",PADDR(Q_constant_mode),PT_DESCRIPTION,"True if the generator is operating under constant Q mode",
00140 PT_double,"Exciter_Q_constant_ki", PADDR(ki_Qconstant), PT_DESCRIPTION, "parameter of the integration control for constant Q mode",
00141 PT_double,"Exciter_Q_constant_kp", PADDR(kp_Qconstant), PT_DESCRIPTION, "parameter of the propotional control for constant Q mode",
00142
00143
00144 PT_double,"P_CONSTANT_Pref[pu]", PADDR(gen_base_set_vals.Pref), PT_DESCRIPTION, "Pref input to governor controls (per-unit), if supported",
00145 PT_double,"Exciter_Q_constant_Qref[pu]", PADDR(gen_base_set_vals.Qref), PT_DESCRIPTION, "Qref input to govornor or AVR controls (per-unit), if supported",
00146
00147
00148 PT_bool, "CVR_enabled",PADDR(CVRenabled),PT_DESCRIPTION,"True if the CVR control is enabled in the exciter",
00149 PT_double,"CVR_ki_cvr", PADDR(ki_cvr), PT_DESCRIPTION, "parameter of the integration control for CVR control",
00150 PT_double,"CVR_kp_cvr", PADDR(kp_cvr), PT_DESCRIPTION, "parameter of the proportional control for CVR control",
00151 PT_double,"CVR_kd_cvr", PADDR(kd_cvr), PT_DESCRIPTION, "parameter of the deviation control for CVR control",
00152 PT_double,"CVR_kt_cvr", PADDR(kt_cvr), PT_DESCRIPTION, "parameter of the gain in feedback loop for CVR control",
00153 PT_double,"CVR_kw_cvr", PADDR(kw_cvr), PT_DESCRIPTION, "parameter of the gain in feedback loop for CVR control",
00154 PT_bool, "CVR_PI",PADDR(CVR_PI),PT_DESCRIPTION,"True if the PI controller is implemented in CVR control",
00155 PT_bool, "CVR_PID",PADDR(CVR_PID),PT_DESCRIPTION,"True if the PID controller is implemented in CVR control",
00156 PT_double,"vset_EMAX",PADDR(vset_EMAX),PT_DESCRIPTION,"Maximum Vset limit",
00157 PT_double,"vset_EMIN",PADDR(vset_EMIN),PT_DESCRIPTION,"Minimum Vset limit",
00158 PT_double,"CVR_Kd1", PADDR(Kd1), PT_DESCRIPTION, "parameter of the second order transfer function for CVR control",
00159 PT_double,"CVR_Kd2", PADDR(Kd2), PT_DESCRIPTION, "parameter of the second order transfer function for CVR control",
00160 PT_double,"CVR_Kd3", PADDR(Kd3), PT_DESCRIPTION, "parameter of the second order transfer function for CVR control",
00161 PT_double,"CVR_Kn1", PADDR(Kn1), PT_DESCRIPTION, "parameter of the second order transfer function for CVR control",
00162 PT_double,"CVR_Kn2", PADDR(Kn2), PT_DESCRIPTION, "parameter of the second order transfer function for CVR control",
00163 PT_double,"vset_delta_MAX",PADDR(vset_delta_MAX),PT_DESCRIPTION,"Maximum delta Vset limit",
00164 PT_double,"vset_delta_MIN",PADDR(vset_delta_MIN),PT_DESCRIPTION,"Minimum delta Vset limit",
00165 PT_double,"vadd",PADDR(gen_base_set_vals.vadd),PT_DESCRIPTION,"Delta Vset",
00166 PT_double,"vadd_a",PADDR(gen_base_set_vals.vadd_a),PT_DESCRIPTION,"Delta Vset before going into bound check",
00167
00168
00169 PT_enumeration,"Governor_type",PADDR(Governor_type),PT_DESCRIPTION,"Governor model for dynamics-capable implementation",
00170 PT_KEYWORD,"NO_GOV",(enumeration)NO_GOV,PT_DESCRIPTION,"No exciter",
00171 PT_KEYWORD,"DEGOV1",(enumeration)DEGOV1,PT_DESCRIPTION,"DEGOV1 Woodward Diesel Governor",
00172 PT_KEYWORD,"GAST",(enumeration)GAST,PT_DESCRIPTION,"GAST Gas Turbine Governor",
00173 PT_KEYWORD,"GGOV1_OLD",(enumeration)GGOV1_OLD,PT_DESCRIPTION,"Older GGOV1 Governor Model",
00174 PT_KEYWORD,"GGOV1",(enumeration)GGOV1,PT_DESCRIPTION,"GGOV1 Governor Model",
00175 PT_KEYWORD,"P_CONSTANT",(enumeration)P_CONSTANT,PT_DESCRIPTION,"P_CONSTANT mode Governor Model",
00176
00177
00178 PT_double,"DEGOV1_R[pu]",PADDR(gov_degov1_R),PT_DESCRIPTION,"Governor droop constant (p.u.)",
00179 PT_double,"DEGOV1_T1[s]",PADDR(gov_degov1_T1),PT_DESCRIPTION,"Governor electric control box time constant (s)",
00180 PT_double,"DEGOV1_T2[s]",PADDR(gov_degov1_T2),PT_DESCRIPTION,"Governor electric control box time constant (s)",
00181 PT_double,"DEGOV1_T3[s]",PADDR(gov_degov1_T3),PT_DESCRIPTION,"Governor electric control box time constant (s)",
00182 PT_double,"DEGOV1_T4[s]",PADDR(gov_degov1_T4),PT_DESCRIPTION,"Governor actuator time constant (s)",
00183 PT_double,"DEGOV1_T5[s]",PADDR(gov_degov1_T5),PT_DESCRIPTION,"Governor actuator time constant (s)",
00184 PT_double,"DEGOV1_T6[s]",PADDR(gov_degov1_T6),PT_DESCRIPTION,"Governor actuator time constant (s)",
00185 PT_double,"DEGOV1_K[pu]",PADDR(gov_degov1_K),PT_DESCRIPTION,"Governor actuator gain",
00186 PT_double,"DEGOV1_TMAX[pu]",PADDR(gov_degov1_TMAX),PT_DESCRIPTION,"Governor actuator upper limit (p.u.)",
00187 PT_double,"DEGOV1_TMIN[pu]",PADDR(gov_degov1_TMIN),PT_DESCRIPTION,"Governor actuator lower limit (p.u.)",
00188 PT_double,"DEGOV1_TD[s]",PADDR(gov_degov1_TD),PT_DESCRIPTION,"Governor combustion delay (s)",
00189
00190
00191 PT_double,"DEGOV1_x1",PADDR(curr_state.gov_degov1.x1),PT_DESCRIPTION,"Governor electric box state variable",
00192 PT_double,"DEGOV1_x2",PADDR(curr_state.gov_degov1.x2),PT_DESCRIPTION,"Governor electric box state variable",
00193 PT_double,"DEGOV1_x4",PADDR(curr_state.gov_degov1.x4),PT_DESCRIPTION,"Governor electric box state variable",
00194 PT_double,"DEGOV1_x5",PADDR(curr_state.gov_degov1.x5),PT_DESCRIPTION,"Governor electric box state variable",
00195 PT_double,"DEGOV1_x6",PADDR(curr_state.gov_degov1.x6),PT_DESCRIPTION,"Governor electric box state variable",
00196 PT_double,"DEGOV1_throttle",PADDR(curr_state.gov_degov1.throttle),PT_DESCRIPTION,"Governor electric box state variable",
00197
00198
00199 PT_double,"GAST_R[pu]",PADDR(gov_gast_R),PT_DESCRIPTION,"Governor droop constant (p.u.)",
00200 PT_double,"GAST_T1[s]",PADDR(gov_gast_T1),PT_DESCRIPTION,"Governor electric control box time constant (s)",
00201 PT_double,"GAST_T2[s]",PADDR(gov_gast_T2),PT_DESCRIPTION,"Governor electric control box time constant (s)",
00202 PT_double,"GAST_T3[s]",PADDR(gov_gast_T3),PT_DESCRIPTION,"Governor temperature limiter time constant (s)",
00203 PT_double,"GAST_AT[s]",PADDR(gov_gast_AT),PT_DESCRIPTION,"Governor Ambient Temperature load limit (units)",
00204 PT_double,"GAST_KT[pu]",PADDR(gov_gast_KT),PT_DESCRIPTION,"Governor temperature control loop gain",
00205 PT_double,"GAST_VMAX[pu]",PADDR(gov_gast_VMAX),PT_DESCRIPTION,"Governor actuator upper limit (p.u.)",
00206 PT_double,"GAST_VMIN[pu]",PADDR(gov_gast_VMIN),PT_DESCRIPTION,"Governor actuator lower limit (p.u.)",
00207
00208
00209 PT_double,"GAST_x1",PADDR(curr_state.gov_gast.x1),PT_DESCRIPTION,"Governor electric box state variable",
00210 PT_double,"GAST_x2",PADDR(curr_state.gov_gast.x2),PT_DESCRIPTION,"Governor electric box state variable",
00211 PT_double,"GAST_x3",PADDR(curr_state.gov_gast.x3),PT_DESCRIPTION,"Governor electric box state variable",
00212 PT_double,"GAST_throttle",PADDR(curr_state.gov_gast.throttle),PT_DESCRIPTION,"Governor electric box state variable",
00213
00214
00215 PT_double,"GGOV1_R[pu]",PADDR(gov_ggv1_r),PT_DESCRIPTION,"Permanent droop, p.u.",
00216 PT_int32,"GGOV1_Rselect",PADDR(gov_ggv1_rselect),PT_DESCRIPTION,"Feedback signal for droop, = 1 selected electrical power, = 0 none (isochronous governor), = -1 fuel valve stroke ( true stroke),= -2 governor output ( requested stroke)",
00217 PT_double,"GGOV1_Tpelec[s]",PADDR(gov_ggv1_Tpelec),PT_DESCRIPTION,"Electrical power transducer time constant, sec. (>0.)",
00218 PT_double,"GGOV1_maxerr",PADDR(gov_ggv1_maxerr),PT_DESCRIPTION,"Maximum value for speed error signal",
00219 PT_double,"GGOV1_minerr",PADDR(gov_ggv1_minerr),PT_DESCRIPTION,"Minimum value for speed error signal",
00220 PT_double,"GGOV1_Kpgov",PADDR(gov_ggv1_Kpgov),PT_DESCRIPTION,"Governor proportional gain",
00221 PT_double,"GGOV1_Kigov",PADDR(gov_ggv1_Kigov),PT_DESCRIPTION,"Governor integral gain",
00222 PT_double,"GGOV1_Kdgov",PADDR(gov_ggv1_Kdgov),PT_DESCRIPTION,"Governor derivative gain",
00223 PT_double,"GGOV1_Tdgov[s]",PADDR(gov_ggv1_Tdgov),PT_DESCRIPTION,"Governor derivative controller time constant, sec.",
00224 PT_double,"GGOV1_vmax",PADDR(gov_ggv1_vmax),PT_DESCRIPTION,"Maximum valve position limit",
00225 PT_double,"GGOV1_vmin",PADDR(gov_ggv1_vmin),PT_DESCRIPTION,"Minimum valve position limit",
00226 PT_double,"GGOV1_Tact",PADDR(gov_ggv1_Tact),PT_DESCRIPTION,"Actuator time constant",
00227 PT_double,"GGOV1_Kturb",PADDR(gov_ggv1_Kturb),PT_DESCRIPTION,"Turbine gain (>0.)",
00228 PT_double,"GGOV1_wfnl[pu]",PADDR(gov_ggv1_wfnl),PT_DESCRIPTION,"No load fuel flow, p.u",
00229 PT_double,"GGOV1_Tb[s]",PADDR(gov_ggv1_Tb),PT_DESCRIPTION,"Turbine lag time constant, sec. (>0.)",
00230 PT_double,"GGOV1_Tc[s]",PADDR(gov_ggv1_Tc),PT_DESCRIPTION,"Turbine lead time constant, sec.",
00231 PT_int32,"GGOV1_Fuel_lag",PADDR(gov_ggv1_Flag),PT_DESCRIPTION,"Switch for fuel source characteristic, = 0 for fuel flow independent of speed, = 1 fuel flow proportional to speed",
00232 PT_double,"GGOV1_Teng",PADDR(gov_ggv1_Teng),PT_DESCRIPTION,"Transport lag time constant for diesel engine",
00233 PT_double,"GGOV1_Tfload",PADDR(gov_ggv1_Tfload),PT_DESCRIPTION,"Load Limiter time constant, sec. (>0.)",
00234 PT_double,"GGOV1_Kpload",PADDR(gov_ggv1_Kpload),PT_DESCRIPTION,"Load limiter proportional gain for PI controller",
00235 PT_double,"GGOV1_Kiload",PADDR(gov_ggv1_Kiload),PT_DESCRIPTION,"Load limiter integral gain for PI controller",
00236 PT_double,"GGOV1_Ldref[pu]",PADDR(gov_ggv1_Ldref),PT_DESCRIPTION,"Load limiter reference value p.u.",
00237 PT_double,"GGOV1_Dm[pu]",PADDR(gov_ggv1_Dm),PT_DESCRIPTION,"Speed sensitivity coefficient, p.u.",
00238 PT_double,"GGOV1_ropen[pu/s]",PADDR(gov_ggv1_ropen),PT_DESCRIPTION,"Maximum valve opening rate, p.u./sec.",
00239 PT_double,"GGOV1_rclose[pu/s]",PADDR(gov_ggv1_rclose),PT_DESCRIPTION,"Minimum valve closing rate, p.u./sec.",
00240 PT_double,"GGOV1_Kimw",PADDR(gov_ggv1_Kimw),PT_DESCRIPTION,"Power controller (reset) gain",
00241 PT_double,"GGOV1_Pmwset[MW]",PADDR(gov_ggv1_Pmwset),PT_DESCRIPTION,"Power controller setpoint, MW",
00242 PT_double,"GGOV1_aset[pu/s]",PADDR(gov_ggv1_aset),PT_DESCRIPTION,"Acceleration limiter setpoint, p.u. / sec.",
00243 PT_double,"GGOV1_Ka",PADDR(gov_ggv1_Ka),PT_DESCRIPTION,"Acceleration limiter Gain",
00244 PT_double,"GGOV1_Ta[s]",PADDR(gov_ggv1_Ta),PT_DESCRIPTION,"Acceleration limiter time constant, sec. (>0.)",
00245 PT_double,"GGOV1_db",PADDR(gov_ggv1_db),PT_DESCRIPTION,"Speed governor dead band",
00246 PT_double,"GGOV1_Tsa[s]",PADDR(gov_ggv1_Tsa),PT_DESCRIPTION,"Temperature detection lead time constant, sec.",
00247 PT_double,"GGOV1_Tsb[s]",PADDR(gov_ggv1_Tsb),PT_DESCRIPTION,"Temperature detection lag time constant, sec.",
00248
00249
00250
00251
00252 PT_bool,"GGOV1_Load_Limit_enable",PADDR(gov_ggv1_fsrt_enable),PT_DESCRIPTION,"Enables/disables load limiter (fsrt) of low-value-select",
00253 PT_bool,"GGOV1_Acceleration_Limit_enable",PADDR(gov_ggv1_fsra_enable),PT_DESCRIPTION,"Enables/disables acceleration limiter (fsra) of low-value-select",
00254 PT_bool,"GGOV1_PID_enable",PADDR(gov_ggv1_fsrn_enable),PT_DESCRIPTION,"Enables/disables PID controller (fsrn) of low-value-select",
00255
00256
00257 PT_double,"GGOV1_fsrt",PADDR(curr_state.gov_ggov1.fsrt),PT_DESCRIPTION,"Load limiter block input to low-value-select",
00258 PT_double,"GGOV1_fsra",PADDR(curr_state.gov_ggov1.fsra),PT_DESCRIPTION,"Acceleration limiter block input to low-value-select",
00259 PT_double,"GGOV1_fsrn",PADDR(curr_state.gov_ggov1.fsrn),PT_DESCRIPTION,"PID block input to low-value-select",
00260 PT_double,"GGOV1_speed_error[pu]",PADDR(curr_state.gov_ggov1.werror),PT_DESCRIPTION,"Speed difference in per-unit for input to PID controller",
00261
00262
00263 PT_double,"GGOV1_x1",PADDR(curr_state.gov_ggov1.x1),
00264 PT_double,"GGOV1_x2",PADDR(curr_state.gov_ggov1.x2),
00265 PT_double,"GGOV1_x2a",PADDR(curr_state.gov_ggov1.x2a),
00266 PT_double,"GGOV1_x3",PADDR(curr_state.gov_ggov1.x3),
00267 PT_double,"GGOV1_x3a",PADDR(curr_state.gov_ggov1.x3a),
00268 PT_double,"GGOV1_x4",PADDR(curr_state.gov_ggov1.x4),
00269 PT_double,"GGOV1_x4a",PADDR(curr_state.gov_ggov1.x4a),
00270 PT_double,"GGOV1_x4b",PADDR(curr_state.gov_ggov1.x4b),
00271 PT_double,"GGOV1_x5",PADDR(curr_state.gov_ggov1.x5),
00272 PT_double,"GGOV1_x5a",PADDR(curr_state.gov_ggov1.x5a),
00273 PT_double,"GGOV1_x5b",PADDR(curr_state.gov_ggov1.x5b),
00274 PT_double,"GGOV1_x6",PADDR(curr_state.gov_ggov1.x6),
00275 PT_double,"GGOV1_x7",PADDR(curr_state.gov_ggov1.x7),
00276 PT_double,"GGOV1_x7a",PADDR(curr_state.gov_ggov1.x7a),
00277 PT_double,"GGOV1_x8",PADDR(curr_state.gov_ggov1.x8),
00278 PT_double,"GGOV1_x8a",PADDR(curr_state.gov_ggov1.x8a),
00279 PT_double,"GGOV1_x9",PADDR(curr_state.gov_ggov1.x9),
00280 PT_double,"GGOV1_x9a",PADDR(curr_state.gov_ggov1.x9a),
00281 PT_double,"GGOV1_x10",PADDR(curr_state.gov_ggov1.x10),
00282 PT_double,"GGOV1_x10a",PADDR(curr_state.gov_ggov1.x10a),
00283 PT_double,"GGOV1_x10b",PADDR(curr_state.gov_ggov1.x10b),
00284 PT_double,"GGOV1_ValveStroke",PADDR(curr_state.gov_ggov1.ValveStroke),
00285 PT_double,"GGOV1_FuelFlow",PADDR(curr_state.gov_ggov1.FuelFlow),
00286 PT_double,"GGOV1_GovOutPut",PADDR(curr_state.gov_ggov1.GovOutPut),
00287 PT_double,"GGOV1_RselectValue",PADDR(curr_state.gov_ggov1.RselectValue),
00288 PT_double,"GGOV1_fsrtNoLim",PADDR(curr_state.gov_ggov1.fsrtNoLim),
00289 PT_double,"GGOV1_err2",PADDR(curr_state.gov_ggov1.err2),
00290 PT_double,"GGOV1_err2a",PADDR(curr_state.gov_ggov1.err2a),
00291 PT_double,"GGOV1_err3",PADDR(curr_state.gov_ggov1.err3),
00292 PT_double,"GGOV1_err4",PADDR(curr_state.gov_ggov1.err4),
00293 PT_double,"GGOV1_err7",PADDR(curr_state.gov_ggov1.err7),
00294 PT_double,"GGOV1_LowValSelect1",PADDR(curr_state.gov_ggov1.LowValSelect1),
00295 PT_double,"GGOV1_LowValSelect",PADDR(curr_state.gov_ggov1.LowValSelect),
00296
00297
00298 PT_double,"P_CONSTANT_Tpelec[s]",PADDR(pconstant_Tpelec),PT_DESCRIPTION,"Electrical power transducer time constant, sec. (>0.)",
00299 PT_double,"P_CONSTANT_Tact",PADDR(pconstant_Tact),PT_DESCRIPTION,"Actuator time constant",
00300 PT_double,"P_CONSTANT_Kturb",PADDR(pconstant_Kturb),PT_DESCRIPTION,"Turbine gain (>0.)",
00301 PT_double,"P_CONSTANT_wfnl[pu]",PADDR(pconstant_wfnl),PT_DESCRIPTION,"No load fuel flow, p.u",
00302 PT_double,"P_CONSTANT_Tb[s]",PADDR(pconstant_Tb),PT_DESCRIPTION,"Turbine lag time constant, sec. (>0.)",
00303 PT_double,"P_CONSTANT_Tc[s]",PADDR(pconstant_Tc),PT_DESCRIPTION,"Turbine lead time constant, sec.",
00304 PT_double,"P_CONSTANT_Teng",PADDR(pconstant_Teng),PT_DESCRIPTION,"Transport lag time constant for diesel engine",
00305 PT_double,"P_CONSTANT_ropen[pu/s]",PADDR(pconstant_ropen),PT_DESCRIPTION,"Maximum valve opening rate, p.u./sec.",
00306 PT_double,"P_CONSTANT_rclose[pu/s]",PADDR(pconstant_rclose),PT_DESCRIPTION,"Minimum valve closing rate, p.u./sec.",
00307 PT_double,"P_CONSTANT_Kimw",PADDR(pconstant_Kimw),PT_DESCRIPTION,"Power controller (reset) gain",
00308
00309
00310 PT_double,"P_CONSTANT_x1",PADDR(curr_state.gov_pconstant.x1),
00311 PT_double,"P_CONSTANT_x4",PADDR(curr_state.gov_pconstant.x4),
00312 PT_double,"P_CONSTANT_x4a",PADDR(curr_state.gov_pconstant.x4a),
00313 PT_double,"P_CONSTANT_x4b",PADDR(curr_state.gov_pconstant.x4b),
00314 PT_double,"P_CONSTANT_x5",PADDR(curr_state.gov_pconstant.x5),
00315 PT_double,"P_CONSTANT_x5a",PADDR(curr_state.gov_pconstant.x5a),
00316 PT_double,"P_CONSTANT_x5b",PADDR(curr_state.gov_pconstant.x5b),
00317 PT_double,"P_CONSTANT_x_Pconstant",PADDR(curr_state.gov_pconstant.x_Pconstant),
00318 PT_double,"P_CONSTANT_err4",PADDR(curr_state.gov_pconstant.err4),
00319 PT_double,"P_CONSTANT_ValveStroke",PADDR(curr_state.gov_pconstant.ValveStroke),
00320 PT_double,"P_CONSTANT_FuelFlow",PADDR(curr_state.gov_pconstant.FuelFlow),
00321 PT_double,"P_CONSTANT_GovOutPut",PADDR(curr_state.gov_pconstant.GovOutPut),
00322
00323 PT_bool,"fuelEmissionCal", PADDR(fuelEmissionCal), PT_DESCRIPTION, "Boolean value indicating whether fuel and emission calculations are used or not",
00324 PT_double,"outputEnergy",PADDR(outputEnergy),PT_DESCRIPTION,"Total energy(kWh) output from the generator",
00325 PT_double,"FuelUse",PADDR(FuelUse),PT_DESCRIPTION,"Total fuel usage (gal) based on kW power output",
00326 PT_double,"efficiency",PADDR(efficiency),PT_DESCRIPTION,"Total energy output per fuel usage (kWh/gal)",
00327 PT_double,"CO2_emission",PADDR(CO2_emission),PT_DESCRIPTION,"Total CO2 emissions (lbs) based on fule usage",
00328 PT_double,"SOx_emission",PADDR(SOx_emission),PT_DESCRIPTION,"Total SOx emissions (lbs) based on fule usage",
00329 PT_double,"NOx_emission",PADDR(NOx_emission),PT_DESCRIPTION,"Total NOx emissions (lbs) based on fule usage",
00330 PT_double,"PM10_emission",PADDR(PM10_emission),PT_DESCRIPTION,"Total PM-10 emissions (lbs) based on fule usage",
00331
00332 PT_double,"frequency_deviation",PADDR(frequency_deviation),PT_DESCRIPTION,"Frequency deviation of diesel_dg",
00333 PT_double,"frequency_deviation_energy",PADDR(frequency_deviation_energy),PT_DESCRIPTION,"Frequency deviation accumulation of diesel_dg",
00334 PT_double,"frequency_deviation_max",PADDR(frequency_deviation_max),PT_DESCRIPTION,"Frequency deviation of diesel_dg",
00335 PT_double,"realPowerChange",PADDR(realPowerChange),PT_DESCRIPTION,"Real power output change of diesel_dg",
00336 PT_double,"ratio_f_p",PADDR(ratio_f_p),PT_DESCRIPTION,"Ratio of frequency deviation to real power output change of diesel_dg",
00337
00338 PT_set, "phases", PADDR(phases), PT_DESCRIPTION, "Specifies which phases to connect to - currently not supported and assumes three-phase connection",
00339 PT_KEYWORD, "A",(set)PHASE_A,
00340 PT_KEYWORD, "B",(set)PHASE_B,
00341 PT_KEYWORD, "C",(set)PHASE_C,
00342 PT_KEYWORD, "N",(set)PHASE_N,
00343 PT_KEYWORD, "S",(set)PHASE_S,
00344
00345
00346 NULL)<1) GL_THROW("unable to publish properties in %s",__FILE__);
00347
00348 defaults = this;
00349
00350 memset(this,0,sizeof(diesel_dg));
00351
00352 if (gl_publish_function(oclass, "interupdate_gen_object", (FUNCTIONADDR)interupdate_diesel_dg)==NULL)
00353 GL_THROW("Unable to publish diesel_dg deltamode function");
00354 if (gl_publish_function(oclass, "postupdate_gen_object", (FUNCTIONADDR)postupdate_diesel_dg)==NULL)
00355 GL_THROW("Unable to publish diesel_dg deltamode function");
00356 }
00357 }
00358
00359
00360 int diesel_dg::create(void)
00361 {
00363
00364 power_factor = 0.0;
00365
00366
00367 Rated_V_LL = 0.0;
00368 Rated_V_LN = 0.0;
00369 Rated_VA = 0.0;
00370
00371 Overload_Limit_Pub = 1.25;
00372 Overload_Limit_Value = 0.0;
00373
00374 Max_Ef = 1.05;
00375 Min_Ef = 0.95;
00376
00377
00378 omega_ref=2*PI*60;
00379 inertia=0.7;
00380 damping=0.0;
00381 number_poles=2;
00382 Ra=0.00625;
00383 Xd=2.06;
00384 Xq=2.5;
00385 Xdp=0.398;
00386 Xqp=0.3;
00387 Xdpp=0.254;
00388 Xqpp=0.254;
00389 Xl=0.1;
00390 Tdp=0.31737;
00391 Tdop=4.45075;
00392 Tqop=3.0;
00393 Tdopp=0.066;
00394 Tqopp=0.075;
00395 Ta=0.03202;
00396 X0=complex(0.005,0.05);
00397 X2=complex(0.0072,0.2540);
00398
00399
00400 gen_base_set_vals.wref = -99.0;
00401 gen_base_set_vals.vset = -99.0;
00402 gen_base_set_vals.Pref = -99.0;
00403 gen_base_set_vals.Qref = -99.0;
00404
00405
00406 exc_KA=50;
00407 exc_TA=0.01;
00408 exc_TB=2.0;
00409 exc_TC=10;
00410 exc_EMAX=3.0;
00411 exc_EMIN=-3.0;
00412
00413
00414 gov_degov1_R=0.05;
00415 gov_degov1_T1=0.2;
00416 gov_degov1_T2=0.3;
00417 gov_degov1_T3=0.5;
00418 gov_degov1_K=0.8;
00419 gov_degov1_T4=1.0;
00420 gov_degov1_T5=0.1;
00421 gov_degov1_T6=0.2;
00422 gov_degov1_TMAX=1.0;
00423 gov_degov1_TMIN=0.0;
00424 gov_degov1_TD=0.01;
00425
00426
00427
00428
00429
00430 gov_gast_R=.05;
00431 gov_gast_T1=0.4;
00432 gov_gast_T2=0.1;
00433 gov_gast_T3=3;
00434 gov_gast_AT=1;
00435 gov_gast_KT=2;
00436 gov_gast_VMAX=1.05;
00437 gov_gast_VMIN=-0.05;
00438
00439
00440 gov_ggv1_r = 0.04;
00441 gov_ggv1_rselect = 1;
00442 gov_ggv1_Tpelec = 1.0;
00443 gov_ggv1_maxerr = 0.05;
00444 gov_ggv1_minerr = -0.05;
00445 gov_ggv1_Kpgov = 0.8;
00446 gov_ggv1_Kigov = 0.2;
00447 gov_ggv1_Kdgov = 0.0;
00448 gov_ggv1_Tdgov = 1.0;
00449 gov_ggv1_vmax = 1.0;
00450 gov_ggv1_vmin = 0.15;
00451 gov_ggv1_Tact = 0.5;
00452 gov_ggv1_Kturb = 1.5;
00453 gov_ggv1_wfnl = 0.2;
00454 gov_ggv1_Tb = 0.1;
00455 gov_ggv1_Tc = 0.0;
00456 gov_ggv1_Flag = 1;
00457 gov_ggv1_Teng = 0.0;
00458 gov_ggv1_Tfload = 3.0;
00459 gov_ggv1_Kpload = 2.0;
00460 gov_ggv1_Kiload = 0.67;
00461 gov_ggv1_Ldref = 1.0;
00462 gov_ggv1_Dm = 0.0;
00463 gov_ggv1_ropen = 0.10;
00464 gov_ggv1_rclose = -0.1;
00465 gov_ggv1_Kimw = 0.002;
00466 gov_ggv1_Pmwset = -1;
00467 gov_ggv1_aset = 0.01;
00468 gov_ggv1_Ka = 10.0;
00469 gov_ggv1_Ta = 0.1;
00470 gov_ggv1_db = 0.0;
00471 gov_ggv1_Tsa = 4.0;
00472 gov_ggv1_Tsb = 5.0;
00473
00474
00475
00476
00477 pconstant_Tpelec = 1.0;
00478 pconstant_Tact = 0.5;
00479 pconstant_Kturb = 1.5;
00480 pconstant_wfnl = 0.2;
00481 pconstant_Tb = 0.1;
00482 pconstant_Tc = 0.0;
00483 pconstant_Flag = 0;
00484 pconstant_Teng = 0.0;
00485 pconstant_ropen = 0.10;
00486 pconstant_rclose = -0.1;
00487 pconstant_Kimw = 0.002;
00488
00489
00490 gov_ggv1_fsrt_enable = true;
00491 gov_ggv1_fsra_enable = true;
00492 gov_ggv1_fsrn_enable = true;
00493
00494
00495 pPGenerated = NULL;
00496 pIGenerated[0] = pIGenerated[1] = pIGenerated[2] = NULL;
00497 pbus_full_Y_mat = NULL;
00498 pbus_full_Y_all_mat = NULL;
00499 generator_admittance[0][0] = generator_admittance[0][1] = generator_admittance[0][2] = complex(0.0,0.0);
00500 generator_admittance[1][0] = generator_admittance[1][1] = generator_admittance[1][2] = complex(0.0,0.0);
00501 generator_admittance[2][0] = generator_admittance[2][1] = generator_admittance[2][2] = complex(0.0,0.0);
00502
00503 full_bus_admittance_mat[0][0] = full_bus_admittance_mat[0][1] = full_bus_admittance_mat[0][2] = complex(0.0,0.0);
00504 full_bus_admittance_mat[1][0] = full_bus_admittance_mat[1][1] = full_bus_admittance_mat[1][2] = complex(0.0,0.0);
00505 full_bus_admittance_mat[2][0] = full_bus_admittance_mat[2][1] = full_bus_admittance_mat[2][2] = complex(0.0,0.0);
00506 value_IGenerated[0] = value_IGenerated[1] = value_IGenerated[2] = complex(0.0,0.0);
00507 Governor_type = NO_GOV;
00508 Exciter_type = NO_EXC;
00509
00510 power_val[0] = power_val[1] = power_val[2] = complex(0.0,0.0);
00511 current_val[0] = current_val[1] = current_val[2] = complex(0.0,0.0);
00512
00513
00514 rotor_speed_convergence_criterion = 0.1;
00515 prev_rotor_speed_val = 0.0;
00516
00517
00518 voltage_convergence_criterion = 0.5;
00519 prev_voltage_val[0] = 0.0;
00520 prev_voltage_val[1] = 0.0;
00521 prev_voltage_val[2] = 0.0;
00522
00523
00524 apply_rotor_speed_convergence = true;
00525 apply_voltage_mag_convergence = false;
00526
00527
00528 power_base = 0.0;
00529 voltage_base = 0.0;
00530 current_base = 0.0;
00531 impedance_base = 0.0;
00532 YS0 = 0.0;
00533 YS1 = 0.0;
00534 YS2 = 0.0;
00535 Rr = 0.0;
00536
00537 torque_delay = NULL;
00538 x5a_delayed = NULL;
00539 torque_delay_len = 0;
00540 x5a_delayed_len = 0;
00541
00542 torque_delay_write_pos = 0;
00543 torque_delay_read_pos = 0;
00544 x5a_delayed_write_pos = 0;
00545 x5a_delayed_read_pos = 0;
00546
00547
00548 curr_state.omega = 2*PI*60.0;
00549
00550 deltamode_inclusive = false;
00551 mapped_freq_variable = NULL;
00552
00553 first_run = true;
00554
00555 prev_time = 0;
00556 prev_time_dbl = 0.0;
00557
00558 is_isochronous_gen = false;
00559
00560 ki_Pconstant = 1;
00561 kp_Pconstant = 0;
00562
00563 Q_constant_mode = false;
00564 ki_Qconstant = 1;
00565 kp_Qconstant = 0;
00566
00567 CVRenabled = false;
00568 ki_cvr = 0;
00569 kp_cvr = 0;
00570 kd_cvr = 0;
00571 CVR_PI = false;
00572 CVR_PID = false;
00573 vset_EMAX = 1.05;
00574 vset_EMIN = 0.95;
00575
00576 Kd1 = 1;
00577 Kd2 = 1;
00578 Kd3 = 1;
00579 Kn1 = 0;
00580 Kn2 = 0;
00581 vset_delta_MAX = 99;
00582 vset_delta_MIN = -99;
00583
00584 last_time = 0;
00585 fuelEmissionCal = false;
00586 outputEnergy = 0.0;
00587 FuelUse = 0.0;
00588 efficiency = 0.0;
00589 CO2_emission = 0.0;
00590 SOx_emission = 0.0;
00591 NOx_emission = 0.0;
00592 PM10_emission = 0.0;
00593
00594 pwr_electric_init = -1;
00595 frequency_deviation_energy = 0;
00596 frequency_deviation_max = 0;
00597
00598 pCircuit_V[0] = pCircuit_V[1] = pCircuit_V[2] = NULL;
00599 pLine_I[0] = pLine_I[1] = pLine_I[2] = NULL;
00600 pPower[0] = pPower[1] = pPower[2] = NULL;
00601 value_Circuit_V[0] = value_Circuit_V[1] = value_Circuit_V[2] = complex(0.0,0.0);
00602 value_Line_I[0] = value_Line_I[1] = value_Line_I[2] = complex(0.0,0.0);
00603 value_Power[0] = value_Power[1] = value_Power[2] = complex(0.0,0.0);
00604 value_prev_Power[0] = value_prev_Power[1] = value_prev_Power[2] = complex(0.0,0.0);
00605
00606 parent_is_powerflow = false;
00607
00608
00609 Gen_type = NON_DYN_CONSTANT_PQ;
00610
00611 return 1;
00612 }
00613
00614
00615 int diesel_dg::init(OBJECT *parent)
00616 {
00617 OBJECT *obj = OBJECTHDR(this);
00618 OBJECT *tmp_obj = NULL;
00619
00620 int temp_idx_x, temp_idx_y;
00621 double ZB, SB, EB;
00622 double test_pf;
00623 gld_property *Frequency_mapped;
00624 gld_property *temp_property_pointer;
00625 gld_wlock *test_rlock;
00626 bool temp_bool_value;
00627 double temp_voltage_magnitude;
00628 complex temp_complex_value;
00629 complex_array temp_complex_array;
00630 gld_property *pNominal_Voltage;
00631 double nominal_voltage_value, nom_test_val;
00632
00633
00634 if ((obj->flags & OF_DELTAMODE) == OF_DELTAMODE)
00635 {
00636 deltamode_inclusive = true;
00637 }
00638
00639
00640 if (parent!=NULL)
00641 {
00642 if (gl_object_isa(parent,"meter","powerflow") || gl_object_isa(parent,"node","powerflow") || gl_object_isa(parent,"load","powerflow"))
00643 {
00644
00645 parent_is_powerflow = true;
00646
00647
00648 if (parent->parent != NULL)
00649 {
00650
00651 tmp_obj = parent->parent;
00652
00653
00654 if ((gl_object_isa(tmp_obj,"meter","powerflow") == false) && (gl_object_isa(tmp_obj,"node","powerflow")==false) && (gl_object_isa(tmp_obj,"load","powerflow")==false))
00655 {
00656
00657 tmp_obj = parent;
00658 }
00659 else
00660 {
00661
00662 if (deltamode_inclusive == true)
00663 {
00664
00665 temp_property_pointer = new gld_property(parent,"Norton_dynamic");
00666
00667
00668 if ((temp_property_pointer->is_valid() != true) || (temp_property_pointer->is_bool() != true))
00669 {
00670 GL_THROW("diesel_dg:%s failed to map Norton-equivalence deltamode variable from %s",obj->name?obj->name:"unnamed",parent->name?parent->name:"unnamed");
00671
00672 }
00673
00674
00675 temp_bool_value = true;
00676 temp_property_pointer->setp<bool>(temp_bool_value,*test_rlock);
00677
00678
00679 delete temp_property_pointer;
00680 }
00681
00682 }
00683 }
00684 else
00685 {
00686
00687 tmp_obj = parent;
00688 }
00689
00690
00691
00692
00693 pCircuit_V[0] = map_complex_value(tmp_obj,"voltage_A");
00694 pCircuit_V[1] = map_complex_value(tmp_obj,"voltage_B");
00695 pCircuit_V[2] = map_complex_value(tmp_obj,"voltage_C");
00696
00697
00698 pLine_I[0] = map_complex_value(tmp_obj,"current_A");
00699 pLine_I[1] = map_complex_value(tmp_obj,"current_B");
00700 pLine_I[2] = map_complex_value(tmp_obj,"current_C");
00701
00702
00703 pPower[0] = map_complex_value(tmp_obj,"power_A");
00704 pPower[1] = map_complex_value(tmp_obj,"power_B");
00705 pPower[2] = map_complex_value(tmp_obj,"power_C");
00706
00707
00708
00709 pNominal_Voltage = new gld_property(parent,"nominal_voltage");
00710
00711
00712 if ((pNominal_Voltage->is_valid() != true) || (pNominal_Voltage->is_double() != true))
00713 {
00714 GL_THROW("diesel_dg:%d %s - Unable to map nominal_voltage from object:%d %s",obj->id,(obj->name ? obj->name : "Unnamed"),parent->id,(parent->name ? parent->name : "Unnamed"));
00715
00716
00717
00718
00719 }
00720
00721
00722 nominal_voltage_value = pNominal_Voltage->get_double();
00723
00724
00725 delete pNominal_Voltage;
00726
00727
00728 Rated_V_LN = Rated_V_LL / sqrt(3.0);
00729
00730
00731 if (Rated_V_LL > 0.0)
00732 {
00733
00734 nom_test_val = Rated_V_LN / nominal_voltage_value;
00735
00736
00737 if ((nom_test_val > 1.01) || (nom_test_val < 0.99))
00738 {
00739 GL_THROW("diesel_dg:%d %s - Rated_V does not match the nominal voltage!",obj->id,(obj->name ? obj->name : "Unnamed"));
00740
00741
00742
00743
00744 }
00745 }
00746 else
00747 {
00748
00749 Rated_V_LL = nominal_voltage_value * sqrt(3.0);
00750
00751
00752 Rated_V_LN = nominal_voltage_value;
00753 }
00754
00755
00756 if (deltamode_inclusive==true)
00757 {
00758
00759 pIGenerated[0] = map_complex_value(tmp_obj,"deltamode_generator_current_A");
00760 pIGenerated[1] = map_complex_value(tmp_obj,"deltamode_generator_current_B");
00761 pIGenerated[2] = map_complex_value(tmp_obj,"deltamode_generator_current_C");
00762
00763
00764 pPGenerated = map_complex_value(tmp_obj,"deltamode_PGenTotal");
00765
00766
00767 temp_property_pointer = new gld_property(tmp_obj,"Norton_dynamic");
00768
00769
00770 if ((temp_property_pointer->is_valid() != true) || (temp_property_pointer->is_bool() != true))
00771 {
00772 GL_THROW("diesel_dg:%s failed to map Norton-equivalence deltamode variable from %s",obj->name?obj->name:"unnamed",tmp_obj->name?tmp_obj->name:"unnamed");
00773
00774
00775
00776
00777 }
00778
00779
00780 temp_bool_value = true;
00781 temp_property_pointer->setp<bool>(temp_bool_value,*test_rlock);
00782
00783
00784 delete temp_property_pointer;
00785 }
00786 }
00787 else
00788 {
00789 GL_THROW("diesel_dg:%s only supports a powerflow node/load/meter or no object as its parent at this time",obj->name?obj->name:"unnamed");
00790
00791
00792
00793
00794 }
00795
00796
00797 temp_property_pointer = new gld_property(parent,"phases");
00798
00799
00800 if ((temp_property_pointer->is_valid() != true) || (temp_property_pointer->is_set() != true))
00801 {
00802 GL_THROW("Unable to map phases property - ensure the parent is a meter or a node or a load");
00803
00804
00805
00806
00807
00808 }
00809
00810
00811 phases = temp_property_pointer->get_set();
00812
00813
00814 delete temp_property_pointer;
00815
00816 if((phases & 0x0007) != 0x0007){
00817 GL_THROW("The diesel_dg object must be connected to all three phases. Please make sure the parent object has all three phases.");
00818
00819
00820
00821
00822 }
00823 }
00824 else
00825 {
00826
00827 parent_is_powerflow = false;
00828
00829 gl_warning("diesel_dg:%d - %s has no parent object - default voltages being used",obj->id,(obj->name ? obj->name : "Unnamed"));
00830
00831
00832
00833
00834
00835 value_Circuit_V[0].SetPolar(Rated_V_LN,0.0);
00836 value_Circuit_V[1].SetPolar(Rated_V_LN,-2.0/3.0*PI);
00837 value_Circuit_V[2].SetPolar(Rated_V_LN,2.0/3.0*PI);
00838 }
00839
00840
00841 if ((Gen_type!=DYNAMIC) && (deltamode_inclusive==true))
00842 {
00843
00844 Gen_type=DYNAMIC;
00845
00846
00847 gl_warning("diesel_dg:%s forced into DYN_SYNCHRONOUS mode",obj->name?obj->name:"unnamed");
00848
00849
00850
00851
00852
00853 }
00854
00855 if (Gen_type == NON_DYN_CONSTANT_PQ)
00856 {
00857
00858 if (Rated_VA <= 0.0)
00859 {
00860 Rated_VA = 0.5e6;
00861
00862 gl_warning("diesel_dg:%s did not have a valid Rated_VA set, assuming 5000 kVA",obj->name?obj->name:"unnamed");
00863
00864
00865
00866
00867 }
00868
00869
00870 power_base = Rated_VA/3.0;
00871
00872
00873 if (power_val[0].Mag()>power_base)
00874 {
00875 gl_warning("diesel_dg:%s - power_out_A is above 1/3 the total rating, capping",obj->name?obj->name:"unnamed");
00876
00877
00878
00879
00880
00881
00882 test_pf = power_val[0].Re()/power_val[0].Mag();
00883
00884
00885 if (power_val[0].Im()<0.0)
00886 power_val[0] = complex((power_base*test_pf),(-1.0*sqrt(1-test_pf*test_pf)*power_base));
00887 else
00888 power_val[0] = complex((power_base*test_pf),(sqrt(1-test_pf*test_pf)*power_base));
00889 }
00890
00891 if (power_val[1].Mag()>power_base)
00892 {
00893 gl_warning("diesel_dg:%s - power_out_B is above 1/3 the total rating, capping",obj->name?obj->name:"unnamed");
00894
00895
00896
00897
00898
00899
00900 test_pf = power_val[1].Re()/power_val[1].Mag();
00901
00902
00903 if (power_val[1].Im()<0.0)
00904 power_val[1] = complex((power_base*test_pf),(-1.0*sqrt(1-test_pf*test_pf)*power_base));
00905 else
00906 power_val[1] = complex((power_base*test_pf),(sqrt(1-test_pf*test_pf)*power_base));
00907 }
00908
00909 if (power_val[2].Mag()>power_base)
00910 {
00911 gl_warning("diesel_dg:%s - power_out_C is above 1/3 the total rating, capping",obj->name?obj->name:"unnamed");
00912
00913
00914
00915
00916
00917
00918 test_pf = power_val[2].Re()/power_val[2].Mag();
00919
00920
00921 if (power_val[2].Im()<0.0)
00922 power_val[2] = complex((power_base*test_pf),(-1.0*sqrt(1-test_pf*test_pf)*power_base));
00923 else
00924 power_val[2] = complex((power_base*test_pf),(sqrt(1-test_pf*test_pf)*power_base));
00925 }
00926 }
00927 else
00928 {
00929
00930 if ((parent->flags & OF_DELTAMODE) != OF_DELTAMODE)
00931 {
00932 GL_THROW("diesel_dg:%s - The parented object does not have deltamode flags enabled.",obj->name?obj->name:"unnamed");
00933
00934
00935
00936
00937
00938 }
00939
00940
00941 if (Rated_VA<=0.0)
00942 {
00943 Rated_VA = 10e6;
00944
00945 gl_warning("diesel_dg:%s did not have a valid Rated_VA set, assuming 10 MVA",obj->name?obj->name:"unnamed");
00946
00947
00948
00949
00950 }
00951
00952
00953 if (Overload_Limit_Pub <= 0.0)
00954 {
00955
00956 Overload_Limit_Pub = 1.25;
00957
00958
00959 gl_warning("diesel_dg:%d %s - overload_limit has a value less than or equal to zero - set to 1.25",obj->id,(obj->name ? obj->name : "Unnamed"));
00960
00961
00962
00963
00964 }
00965
00966
00967 Overload_Limit_Value = Rated_VA * Overload_Limit_Pub;
00968
00969
00970 if (Rated_V_LL<=0.0)
00971 {
00972 Rated_V_LL = 15000.0;
00973
00974 gl_warning("diesel_dg:%s did not have a valid Rated_V set, assuming 15 kV",obj->name?obj->name:"unnamed");
00975
00976
00977
00978
00979
00980 }
00981
00982
00983 power_base = Rated_VA/3.0;
00984 voltage_base = Rated_V_LN;
00985 current_base = power_base / voltage_base;
00986 impedance_base = voltage_base / current_base;
00987
00988
00989 YS0 = complex(1.0)/(X0*impedance_base);
00990 YS1 = complex(1.0)/(complex(Ra,Xdpp)*impedance_base);
00991 YS2 = complex(1.0)/(X2*impedance_base);
00992
00993
00994 convert_Ypn0_to_Yabc(YS0,YS1,YS2, &generator_admittance[0][0]);
00995
00996
00997 Rr = 2.0*(X2.Re()-Ra);
00998
00999
01000 if ((deltamode_inclusive == true) && (parent_is_powerflow == true))
01001 {
01002
01003 pbus_full_Y_mat = new gld_property(parent,"deltamode_full_Y_matrix");
01004
01005
01006 if ((pbus_full_Y_mat->is_valid() != true) || (pbus_full_Y_mat->is_complex_array() != true))
01007 {
01008 GL_THROW("diesel_dg:%s failed to map Norton-equivalence deltamode variable from %s",obj->name?obj->name:"unnamed",parent->name?parent->name:"unnamed");
01009
01010 }
01011
01012
01013 pbus_full_Y_mat->getp<complex_array>(temp_complex_array,*test_rlock);
01014
01015
01016 if (temp_complex_array.is_valid(0,0) != true)
01017 {
01018
01019 temp_complex_array.grow_to(3,3);
01020
01021
01022 for (temp_idx_x=0; temp_idx_x<3; temp_idx_x++)
01023 {
01024 for (temp_idx_y=0; temp_idx_y<3; temp_idx_y++)
01025 {
01026 temp_complex_array.set_at(temp_idx_x,temp_idx_y,complex(0.0,0.0));
01027 }
01028 }
01029 }
01030 else
01031 {
01032 if ((temp_complex_array.get_rows() != 3) && (temp_complex_array.get_cols() != 3))
01033 {
01034 GL_THROW("diesel_dg:%s exposed Norton-equivalent matrix is the wrong size!",obj->name?obj->name:"unnamed");
01035
01036
01037
01038
01039 }
01040
01041 }
01042
01043
01044 for (temp_idx_x=0; temp_idx_x<3; temp_idx_x++)
01045 {
01046 for (temp_idx_y=0; temp_idx_y<3; temp_idx_y++)
01047 {
01048
01049 temp_complex_value = temp_complex_array.get_at(temp_idx_x,temp_idx_y);
01050
01051
01052 temp_complex_value += generator_admittance[temp_idx_x][temp_idx_y];
01053
01054
01055 temp_complex_array.set_at(temp_idx_x,temp_idx_y,temp_complex_value);
01056 }
01057 }
01058
01059
01060 pbus_full_Y_mat->setp<complex_array>(temp_complex_array,*test_rlock);
01061
01062
01063
01064 pbus_full_Y_all_mat = new gld_property(parent,"deltamode_full_Y_all_matrix");
01065
01066
01067 if ((pbus_full_Y_all_mat->is_valid() != true) || (pbus_full_Y_all_mat->is_complex_array() != true))
01068 {
01069 GL_THROW("diesel_dg:%s failed to map Norton-equivalence deltamode variable from %s",obj->name?obj->name:"unnamed",parent->name?parent->name:"unnamed");
01070
01071 }
01072 }
01073
01074
01075 if (Governor_type == P_CONSTANT) {
01076 for (int i = 0; i < 3; i++) {
01077 power_val[i].Re() = Rated_VA * gen_base_set_vals.Pref/3;
01078 }
01079 }
01080 if (Q_constant_mode == true) {
01081 for (int i = 0; i < 3; i++) {
01082 power_val[i].Im() = Rated_VA * gen_base_set_vals.Qref/3;
01083 }
01084 }
01085
01086
01087 if (power_val[0].Mag()>power_base)
01088 {
01089 gl_warning("diesel_dg:%s - power_out_A is above 1/3 the total rating, capping",obj->name?obj->name:"unnamed");
01090
01091
01092
01093
01094
01095
01096 test_pf = power_val[0].Re()/power_val[0].Mag();
01097
01098
01099 if (power_val[0].Im()<0.0)
01100 power_val[0] = complex((power_base*test_pf),(-1.0*sqrt(1-test_pf*test_pf)*power_base));
01101 else
01102 power_val[0] = complex((power_base*test_pf),(sqrt(1-test_pf*test_pf)*power_base));
01103 }
01104
01105 if (power_val[1].Mag()>power_base)
01106 {
01107 gl_warning("diesel_dg:%s - power_out_B is above 1/3 the total rating, capping",obj->name?obj->name:"unnamed");
01108
01109
01110
01111
01112
01113
01114 test_pf = power_val[1].Re()/power_val[1].Mag();
01115
01116
01117 if (power_val[1].Im()<0.0)
01118 power_val[1] = complex((power_base*test_pf),(-1.0*sqrt(1-test_pf*test_pf)*power_base));
01119 else
01120 power_val[1] = complex((power_base*test_pf),(sqrt(1-test_pf*test_pf)*power_base));
01121 }
01122
01123 if (power_val[2].Mag()>power_base)
01124 {
01125 gl_warning("diesel_dg:%s - power_out_C is above 1/3 the total rating, capping",obj->name?obj->name:"unnamed");
01126
01127
01128
01129
01130
01131
01132 test_pf = power_val[2].Re()/power_val[2].Mag();
01133
01134
01135 if (power_val[2].Im()<0.0)
01136 power_val[2] = complex((power_base*test_pf),(-1.0*sqrt(1-test_pf*test_pf)*power_base));
01137 else
01138 power_val[2] = complex((power_base*test_pf),(sqrt(1-test_pf*test_pf)*power_base));
01139 }
01140
01141
01142 if (power_val[0].Mag() == 0.0)
01143 {
01144 gl_warning("diesel_dg:%s - power_out_A is zero - arbitrarily setting to 50%%",obj->name?obj->name:"unnamed");
01145
01146
01147
01148
01149
01150
01151 power_val[0] = complex(0.5*power_base,0.0);
01152 }
01153
01154 if (power_val[1].Mag() == 0.0)
01155 {
01156 gl_warning("diesel_dg:%s - power_out_B is zero - arbitrarily setting to 50%%",obj->name?obj->name:"unnamed");
01157
01158
01159
01160
01161
01162
01163 power_val[1] = complex(0.5*power_base,0.0);
01164 }
01165
01166 if (power_val[2].Mag() == 0.0)
01167 {
01168 gl_warning("diesel_dg:%s - power_out_C is zero - arbitrarily setting to 50%%",obj->name?obj->name:"unnamed");
01169
01170
01171
01172
01173
01174
01175 power_val[2] = complex(0.5*power_base,0.0);
01176 }
01177
01178 if (apply_rotor_speed_convergence == true)
01179 {
01180
01181 if (rotor_speed_convergence_criterion<0.0)
01182 {
01183 gl_warning("diesel_dg:%s - rotor_speed_convergence is less than zero - negating",obj->name?obj->name:"unnamed");
01184
01185
01186
01187
01188
01189 rotor_speed_convergence_criterion = -rotor_speed_convergence_criterion;
01190 }
01191 else if (rotor_speed_convergence_criterion==0.0)
01192 {
01193 gl_warning("diesel_dg:%s - rotor_speed_convergence is zero - it may never exit deltamode!",obj->name?obj->name:"unnamed");
01194
01195
01196
01197
01198 }
01199
01200
01201
01202 switch(Governor_type) {
01203 case NO_GOV:
01204 {
01205 break;
01206 }
01207 case DEGOV1:
01208 {
01209
01210 if (gov_degov1_R == 0.0)
01211 {
01212 is_isochronous_gen = true;
01213 }
01214 break;
01215 }
01216 case GAST:
01217 {
01218
01219 if (gov_gast_R == 0.0)
01220 {
01221 is_isochronous_gen = true;
01222 }
01223 break;
01224 }
01225 case GGOV1_OLD:
01226 case GGOV1:
01227 {
01228
01229 if ((gov_ggv1_r == 0.0) && (gov_ggv1_rselect==0))
01230 {
01231 is_isochronous_gen = true;
01232 }
01233 break;
01234 }
01235 default:
01236 {
01237
01238 break;
01239 }
01240 }
01241 }
01242
01243
01244 if (apply_voltage_mag_convergence == true)
01245 {
01246
01247 if (Exciter_type == NO_EXC)
01248 {
01249 gl_warning("diesel_dg:%s - voltage convergence is enabled, but no exciter is present",(obj->name ? obj->name : "unnamed"));
01250
01251
01252
01253
01254 }
01255
01256
01257 if (voltage_convergence_criterion<0.0)
01258 {
01259 gl_warning("diesel_dg:%s - voltage_convergence is less than zero - negating",obj->name?obj->name:"unnamed");
01260
01261
01262
01263
01264
01265 voltage_convergence_criterion = -voltage_convergence_criterion;
01266 }
01267 else if (voltage_convergence_criterion==0.0)
01268 {
01269 gl_warning("diesel_dg:%s - voltage_convergence is zero - it may never exit deltamode!",obj->name?obj->name:"unnamed");
01270
01271
01272
01273
01274 }
01275
01276 }
01277
01278
01279 if ((Min_Ef<=0.0) && (Exciter_type != NO_EXC))
01280 {
01281 GL_THROW("diesel_dg:%s - Vterm_min is less than or equal to zero",obj->name?obj->name:"unnamed");
01282
01283
01284
01285
01286 }
01287
01288
01289 if ((Max_Ef<=Min_Ef) && (Exciter_type != NO_EXC))
01290 {
01291 GL_THROW("diesel_dg:%s - Vterm_max is less than or equal to Vterm_min",obj->name?obj->name:"unnamed");
01292
01293
01294
01295
01296 }
01297
01298 }
01299
01300
01301 if (deltamode_inclusive)
01302 {
01303
01304 if (enable_subsecond_models!=true)
01305 {
01306 gl_warning("diesel_dg:%s indicates it wants to run deltamode, but the module-level flag is not set!",obj->name?obj->name:"unnamed");
01307
01308
01309
01310
01311 }
01312 else
01313 {
01314
01315
01316 Frequency_mapped = NULL;
01317
01318
01319 Frequency_mapped = new gld_property("powerflow::master_frequency_update");
01320
01321
01322 if ((Frequency_mapped->is_valid() != true) || (Frequency_mapped->is_bool() != true))
01323 {
01324 GL_THROW("diesel_dg:%s - Failed to map frequency checking variable from powerflow for deltamode",obj->name?obj->name:"unnamed");
01325
01326
01327
01328
01329
01330 }
01331
01332
01333 Frequency_mapped->getp<bool>(temp_bool_value,*test_rlock);
01334
01335
01336 if (temp_bool_value == false)
01337 {
01338
01339 mapped_freq_variable = new gld_property("powerflow::current_frequency");
01340
01341
01342 if ((mapped_freq_variable->is_valid() != true) || (mapped_freq_variable->is_double() != true))
01343 {
01344 GL_THROW("diesel_dg:%s - Failed to map frequency checking variable from powerflow for deltamode",obj->name?obj->name:"unnamed");
01345
01346 }
01347
01348
01349 temp_bool_value = true;
01350 Frequency_mapped->setp<bool>(temp_bool_value,*test_rlock);
01351 }
01352
01353
01354
01355 delete Frequency_mapped;
01356
01357 gen_object_count++;
01358 }
01359 }
01360 else
01361 {
01362 if (enable_subsecond_models == true)
01363 {
01364 GL_THROW("diesel_dg:%d %s - Deltamode is enabled for the module, but not this generator!",obj->id,(obj->name ? obj->name : "Unnamed"));
01365
01366
01367
01368
01369
01370 }
01371 }
01372
01373
01374 if (gen_base_set_vals.vset < -90) {
01375 Vset_defined = false;
01376 }
01377 else {
01378 Vset_defined = true;
01379 Vref = gen_base_set_vals.vset;
01380 }
01381
01382 if (Kd1 == 0) {
01383 if (Kd2 == 0) {
01384 gl_warning("diesel_dg:%d %s - cannot set both Kd1 and Kd2 as 0 for the CVR conntrol! Have changed Kd2 to be 1",obj->id,(obj->name ? obj->name : "Unnamed"));
01385
01386
01387
01388
01389
01390 }
01391 Kd2 = 1;
01392 }
01393
01394
01395
01396
01397
01398
01399 dg_1000_a = 0.067;
01400 dg_1000_b = 5.2435/1000 * (Rated_VA/1000);
01401
01402 return 1;
01403 }
01404
01405
01406 TIMESTAMP diesel_dg::presync(TIMESTAMP t0, TIMESTAMP t1)
01407 {
01408
01409 return TS_NEVER;
01410 }
01411
01412 TIMESTAMP diesel_dg::sync(TIMESTAMP t0, TIMESTAMP t1)
01413 {
01414 OBJECT *obj = OBJECTHDR(this);
01415 double tdiff, ang_diff;
01416 complex temp_current_val[3];
01417 complex temp_voltage_val[3];
01418 complex rotate_value;
01419 TIMESTAMP tret_value;
01420 double vdiff;
01421 double voltage_mag_curr;
01422 double real_diff;
01423 double reactive_diff;
01424 complex temp_power_val[3];
01425 complex temp_complex_value_power;
01426 gld_wlock *test_rlock;
01427
01428
01429 tret_value = TS_NEVER;
01430
01431
01432 reset_powerflow_accumulators();
01433
01434
01435 if (first_run == true)
01436 {
01437
01438 if (deltamode_inclusive && enable_subsecond_models && (torque_delay==NULL))
01439 {
01440 if (((gen_object_current == -1) || (delta_objects==NULL)) && (enable_subsecond_models == true))
01441 {
01442
01443 allocate_deltamode_arrays();
01444 }
01445
01446
01447 if (gen_object_current>=gen_object_count)
01448 {
01449 GL_THROW("Too many objects tried to populate deltamode objects array in the generators module!");
01450
01451
01452
01453
01454
01455 }
01456
01457
01458 delta_objects[gen_object_current] = obj;
01459
01460
01461 delta_functions[gen_object_current] = (FUNCTIONADDR)(gl_get_function(obj,"interupdate_gen_object"));
01462
01463
01464 if (delta_functions[gen_object_current] == NULL)
01465 {
01466 GL_THROW("Failure to map deltamode function for device:%s",obj->name);
01467
01468
01469
01470
01471
01472 }
01473
01474
01475 post_delta_functions[gen_object_current] = (FUNCTIONADDR)(gl_get_function(obj,"postupdate_gen_object"));
01476
01477
01478 if (post_delta_functions[gen_object_current] == NULL)
01479 {
01480 GL_THROW("Failure to map post-deltamode function for device:%s",obj->name);
01481
01482
01483
01484
01485
01486 }
01487
01488
01489 gen_object_current++;
01490
01491
01492 if (obj->parent != NULL)
01493 {
01494 if (gl_object_isa(obj->parent,"meter","powerflow") || gl_object_isa(obj->parent,"load","powerflow") || gl_object_isa(obj->parent,"node","powerflow") || gl_object_isa(obj->parent,"elec_frequency","powerflow"))
01495 {
01496
01497 temp_complex_value_power = power_val[0] + power_val[1] + power_val[2];
01498
01499
01500 pPGenerated->setp<complex>(temp_complex_value_power,*test_rlock);
01501
01502 }
01503 else
01504 {
01505 GL_THROW("diesel_dg:%s - invalid parent object:%s",(obj->name?obj->name:"unnamed"),(obj->parent->name?obj->parent->name:"unnamed"));
01506
01507
01508
01509
01510 }
01511 }
01512
01513
01514 torque_delay_len=1;
01515
01516
01517 torque_delay = (double *)gl_malloc(torque_delay_len*sizeof(double));
01518
01519
01520 if (torque_delay == NULL)
01521 {
01522 gl_error("diesel_dg: failed to allocate to allocate the delayed torque array for DEGOV1!");
01523
01524
01525 return TS_INVALID;
01526 }
01527
01528
01529 torque_delay_write_pos = 0;
01530 torque_delay_read_pos = 0;
01531
01532
01533 tret_value = t1;
01534 }
01535
01536 }
01537
01538
01539 if (Gen_type == NON_DYN_CONSTANT_PQ)
01540 {
01541
01542
01543 value_Power[0] = -power_val[0] + value_prev_Power[0];
01544 value_Power[1] = -power_val[1] + value_prev_Power[1];
01545 value_Power[2] = -power_val[2] + value_prev_Power[2];
01546
01547
01548 value_prev_Power[0] = power_val[0];
01549 value_prev_Power[1] = power_val[1];
01550 value_prev_Power[2] = power_val[2];
01551 }
01552 else if (Gen_type == DYNAMIC)
01553 {
01554
01555 if ((prev_time < t1) && (first_run == false))
01556 {
01557
01558 pull_powerflow_values();
01559
01560
01561 tdiff = (double)(t1)-prev_time_dbl;
01562
01563
01564 ang_diff = (curr_state.omega - omega_ref)*tdiff;
01565 curr_state.rotor_angle += ang_diff;
01566
01567
01568 rotate_value = complex_exp(ang_diff);
01569
01570
01571 value_Circuit_V[0] = value_Circuit_V[0]*rotate_value;
01572 value_Circuit_V[1] = value_Circuit_V[1]*rotate_value;
01573 value_Circuit_V[2] = value_Circuit_V[2]*rotate_value;
01574
01575
01576 push_powerflow_values(true);
01577
01578
01579 value_IGenerated[0] = value_IGenerated[0]*rotate_value;
01580 value_IGenerated[1] = value_IGenerated[1]*rotate_value;
01581 value_IGenerated[2] = value_IGenerated[2]*rotate_value;
01582
01583 if (Governor_type == P_CONSTANT) {
01584
01585 real_diff = (gen_base_set_vals.Pref - (power_val[0].Re() + power_val[1].Re() + power_val[2].Re()) / Rated_VA) / 3.0;
01586 real_diff = real_diff * Rated_VA;
01587
01588
01589 temp_power_val[0] = power_val[0] + complex(real_diff, 0.0);
01590 temp_power_val[1] = power_val[1] + complex(real_diff, 0.0);
01591 temp_power_val[2] = power_val[2] + complex(real_diff, 0.0);
01592
01593
01594 temp_current_val[0] = ~(temp_power_val[0]/value_Circuit_V[0]) + generator_admittance[0][0]*value_Circuit_V[0] + generator_admittance[0][1]*value_Circuit_V[1] + generator_admittance[0][2]*value_Circuit_V[2];
01595 temp_current_val[1] = ~(temp_power_val[1]/value_Circuit_V[1]) + generator_admittance[1][0]*value_Circuit_V[0] + generator_admittance[1][1]*value_Circuit_V[1] + generator_admittance[1][2]*value_Circuit_V[2];
01596 temp_current_val[2] = ~(temp_power_val[2]/value_Circuit_V[2]) + generator_admittance[2][0]*value_Circuit_V[0] + generator_admittance[2][1]*value_Circuit_V[1] + generator_admittance[2][2]*value_Circuit_V[2];
01597
01598
01599 value_IGenerated[0] = temp_current_val[0];
01600 value_IGenerated[1] = temp_current_val[1];
01601 value_IGenerated[2] = temp_current_val[2];
01602
01603
01604 tret_value = t1;
01605 }
01606
01607
01608 prev_time = t1;
01609 prev_time_dbl = (double)(t1);
01610
01611
01612 if (Exciter_type == SEXS)
01613 {
01614
01615 convert_abc_to_pn0(&value_Circuit_V[0],&temp_voltage_val[0]);
01616
01617
01618 voltage_mag_curr = temp_voltage_val[0].Mag()/voltage_base;
01619
01620 if (Q_constant_mode == true) {
01621
01622 reactive_diff = (gen_base_set_vals.Qref - (power_val[0].Im() + power_val[1].Im() + power_val[2].Im()) / Rated_VA) / 3.0;
01623 reactive_diff = reactive_diff * Rated_VA;
01624
01625
01626 temp_power_val[0] = power_val[0] + complex(real_diff,reactive_diff);
01627 temp_power_val[1] = power_val[1] + complex(real_diff,reactive_diff);
01628 temp_power_val[2] = power_val[2] + complex(real_diff,reactive_diff);
01629
01630
01631 temp_current_val[0] = ~(temp_power_val[0]/value_Circuit_V[0]) + generator_admittance[0][0]*value_Circuit_V[0] + generator_admittance[0][1]*value_Circuit_V[1] + generator_admittance[0][2]*value_Circuit_V[2];
01632 temp_current_val[1] = ~(temp_power_val[1]/value_Circuit_V[1]) + generator_admittance[1][0]*value_Circuit_V[0] + generator_admittance[1][1]*value_Circuit_V[1] + generator_admittance[1][2]*value_Circuit_V[2];
01633 temp_current_val[2] = ~(temp_power_val[2]/value_Circuit_V[2]) + generator_admittance[2][0]*value_Circuit_V[0] + generator_admittance[2][1]*value_Circuit_V[1] + generator_admittance[2][2]*value_Circuit_V[2];
01634
01635
01636 value_IGenerated[0] = temp_current_val[0];
01637 value_IGenerated[1] = temp_current_val[1];
01638 value_IGenerated[2] = temp_current_val[2];
01639
01640
01641 tret_value = t1;
01642 }
01643
01644 if ((voltage_mag_curr>Max_Ef) || (voltage_mag_curr<Min_Ef))
01645 {
01646
01647
01648 vdiff = temp_voltage_val[0].Mag()/voltage_base - gen_base_set_vals.vset;
01649
01650
01651 reactive_diff = (YS1_Full.Im()*(vdiff*voltage_base)*voltage_base)/3.0;
01652
01653
01654 temp_power_val[0] = power_val[0] + complex(0.0,reactive_diff);
01655 temp_power_val[1] = power_val[1] + complex(0.0,reactive_diff);
01656 temp_power_val[2] = power_val[2] + complex(0.0,reactive_diff);
01657
01658
01659 temp_current_val[0] = ~(temp_power_val[0]/value_Circuit_V[0]) + generator_admittance[0][0]*value_Circuit_V[0] + generator_admittance[0][1]*value_Circuit_V[1] + generator_admittance[0][2]*value_Circuit_V[2];
01660 temp_current_val[1] = ~(temp_power_val[1]/value_Circuit_V[1]) + generator_admittance[1][0]*value_Circuit_V[0] + generator_admittance[1][1]*value_Circuit_V[1] + generator_admittance[1][2]*value_Circuit_V[2];
01661 temp_current_val[2] = ~(temp_power_val[2]/value_Circuit_V[2]) + generator_admittance[2][0]*value_Circuit_V[0] + generator_admittance[2][1]*value_Circuit_V[1] + generator_admittance[2][2]*value_Circuit_V[2];
01662
01663
01664 value_IGenerated[0] = temp_current_val[0];
01665 value_IGenerated[1] = temp_current_val[1];
01666 value_IGenerated[2] = temp_current_val[2];
01667
01668
01669 tret_value = t1;
01670 }
01671
01672 }
01673
01674 }
01675
01676 }
01677 else
01678 {
01679 GL_THROW("diesel_dg:%d %s - Unknown Gen_type specified!",obj->id,(obj->name ? obj->name : "Unnamed"));
01680
01681
01682
01683 }
01684
01685
01686 push_powerflow_values(false);
01687
01688 return tret_value;
01689 }
01690
01691
01692 TIMESTAMP diesel_dg::postsync(TIMESTAMP t0, TIMESTAMP t1)
01693 {
01694 complex temp_current_val[3];
01695 int ret_state;
01696 OBJECT *obj = OBJECTHDR(this);
01697 complex aval, avalsq;
01698 TIMESTAMP dt;
01699 complex_array temp_complex_array;
01700 int index_x, index_y;
01701 gld_wlock *test_rlock;
01702
01703 TIMESTAMP t2 = TS_NEVER;
01704
01705
01706 reset_powerflow_accumulators();
01707
01708 if (Gen_type == DYNAMIC)
01709 {
01710
01711 if (deltamode_endtime != TS_NEVER)
01712 {
01713 deltamode_endtime = TS_NEVER;
01714 deltamode_endtime_dbl = TSNVRDBL;
01715 }
01716
01717
01718 pull_powerflow_values();
01719
01720
01721 if (fuelEmissionCal == true) {
01722
01723 if (first_run == true)
01724 {
01725 dt = 0;
01726 }
01727 else if (last_time == 0)
01728 {
01729 last_time = t1;
01730 dt = 0;
01731 }
01732 else if (last_time < t1)
01733 {
01734 dt = t1 - last_time;
01735 last_time = t1;
01736 }
01737 else
01738 dt = 0;
01739
01740 outputEnergy += fabs(curr_state.pwr_electric.Re()/1000) * (double)dt / 3600;
01741 FuelUse += (fabs(curr_state.pwr_electric.Re()/1000) * dg_1000_a + dg_1000_b) * (double)dt / 3600;
01742 if (FuelUse != 0) {
01743 efficiency = outputEnergy/FuelUse;
01744 }
01745 CO2_emission += (-6e-5 * pow(FuelUse, 3) + 0.0087 * pow(FuelUse, 2) - FuelUse * 0.3464 + 25.824) * (double)dt / 3600;
01746 SOx_emission += (-5e-7 * pow(FuelUse, 2) + FuelUse * 0.0001 + 0.0206) * (double)dt / 3600;
01747 NOx_emission += (6e-5 * pow(FuelUse, 2) - FuelUse * 0.0048 + 0.2551) * (double)dt / 3600;
01748 PM10_emission += (-2e-9 * pow(FuelUse, 4) + 3e-7 * pow(FuelUse, 3) - 2e-5 * pow(FuelUse, 2) + FuelUse * 8e-5 + 0.0083) * (double)dt / 3600;
01749
01750 if (pwr_electric_init <= 0) {
01751 pwr_electric_init = curr_state.pwr_electric.Re();
01752 }
01753 }
01754
01755
01756
01757 temp_current_val[0] = (value_IGenerated[0] - generator_admittance[0][0]*value_Circuit_V[0] - generator_admittance[0][1]*value_Circuit_V[1] - generator_admittance[0][2]*value_Circuit_V[2]);
01758 temp_current_val[1] = (value_IGenerated[1] - generator_admittance[1][0]*value_Circuit_V[0] - generator_admittance[1][1]*value_Circuit_V[1] - generator_admittance[1][2]*value_Circuit_V[2]);
01759 temp_current_val[2] = (value_IGenerated[2] - generator_admittance[2][0]*value_Circuit_V[0] - generator_admittance[2][1]*value_Circuit_V[1] - generator_admittance[2][2]*value_Circuit_V[2]);
01760
01761
01762 power_val[0] = value_Circuit_V[0]*~temp_current_val[0];
01763 power_val[1] = value_Circuit_V[1]*~temp_current_val[1];
01764 power_val[2] = value_Circuit_V[2]*~temp_current_val[2];
01765
01766
01767 curr_state.pwr_electric = power_val[0] + power_val[1] + power_val[2];
01768 }
01769
01770 if (first_run == true)
01771 {
01772 if (deltamode_inclusive && enable_subsecond_models && (torque_delay!=NULL))
01773 {
01774 ret_state = init_dynamics(&curr_state);
01775
01776 if (ret_state == FAILED)
01777 {
01778 GL_THROW("diesel_dg:%s - unsuccessful call to dynamics initialization",(obj->name?obj->name:"unnamed"));
01779
01780
01781
01782
01783 }
01784
01785
01786
01787 aval = complex(cos(2.0*PI/3.0),sin(2.0*PI/3.0));
01788 avalsq = aval*aval;
01789
01790
01791 pbus_full_Y_all_mat->getp<complex_array>(temp_complex_array,*test_rlock);
01792
01793
01794 if ((temp_complex_array.get_rows() == 3) && (temp_complex_array.get_cols() == 3))
01795 {
01796
01797 for (index_x=0; index_x<3; index_x++)
01798 {
01799 for (index_y=0; index_y<3; index_y++)
01800 {
01801 full_bus_admittance_mat[index_x][index_y] = temp_complex_array.get_at(index_x,index_y);
01802 }
01803 }
01804 }
01805
01806
01807
01808 YS1_Full = full_bus_admittance_mat[0][0]+aval*full_bus_admittance_mat[1][0]+avalsq*full_bus_admittance_mat[2][0];
01809 YS1_Full += avalsq*full_bus_admittance_mat[0][1]+full_bus_admittance_mat[1][1]+aval*full_bus_admittance_mat[2][1];
01810 YS1_Full += aval*full_bus_admittance_mat[0][2]+avalsq*full_bus_admittance_mat[1][2]+full_bus_admittance_mat[2][2];
01811 YS1_Full /= 3.0;
01812
01813 }
01814
01815
01816
01817 first_run = false;
01818 }
01819
01820 return t2;
01821 }
01822
01823
01824 gld_property *diesel_dg::map_complex_value(OBJECT *obj, char *name)
01825 {
01826 gld_property *pQuantity;
01827 OBJECT *objhdr = OBJECTHDR(this);
01828
01829
01830 pQuantity = new gld_property(obj,name);
01831
01832
01833 if ((pQuantity->is_valid() != true) || (pQuantity->is_complex() != true))
01834 {
01835 GL_THROW("diesel_dg:%d %s - Unable to map property %s from object:%d %s",objhdr->id,(objhdr->name ? objhdr->name : "Unnamed"),name,obj->id,(obj->name ? obj->name : "Unnamed"));
01836
01837
01838
01839
01840 }
01841
01842
01843 return pQuantity;
01844 }
01845
01846
01847 gld_property *diesel_dg::map_double_value(OBJECT *obj, char *name)
01848 {
01849 gld_property *pQuantity;
01850 OBJECT *objhdr = OBJECTHDR(this);
01851
01852
01853 pQuantity = new gld_property(obj,name);
01854
01855
01856 if ((pQuantity->is_valid() != true) || (pQuantity->is_double() != true))
01857 {
01858 GL_THROW("diesel_dg:%d %s - Unable to map property %s from object:%d %s",objhdr->id,(objhdr->name ? objhdr->name : "Unnamed"),name,obj->id,(obj->name ? obj->name : "Unnamed"));
01859
01860
01861
01862
01863 }
01864
01865
01866 return pQuantity;
01867 }
01868
01869
01870 void diesel_dg::pull_powerflow_values(void)
01871 {
01872 int indexval;
01873
01874
01875 if (parent_is_powerflow == true)
01876 {
01877 for (indexval=0; indexval<3; indexval++)
01878 {
01879
01880 value_Circuit_V[indexval] = pCircuit_V[indexval]->get_complex();
01881
01882
01883 if (deltamode_inclusive == true)
01884 {
01885
01886 value_IGenerated[indexval] = pIGenerated[indexval]->get_complex();
01887 }
01888 }
01889 }
01890
01891 }
01892
01893
01894
01895 void diesel_dg::push_powerflow_values(bool update_voltage)
01896 {
01897 complex temp_complex_val;
01898 gld_wlock *test_rlock;
01899 int indexval;
01900
01901
01902 if (parent_is_powerflow == true)
01903 {
01904
01905 if (Gen_type == NON_DYN_CONSTANT_PQ)
01906 {
01907
01908 for (indexval=0; indexval<3; indexval++)
01909 {
01910
01911
01912 temp_complex_val = pPower[indexval]->get_complex();
01913
01914
01915 temp_complex_val += value_Power[indexval];
01916
01917
01918 pPower[indexval]->setp<complex>(temp_complex_val,*test_rlock);
01919 }
01920 }
01921 else if (Gen_type == DYNAMIC)
01922 {
01923 if (update_voltage == true)
01924 {
01925
01926 for (indexval=0; indexval<3; indexval++)
01927 {
01928
01929 pCircuit_V[indexval]->setp<complex>(value_Circuit_V[indexval],*test_rlock);
01930 }
01931 }
01932 else
01933 {
01934
01935 for (indexval=0; indexval<3; indexval++)
01936 {
01937
01938
01939 temp_complex_val = pLine_I[indexval]->get_complex();
01940
01941
01942 temp_complex_val += value_Line_I[indexval];
01943
01944
01945 pLine_I[indexval]->setp<complex>(temp_complex_val,*test_rlock);
01946
01947
01948 if (deltamode_inclusive == true)
01949 {
01950
01951
01952 pIGenerated[indexval]->setp<complex>(value_IGenerated[indexval],*test_rlock);
01953 }
01954 }
01955 }
01956 }
01957
01958 }
01959
01960 }
01961
01962
01963 void diesel_dg::reset_powerflow_accumulators(void)
01964 {
01965 int indexval;
01966
01967
01968 for (indexval=0; indexval<3; indexval++)
01969 {
01970
01971 value_Line_I[indexval] = complex(0.0,0.0);
01972 }
01973 }
01974
01975
01976
01977
01978
01979
01980 void diesel_dg::convert_Ypn0_to_Yabc(complex Y0, complex Y1, complex Y2, complex *Yabcmat)
01981 {
01982 complex aval, aval_sq;
01983
01984
01985 aval = complex(cos(2.0*PI/3.0),sin(2.0*PI/3.0));
01986
01987
01988 aval_sq = aval*aval;
01989
01990
01991
01992
01993
01994 Yabcmat[0] = (Y0 + Y1 + Y2)/3.0;
01995 Yabcmat[1] = (Y0 + aval*Y1+aval_sq*Y2)/3.0;
01996 Yabcmat[2] = (Y0 + aval_sq*Y1+aval*Y2)/3.0;
01997 Yabcmat[3] = (Y0 + aval_sq*Y1+aval*Y2)/3.0;
01998 Yabcmat[4] = (Y0 + Y1 + Y2)/3.0;
01999 Yabcmat[5] = (Y0 + aval*Y1+aval_sq*Y2)/3.0;
02000 Yabcmat[6] = (Y0 + aval*Y1+aval_sq*Y2)/3.0;
02001 Yabcmat[7] = (Y0 + aval_sq*Y1+aval*Y2)/3.0;
02002 Yabcmat[8] = (Y0 + Y1 + Y2)/3.0;
02003 }
02004
02005
02006
02007
02008 void diesel_dg::convert_pn0_to_abc(complex *Xpn0, complex *Xabc)
02009 {
02010 complex aval, aval_sq;
02011
02012
02013 aval = complex(cos(2.0*PI/3.0),sin(2.0*PI/3.0));
02014
02015
02016 aval_sq = aval*aval;
02017
02018
02019 Xabc[0] = Xpn0[2] + Xpn0[0] + Xpn0[1];
02020 Xabc[1] = Xpn0[2] + aval_sq*Xpn0[0] + aval*Xpn0[1];
02021 Xabc[2] = Xpn0[2] + aval*Xpn0[0] + aval_sq*Xpn0[1];
02022 }
02023
02024
02025
02026
02027 void diesel_dg::convert_abc_to_pn0(complex *Xabc, complex *Xpn0)
02028 {
02029 complex aval, aval_sq;
02030
02031
02032 aval = complex(cos(2.0*PI/3.0),sin(2.0*PI/3.0));
02033
02034
02035 aval_sq = aval*aval;
02036
02037
02038
02039 Xpn0[0] = (Xabc[0] + (aval*Xabc[1]) + (aval_sq*Xabc[2]))/3.0;
02040 Xpn0[1] = (Xabc[0] + (aval_sq*Xabc[1]) + (aval*Xabc[2]))/3.0;
02041 Xpn0[2] = (Xabc[0] + Xabc[1] + Xabc[2])/3.0;
02042 }
02043
02045
02047
02048 SIMULATIONMODE diesel_dg::inter_deltaupdate(unsigned int64 delta_time, unsigned long dt, unsigned int iteration_count_val)
02049 {
02050 unsigned char pass_mod;
02051 unsigned int loop_index;
02052 double temp_double, temp_mag_val, temp_mag_diff;
02053 double temp_double_freq_val;
02054 double deltat, deltath;
02055 double omega_pu;
02056 double x5a_now;
02057 complex temp_rotation;
02058 complex temp_complex[3];
02059 complex temp_current_val[3];
02060 gld_wlock *test_rlock;
02061
02062
02063 deltat = (double)dt/(double)DT_SECOND;
02064 deltath = deltat/2.0;
02065
02066
02067 reset_powerflow_accumulators();
02068
02069
02070 pull_powerflow_values();
02071
02072
02073 if ((delta_time==0) && (iteration_count_val==0))
02074 {
02075
02076
02077 if (Governor_type == DEGOV1)
02078 {
02079
02080 if (torque_delay!=NULL)
02081 {
02082 gl_free(torque_delay);
02083 }
02084
02085
02086 torque_delay_len=(unsigned int)(gov_degov1_TD*DT_SECOND/dt);
02087
02088
02089 temp_double = gov_degov1_TD-(double)(torque_delay_len*dt)/(double)DT_SECOND;
02090
02091 if (temp_double > 0.0)
02092 torque_delay_len += 1;
02093
02094
02095
02096 torque_delay = (double *)gl_malloc(torque_delay_len*sizeof(double));
02097
02098
02099 if (torque_delay == NULL)
02100 {
02101 gl_error("diesel_dg: failed to allocate to allocate the delayed torque array for Governor!");
02102
02103
02104
02105
02106
02107 return SM_ERROR;
02108 }
02109
02110
02111 torque_delay_write_pos = torque_delay_len-1;
02112 torque_delay_read_pos = 0;
02113 }
02114
02115
02116 init_dynamics(&curr_state);
02117
02118
02119 if ((Governor_type == GGOV1) || (Governor_type == GGOV1_OLD))
02120 {
02121
02122 if (x5a_delayed!=NULL)
02123 {
02124 gl_free(x5a_delayed);
02125 }
02126
02127 if (gov_ggv1_Teng > 0)
02128 {
02129
02130 x5a_delayed_len=(unsigned int)(gov_ggv1_Teng*DT_SECOND/dt);
02131
02132
02133 temp_double = gov_ggv1_Teng-(double)(x5a_delayed_len*dt)/(double)DT_SECOND;
02134
02135 if (temp_double > 0.0)
02136 x5a_delayed_len += 1;
02137
02138
02139
02140 x5a_delayed = (double *)gl_malloc(x5a_delayed_len*sizeof(double));
02141
02142
02143 if (x5a_delayed == NULL)
02144 {
02145 gl_error("diesel_dg: failed to allocate to allocate the delayed x5a array for Governor!");
02146
02147
02148
02149
02150
02151 return SM_ERROR;
02152 }
02153
02154
02155 x5a_delayed_write_pos = x5a_delayed_len-1;
02156 x5a_delayed_read_pos = 0;
02157
02158
02159 for (loop_index=0; loop_index<x5a_delayed_len; loop_index++)
02160 {
02161 x5a_delayed[loop_index] = curr_state.gov_ggov1.x5a;
02162 }
02163 }
02164 else
02165 {
02166 x5a_delayed = NULL;
02167 x5a_delayed_write_pos = -1;
02168 x5a_delayed_read_pos = -1;
02169 }
02170 }
02171
02172
02173 prev_rotor_speed_val = curr_state.omega;
02174
02175
02176 memcpy(&next_state,&curr_state,sizeof(MAC_STATES));
02177
02178 }
02179 else if (iteration_count_val == 0)
02180 {
02181
02182 if (Governor_type == DEGOV1)
02183 {
02184
02185 torque_delay_write_pos++;
02186 torque_delay_read_pos++;
02187
02188
02189 if (torque_delay_read_pos >= torque_delay_len)
02190 torque_delay_read_pos = 0;
02191
02192 if (torque_delay_write_pos >= torque_delay_len)
02193 torque_delay_write_pos = 0;
02194 }
02195 else if ((Governor_type == GGOV1) || (Governor_type == GGOV1_OLD))
02196 {
02197 if (gov_ggv1_Teng > 0)
02198 {
02199
02200 x5a_delayed_write_pos++;
02201 x5a_delayed_read_pos++;
02202
02203
02204 if (x5a_delayed_read_pos >= x5a_delayed_len)
02205 x5a_delayed_read_pos = 0;
02206
02207 if (x5a_delayed_write_pos >= x5a_delayed_len)
02208 x5a_delayed_write_pos = 0;
02209 }
02210
02211 }
02212 }
02213
02214
02215 pass_mod = iteration_count_val - ((iteration_count_val >> 1) << 1);
02216
02217
02218 if (pass_mod==0)
02219 {
02220
02221 temp_current_val[0] = (value_IGenerated[0] - generator_admittance[0][0]*value_Circuit_V[0] - generator_admittance[0][1]*value_Circuit_V[1] - generator_admittance[0][2]*value_Circuit_V[2]);
02222 temp_current_val[1] = (value_IGenerated[1] - generator_admittance[1][0]*value_Circuit_V[0] - generator_admittance[1][1]*value_Circuit_V[1] - generator_admittance[1][2]*value_Circuit_V[2]);
02223 temp_current_val[2] = (value_IGenerated[2] - generator_admittance[2][0]*value_Circuit_V[0] - generator_admittance[2][1]*value_Circuit_V[1] - generator_admittance[2][2]*value_Circuit_V[2]);
02224
02225
02226 power_val[0] = value_Circuit_V[0]*~temp_current_val[0];
02227 power_val[1] = value_Circuit_V[1]*~temp_current_val[1];
02228 power_val[2] = value_Circuit_V[2]*~temp_current_val[2];
02229
02230
02231 curr_state.pwr_electric = power_val[0] + power_val[1] + power_val[2];
02232
02233
02234 next_state.pwr_electric = curr_state.pwr_electric;
02235
02236
02237 if (fuelEmissionCal == true) {
02238
02239 outputEnergy += fabs(curr_state.pwr_electric.Re()/1000) * (double)deltat / 3600;
02240 FuelUse += (fabs(curr_state.pwr_electric.Re()/1000) * dg_1000_a + dg_1000_b) * (double)deltat / 3600;
02241 if (FuelUse != 0) {
02242 efficiency = outputEnergy/FuelUse;
02243 }
02244 CO2_emission += (-6e-5 * pow(FuelUse, 3) + 0.0087 * pow(FuelUse, 2) - FuelUse * 0.3464 + 25.824) * (double)deltat / 3600;
02245 SOx_emission += (-5e-7 * pow(FuelUse, 2) + FuelUse * 0.0001 + 0.0206) * (double)deltat / 3600;
02246 NOx_emission += (6e-5 * pow(FuelUse, 2) - FuelUse * 0.0048 + 0.2551) * (double)deltat / 3600;
02247 PM10_emission += (-2e-9 * pow(FuelUse, 4) + 3e-7 * pow(FuelUse, 3) - 2e-5 * pow(FuelUse, 2) + FuelUse * 8e-5 + 0.0083) * (double)deltat / 3600;
02248
02249
02250 frequency_deviation = (curr_state.omega - 2 * PI * 60)/(2 * PI * 60);
02251 frequency_deviation_energy += fabs(frequency_deviation);
02252
02253
02254 if (frequency_deviation <= 0 && frequency_deviation_max <= 0) {
02255 if (frequency_deviation < frequency_deviation_max) {
02256 frequency_deviation_max = fabs(frequency_deviation);
02257 }
02258 }
02259 else if (frequency_deviation >= 0 && frequency_deviation_max >= 0) {
02260 if (frequency_deviation > frequency_deviation_max) {
02261 frequency_deviation_max = fabs(frequency_deviation);
02262 }
02263 }
02264 else if (frequency_deviation > 0 && frequency_deviation_max < 0) {
02265 if (frequency_deviation > -frequency_deviation_max) {
02266 frequency_deviation_max = fabs(frequency_deviation);
02267 }
02268 }
02269 else if (frequency_deviation < 0 && frequency_deviation_max > 0) {
02270 if (-frequency_deviation > frequency_deviation_max) {
02271 frequency_deviation_max = fabs(-frequency_deviation);
02272 }
02273 }
02274 realPowerChange = curr_state.pwr_electric.Re() - pwr_electric_init;
02275 ratio_f_p = -frequency_deviation/(realPowerChange/Rated_VA);
02276 }
02277
02278
02279 apply_dynamics(&curr_state,&predictor_vals,deltat);
02280
02281
02282 if (Q_constant_mode == true) {
02283 next_state.avr.xfd = curr_state.avr.xfd + predictor_vals.avr.xfd*deltat;
02284 next_state.Vfd = next_state.avr.xfd + predictor_vals.avr.xfd*(kp_Qconstant/ki_Qconstant);
02285 }
02286
02287 next_state.Flux1d = curr_state.Flux1d + predictor_vals.Flux1d*deltat;
02288 next_state.Flux2q = curr_state.Flux2q + predictor_vals.Flux2q*deltat;
02289 next_state.EpRotated = curr_state.EpRotated + predictor_vals.EpRotated*deltat;
02290 next_state.rotor_angle = curr_state.rotor_angle + predictor_vals.rotor_angle*deltat;
02291 next_state.omega = curr_state.omega + predictor_vals.omega*deltat;
02292
02293 next_state.VintRotated = (Xqpp-Xdpp)*curr_state.Irotated.Im();
02294 next_state.VintRotated += (Xqpp-Xl)/(Xqp-Xl)*next_state.EpRotated.Re() - (Xqp-Xqpp)/(Xqp-Xl)*next_state.Flux2q;
02295 next_state.VintRotated += complex(0.0,1.0)*((Xdpp-Xl)/(Xdp-Xl)*next_state.EpRotated.Im()+(Xdp-Xdpp)/(Xdp-Xl)*next_state.Flux1d);
02296
02297
02298 temp_rotation = complex(0.0,1.0)*complex_exp(-1.0*next_state.rotor_angle);
02299 temp_complex[0] = next_state.VintRotated/temp_rotation*voltage_base;
02300 temp_complex[1] = temp_complex[2] = 0.0;
02301
02302
02303 convert_pn0_to_abc(&temp_complex[0], &next_state.EintVal[0]);
02304
02305
02306 if (Governor_type == DEGOV1)
02307 {
02308 next_state.gov_degov1.x1 = curr_state.gov_degov1.x1 + predictor_vals.gov_degov1.x1*deltat;
02309 next_state.gov_degov1.x2 = curr_state.gov_degov1.x2 + predictor_vals.gov_degov1.x2*deltat;
02310 next_state.gov_degov1.x4 = curr_state.gov_degov1.x4 + predictor_vals.gov_degov1.x4*deltat;
02311 next_state.gov_degov1.x5 = curr_state.gov_degov1.x5 + predictor_vals.gov_degov1.x5*deltat;
02312 next_state.gov_degov1.x6 = curr_state.gov_degov1.x6 + predictor_vals.gov_degov1.x6*deltat;
02313 }
02314 else if (Governor_type == GAST)
02315 {
02316 next_state.gov_gast.x1 = curr_state.gov_gast.x1 + predictor_vals.gov_gast.x1*deltat;
02317 next_state.gov_gast.x2 = curr_state.gov_gast.x2 + predictor_vals.gov_gast.x2*deltat;
02318 next_state.gov_gast.x3 = curr_state.gov_gast.x3 + predictor_vals.gov_gast.x3*deltat;
02319 }
02320 else if (Governor_type == P_CONSTANT)
02321 {
02322
02323 next_state.gov_pconstant.x1 = curr_state.gov_pconstant.x1 + predictor_vals.gov_pconstant.x1*deltat;
02324 next_state.gov_pconstant.x4 = curr_state.gov_pconstant.x4 + predictor_vals.gov_pconstant.x4*deltat;
02325 next_state.gov_pconstant.x5b = curr_state.gov_pconstant.x5b + predictor_vals.gov_pconstant.x5b*deltat;
02326 next_state.gov_pconstant.x_Pconstant = curr_state.gov_pconstant.x_Pconstant + predictor_vals.gov_pconstant.x_Pconstant*deltat;
02327 next_state.gov_pconstant.GovOutPut = next_state.gov_pconstant.x_Pconstant + (gen_base_set_vals.Pref - next_state.gov_pconstant.x1) * kp_Pconstant;
02328
02329
02330
02331 next_state.gov_pconstant.ValveStroke = next_state.gov_pconstant.x4;
02332 if (pconstant_Flag == 0)
02333 {
02334 next_state.gov_pconstant.FuelFlow = next_state.gov_pconstant.ValveStroke * 1.0;
02335 }
02336 else if (pconstant_Flag == 1)
02337 {
02338 next_state.gov_pconstant.FuelFlow = next_state.gov_pconstant.ValveStroke*next_state.omega/omega_ref;
02339 }
02340 else
02341 {
02342 gl_error("wrong pconstant_Flag_flag");
02343 return SM_ERROR;
02344 }
02345
02346 x5a_now = pconstant_Kturb*(next_state.gov_pconstant.FuelFlow - pconstant_wfnl);
02347
02348 if (pconstant_Teng > 0)
02349 {
02350
02351 x5a_delayed[x5a_delayed_write_pos] = x5a_now;
02352
02353
02354 next_state.gov_pconstant.x5a = x5a_delayed[x5a_delayed_read_pos];
02355 }
02356 else
02357 {
02358
02359 next_state.gov_pconstant.x5a = x5a_now;
02360 }
02361 next_state.gov_pconstant.x5 = (1.0 - pconstant_Tc/pconstant_Tb)*next_state.gov_pconstant.x5b + pconstant_Tc/pconstant_Tb*next_state.gov_pconstant.x5a;
02362
02363
02364 next_state.pwr_mech = Rated_VA*(next_state.gov_pconstant.x5);
02365
02366
02367 if (next_state.pwr_mech > Overload_Limit_Value)
02368 {
02369
02370 next_state.pwr_mech = Overload_Limit_Value;
02371
02372
02373 next_state.gov_pconstant.x5 = Overload_Limit_Value / Rated_VA;
02374 }
02375
02376
02377 next_state.torque_mech = next_state.pwr_mech / next_state.omega;
02378 }
02379 else if ((Governor_type == GGOV1) || (Governor_type == GGOV1_OLD))
02380 {
02381
02382 next_state.gov_ggov1.x1 = curr_state.gov_ggov1.x1 + predictor_vals.gov_ggov1.x1*deltat;
02383 next_state.gov_ggov1.x2a = curr_state.gov_ggov1.x2a + predictor_vals.gov_ggov1.x2a*deltat;
02384 next_state.gov_ggov1.x3 = curr_state.gov_ggov1.x3 + predictor_vals.gov_ggov1.x3*deltat;
02385 next_state.gov_ggov1.x4 = curr_state.gov_ggov1.x4 + predictor_vals.gov_ggov1.x4*deltat;
02386 next_state.gov_ggov1.x5b = curr_state.gov_ggov1.x5b + predictor_vals.gov_ggov1.x5b*deltat;
02387 next_state.gov_ggov1.x6 = curr_state.gov_ggov1.x6 + predictor_vals.gov_ggov1.x6*deltat;
02388 next_state.gov_ggov1.x7 = curr_state.gov_ggov1.x7 + predictor_vals.gov_ggov1.x7*deltat;
02389 next_state.gov_ggov1.x8a = curr_state.gov_ggov1.x8a + predictor_vals.gov_ggov1.x8a*deltat;
02390 next_state.gov_ggov1.x9a = curr_state.gov_ggov1.x9a + predictor_vals.gov_ggov1.x9a*deltat;
02391 next_state.gov_ggov1.x10b = curr_state.gov_ggov1.x10b + predictor_vals.gov_ggov1.x10b*deltat;
02392
02393
02394
02395 if (next_state.gov_ggov1.x8a > (1.1*gov_ggv1_r))
02396 {
02397 next_state.gov_ggov1.x8 = 1.1 * gov_ggv1_r;
02398 }
02399 else if (next_state.gov_ggov1.x8a < (-1.1*gov_ggv1_r))
02400 {
02401 next_state.gov_ggov1.x8 = -1.1 * gov_ggv1_r;
02402 }
02403 else
02404 {
02405 next_state.gov_ggov1.x8 = next_state.gov_ggov1.x8a;
02406 }
02407
02408
02409 next_state.gov_ggov1.ValveStroke = next_state.gov_ggov1.x4;
02410 if (gov_ggv1_Flag == 0)
02411 {
02412 next_state.gov_ggov1.FuelFlow = next_state.gov_ggov1.ValveStroke * 1.0;
02413 }
02414 else if (gov_ggv1_Flag == 1)
02415 {
02416 next_state.gov_ggov1.FuelFlow = next_state.gov_ggov1.ValveStroke*next_state.omega/omega_ref;
02417 }
02418 else
02419 {
02420 gl_error("wrong ggv1_flag");
02421 return SM_ERROR;
02422 }
02423
02424
02425 next_state.gov_ggov1.GovOutPut = curr_state.gov_ggov1.GovOutPut;
02426
02427 if (gov_ggv1_rselect == 1)
02428 {
02429 next_state.gov_ggov1.RselectValue = next_state.gov_ggov1.x1;
02430 }
02431 else if (gov_ggv1_rselect == -1)
02432 {
02433 next_state.gov_ggov1.RselectValue = next_state.gov_ggov1.ValveStroke;
02434 }
02435 else if (gov_ggv1_rselect == -2)
02436 {
02437 next_state.gov_ggov1.RselectValue = next_state.gov_ggov1.GovOutPut;
02438 }
02439 else if (gov_ggv1_rselect == 0)
02440 {
02441 next_state.gov_ggov1.RselectValue = 0.0;
02442 }
02443 else
02444 {
02445 gl_error("wrong ggv1_rselect parameter");
02446 return SM_ERROR;
02447 }
02448
02449
02450
02451
02452 next_state.gov_ggov1.werror = next_state.omega/omega_ref - gen_base_set_vals.wref;
02453 next_state.gov_ggov1.err2a = gen_base_set_vals.Pref + next_state.gov_ggov1.x8 - next_state.gov_ggov1.werror - gov_ggv1_r*next_state.gov_ggov1.RselectValue;
02454
02455 if (next_state.gov_ggov1.err2a > gov_ggv1_maxerr)
02456 {
02457 next_state.gov_ggov1.err2 = gov_ggv1_maxerr;
02458 }
02459 else if (next_state.gov_ggov1.err2a < gov_ggv1_minerr)
02460 {
02461 next_state.gov_ggov1.err2 = gov_ggv1_minerr;
02462 }
02463 else if ((next_state.gov_ggov1.err2a <= gov_ggv1_db) && (next_state.gov_ggov1.err2a >= -gov_ggv1_db))
02464 {
02465 next_state.gov_ggov1.err2 = 0.0;
02466 }
02467 else
02468 {
02469 if (next_state.gov_ggov1.err2a > 0.0)
02470 {
02471 next_state.gov_ggov1.err2 = (gov_ggv1_maxerr/(gov_ggv1_maxerr-gov_ggv1_db))*next_state.gov_ggov1.err2a - (gov_ggv1_maxerr*gov_ggv1_db/(gov_ggv1_maxerr-gov_ggv1_db));
02472 }
02473 else if (next_state.gov_ggov1.err2a < 0.0)
02474 {
02475 next_state.gov_ggov1.err2 = (gov_ggv1_minerr/(gov_ggv1_minerr+gov_ggv1_db))*next_state.gov_ggov1.err2a + (gov_ggv1_minerr*gov_ggv1_db/(gov_ggv1_minerr+gov_ggv1_db));
02476 }
02477 }
02478 next_state.gov_ggov1.x2 = gov_ggv1_Kpgov/gov_ggv1_Tdgov*(next_state.gov_ggov1.err2 - next_state.gov_ggov1.x2a);
02479
02480
02481 if ((Governor_type == GGOV1_OLD) || ((Governor_type == GGOV1) && (gov_ggv1_Kpgov == 0.0)))
02482 {
02483 next_state.gov_ggov1.x3a = gov_ggv1_Kigov*next_state.gov_ggov1.err2;
02484 }
02485 else
02486 {
02487 next_state.gov_ggov1.err3 = next_state.gov_ggov1.GovOutPut - next_state.gov_ggov1.x3;
02488 next_state.gov_ggov1.x3a = gov_ggv1_Kigov/gov_ggv1_Kpgov*next_state.gov_ggov1.err3;
02489 }
02490
02491 next_state.gov_ggov1.fsrn = next_state.gov_ggov1.x2 + gov_ggv1_Kpgov*next_state.gov_ggov1.err2 + next_state.gov_ggov1.x3;
02492
02493
02494 x5a_now = gov_ggv1_Kturb*(next_state.gov_ggov1.FuelFlow - gov_ggv1_wfnl);
02495
02496 if (gov_ggv1_Teng > 0)
02497 {
02498
02499 x5a_delayed[x5a_delayed_write_pos] = x5a_now;
02500
02501
02502 next_state.gov_ggov1.x5a = x5a_delayed[x5a_delayed_read_pos];
02503 }
02504 else
02505 {
02506
02507 next_state.gov_ggov1.x5a = x5a_now;
02508 }
02509 next_state.gov_ggov1.x5 = (1.0 - gov_ggv1_Tc/gov_ggv1_Tb)*next_state.gov_ggov1.x5b + gov_ggv1_Tc/gov_ggv1_Tb*next_state.gov_ggov1.x5a;
02510 if (gov_ggv1_Dm > 0.0)
02511 {
02512
02513 next_state.pwr_mech = Rated_VA*(next_state.gov_ggov1.x5 - gov_ggv1_Dm*(next_state.omega/omega_ref - gen_base_set_vals.wref));
02514
02515
02516 if (next_state.pwr_mech > Overload_Limit_Value)
02517 {
02518
02519 next_state.pwr_mech = Overload_Limit_Value;
02520
02521
02522 next_state.gov_ggov1.x5 = Overload_Limit_Value / Rated_VA + gov_ggv1_Dm*(next_state.omega/omega_ref - gen_base_set_vals.wref);
02523 }
02524 }
02525 else
02526 {
02527
02528 next_state.pwr_mech = Rated_VA*(next_state.gov_ggov1.x5);
02529
02530
02531 if (next_state.pwr_mech > Overload_Limit_Value)
02532 {
02533
02534 next_state.pwr_mech = Overload_Limit_Value;
02535
02536
02537 next_state.gov_ggov1.x5 = next_state.pwr_mech / Rated_VA;
02538 }
02539 }
02540
02541 next_state.torque_mech = next_state.pwr_mech / next_state.omega;
02542
02543
02544 if (gov_ggv1_Dm < 0.0)
02545 {
02546 next_state.gov_ggov1.x10a = next_state.gov_ggov1.FuelFlow * pow((next_state.omega/omega_ref),gov_ggv1_Dm);
02547 }
02548 else
02549 {
02550 next_state.gov_ggov1.x10a = next_state.gov_ggov1.FuelFlow;
02551 }
02552 next_state.gov_ggov1.x10 = (1.0 - gov_ggv1_Tsa/gov_ggv1_Tsb)*next_state.gov_ggov1.x10b + gov_ggv1_Tsa/gov_ggv1_Tsb*next_state.gov_ggov1.x10a;
02553
02554
02555 next_state.gov_ggov1.err7 = next_state.gov_ggov1.GovOutPut - next_state.gov_ggov1.x7;
02556 if (gov_ggv1_Kpload > 0.0)
02557 {
02558 next_state.gov_ggov1.x7a = gov_ggv1_Kiload/gov_ggv1_Kpload*next_state.gov_ggov1.err7;
02559 }
02560 else
02561 {
02562 next_state.gov_ggov1.x7a = gov_ggv1_Kiload*next_state.gov_ggov1.err7;
02563 }
02564 next_state.gov_ggov1.fsrtNoLim = next_state.gov_ggov1.x7 + gov_ggv1_Kpload*(-1.0 * next_state.gov_ggov1.x6 + gov_ggv1_Ldref*(gov_ggv1_Ldref/gov_ggv1_Kturb+gov_ggv1_wfnl));
02565 if (next_state.gov_ggov1.fsrtNoLim > 1.0)
02566 {
02567 next_state.gov_ggov1.fsrt = 1.0;
02568 }
02569 else
02570 {
02571 next_state.gov_ggov1.fsrt = next_state.gov_ggov1.fsrtNoLim;
02572 }
02573
02574
02575 next_state.gov_ggov1.x9 = 1.0/gov_ggv1_Ta*((next_state.omega/omega_ref - gen_base_set_vals.wref) - next_state.gov_ggov1.x9a);
02576 next_state.gov_ggov1.fsra = gov_ggv1_Ka*deltat*(gov_ggv1_aset - next_state.gov_ggov1.x9) + next_state.gov_ggov1.GovOutPut;
02577
02578
02579 if (gov_ggv1_fsrt_enable == false)
02580 {
02581 next_state.gov_ggov1.fsrt = 99999999.0;
02582 }
02583
02584 if (gov_ggv1_fsra_enable == false)
02585 {
02586 next_state.gov_ggov1.fsra = 99999999.0;
02587 }
02588
02589 if (gov_ggv1_fsrn_enable == false)
02590 {
02591 next_state.gov_ggov1.fsrn = 99999999.0;
02592 }
02593
02594
02595 if (next_state.gov_ggov1.fsrt < next_state.gov_ggov1.fsrn)
02596 {
02597 next_state.gov_ggov1.LowValSelect1 = next_state.gov_ggov1.fsrt;
02598 }
02599 else
02600 {
02601 next_state.gov_ggov1.LowValSelect1 = next_state.gov_ggov1.fsrn;
02602 }
02603
02604 if (next_state.gov_ggov1.fsra < next_state.gov_ggov1.LowValSelect1)
02605 {
02606 next_state.gov_ggov1.LowValSelect = next_state.gov_ggov1.fsra;
02607 }
02608 else
02609 {
02610 next_state.gov_ggov1.LowValSelect = next_state.gov_ggov1.LowValSelect1;
02611 }
02612
02613 if (next_state.gov_ggov1.LowValSelect > gov_ggv1_vmax)
02614 {
02615 next_state.gov_ggov1.GovOutPut = gov_ggv1_vmax;
02616 }
02617 else if (next_state.gov_ggov1.LowValSelect < gov_ggv1_vmin)
02618 {
02619 next_state.gov_ggov1.GovOutPut = gov_ggv1_vmin;
02620 }
02621 else
02622 {
02623 next_state.gov_ggov1.GovOutPut = next_state.gov_ggov1.LowValSelect;
02624 }
02625
02626 }
02627
02628
02629
02630 if (Exciter_type == SEXS)
02631 {
02632
02633
02634
02635
02636
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661 if (CVRenabled) {
02662
02663
02664 if (CVRmode == HighOrder) {
02665 if (Kd1 != 0) {
02666 next_state.avr.x_cvr1 = curr_state.avr.x_cvr1 + predictor_vals.avr.x_cvr1*deltat;
02667 next_state.avr.x_cvr2 = curr_state.avr.x_cvr2 + predictor_vals.avr.x_cvr2*deltat;
02668 gen_base_set_vals.vadd = (Kn1/Kd1) * next_state.avr.x_cvr1 + (Kn2/Kd1) * next_state.avr.x_cvr2 + kp_cvr * predictor_vals.avr.diff_f;
02669 }
02670 else {
02671 next_state.avr.x_cvr1 = curr_state.avr.x_cvr1 + predictor_vals.avr.x_cvr1*deltat;
02672 gen_base_set_vals.vadd = (Kn2/Kd2 - (Kd3 * Kn1)/(Kd2 * Kd2)) * next_state.avr.x_cvr1 + (kp_cvr + Kn1/Kd2) * predictor_vals.avr.diff_f;
02673 }
02674
02675
02676 if (gen_base_set_vals.vadd >= vset_delta_MAX)
02677 gen_base_set_vals.vadd = vset_delta_MAX;
02678
02679 if (gen_base_set_vals.vadd <= vset_delta_MIN)
02680 gen_base_set_vals.vadd = vset_delta_MIN;
02681
02682 }
02683
02684 else if (CVRmode == Feedback) {
02685 next_state.avr.x_cvr1 = curr_state.avr.x_cvr1 + predictor_vals.avr.x_cvr1*deltat;
02686 gen_base_set_vals.vadd_a = kp_cvr * predictor_vals.avr.diff_f + next_state.avr.x_cvr1;
02687
02688
02689 if (gen_base_set_vals.vadd_a >= vset_delta_MAX) {
02690 gen_base_set_vals.vadd = vset_delta_MAX;
02691 }
02692 else if (gen_base_set_vals.vadd_a <= vset_delta_MIN) {
02693 gen_base_set_vals.vadd = vset_delta_MIN;
02694 }
02695 else {
02696 gen_base_set_vals.vadd = gen_base_set_vals.vadd_a;
02697 }
02698 }
02699
02700
02701 gen_base_set_vals.vset = gen_base_set_vals.vadd + Vref;
02702 }
02703
02704
02705 next_state.avr.xe = curr_state.avr.xe + predictor_vals.avr.xe*deltat;
02706 next_state.avr.xb = curr_state.avr.xb + predictor_vals.avr.xb*deltat;
02707 }
02708
02709
02710
02711 omega_pu = curr_state.omega/omega_ref;
02712
02713
02714 value_IGenerated[0] = next_state.EintVal[0]*YS1*omega_pu;
02715 value_IGenerated[1] = next_state.EintVal[1]*YS1*omega_pu;
02716 value_IGenerated[2] = next_state.EintVal[2]*YS1*omega_pu;
02717
02718
02719 push_powerflow_values(false);
02720
02721 return SM_DELTA_ITER;
02722 }
02723 else
02724 {
02725
02726 apply_dynamics(&next_state,&corrector_vals,deltat);
02727
02728
02729 if (Q_constant_mode == true) {
02730 next_state.avr.xfd = curr_state.avr.xfd + (predictor_vals.avr.xfd + corrector_vals.avr.xfd)*deltath;
02731 next_state.Vfd = next_state.avr.xfd + (predictor_vals.avr.xfd + corrector_vals.avr.xfd)*0.5*(kp_Qconstant/ki_Qconstant);
02732 }
02733
02734 next_state.Flux1d = curr_state.Flux1d + (predictor_vals.Flux1d + corrector_vals.Flux1d)*deltath;
02735 next_state.Flux2q = curr_state.Flux2q + (predictor_vals.Flux2q + corrector_vals.Flux2q)*deltath;
02736 next_state.EpRotated = curr_state.EpRotated + (predictor_vals.EpRotated + corrector_vals.EpRotated)*deltath;
02737 next_state.rotor_angle = curr_state.rotor_angle + (predictor_vals.rotor_angle + corrector_vals.rotor_angle)*deltath;
02738 next_state.omega = curr_state.omega + (predictor_vals.omega + corrector_vals.omega)*deltath;
02739
02740 next_state.VintRotated = (Xqpp-Xdpp)*next_state.Irotated.Im();
02741 next_state.VintRotated += (Xqpp-Xl)/(Xqp-Xl)*next_state.EpRotated.Re() - (Xqp-Xqpp)/(Xqp-Xl)*next_state.Flux2q;
02742 next_state.VintRotated += complex(0.0,1.0)*((Xdpp-Xl)/(Xdp-Xl)*next_state.EpRotated.Im()+(Xdp-Xdpp)/(Xdp-Xl)*next_state.Flux1d);
02743
02744
02745 temp_rotation = complex(0.0,1.0)*complex_exp(-1.0*next_state.rotor_angle);
02746 temp_complex[0] = next_state.VintRotated/temp_rotation*voltage_base;
02747 temp_complex[1] = temp_complex[2] = 0.0;
02748
02749
02750 convert_pn0_to_abc(&temp_complex[0], &next_state.EintVal[0]);
02751
02752
02753 if (Governor_type == DEGOV1)
02754 {
02755 next_state.gov_degov1.x1 = curr_state.gov_degov1.x1 + (predictor_vals.gov_degov1.x1 + corrector_vals.gov_degov1.x1)*deltath;
02756 next_state.gov_degov1.x2 = curr_state.gov_degov1.x2 + (predictor_vals.gov_degov1.x2 + corrector_vals.gov_degov1.x2)*deltath;
02757 next_state.gov_degov1.x4 = curr_state.gov_degov1.x4 + (predictor_vals.gov_degov1.x4 + corrector_vals.gov_degov1.x4)*deltath;
02758 next_state.gov_degov1.x5 = curr_state.gov_degov1.x5 + (predictor_vals.gov_degov1.x5 + corrector_vals.gov_degov1.x5)*deltath;
02759 next_state.gov_degov1.x6 = curr_state.gov_degov1.x6 + (predictor_vals.gov_degov1.x6 + corrector_vals.gov_degov1.x6)*deltath;
02760 }
02761 else if (Governor_type == GAST)
02762 {
02763 next_state.gov_gast.x1 = curr_state.gov_gast.x1 + (predictor_vals.gov_gast.x1 + corrector_vals.gov_gast.x1)*deltath;
02764 next_state.gov_gast.x2 = curr_state.gov_gast.x2 + (predictor_vals.gov_gast.x2 + corrector_vals.gov_gast.x2)*deltath;
02765 next_state.gov_gast.x3 = curr_state.gov_gast.x3 + (predictor_vals.gov_gast.x3 + corrector_vals.gov_gast.x3)*deltath;
02766 }
02767 else if (Governor_type == P_CONSTANT)
02768 {
02769
02770 next_state.gov_pconstant.x1 = curr_state.gov_pconstant.x1 + (predictor_vals.gov_pconstant.x1 + corrector_vals.gov_pconstant.x1)*deltath;
02771 next_state.gov_pconstant.x4 = curr_state.gov_pconstant.x4 + (predictor_vals.gov_pconstant.x4 + corrector_vals.gov_pconstant.x4)*deltath;
02772 next_state.gov_pconstant.x5b = curr_state.gov_pconstant.x5b + (predictor_vals.gov_pconstant.x5b + corrector_vals.gov_pconstant.x5b)*deltath;
02773 next_state.gov_pconstant.x_Pconstant = curr_state.gov_pconstant.x_Pconstant + (predictor_vals.gov_pconstant.x_Pconstant + corrector_vals.gov_pconstant.x_Pconstant)*deltath;
02774 next_state.gov_pconstant.GovOutPut = next_state.gov_pconstant.x_Pconstant + (gen_base_set_vals.Pref - next_state.gov_pconstant.x1) * kp_Pconstant;
02775
02776
02777
02778 next_state.gov_pconstant.ValveStroke = next_state.gov_pconstant.x4;
02779 if (pconstant_Flag == 0)
02780 {
02781 next_state.gov_pconstant.FuelFlow = next_state.gov_pconstant.ValveStroke * 1.0;
02782 }
02783 else if (pconstant_Flag == 1)
02784 {
02785 next_state.gov_pconstant.FuelFlow = next_state.gov_pconstant.ValveStroke*next_state.omega/omega_ref;
02786 }
02787 else
02788 {
02789 gl_error("wrong pconstant_flag");
02790 return SM_ERROR;
02791 }
02792
02793
02794 x5a_now = pconstant_Kturb*(next_state.gov_pconstant.FuelFlow - pconstant_wfnl);
02795
02796 if (pconstant_Teng > 0)
02797 {
02798
02799 x5a_delayed[x5a_delayed_write_pos] = x5a_now;
02800
02801
02802 next_state.gov_pconstant.x5a = x5a_delayed[x5a_delayed_read_pos];
02803 }
02804 else
02805 {
02806
02807 next_state.gov_pconstant.x5a = x5a_now;
02808 }
02809 next_state.gov_pconstant.x5 = (1.0 - pconstant_Tc/pconstant_Tb)*next_state.gov_pconstant.x5b + pconstant_Tc/pconstant_Tb*next_state.gov_pconstant.x5a;
02810
02811
02812 next_state.pwr_mech = Rated_VA*(next_state.gov_pconstant.x5);
02813
02814
02815 if (next_state.pwr_mech > Overload_Limit_Value)
02816 {
02817
02818 next_state.pwr_mech = Overload_Limit_Value;
02819
02820
02821 next_state.gov_pconstant.x5 = Overload_Limit_Value / Rated_VA;
02822 }
02823
02824
02825 next_state.torque_mech = next_state.pwr_mech / next_state.omega;
02826
02827 }
02828 else if ((Governor_type == GGOV1) || (Governor_type == GGOV1_OLD))
02829 {
02830
02831 next_state.gov_ggov1.x1 = curr_state.gov_ggov1.x1 + (predictor_vals.gov_ggov1.x1 + corrector_vals.gov_ggov1.x1)*deltath;
02832 next_state.gov_ggov1.x2a = curr_state.gov_ggov1.x2a + (predictor_vals.gov_ggov1.x2a + corrector_vals.gov_ggov1.x2a)*deltath;
02833 next_state.gov_ggov1.x3 = curr_state.gov_ggov1.x3 + (predictor_vals.gov_ggov1.x3 + corrector_vals.gov_ggov1.x3)*deltath;
02834 next_state.gov_ggov1.x4 = curr_state.gov_ggov1.x4 + (predictor_vals.gov_ggov1.x4 + corrector_vals.gov_ggov1.x4)*deltath;
02835 next_state.gov_ggov1.x5b = curr_state.gov_ggov1.x5b + (predictor_vals.gov_ggov1.x5b + corrector_vals.gov_ggov1.x5b)*deltath;
02836 next_state.gov_ggov1.x6 = curr_state.gov_ggov1.x6 + (predictor_vals.gov_ggov1.x6 + corrector_vals.gov_ggov1.x6)*deltath;
02837 next_state.gov_ggov1.x7 = curr_state.gov_ggov1.x7 + (predictor_vals.gov_ggov1.x7 + corrector_vals.gov_ggov1.x7)*deltath;
02838 next_state.gov_ggov1.x8a = curr_state.gov_ggov1.x8a + (predictor_vals.gov_ggov1.x8a + corrector_vals.gov_ggov1.x8a)*deltath;
02839 next_state.gov_ggov1.x9a = curr_state.gov_ggov1.x9a + (predictor_vals.gov_ggov1.x9a + corrector_vals.gov_ggov1.x9a)*deltath;
02840 next_state.gov_ggov1.x10b = curr_state.gov_ggov1.x10b + (predictor_vals.gov_ggov1.x10b + corrector_vals.gov_ggov1.x10b)*deltath;
02841
02842
02843
02844 if (next_state.gov_ggov1.x8a > (1.1*gov_ggv1_r))
02845 {
02846 next_state.gov_ggov1.x8 = 1.1 * gov_ggv1_r;
02847 }
02848 else if (next_state.gov_ggov1.x8a < (-1.1*gov_ggv1_r))
02849 {
02850 next_state.gov_ggov1.x8 = -1.1 * gov_ggv1_r;
02851 }
02852 else
02853 {
02854 next_state.gov_ggov1.x8 = next_state.gov_ggov1.x8a;
02855 }
02856
02857
02858 next_state.gov_ggov1.ValveStroke = next_state.gov_ggov1.x4;
02859 if (gov_ggv1_Flag == 0)
02860 {
02861 next_state.gov_ggov1.FuelFlow = next_state.gov_ggov1.ValveStroke * 1.0;
02862 }
02863 else if (gov_ggv1_Flag == 1)
02864 {
02865 next_state.gov_ggov1.FuelFlow = next_state.gov_ggov1.ValveStroke*next_state.omega/omega_ref;
02866 }
02867 else
02868 {
02869 gl_error("wrong ggv1_flag");
02870 return SM_ERROR;
02871 }
02872
02873
02874
02875
02876
02877 if (gov_ggv1_rselect == 1)
02878 {
02879 next_state.gov_ggov1.RselectValue = next_state.gov_ggov1.x1;
02880 }
02881 else if (gov_ggv1_rselect == -1)
02882 {
02883 next_state.gov_ggov1.RselectValue = next_state.gov_ggov1.ValveStroke;
02884 }
02885 else if (gov_ggv1_rselect == -2)
02886 {
02887 next_state.gov_ggov1.RselectValue = next_state.gov_ggov1.GovOutPut;
02888 }
02889 else if (gov_ggv1_rselect == 0)
02890 {
02891 next_state.gov_ggov1.RselectValue = 0.0;
02892 }
02893 else
02894 {
02895 gl_error("wrong ggv1_rselect parameter");
02896 return SM_ERROR;
02897 }
02898
02899
02900 next_state.gov_ggov1.werror = next_state.omega/omega_ref - gen_base_set_vals.wref;
02901 next_state.gov_ggov1.err2a = gen_base_set_vals.Pref + next_state.gov_ggov1.x8 - next_state.gov_ggov1.werror - gov_ggv1_r*next_state.gov_ggov1.RselectValue;
02902 if (next_state.gov_ggov1.err2a > gov_ggv1_maxerr)
02903 {
02904 next_state.gov_ggov1.err2 = gov_ggv1_maxerr;
02905 }
02906 else if (next_state.gov_ggov1.err2a < gov_ggv1_minerr)
02907 {
02908 next_state.gov_ggov1.err2 = gov_ggv1_minerr;
02909 }
02910 else if ((next_state.gov_ggov1.err2a <= gov_ggv1_db) && (next_state.gov_ggov1.err2a >= -gov_ggv1_db))
02911 {
02912 next_state.gov_ggov1.err2 = 0.0;
02913 }
02914 else
02915 {
02916 if (next_state.gov_ggov1.err2a > 0.0)
02917 {
02918 next_state.gov_ggov1.err2 = (gov_ggv1_maxerr/(gov_ggv1_maxerr-gov_ggv1_db))*next_state.gov_ggov1.err2a - (gov_ggv1_maxerr*gov_ggv1_db/(gov_ggv1_maxerr-gov_ggv1_db));
02919 }
02920 else if (next_state.gov_ggov1.err2a < 0.0)
02921 {
02922 next_state.gov_ggov1.err2 = (gov_ggv1_minerr/(gov_ggv1_minerr+gov_ggv1_db))*next_state.gov_ggov1.err2a + (gov_ggv1_minerr*gov_ggv1_db/(gov_ggv1_minerr+gov_ggv1_db));
02923 }
02924 }
02925 next_state.gov_ggov1.x2 = gov_ggv1_Kpgov/gov_ggv1_Tdgov*(next_state.gov_ggov1.err2 - next_state.gov_ggov1.x2a);
02926
02927
02928 if ((Governor_type == GGOV1_OLD) || ((Governor_type == GGOV1) && (gov_ggv1_Kpgov == 0.0)))
02929 {
02930 next_state.gov_ggov1.x3a = gov_ggv1_Kigov*next_state.gov_ggov1.err2;
02931 }
02932 else
02933 {
02934 next_state.gov_ggov1.err3 = next_state.gov_ggov1.GovOutPut - next_state.gov_ggov1.x3;
02935 next_state.gov_ggov1.x3a = gov_ggv1_Kigov/gov_ggv1_Kpgov*next_state.gov_ggov1.err3;
02936 }
02937 next_state.gov_ggov1.fsrn = next_state.gov_ggov1.x2 + gov_ggv1_Kpgov*next_state.gov_ggov1.err2 + next_state.gov_ggov1.x3;
02938
02939
02940 x5a_now = gov_ggv1_Kturb*(next_state.gov_ggov1.FuelFlow - gov_ggv1_wfnl);
02941
02942 if (gov_ggv1_Teng > 0)
02943 {
02944
02945 x5a_delayed[x5a_delayed_write_pos] = x5a_now;
02946
02947
02948 next_state.gov_ggov1.x5a = x5a_delayed[x5a_delayed_read_pos];
02949 }
02950 else
02951 {
02952
02953 next_state.gov_ggov1.x5a = x5a_now;
02954 }
02955 next_state.gov_ggov1.x5 = (1.0 - gov_ggv1_Tc/gov_ggv1_Tb)*next_state.gov_ggov1.x5b + gov_ggv1_Tc/gov_ggv1_Tb*next_state.gov_ggov1.x5a;
02956 if (gov_ggv1_Dm > 0.0)
02957 {
02958
02959 next_state.pwr_mech = Rated_VA*(next_state.gov_ggov1.x5 - gov_ggv1_Dm*(next_state.omega/omega_ref - gen_base_set_vals.wref));
02960
02961
02962 if (next_state.pwr_mech > Overload_Limit_Value)
02963 {
02964
02965 next_state.pwr_mech = Overload_Limit_Value;
02966
02967
02968 next_state.gov_ggov1.x5 = Overload_Limit_Value / Rated_VA + gov_ggv1_Dm*(next_state.omega/omega_ref - gen_base_set_vals.wref);
02969 }
02970 }
02971 else
02972 {
02973
02974 next_state.pwr_mech = Rated_VA*(next_state.gov_ggov1.x5);
02975
02976
02977 if (next_state.pwr_mech > Overload_Limit_Value)
02978 {
02979
02980 next_state.pwr_mech = Overload_Limit_Value;
02981
02982
02983 next_state.gov_ggov1.x5 = Overload_Limit_Value / Rated_VA;
02984 }
02985 }
02986
02987 next_state.torque_mech = next_state.pwr_mech / next_state.omega;
02988
02989
02990 if (gov_ggv1_Dm < 0.0)
02991 {
02992 next_state.gov_ggov1.x10a = next_state.gov_ggov1.FuelFlow * pow((next_state.omega/omega_ref),gov_ggv1_Dm);
02993 }
02994 else
02995 {
02996 next_state.gov_ggov1.x10a = next_state.gov_ggov1.FuelFlow;
02997 }
02998 next_state.gov_ggov1.x10 = (1.0 - gov_ggv1_Tsa/gov_ggv1_Tsb)*next_state.gov_ggov1.x10b + gov_ggv1_Tsa/gov_ggv1_Tsb*next_state.gov_ggov1.x10a;
02999
03000
03001 next_state.gov_ggov1.err7 = next_state.gov_ggov1.GovOutPut - next_state.gov_ggov1.x7;
03002 if (gov_ggv1_Kpload > 0.0)
03003 {
03004 next_state.gov_ggov1.x7a = gov_ggv1_Kiload/gov_ggv1_Kpload*next_state.gov_ggov1.err7;
03005 }
03006 else
03007 {
03008 next_state.gov_ggov1.x7a = gov_ggv1_Kiload*next_state.gov_ggov1.err7;
03009 }
03010 next_state.gov_ggov1.fsrtNoLim = next_state.gov_ggov1.x7 + gov_ggv1_Kpload*(-1.0 * next_state.gov_ggov1.x6 + gov_ggv1_Ldref*(gov_ggv1_Ldref/gov_ggv1_Kturb+gov_ggv1_wfnl));
03011 if (next_state.gov_ggov1.fsrtNoLim > 1.0)
03012 {
03013 next_state.gov_ggov1.fsrt = 1.0;
03014 }
03015 else
03016 {
03017 next_state.gov_ggov1.fsrt = next_state.gov_ggov1.fsrtNoLim;
03018 }
03019
03020
03021 next_state.gov_ggov1.x9 = 1.0/gov_ggv1_Ta*((next_state.omega/omega_ref - gen_base_set_vals.wref) - next_state.gov_ggov1.x9a);
03022 next_state.gov_ggov1.fsra = gov_ggv1_Ka*deltat*(gov_ggv1_aset - next_state.gov_ggov1.x9) + next_state.gov_ggov1.GovOutPut;
03023
03024
03025 if (gov_ggv1_fsrt_enable == false)
03026 {
03027 next_state.gov_ggov1.fsrt = 99999999.0;
03028 }
03029
03030 if (gov_ggv1_fsra_enable == false)
03031 {
03032 next_state.gov_ggov1.fsra = 99999999.0;
03033 }
03034
03035 if (gov_ggv1_fsrn_enable == false)
03036 {
03037 next_state.gov_ggov1.fsrn = 99999999.0;
03038 }
03039
03040
03041 if (next_state.gov_ggov1.fsrt < next_state.gov_ggov1.fsrn)
03042 {
03043 next_state.gov_ggov1.LowValSelect1 = next_state.gov_ggov1.fsrt;
03044 }
03045 else
03046 {
03047 next_state.gov_ggov1.LowValSelect1 = next_state.gov_ggov1.fsrn;
03048 }
03049
03050 if (next_state.gov_ggov1.fsra < next_state.gov_ggov1.LowValSelect1)
03051 {
03052 next_state.gov_ggov1.LowValSelect = next_state.gov_ggov1.fsra;
03053 }
03054 else
03055 {
03056 next_state.gov_ggov1.LowValSelect = next_state.gov_ggov1.LowValSelect1;
03057 }
03058
03059 if (next_state.gov_ggov1.LowValSelect > gov_ggv1_vmax)
03060 {
03061 next_state.gov_ggov1.GovOutPut = gov_ggv1_vmax;
03062 }
03063 else if (next_state.gov_ggov1.LowValSelect < gov_ggv1_vmin)
03064 {
03065 next_state.gov_ggov1.GovOutPut = gov_ggv1_vmin;
03066 }
03067 else
03068 {
03069 next_state.gov_ggov1.GovOutPut = next_state.gov_ggov1.LowValSelect;
03070 }
03071
03072 }
03073
03074
03075
03076
03077 if (Exciter_type == SEXS)
03078 {
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089
03090
03091
03092
03093
03094
03095
03096
03097
03098
03099
03100
03101
03102
03103
03104
03105
03106
03107
03108
03109
03110 if (CVRenabled) {
03111
03112
03113 if (CVRmode == HighOrder) {
03114 if (Kd1 != 0) {
03115 next_state.avr.x_cvr1 = curr_state.avr.x_cvr1 + (corrector_vals.avr.x_cvr1 + predictor_vals.avr.x_cvr1)*deltath;
03116 next_state.avr.x_cvr2 = curr_state.avr.x_cvr2 + (corrector_vals.avr.x_cvr2 + predictor_vals.avr.x_cvr2)*deltath;
03117 gen_base_set_vals.vadd = (Kn1/Kd1) * next_state.avr.x_cvr1 + (Kn2/Kd1) * next_state.avr.x_cvr2 + kp_cvr * (predictor_vals.avr.diff_f + corrector_vals.avr.diff_f) * 0.5;
03118 }
03119 else {
03120 next_state.avr.x_cvr1 = curr_state.avr.x_cvr1 + (corrector_vals.avr.x_cvr1 + predictor_vals.avr.x_cvr1)*deltath;
03121 gen_base_set_vals.vadd = (Kn2/Kd2 - (Kd3 * Kn1)/(Kd2 * Kd2)) * next_state.avr.x_cvr1 + (kp_cvr + Kn1/Kd2) * (predictor_vals.avr.diff_f + corrector_vals.avr.diff_f) * 0.5;
03122 }
03123
03124
03125 if (gen_base_set_vals.vadd >= vset_delta_MAX)
03126 gen_base_set_vals.vadd = vset_delta_MAX;
03127
03128 if (gen_base_set_vals.vadd <= vset_delta_MIN)
03129 gen_base_set_vals.vadd = vset_delta_MIN;
03130
03131 }
03132
03133 else if (CVRmode == Feedback) {
03134 next_state.avr.x_cvr1 = curr_state.avr.x_cvr1 + (corrector_vals.avr.x_cvr1 + predictor_vals.avr.x_cvr1)*deltath;
03135 gen_base_set_vals.vadd_a = kp_cvr * (predictor_vals.avr.diff_f + corrector_vals.avr.diff_f) * 0.5 + next_state.avr.x_cvr1;
03136
03137
03138 if (gen_base_set_vals.vadd_a >= vset_delta_MAX) {
03139 gen_base_set_vals.vadd = vset_delta_MAX;
03140 }
03141 else if (gen_base_set_vals.vadd_a <= vset_delta_MIN) {
03142 gen_base_set_vals.vadd = vset_delta_MIN;
03143 }
03144 else {
03145 gen_base_set_vals.vadd = gen_base_set_vals.vadd_a;
03146 }
03147 }
03148
03149
03150 gen_base_set_vals.vset = gen_base_set_vals.vadd + Vref;
03151 }
03152
03153 next_state.avr.xe = curr_state.avr.xe + (predictor_vals.avr.xe + corrector_vals.avr.xe)*deltath;
03154 next_state.avr.xb = curr_state.avr.xb + (predictor_vals.avr.xb + corrector_vals.avr.xb)*deltath;
03155 }
03156
03157
03158
03159 omega_pu = next_state.omega/omega_ref;
03160
03161
03162 value_IGenerated[0] = next_state.EintVal[0]*YS1*omega_pu;
03163 value_IGenerated[1] = next_state.EintVal[1]*YS1*omega_pu;
03164 value_IGenerated[2] = next_state.EintVal[2]*YS1*omega_pu;
03165
03166
03167 memcpy(&curr_state,&next_state,sizeof(MAC_STATES));
03168
03169
03170 temp_double = fabs(curr_state.omega - prev_rotor_speed_val);
03171
03172
03173 prev_rotor_speed_val = curr_state.omega;
03174
03175
03176
03177 if (mapped_freq_variable!=NULL)
03178 {
03179
03180 temp_double_freq_val = curr_state.omega/(2.0*PI);
03181
03182
03183 mapped_freq_variable->setp<double>(temp_double_freq_val,*test_rlock);
03184 }
03185
03186
03187 push_powerflow_values(false);
03188
03189
03190 if (apply_rotor_speed_convergence == true)
03191 {
03192
03193 if (temp_double<=rotor_speed_convergence_criterion)
03194 {
03195
03196 if (is_isochronous_gen == true)
03197 {
03198
03199 temp_double = fabs(curr_state.omega - omega_ref);
03200
03201
03202 if (temp_double<=rotor_speed_convergence_criterion)
03203 {
03204
03205 if (apply_voltage_mag_convergence == false)
03206 {
03207
03208 return SM_EVENT;
03209 }
03210
03211 }
03212 else
03213 {
03214 return SM_DELTA;
03215 }
03216 }
03217 else
03218 {
03219 if (apply_voltage_mag_convergence == false)
03220 {
03221
03222 return SM_EVENT;
03223 }
03224
03225 }
03226 }
03227 else
03228 {
03229 return SM_DELTA;
03230
03231 }
03232 }
03233
03234
03235 if ((apply_voltage_mag_convergence == true) && (Exciter_type != NO_EXC))
03236 {
03237
03238 temp_double = 0.0;
03239
03240
03241 for (loop_index=0; loop_index<3; loop_index++)
03242 {
03243 temp_mag_val = value_Circuit_V[loop_index].Mag();
03244 temp_mag_diff = fabs(temp_mag_val - prev_voltage_val[loop_index]);
03245
03246
03247 if (temp_mag_diff > temp_double)
03248 {
03249 temp_double = temp_mag_diff;
03250 }
03251
03252
03253 prev_voltage_val[loop_index] = temp_mag_val;
03254 }
03255
03256
03257 if (temp_double<=voltage_convergence_criterion)
03258 {
03259
03260 return SM_EVENT;
03261 }
03262 else
03263 {
03264 return SM_DELTA;
03265
03266 }
03267 }
03268
03269
03270 return SM_EVENT;
03271 }
03272 }
03273
03274
03275
03276
03277
03278 STATUS diesel_dg::post_deltaupdate(complex *useful_value, unsigned int mode_pass)
03279 {
03280 if (mode_pass == 0)
03281 {
03282
03283 curr_state.omega = useful_value->Re();
03284
03285
03286 if (deltamode_supersec_endtime != deltamode_endtime)
03287 {
03288 prev_time = deltamode_supersec_endtime;
03289 prev_time_dbl = deltamode_endtime_dbl;
03290 }
03291 else
03292 {
03293 prev_time = deltamode_endtime;
03294 prev_time_dbl = (double)(deltamode_endtime);
03295 }
03296 }
03297 else
03298 return FAILED;
03299
03300 return SUCCESS;
03301 }
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311
03312
03313
03314
03315 STATUS diesel_dg::apply_dynamics(MAC_STATES *curr_time, MAC_STATES *curr_delta, double deltaT)
03316 {
03317 complex current_pu[3];
03318 complex Ipn0[3];
03319 complex temp_complex;
03320 double omega_pu;
03321 double temp_double_1, temp_double_2, temp_double_3, delomega, x0;
03322 double torquenow, x5a_now;
03323 complex temp_current_val[3];
03324 double diff_f, temp_Vfd;
03325
03326
03327
03328
03329 current_pu[0] = (value_IGenerated[0] - generator_admittance[0][0]*value_Circuit_V[0] - generator_admittance[0][1]*value_Circuit_V[1] - generator_admittance[0][2]*value_Circuit_V[2])/current_base;
03330 current_pu[1] = (value_IGenerated[1] - generator_admittance[1][0]*value_Circuit_V[0] - generator_admittance[1][1]*value_Circuit_V[1] - generator_admittance[1][2]*value_Circuit_V[2])/current_base;
03331 current_pu[2] = (value_IGenerated[2] - generator_admittance[2][0]*value_Circuit_V[0] - generator_admittance[2][1]*value_Circuit_V[1] - generator_admittance[2][2]*value_Circuit_V[2])/current_base;
03332
03333
03334 current_val[0]=current_pu[0]*current_base;
03335 current_val[1]=current_pu[1]*current_base;
03336 current_val[2]=current_pu[2]*current_base;
03337
03338
03339
03340 omega_pu = curr_time->omega/omega_ref;
03341
03342
03343 convert_abc_to_pn0(¤t_pu[0],&Ipn0[0]);
03344
03345
03346 temp_complex = complex_exp(-1.0*curr_time->rotor_angle);
03347 curr_time->Irotated = temp_complex*complex(0.0,1.0)*Ipn0[0];
03348
03349
03350 temp_double_1 = -(Xqpp-Xl)/(Xqp-Xl)*curr_time->EpRotated.Re()*curr_time->Irotated.Re();
03351 temp_double_1 -=(Xdpp-Xl)/(Xdp-Xl)*curr_time->EpRotated.Im()*curr_time->Irotated.Im();
03352 temp_double_1 -=(Xdp-Xdpp)/(Xdp-Xl)*curr_time->Flux1d*curr_time->Irotated.Im();
03353 temp_double_1 +=(Xqp-Xqpp)/(Xqp-Xl)*curr_time->Flux2q*curr_time->Irotated.Re();
03354 temp_double_1 -=(Xqpp-Xdpp)*curr_time->Irotated.Re()*curr_time->Irotated.Im();
03355 temp_double_3 = Ipn0[1].Mag();
03356 temp_double_1 -=0.5*Rr*temp_double_3*temp_double_3;
03357 curr_time->torque_elec=-temp_double_1*Rated_VA/omega_ref;
03358 temp_double_1 =(curr_time->torque_mech/(Rated_VA/omega_ref)-curr_time->torque_elec/(Rated_VA/omega_ref));
03359 temp_double_1 -=damping*(curr_time->omega-omega_ref)/omega_ref;
03360
03361 curr_time->pwr_mech = curr_time->torque_mech*curr_time->omega;
03362
03363
03364 if (curr_time->pwr_mech > Overload_Limit_Value)
03365 {
03366
03367 curr_time->pwr_mech = Overload_Limit_Value;
03368
03369
03370 curr_time->torque_mech = Overload_Limit_Value / curr_time->omega;
03371 }
03372
03373 temp_double_2 = omega_ref/(2.0*inertia);
03374
03375
03376 curr_delta->omega = temp_double_1*temp_double_2;
03377
03378
03379 curr_delta->rotor_angle = (omega_pu-1.0)*omega_ref;
03380
03381
03382 curr_delta->Flux1d = (-curr_time->Flux1d + curr_time->EpRotated.Im() - ((Xdp-Xl)*curr_time->Irotated.Re()))/Tdopp;
03383 curr_delta->Flux2q = (-curr_time->Flux2q - curr_time->EpRotated.Re() - ((Xqp-Xl)*curr_time->Irotated.Im()))/Tqopp;
03384
03385
03386 temp_double_1 = curr_time->Vfd - curr_time->EpRotated.Im();
03387 temp_double_2 = curr_time->Flux1d + (Xdp-Xl)*curr_time->Irotated.Re() - curr_time->EpRotated.Im();
03388 temp_double_2 /= (Xdp-Xl);
03389 temp_double_2 /= (Xdp-Xl);
03390 temp_double_3 = curr_time->Irotated.Re() - (Xdp-Xdpp)*temp_double_2;
03391 temp_double_1 -= (Xd-Xdp)*temp_double_3;
03392
03393
03394 curr_delta->EpRotated.SetImag(temp_double_1/Tdop);
03395
03396
03397 temp_double_1 = -curr_time->EpRotated.Re();
03398 temp_double_2 = curr_time->Flux2q + (Xqp-Xl)*curr_time->Irotated.Im() + curr_time->EpRotated.Re();
03399 temp_double_2 /= (Xqp-Xl);
03400 temp_double_2 /= (Xqp-Xl);
03401 temp_double_3 = curr_time->Irotated.Im() - (Xqp-Xqpp)*temp_double_2;
03402 temp_double_1 += (Xq-Xqp)*temp_double_3;
03403
03404
03405 curr_delta->EpRotated.SetReal(temp_double_1/Tqop);
03406
03407
03408 if (Governor_type == DEGOV1)
03409 {
03410
03411 if (curr_time->gov_degov1.x4>gov_degov1_TMAX)
03412 curr_time->gov_degov1.x4 = gov_degov1_TMAX;
03413
03414 if (curr_time->gov_degov1.x4<gov_degov1_TMIN)
03415 curr_time->gov_degov1.x4 = gov_degov1_TMIN;
03416
03417
03418 curr_time->gov_degov1.throttle = gov_degov1_T4*curr_time->gov_degov1.x6 + curr_time->gov_degov1.x4;
03419
03420
03421 torque_delay[torque_delay_write_pos]=curr_time->gov_degov1.throttle;
03422
03423
03424 torquenow = torque_delay[torque_delay_read_pos];
03425
03426
03427 curr_time->torque_mech = (Rated_VA/omega_ref)*torquenow;
03428 curr_time->pwr_mech = curr_time->torque_mech*curr_time->omega;
03429
03430
03431 if (curr_time->pwr_mech > Overload_Limit_Value)
03432 {
03433
03434 curr_time->pwr_mech = Overload_Limit_Value;
03435
03436
03437 curr_time->torque_mech = Overload_Limit_Value / curr_time->omega;
03438 }
03439
03440
03441 temp_double_1 = gen_base_set_vals.wref - curr_time->omega/omega_ref-gov_degov1_R*curr_time->gov_degov1.throttle;
03442
03443
03444 curr_delta->gov_degov1.x2 = (temp_double_1-curr_time->gov_degov1.x1-gov_degov1_T1*curr_time->gov_degov1.x2)/(gov_degov1_T1*gov_degov1_T2);
03445 curr_delta->gov_degov1.x1 = curr_time->gov_degov1.x2;
03446
03447
03448 temp_double_1 = gov_degov1_T3*curr_time->gov_degov1.x2 + curr_time->gov_degov1.x1;
03449
03450
03451 curr_delta->gov_degov1.x5 = (gov_degov1_K*temp_double_1-curr_time->gov_degov1.x5)/gov_degov1_T5;
03452 curr_delta->gov_degov1.x6 = (curr_time->gov_degov1.x5 - curr_time->gov_degov1.x6)/gov_degov1_T6;
03453 curr_delta->gov_degov1.x4 = curr_time->gov_degov1.x6;
03454
03455
03456 if (((curr_time->gov_degov1.x4>=gov_degov1_TMAX) && (curr_time->gov_degov1.x6>0)) || ((curr_time->gov_degov1.x4<=gov_degov1_TMIN) && (curr_time->gov_degov1.x6<0)))
03457 {
03458 curr_delta->gov_degov1.x4 = 0;
03459 }
03460 }
03461 else if (Governor_type == GAST)
03462 {
03463
03464 if (curr_time->gov_gast.x1 > gov_gast_VMAX)
03465 curr_time->gov_gast.x1 = gov_gast_VMAX;
03466
03467 if (curr_time->gov_gast.x1 < gov_gast_VMIN)
03468 curr_time->gov_gast.x1 = gov_gast_VMIN;
03469
03470
03471 curr_time->gov_gast.throttle = curr_time->gov_gast.x2;
03472
03473
03474 torquenow=curr_time->gov_gast.throttle;
03475
03476
03477 curr_time->torque_mech = (Rated_VA/omega_ref)*torquenow;
03478 curr_time->pwr_mech = curr_time->torque_mech*curr_time->omega;
03479
03480
03481 if (curr_time->pwr_mech > Overload_Limit_Value)
03482 {
03483
03484 curr_time->pwr_mech = Overload_Limit_Value;
03485
03486
03487 curr_time->torque_mech = Overload_Limit_Value / curr_time->omega;
03488 }
03489
03490
03491 delomega = curr_time->gov_gast.throttle - (curr_time->omega/omega_ref-1)*gov_gast_R;
03492 if (delomega <= gov_gast_AT+gov_gast_KT*(gov_gast_AT-curr_time->gov_gast.x3))
03493 {
03494 x0=delomega;
03495 }
03496 else
03497 {
03498 x0=gov_gast_AT+gov_gast_KT*(gov_gast_AT-curr_time->gov_gast.x3);
03499 }
03500
03501
03502
03503
03504
03505 curr_delta->gov_gast.x1 = (x0 - curr_time->gov_gast.x1)/gov_gast_T1;
03506 curr_delta->gov_gast.x2 = (curr_time->gov_gast.x1 - curr_time->gov_gast.x2)/gov_gast_T2;
03507 curr_delta->gov_gast.x3 = (curr_time->gov_gast.x2 - curr_time->gov_gast.x3)/gov_gast_T3;
03508
03509
03510 if (((curr_time->gov_gast.x1>=gov_gast_VMAX) && (x0>0)) || ((curr_time->gov_gast.x1<=gov_gast_VMIN) && (x0<0)))
03511 {
03512 curr_delta->gov_gast.x1 = 0;
03513 }
03514 }
03515 else if (Governor_type == P_CONSTANT)
03516 {
03517
03518
03519 temp_current_val[0] = (value_IGenerated[0] - generator_admittance[0][0]*value_Circuit_V[0] - generator_admittance[0][1]*value_Circuit_V[1] - generator_admittance[0][2]*value_Circuit_V[2]);
03520 temp_current_val[1] = (value_IGenerated[1] - generator_admittance[1][0]*value_Circuit_V[0] - generator_admittance[1][1]*value_Circuit_V[1] - generator_admittance[1][2]*value_Circuit_V[2]);
03521 temp_current_val[2] = (value_IGenerated[2] - generator_admittance[2][0]*value_Circuit_V[0] - generator_admittance[2][1]*value_Circuit_V[1] - generator_admittance[2][2]*value_Circuit_V[2]);
03522
03523 complex pwr_electric_dynamics = value_Circuit_V[0]*~temp_current_val[0] + value_Circuit_V[1]*~temp_current_val[1] + value_Circuit_V[2]*~temp_current_val[2];
03524
03525
03526 curr_delta->gov_pconstant.x1 = 1.0/pconstant_Tpelec*(pwr_electric_dynamics.Re() / Rated_VA - curr_time->gov_pconstant.x1);
03527
03528
03529 double diff_Pelec = gen_base_set_vals.Pref - curr_time->gov_pconstant.x1;
03530
03531 curr_delta->gov_pconstant.x_Pconstant = diff_Pelec * ki_Pconstant;
03532
03533
03534 curr_time->gov_pconstant.err4 = curr_time->gov_pconstant.GovOutPut - curr_time->gov_pconstant.x4;
03535 curr_time->gov_pconstant.x4a = 1.0/pconstant_Tact*curr_time->gov_pconstant.err4;
03536 if (curr_time->gov_pconstant.x4a > pconstant_ropen)
03537 {
03538 curr_time->gov_pconstant.x4b = pconstant_ropen;
03539 }
03540 else if (curr_time->gov_pconstant.x4a < pconstant_rclose)
03541 {
03542 curr_time->gov_pconstant.x4b = pconstant_rclose;
03543 }
03544 else
03545 {
03546 curr_time->gov_pconstant.x4b = curr_time->gov_pconstant.x4a;
03547 }
03548 curr_delta->gov_pconstant.x4 = curr_time->gov_pconstant.x4b;
03549 curr_time->gov_pconstant.ValveStroke = curr_time->gov_pconstant.x4;
03550 if (pconstant_Flag == 0)
03551 {
03552 curr_time->gov_pconstant.FuelFlow = curr_time->gov_pconstant.ValveStroke * 1.0;
03553 }
03554 else if (pconstant_Flag == 1)
03555 {
03556 curr_time->gov_pconstant.FuelFlow = curr_time->gov_pconstant.ValveStroke * curr_time->omega / omega_ref;
03557 }
03558 else
03559 {
03560 gl_error("wrong pconstant_Flag");
03561 return FAILED;
03562 }
03563
03564
03565
03566
03567 x5a_now = pconstant_Kturb*(curr_time->gov_pconstant.FuelFlow - pconstant_wfnl);
03568
03569
03570 if (pconstant_Teng > 0)
03571 {
03572
03573 x5a_delayed[x5a_delayed_write_pos] = x5a_now;
03574
03575
03576 curr_time->gov_pconstant.x5a = x5a_delayed[x5a_delayed_read_pos];
03577 }
03578 else
03579 {
03580 curr_time->gov_pconstant.x5a = x5a_now;
03581 }
03582 curr_delta->gov_pconstant.x5b = 1.0/pconstant_Tb*(curr_time->gov_pconstant.x5a - curr_time->gov_pconstant.x5b);
03583 curr_time->gov_pconstant.x5 = (1.0 - pconstant_Tc/pconstant_Tb)*curr_time->gov_pconstant.x5b + pconstant_Tc/pconstant_Tb*curr_time->gov_pconstant.x5a;
03584
03585 curr_time->pwr_mech = Rated_VA*curr_time->gov_pconstant.x5;
03586
03587
03588 if (curr_time->pwr_mech > Overload_Limit_Value)
03589 {
03590
03591 curr_time->pwr_mech = Overload_Limit_Value;
03592
03593
03594 curr_time->gov_pconstant.x5 = Overload_Limit_Value / Rated_VA;
03595 }
03596
03597
03598 curr_time->torque_mech = curr_time->pwr_mech / curr_time->omega;
03599
03600 }
03601 else if ((Governor_type == GGOV1) || (Governor_type == GGOV1_OLD))
03602 {
03603
03604
03605 curr_delta->gov_ggov1.x1 = 1.0/gov_ggv1_Tpelec*(curr_time->pwr_electric.Re() / Rated_VA - curr_time->gov_ggov1.x1);
03606
03607
03608 if (curr_time->gov_ggov1.x8a > (1.1 * gov_ggv1_r))
03609 {
03610 curr_time->gov_ggov1.x8 = 1.1 * gov_ggv1_r;
03611 curr_delta->gov_ggov1.x8a = 0.0;
03612 }
03613 else if (curr_time->gov_ggov1.x8a < (-1.1 * gov_ggv1_r))
03614 {
03615 curr_time->gov_ggov1.x8 = -1.1 * gov_ggv1_r;
03616 curr_delta->gov_ggov1.x8a = 0.0;
03617 }
03618 else
03619 {
03620 curr_delta->gov_ggov1.x8a = gov_ggv1_Kimw*(gov_ggv1_Pmwset/Rated_VA - curr_time->gov_ggov1.x1);
03621 curr_time->gov_ggov1.x8 = curr_time->gov_ggov1.x8a;
03622 }
03623
03624
03625
03626 if (gov_ggv1_rselect == 1)
03627 {
03628 curr_time->gov_ggov1.RselectValue = curr_time->gov_ggov1.x1;
03629 }
03630 else if (gov_ggv1_rselect == -1)
03631 {
03632 curr_time->gov_ggov1.RselectValue = curr_time->gov_ggov1.ValveStroke;
03633 }
03634 else if (gov_ggv1_rselect == -2)
03635 {
03636 curr_time->gov_ggov1.RselectValue = curr_time->gov_ggov1.GovOutPut;
03637 }
03638 else if (gov_ggv1_rselect == 0)
03639 {
03640 curr_time->gov_ggov1.RselectValue = 0.0;
03641 }
03642 else
03643 {
03644 gl_error("Wrong ggv1_rselect parameter");
03645 return FAILED;
03646 }
03647
03648
03649 curr_time->gov_ggov1.werror = curr_time->omega/omega_ref - gen_base_set_vals.wref;
03650 curr_time->gov_ggov1.err2a = gen_base_set_vals.Pref + curr_time->gov_ggov1.x8 - curr_time->gov_ggov1.werror - gov_ggv1_r*curr_time->gov_ggov1.RselectValue;
03651 if (curr_time->gov_ggov1.err2a > gov_ggv1_maxerr)
03652 {
03653 curr_time->gov_ggov1.err2 = gov_ggv1_maxerr;
03654 }
03655 else if (curr_time->gov_ggov1.err2a < gov_ggv1_minerr)
03656 {
03657 curr_time->gov_ggov1.err2 = gov_ggv1_minerr;
03658 }
03659 else if ((curr_time->gov_ggov1.err2a <= gov_ggv1_db) && (curr_time->gov_ggov1.err2a >= -gov_ggv1_db))
03660 {
03661 curr_time->gov_ggov1.err2 = 0.0;
03662 }
03663 else
03664 {
03665 if (curr_time->gov_ggov1.err2a > 0.0)
03666 {
03667 curr_time->gov_ggov1.err2 = (gov_ggv1_maxerr/(gov_ggv1_maxerr-gov_ggv1_db))*curr_time->gov_ggov1.err2a - (gov_ggv1_maxerr*gov_ggv1_db/(gov_ggv1_maxerr-gov_ggv1_db));
03668 }
03669 else if (curr_time->gov_ggov1.err2a < 0.0)
03670 {
03671 curr_time->gov_ggov1.err2 = (gov_ggv1_minerr/(gov_ggv1_minerr+gov_ggv1_db))*curr_time->gov_ggov1.err2a + (gov_ggv1_minerr*gov_ggv1_db/(gov_ggv1_minerr+gov_ggv1_db));
03672 }
03673 }
03674 curr_delta->gov_ggov1.x2a = 1.0/gov_ggv1_Tdgov*(curr_time->gov_ggov1.err2 - curr_time->gov_ggov1.x2a);
03675 curr_time->gov_ggov1.x2 = gov_ggv1_Kpgov/gov_ggv1_Tdgov*(curr_time->gov_ggov1.err2 - curr_time->gov_ggov1.x2a);
03676
03677
03678
03679 if ((Governor_type == GGOV1_OLD) || ((Governor_type == GGOV1) && (gov_ggv1_Kpgov == 0.0)))
03680 {
03681 curr_time->gov_ggov1.x3a = gov_ggv1_Kigov*curr_time->gov_ggov1.err2;
03682 }
03683 else
03684 {
03685 curr_time->gov_ggov1.err3 = curr_time->gov_ggov1.GovOutPut - curr_time->gov_ggov1.x3;
03686 curr_time->gov_ggov1.x3a = gov_ggv1_Kigov/gov_ggv1_Kpgov*curr_time->gov_ggov1.err3;
03687 }
03688
03689 curr_delta->gov_ggov1.x3 = curr_time->gov_ggov1.x3a;
03690 curr_time->gov_ggov1.fsrn = curr_time->gov_ggov1.x2 + gov_ggv1_Kpgov*curr_time->gov_ggov1.err2 + curr_time->gov_ggov1.x3;
03691
03692
03693 curr_time->gov_ggov1.err4 = curr_time->gov_ggov1.GovOutPut - curr_time->gov_ggov1.x4;
03694 curr_time->gov_ggov1.x4a = 1.0/gov_ggv1_Tact*curr_time->gov_ggov1.err4;
03695 if (curr_time->gov_ggov1.x4a > gov_ggv1_ropen)
03696 {
03697 curr_time->gov_ggov1.x4b = gov_ggv1_ropen;
03698 }
03699 else if (curr_time->gov_ggov1.x4a < gov_ggv1_rclose)
03700 {
03701 curr_time->gov_ggov1.x4b = gov_ggv1_rclose;
03702 }
03703 else
03704 {
03705 curr_time->gov_ggov1.x4b = curr_time->gov_ggov1.x4a;
03706 }
03707 curr_delta->gov_ggov1.x4 = curr_time->gov_ggov1.x4b;
03708 curr_time->gov_ggov1.ValveStroke = curr_time->gov_ggov1.x4;
03709 if (gov_ggv1_Flag == 0)
03710 {
03711 curr_time->gov_ggov1.FuelFlow = curr_time->gov_ggov1.ValveStroke * 1.0;
03712 }
03713 else if (gov_ggv1_Flag == 1)
03714 {
03715 curr_time->gov_ggov1.FuelFlow = curr_time->gov_ggov1.ValveStroke * curr_time->omega / omega_ref;
03716 }
03717 else
03718 {
03719 gl_error("wrong ggv1_Flag");
03720 return FAILED;
03721 }
03722
03723
03724
03725
03726 x5a_now = gov_ggv1_Kturb*(curr_time->gov_ggov1.FuelFlow - gov_ggv1_wfnl);
03727
03728
03729 if (gov_ggv1_Teng > 0)
03730 {
03731
03732 x5a_delayed[x5a_delayed_write_pos] = x5a_now;
03733
03734
03735 curr_time->gov_ggov1.x5a = x5a_delayed[x5a_delayed_read_pos];
03736 }
03737 else
03738 {
03739 curr_time->gov_ggov1.x5a = x5a_now;
03740 }
03741 curr_delta->gov_ggov1.x5b = 1.0/gov_ggv1_Tb*(curr_time->gov_ggov1.x5a - curr_time->gov_ggov1.x5b);
03742 curr_time->gov_ggov1.x5 = (1.0 - gov_ggv1_Tc/gov_ggv1_Tb)*curr_time->gov_ggov1.x5b + gov_ggv1_Tc/gov_ggv1_Tb*curr_time->gov_ggov1.x5a;
03743 if (gov_ggv1_Dm > 0.0)
03744 {
03745 curr_time->pwr_mech = Rated_VA*(curr_time->gov_ggov1.x5 - gov_ggv1_Dm*(curr_time->omega/omega_ref - gen_base_set_vals.wref));
03746
03747
03748 if (curr_time->pwr_mech > Overload_Limit_Value)
03749 {
03750
03751 curr_time->pwr_mech = Overload_Limit_Value;
03752
03753
03754 curr_time->torque_mech = Overload_Limit_Value / Rated_VA + gov_ggv1_Dm*(curr_time->omega/omega_ref - gen_base_set_vals.wref);
03755 }
03756 }
03757 else
03758 {
03759 curr_time->pwr_mech = Rated_VA*curr_time->gov_ggov1.x5;
03760
03761
03762 if (curr_time->pwr_mech > Overload_Limit_Value)
03763 {
03764
03765 curr_time->pwr_mech = Overload_Limit_Value;
03766
03767
03768 curr_time->gov_ggov1.x5 = Overload_Limit_Value / Rated_VA;
03769 }
03770 }
03771
03772 curr_time->torque_mech = curr_time->pwr_mech / curr_time->omega;
03773
03774
03775 if (gov_ggv1_Dm < 0.0)
03776 {
03777 curr_time->gov_ggov1.x10a = curr_time->gov_ggov1.FuelFlow * pow((curr_time->omega/omega_ref),gov_ggv1_Dm);
03778 }
03779 else
03780 {
03781 curr_time->gov_ggov1.x10a = curr_time->gov_ggov1.FuelFlow;
03782 }
03783 curr_delta->gov_ggov1.x10b = 1.0/gov_ggv1_Tsb*(curr_time->gov_ggov1.x10a - curr_time->gov_ggov1.x10b);
03784 curr_time->gov_ggov1.x10 = (1.0 - gov_ggv1_Tsa/gov_ggv1_Tsb)*curr_time->gov_ggov1.x10b + gov_ggv1_Tsa/gov_ggv1_Tsb*curr_time->gov_ggov1.x10a;
03785
03786
03787 curr_delta->gov_ggov1.x6 = 1.0/gov_ggv1_Tfload*(curr_time->gov_ggov1.x10 - curr_time->gov_ggov1.x6);
03788
03789
03790 curr_time->gov_ggov1.err7 = curr_time->gov_ggov1.GovOutPut - curr_time->gov_ggov1.x7;
03791 if (gov_ggv1_Kpload > 0.0)
03792 {
03793 curr_time->gov_ggov1.x7a = gov_ggv1_Kiload/gov_ggv1_Kpload*curr_time->gov_ggov1.err7;
03794 }
03795 else
03796 {
03797 curr_time->gov_ggov1.x7a = gov_ggv1_Kiload*curr_time->gov_ggov1.err7;
03798 }
03799 curr_delta->gov_ggov1.x7 = curr_time->gov_ggov1.x7a;
03800 curr_time->gov_ggov1.fsrtNoLim = curr_time->gov_ggov1.x7 + gov_ggv1_Kpload*(-1.0 * curr_time->gov_ggov1.x6 + gov_ggv1_Ldref*(gov_ggv1_Ldref/gov_ggv1_Kturb+gov_ggv1_wfnl));
03801 if (curr_time->gov_ggov1.fsrtNoLim > 1.0)
03802 {
03803 curr_time->gov_ggov1.fsrt = 1.0;
03804 }
03805 else
03806 {
03807 curr_time->gov_ggov1.fsrt = curr_time->gov_ggov1.fsrtNoLim;
03808 }
03809
03810
03811 curr_delta->gov_ggov1.x9a = 1.0/gov_ggv1_Ta*((curr_time->omega/omega_ref - gen_base_set_vals.wref) - curr_time->gov_ggov1.x9a);
03812 curr_time->gov_ggov1.x9 = 1.0/gov_ggv1_Ta*((curr_time->omega/omega_ref - gen_base_set_vals.wref) - curr_time->gov_ggov1.x9a);
03813 curr_time->gov_ggov1.fsra = gov_ggv1_Ka*deltaT*(gov_ggv1_aset - curr_time->gov_ggov1.x9) + curr_time->gov_ggov1.GovOutPut;
03814
03815
03816 if (gov_ggv1_fsrt_enable == false)
03817 {
03818 curr_time->gov_ggov1.fsrt = 99999999.0;
03819 }
03820
03821 if (gov_ggv1_fsra_enable == false)
03822 {
03823 curr_time->gov_ggov1.fsra = 99999999.0;
03824 }
03825
03826 if (gov_ggv1_fsrn_enable == false)
03827 {
03828 curr_time->gov_ggov1.fsrn = 99999999.0;
03829 }
03830
03831
03832 if (curr_time->gov_ggov1.fsrt < curr_time->gov_ggov1.fsrn)
03833 {
03834 curr_time->gov_ggov1.LowValSelect1 = curr_time->gov_ggov1.fsrt;
03835 }
03836 else
03837 {
03838 curr_time->gov_ggov1.LowValSelect1 = curr_time->gov_ggov1.fsrn;
03839 }
03840
03841 if (curr_time->gov_ggov1.fsra < curr_time->gov_ggov1.LowValSelect1)
03842 {
03843 curr_time->gov_ggov1.LowValSelect = curr_time->gov_ggov1.fsra;
03844 }
03845 else
03846 {
03847 curr_time->gov_ggov1.LowValSelect = curr_time->gov_ggov1.LowValSelect1;
03848 }
03849
03850 if (curr_time->gov_ggov1.LowValSelect > gov_ggv1_vmax)
03851 {
03852 curr_time->gov_ggov1.GovOutPut = gov_ggv1_vmax;
03853 }
03854 else if (curr_time->gov_ggov1.LowValSelect < gov_ggv1_vmin)
03855 {
03856 curr_time->gov_ggov1.GovOutPut = gov_ggv1_vmin;
03857 }
03858 else
03859 {
03860 curr_time->gov_ggov1.GovOutPut = curr_time->gov_ggov1.LowValSelect;
03861 }
03862 }
03863
03864
03865
03866 if (Exciter_type == SEXS)
03867 {
03868 if (Q_constant_mode == true) {
03869
03870
03871 temp_double_1 = curr_time->pwr_electric.Im() / Rated_VA;
03872
03873
03874 temp_double_2 = gen_base_set_vals.Qref - temp_double_1;
03875 }
03876 else {
03877
03878
03879
03880
03881
03882
03883
03884
03885 if (CVRenabled) {
03886
03887 curr_delta->avr.diff_f = (omega_pu - 1.0);
03888
03889
03890 if (CVRmode == HighOrder) {
03891 if (Kd1 != 0) {
03892 curr_delta->avr.x_cvr1 = curr_time->avr.x_cvr1 * (-Kd2/Kd1) + curr_time->avr.x_cvr2 * (-Kd3/Kd1) + curr_delta->avr.diff_f;
03893 curr_delta->avr.x_cvr2 = curr_time->avr.x_cvr1;
03894 }
03895 else {
03896 curr_delta->avr.x_cvr1 = curr_time->avr.x_cvr1 * (-Kd3/Kd2) + curr_delta->avr.diff_f;
03897 }
03898 }
03899
03900
03901 else if (CVRmode == Feedback) {
03902 temp_double_1 = curr_delta->avr.diff_f * ki_cvr + (gen_base_set_vals.vadd - gen_base_set_vals.vadd_a) * kw_cvr;
03903 curr_delta->avr.x_cvr1 = (temp_double_1 - curr_time->avr.x_cvr1 * Kd1)/Kd2;
03904 }
03905 }
03906
03907
03908 temp_double_1 = (value_Circuit_V[0].Mag() + value_Circuit_V[1].Mag() + value_Circuit_V[2].Mag())/voltage_base/3.0;
03909
03910
03911 temp_double_2 = gen_base_set_vals.vset - temp_double_1;
03912 }
03913
03914
03915 curr_delta->avr.xb = (temp_double_2 + curr_time->avr.bias - curr_time->avr.xb)/exc_TB;
03916
03917
03918 temp_double_1 = curr_time->avr.xb + exc_TC*curr_delta->avr.xb;
03919
03920
03921 curr_delta->avr.xe = (exc_KA*temp_double_1 - curr_time->avr.xe)/exc_TA;
03922
03923
03924 if (((curr_time->avr.xe>=exc_EMAX) && (curr_delta->avr.xe>0)) || ((curr_time->avr.xe<=exc_EMIN) && (curr_delta->avr.xe<0)))
03925 {
03926 curr_delta->avr.xe = 0.0;
03927 }
03928
03929
03930 if (curr_time->avr.xe >= exc_EMAX)
03931 curr_time->avr.xe = exc_EMAX;
03932
03933 if (curr_time->avr.xe <= exc_EMIN)
03934 curr_time->avr.xe = exc_EMIN;
03935
03936 if (Q_constant_mode == true) {
03937
03938 curr_delta->avr.xfd = curr_time->avr.xe*ki_Qconstant;
03939 }
03940 else {
03941
03942
03943 curr_time->Vfd = curr_time->avr.xe;
03944
03945
03946
03947
03948
03949
03950
03951
03952
03953
03954
03955
03956
03957
03958
03959
03960
03961
03962
03963
03964
03965
03966
03967
03968
03969 }
03970
03971 }
03972 else
03973 {
03974 curr_delta->avr.xb = 0.0;
03975 curr_delta->avr.xe = 0.0;
03976 }
03977
03978 return SUCCESS;
03979 }
03980
03981
03982
03983
03984 STATUS diesel_dg::init_dynamics(MAC_STATES *curr_time)
03985 {
03986 complex voltage_pu[3];
03987 complex current_pu[3];
03988 complex Vpn0[3];
03989 complex Ipn0[3];
03990 complex temp_complex_1, temp_complex_2;
03991 double omega_pu;
03992 double temp_double_1, temp_double_2, temp_double_3;
03993 unsigned int index_val;
03994
03995
03996 voltage_pu[0] = value_Circuit_V[0]/voltage_base;
03997 voltage_pu[1] = value_Circuit_V[1]/voltage_base;
03998 voltage_pu[2] = value_Circuit_V[2]/voltage_base;
03999
04000
04001 current_pu[0] = (value_IGenerated[0] - generator_admittance[0][0]*value_Circuit_V[0] - generator_admittance[0][1]*value_Circuit_V[1] - generator_admittance[0][2]*value_Circuit_V[2])/current_base;
04002 current_pu[1] = (value_IGenerated[1] - generator_admittance[1][0]*value_Circuit_V[0] - generator_admittance[1][1]*value_Circuit_V[1] - generator_admittance[1][2]*value_Circuit_V[2])/current_base;
04003 current_pu[2] = (value_IGenerated[2] - generator_admittance[2][0]*value_Circuit_V[0] - generator_admittance[2][1]*value_Circuit_V[1] - generator_admittance[2][2]*value_Circuit_V[2])/current_base;
04004
04005
04006 current_val[0]=current_pu[0]*current_base;
04007 current_val[1]=current_pu[1]*current_base;
04008 current_val[2]=current_pu[2]*current_base;
04009
04010
04011 curr_time->pwr_electric = (voltage_pu[0]*~current_pu[0]+voltage_pu[1]*~current_pu[1]+voltage_pu[2]*~current_pu[2])*voltage_base*current_base;
04012
04013
04014 omega_pu = curr_time->omega/omega_ref;
04015
04016
04017 convert_abc_to_pn0(&voltage_pu[0],&Vpn0[0]);
04018 convert_abc_to_pn0(¤t_pu[0],&Ipn0[0]);
04019
04020
04021 temp_complex_1 = Vpn0[0]+complex(Ra,Xq)*Ipn0[0];
04022 curr_time->rotor_angle = temp_complex_1.Arg();
04023
04024
04025 temp_complex_1 = (Vpn0[0]+complex(Ra,Xdpp)*Ipn0[0])/omega_pu;
04026
04027
04028 temp_complex_2 = complex_exp(-1.0*curr_time->rotor_angle);
04029 curr_time->Irotated = temp_complex_2*complex(0.0,1.0)*Ipn0[0];
04030 curr_time->VintRotated = (temp_complex_2*complex(0.0,1.0)*temp_complex_1);
04031
04032
04033 temp_complex_1 = temp_complex_2*complex(0.0,1.0)*Vpn0[0];
04034
04035
04036 curr_time->EpRotated = temp_complex_1.Re() + Ra*curr_time->Irotated.Re() - Xqp*curr_time->Irotated.Im();
04037 curr_time->EpRotated += complex(0.0,1.0)*(temp_complex_1.Im() + Ra*curr_time->Irotated.Im() + Xdp*curr_time->Irotated.Re());
04038
04039
04040 curr_time->Flux1d = curr_time->EpRotated.Im() - (Xdp-Xl)*curr_time->Irotated.Re();
04041 curr_time->Flux2q = -curr_time->EpRotated.Re() - (Xqp-Xl)*curr_time->Irotated.Im();
04042
04043
04044 temp_double_1 = -curr_time->EpRotated.Im();
04045 temp_double_2 = curr_time->Irotated.Re();
04046 temp_double_3 = curr_time->Flux1d + (Xdp-Xl)*curr_time->Irotated.Re() - curr_time->EpRotated.Im();
04047 temp_double_3 /= (Xdp-Xl);
04048 temp_double_3 /= (Xdp-Xl);
04049 temp_double_2 -= (Xdp-Xdpp)*temp_double_3;
04050 temp_double_1 -= (Xd-Xdp)*temp_double_2;
04051
04052
04053 curr_time->Vfd = -1.0*temp_double_1;
04054 curr_time->avr.xfd = curr_time->Vfd;
04055
04056
04057 temp_double_1 = -(Xqpp-Xl)/(Xqp-Xl)*curr_time->EpRotated.Re()*curr_time->Irotated.Re();
04058 temp_double_1 -= (Xdpp-Xl)/(Xdp-Xl)*curr_time->EpRotated.Im()*curr_time->Irotated.Im();
04059 temp_double_1 -= (Xdp-Xdpp)/(Xdp-Xl)*curr_time->Flux1d*curr_time->Irotated.Im();
04060 temp_double_1 += (Xqp-Xqpp)/(Xqp-Xl)*curr_time->Flux2q*curr_time->Irotated.Re();
04061 temp_double_1 -= (Xqpp-Xdpp)*curr_time->Irotated.Re()*curr_time->Irotated.Im();
04062 temp_double_1 -= 0.5*Rr*Ipn0[1].Mag()*Ipn0[1].Mag();
04063 curr_time->torque_elec = -1.0*temp_double_1*Rated_VA/omega_ref;
04064 temp_double_1 -= damping*(curr_time->omega-omega_ref)/omega_ref;
04065
04066
04067 curr_time->torque_mech = -1.0*temp_double_1*Rated_VA/omega_ref;
04068 curr_time->pwr_mech = curr_time->torque_mech*curr_time->omega;
04069
04070
04071 if (curr_time->pwr_mech > Overload_Limit_Value)
04072 {
04073
04074 curr_time->pwr_mech = Overload_Limit_Value;
04075
04076
04077 curr_time->torque_mech = Overload_Limit_Value / curr_time->omega;
04078 }
04079
04080
04081 if (Governor_type == DEGOV1)
04082 {
04083 curr_time->gov_degov1.x1 = 0;
04084 curr_time->gov_degov1.x2 = 0;
04085 curr_time->gov_degov1.x5 = 0;
04086 curr_time->gov_degov1.x6 = 0;
04087 curr_time->gov_degov1.x4 = curr_time->torque_mech/(Rated_VA/omega_ref);
04088 curr_time->gov_degov1.throttle = curr_time->gov_degov1.x4;
04089
04090 if (gen_base_set_vals.wref < -90.0)
04091 {
04092 gen_base_set_vals.wref = curr_time->gov_degov1.throttle*gov_degov1_R+curr_time->omega/omega_ref;
04093 }
04094
04095
04096
04097 for (index_val=0; index_val<torque_delay_len; index_val++)
04098 {
04099 torque_delay[index_val] = curr_time->gov_degov1.throttle;
04100 }
04101 }
04102 else if (Governor_type == GAST)
04103 {
04104 curr_time->gov_gast.x1 = curr_time->torque_mech/(Rated_VA/omega_ref);
04105 curr_time->gov_gast.x2 = curr_time->torque_mech/(Rated_VA/omega_ref);
04106 curr_time->gov_gast.x3 = curr_time->torque_mech/(Rated_VA/omega_ref);
04107 curr_time->gov_gast.throttle = curr_time->torque_mech/(Rated_VA/omega_ref);
04108 }
04109 else if (Governor_type == P_CONSTANT)
04110 {
04111
04112 if (gen_base_set_vals.wref < -90.0)
04113 {
04114 gen_base_set_vals.wref = curr_time->omega/omega_ref;
04115 }
04116
04117
04118 curr_time->gov_pconstant.x5 = curr_time->pwr_mech / Rated_VA;
04119
04120
04121 curr_time->torque_mech = curr_time->pwr_mech / curr_time->omega;
04122
04123 curr_time->gov_pconstant.x5b = curr_time->gov_pconstant.x5;
04124 curr_time->gov_pconstant.x5a = curr_time->gov_pconstant.x5b;
04125 curr_time->gov_pconstant.FuelFlow = curr_time->gov_pconstant.x5/gov_ggv1_Kturb + gov_ggv1_wfnl;
04126
04127 pconstant_Flag = 0;
04128
04129 if (pconstant_Flag == 0)
04130 {
04131 curr_time->gov_pconstant.ValveStroke = curr_time->gov_pconstant.FuelFlow;
04132 }
04133 else if (pconstant_Flag == 1)
04134 {
04135 curr_time->gov_pconstant.ValveStroke = curr_time->gov_pconstant.FuelFlow/(curr_time->omega/omega_ref);
04136 }
04137 else
04138 {
04139
04140 gl_error("wrong pconstant_Flag");
04141 return FAILED;
04142 }
04143
04144 curr_time->gov_pconstant.x4 = curr_time->gov_pconstant.ValveStroke;
04145 curr_time->gov_pconstant.GovOutPut = curr_time->gov_pconstant.ValveStroke;
04146 curr_time->gov_pconstant.x1 = curr_time->pwr_electric.Re() / Rated_VA;
04147 curr_time->gov_pconstant.x_Pconstant = curr_time->gov_pconstant.GovOutPut;
04148
04149 }
04150 else if ((Governor_type == GGOV1) || (Governor_type == GGOV1_OLD))
04151 {
04152 if (gen_base_set_vals.wref < -90.0)
04153 {
04154 gen_base_set_vals.wref = curr_time->omega/omega_ref;
04155 }
04156
04157
04158 if (gov_ggv1_Dm > 0.0)
04159 {
04160 curr_time->gov_ggov1.x5 = curr_time->pwr_mech/Rated_VA + gov_ggv1_Dm*(curr_time->omega/omega_ref - gen_base_set_vals.wref);
04161 }
04162 else
04163 {
04164 curr_time->gov_ggov1.x5 = curr_time->pwr_mech / Rated_VA;
04165 }
04166
04167 curr_time->torque_mech = curr_time->pwr_mech / curr_time->omega;
04168
04169 curr_time->gov_ggov1.x5b = curr_time->gov_ggov1.x5;
04170 curr_time->gov_ggov1.x5a = curr_time->gov_ggov1.x5b;
04171 curr_time->gov_ggov1.FuelFlow = curr_time->gov_ggov1.x5/gov_ggv1_Kturb + gov_ggv1_wfnl;
04172
04173 if (gov_ggv1_Flag == 0)
04174 {
04175 curr_time->gov_ggov1.ValveStroke = curr_time->gov_ggov1.FuelFlow;
04176 }
04177 else if (gov_ggv1_Flag == 1)
04178 {
04179 curr_time->gov_ggov1.ValveStroke = curr_time->gov_ggov1.FuelFlow/(curr_time->omega/omega_ref);
04180 }
04181 else
04182 {
04183
04184 gl_error("wrong ggv1_Flag");
04185 return FAILED;
04186 }
04187
04188 curr_time->gov_ggov1.x4 = curr_time->gov_ggov1.ValveStroke;
04189 curr_time->gov_ggov1.GovOutPut = curr_time->gov_ggov1.ValveStroke;
04190 curr_time->gov_ggov1.x3 = curr_time->gov_ggov1.GovOutPut;
04191 curr_time->gov_ggov1.x7 = curr_time->gov_ggov1.GovOutPut;
04192 curr_time->gov_ggov1.fsrn = curr_time->gov_ggov1.GovOutPut;
04193 curr_time->gov_ggov1.fsra = curr_time->gov_ggov1.GovOutPut;
04194 curr_time->gov_ggov1.x1 = curr_time->pwr_electric.Re() / Rated_VA;
04195
04196 if (gov_ggv1_rselect == 1)
04197 {
04198 curr_time->gov_ggov1.RselectValue = curr_time->gov_ggov1.x1;
04199 }
04200 else if (gov_ggv1_rselect == -1)
04201 {
04202 curr_time->gov_ggov1.RselectValue = curr_time->gov_ggov1.ValveStroke;
04203 }
04204 else if (gov_ggv1_rselect == -2)
04205 {
04206 curr_time->gov_ggov1.RselectValue = curr_time->gov_ggov1.GovOutPut;
04207 }
04208 else if (gov_ggv1_rselect == 0)
04209 {
04210 curr_time->gov_ggov1.RselectValue = 0.0;
04211 }
04212 else
04213 {
04214 gl_error("wrong ggv1_rselect parameter");
04215 return FAILED;
04216 }
04217
04218 if (gov_ggv1_Pmwset < 0 || gov_ggv1_rselect != 1)
04219
04220 {
04221 gov_ggv1_Pmwset = Rated_VA*curr_time->gov_ggov1.x1;
04222 }
04223
04224
04225 curr_time->gov_ggov1.x8a = 0.0;
04226 curr_time->gov_ggov1.x8 = curr_time->gov_ggov1.x8a;
04227 curr_time->gov_ggov1.err2a = 0.0;
04228 curr_time->gov_ggov1.werror = curr_time->omega/omega_ref - gen_base_set_vals.wref;
04229
04230 if (gen_base_set_vals.Pref < -90.0)
04231 {
04232 gen_base_set_vals.Pref = curr_time->gov_ggov1.err2a - curr_time->gov_ggov1.x8 + curr_time->gov_ggov1.werror + gov_ggv1_r*curr_time->gov_ggov1.RselectValue;
04233 }
04234
04235
04236 if (curr_time->gov_ggov1.err2a > gov_ggv1_maxerr)
04237 {
04238 curr_time->gov_ggov1.err2 = gov_ggv1_maxerr;
04239 }
04240 else if (curr_time->gov_ggov1.err2a < gov_ggv1_minerr)
04241 {
04242 curr_time->gov_ggov1.err2 = gov_ggv1_minerr;
04243 }
04244 else if ((curr_time->gov_ggov1.err2a <= gov_ggv1_db) && (curr_time->gov_ggov1.err2a >= -gov_ggv1_db))
04245 {
04246 curr_time->gov_ggov1.err2 = 0.0;
04247 }
04248 else
04249 {
04250 if (curr_time->gov_ggov1.err2a > 0)
04251 {
04252 curr_time->gov_ggov1.err2 = (gov_ggv1_maxerr/(gov_ggv1_maxerr - gov_ggv1_db))*curr_time->gov_ggov1.err2a - (gov_ggv1_maxerr*gov_ggv1_db/(gov_ggv1_maxerr-gov_ggv1_db));
04253 }
04254 else if (curr_time->gov_ggov1.err2a < 0)
04255 {
04256 curr_time->gov_ggov1.err2 = (gov_ggv1_minerr/(gov_ggv1_minerr + gov_ggv1_db))*curr_time->gov_ggov1.err2a + (gov_ggv1_minerr*gov_ggv1_db/(gov_ggv1_minerr+gov_ggv1_db));
04257 }
04258
04259 }
04260
04261 curr_time->gov_ggov1.x2a = curr_time->gov_ggov1.err2;
04262 curr_time->gov_ggov1.x2 = gov_ggv1_Kpgov/gov_ggv1_Tdgov*(curr_time->gov_ggov1.err2 - curr_time->gov_ggov1.x2a);
04263 curr_time->gov_ggov1.x7 = curr_time->gov_ggov1.GovOutPut;
04264
04265 if (gov_ggv1_Dm < 0.0)
04266 {
04267 curr_time->gov_ggov1.x10a = curr_time->gov_ggov1.FuelFlow * pow((curr_time->omega/omega_ref),gov_ggv1_Dm);
04268 }
04269 else
04270 {
04271 curr_time->gov_ggov1.x10a = curr_time->gov_ggov1.FuelFlow;
04272 }
04273 curr_time->gov_ggov1.x10b = curr_time->gov_ggov1.x10a;
04274 curr_time->gov_ggov1.x10 = (1.0 - gov_ggv1_Tsa/gov_ggv1_Tsb)*curr_time->gov_ggov1.x10b + gov_ggv1_Tsa/gov_ggv1_Tsb*curr_time->gov_ggov1.x10a;
04275 curr_time->gov_ggov1.x6 = curr_time->gov_ggov1.x10;
04276
04277 curr_time->gov_ggov1.x7 = curr_time->gov_ggov1.GovOutPut;
04278 curr_time->gov_ggov1.err7 = 0.0;
04279 if (gov_ggv1_Kpload > 0.0)
04280 {
04281 curr_time->gov_ggov1.x7a = gov_ggv1_Kiload / gov_ggv1_Kpload * curr_time->gov_ggov1.err7;
04282 }
04283 else
04284 {
04285 curr_time->gov_ggov1.x7a = gov_ggv1_Kiload * curr_time->gov_ggov1.err7;
04286 }
04287
04288 curr_time->gov_ggov1.x9a = curr_time->omega/omega_ref - gen_base_set_vals.wref;
04289 curr_time->gov_ggov1.x9 = 1.0 / gov_ggv1_Ta * ((curr_time->omega/omega_ref - gen_base_set_vals.wref) - curr_time->gov_ggov1.x9a);
04290
04291 }
04292
04293
04294
04295 if (Exciter_type == SEXS)
04296 {
04297 curr_time->avr.xe = curr_time->Vfd;
04298 curr_time->avr.xb = curr_time->avr.xe/exc_KA;
04299
04300 if (Vset_defined == false)
04301 {
04302
04303 gen_base_set_vals.vset = (voltage_pu[0].Mag() + voltage_pu[1].Mag() + voltage_pu[2].Mag())/3.0;
04304 Vref = gen_base_set_vals.vset;
04305 }
04306
04307 gen_base_set_vals.vseta = gen_base_set_vals.vset;
04308 gen_base_set_vals.vsetb = gen_base_set_vals.vset;
04309
04310
04311
04313
04314
04315
04316
04317 if (CVRenabled == true) {
04318 curr_time->avr.x_cvr1 = 0;
04319 curr_time->avr.x_cvr2 = 0;
04320 gen_base_set_vals.vadd = 0;
04321 gen_base_set_vals.vadd_a = 0;
04322 }
04323
04324
04325
04326 if (Q_constant_mode == true) {
04327 curr_time->avr.bias = 0;
04328 }
04329
04330 else {
04331 curr_time->avr.bias = curr_time->avr.xb;
04332 }
04333 }
04334
04335
04336 return SUCCESS;
04337 }
04338
04339
04340
04341 complex diesel_dg::complex_exp(double angle)
04342 {
04343 complex output_val;
04344
04345
04346 output_val = complex(cos(angle),sin(angle));
04347
04348 return output_val;
04349 }
04350
04351
04352 double diesel_dg::abs_complex(complex val)
04353 {
04354 double res;
04355 res = sqrt(val.Re() * val.Re() + val.Im() * val.Im());
04356
04357 return res;
04358 }
04359
04361
04363
04364 EXPORT int create_diesel_dg(OBJECT **obj, OBJECT *parent)
04365 {
04366 try
04367 {
04368 *obj = gl_create_object(diesel_dg::oclass);
04369 if (*obj!=NULL)
04370 {
04371 diesel_dg *my = OBJECTDATA(*obj,diesel_dg);
04372 gl_set_parent(*obj,parent);
04373 return my->create();
04374 }
04375 else
04376 return 0;
04377 }
04378 CREATE_CATCHALL(diesel_dg);
04379 }
04380
04381 EXPORT int init_diesel_dg(OBJECT *obj, OBJECT *parent)
04382 {
04383 try
04384 {
04385 if (obj!=NULL)
04386 return OBJECTDATA(obj,diesel_dg)->init(parent);
04387 else
04388 return 0;
04389 }
04390 INIT_CATCHALL(diesel_dg);
04391 }
04392
04393 EXPORT TIMESTAMP sync_diesel_dg(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
04394 {
04395 TIMESTAMP t1 = TS_INVALID;
04396 diesel_dg *my = OBJECTDATA(obj,diesel_dg);
04397 try
04398 {
04399 switch (pass) {
04400 case PC_PRETOPDOWN:
04401 t1 = my->presync(obj->clock,t0);
04402 break;
04403 case PC_BOTTOMUP:
04404 t1 = my->sync(obj->clock,t0);
04405 break;
04406 case PC_POSTTOPDOWN:
04407 t1 = my->postsync(obj->clock,t0);
04408 break;
04409 default:
04410 GL_THROW("invalid pass request (%d)", pass);
04411 break;
04412 }
04413 if (pass==clockpass)
04414 obj->clock = t1;
04415 }
04416 SYNC_CATCHALL(diesel_dg);
04417 return t1;
04418 }
04419
04420
04421
04422
04423
04424
04425
04426
04427
04428
04429
04430
04431
04432
04433
04434
04435
04436
04437
04438
04439 EXPORT SIMULATIONMODE interupdate_diesel_dg(OBJECT *obj, unsigned int64 delta_time, unsigned long dt, unsigned int iteration_count_val)
04440 {
04441 diesel_dg *my = OBJECTDATA(obj,diesel_dg);
04442 SIMULATIONMODE status = SM_ERROR;
04443 try
04444 {
04445 status = my->inter_deltaupdate(delta_time,dt,iteration_count_val);
04446 return status;
04447 }
04448 catch (char *msg)
04449 {
04450 gl_error("interupdate_diesel_dg(obj=%d;%s): %s", obj->id, obj->name?obj->name:"unnamed", msg);
04451 return status;
04452 }
04453 }
04454
04455 EXPORT STATUS postupdate_diesel_dg(OBJECT *obj, complex *useful_value, unsigned int mode_pass)
04456 {
04457 diesel_dg *my = OBJECTDATA(obj,diesel_dg);
04458 STATUS status = FAILED;
04459 try
04460 {
04461 status = my->post_deltaupdate(useful_value, mode_pass);
04462 return status;
04463 }
04464 catch (char *msg)
04465 {
04466 gl_error("postupdate_diesel_dg(obj=%d;%s): %s", obj->id, obj->name?obj->name:"unnamed", msg);
04467 return status;
04468 }
04469 }