00001
00002
00003
00004 #include <stdlib.h>
00005 #include <stdio.h>
00006 #include <errno.h>
00007 #include <math.h>
00008 #include "gridlabd.h"
00009
00010 #define _GENERATORS_GLOBALS
00011 #include "generators.h"
00012 #undef _GENERATORS_GLOBALS
00013
00014
00015 #include "diesel_dg.h"
00016 #include "windturb_dg.h"
00017 #include "battery.h"
00018 #include "inverter.h"
00019 #include "rectifier.h"
00020 #include "solar.h"
00021 #include "central_dg_control.h"
00022 #include "controller_dg.h"
00023
00024
00025 EXPORT CLASS *init(CALLBACKS *fntable, MODULE *module, int argc, char *argv[])
00026 {
00027 if (set_callback(fntable)==NULL)
00028 {
00029 errno = EINVAL;
00030 return NULL;
00031 }
00032
00033
00034 gl_global_create("generators::default_line_voltage",PT_double,&default_line_voltage,PT_UNITS,"V",PT_DESCRIPTION,"line voltage (L-N) to use when no circuit is attached",NULL);
00035 gl_global_create("generators::enable_subsecond_models", PT_bool, &enable_subsecond_models,PT_DESCRIPTION,"Enable deltamode capabilities within the generators module",NULL);
00036 gl_global_create("generators::deltamode_timestep", PT_double, &deltamode_timestep_publish,PT_UNITS,"ns",PT_DESCRIPTION,"Desired minimum timestep for deltamode-related simulations",NULL);
00037 gl_global_create("generators::default_temperature_value", PT_double, &default_temperature_value,PT_UNITS,"degF",PT_DESCRIPTION,"Temperature when no climate module is detected",NULL);
00038
00039
00040 new diesel_dg(module);
00041 new windturb_dg(module);
00042 new energy_storage(module);
00043 new inverter(module);
00044 new rectifier(module);
00045 new battery(module);
00046 new solar(module);
00047 new central_dg_control(module);
00048 new controller_dg(module);
00049
00050
00051 return diesel_dg::oclass;
00052 }
00053
00054
00055 void schedule_deltamode_start(TIMESTAMP tstart)
00056 {
00057 if (enable_subsecond_models == true)
00058 {
00059 if ( (tstart<deltamode_starttime) && ((tstart-gl_globalclock)<0x7fffffff ))
00060 deltamode_starttime = tstart;
00061 }
00062 else
00063 {
00064 GL_THROW("generators: a call was made to deltamode functions, but subsecond models are not enabled!");
00065
00066
00067
00068
00069
00070
00071 }
00072 }
00073
00074
00075
00076 void allocate_deltamode_arrays(void)
00077 {
00078 int obj_idx;
00079
00080 if ((gen_object_current == -1) || (delta_objects==NULL))
00081 {
00082
00083 delta_objects = (OBJECT**)gl_malloc(gen_object_count*sizeof(OBJECT*));
00084
00085
00086 if (delta_objects == NULL)
00087 {
00088 GL_THROW("Failed to allocate deltamode objects array for generators module!");
00089
00090
00091
00092
00093
00094 }
00095
00096
00097 delta_functions = (FUNCTIONADDR*)gl_malloc(gen_object_count*sizeof(FUNCTIONADDR));
00098
00099
00100 if (delta_functions == NULL)
00101 {
00102 GL_THROW("Failed to allocate deltamode objects function array for generators module!");
00103
00104
00105
00106
00107
00108 }
00109
00110
00111 post_delta_functions = (FUNCTIONADDR*)gl_malloc(gen_object_count*sizeof(FUNCTIONADDR));
00112
00113
00114 if (post_delta_functions == NULL)
00115 {
00116 GL_THROW("Failed to allocate deltamode objects function array for generators module!");
00117
00118 }
00119
00120
00121 delta_preupdate_functions = (FUNCTIONADDR*)gl_malloc(gen_object_count*sizeof(FUNCTIONADDR));
00122
00123
00124 if (delta_preupdate_functions == NULL)
00125 {
00126 GL_THROW("Failed to allocate deltamode objects function array for generators module!");
00127
00128 }
00129
00130
00131 for (obj_idx=0; obj_idx<gen_object_count; obj_idx++)
00132 {
00133 delta_objects[obj_idx] = NULL;
00134 delta_functions[obj_idx] = NULL;
00135 post_delta_functions[obj_idx] = NULL;
00136 delta_preupdate_functions[obj_idx] = NULL;
00137 }
00138
00139
00140 gen_object_current = 0;
00141 }
00142
00143 }
00144
00145
00146
00147
00148
00149
00150
00151 EXPORT unsigned long deltamode_desired(int *flags)
00152 {
00153 unsigned long dt_val;
00154
00155 if (enable_subsecond_models == true)
00156 {
00157
00158 if ((deltamode_starttime>=gl_globalclock) && (deltamode_starttime<TS_NEVER))
00159 {
00160
00161 *flags |= DMF_SOFTEVENT;
00162
00163
00164 dt_val = (unsigned long)(deltamode_starttime - gl_globalclock);
00165
00166 gl_debug("generators: deltamode desired in %d", dt_val);
00167 return dt_val;
00168 }
00169 else
00170 {
00171
00172 return DT_INFINITY;
00173 }
00174 }
00175 else
00176 {
00177 return DT_INFINITY;
00178 }
00179 }
00180
00181
00182
00183
00184
00185 EXPORT unsigned long preupdate(MODULE *module, TIMESTAMP t0, unsigned int64 dt)
00186 {
00187 int curr_object_number;
00188 STATUS status_value;
00189
00190 if (enable_subsecond_models == true)
00191 {
00192 if (deltamode_timestep_publish<=0.0)
00193 {
00194 gl_error("generators::deltamode_timestep must be a positive, non-zero number!");
00195
00196
00197
00198
00199
00200 return DT_INVALID;
00201 }
00202 else
00203 {
00204
00205 deltamode_timestep = (unsigned long)(deltamode_timestep_publish+0.5);
00206
00207
00208
00209 for (curr_object_number=0; curr_object_number<gen_object_count; curr_object_number++)
00210 {
00211
00212 if (delta_preupdate_functions[curr_object_number] != NULL)
00213 {
00214
00215 status_value = ((STATUS (*)(OBJECT *, TIMESTAMP, unsigned int64))(*delta_preupdate_functions[curr_object_number]))(delta_objects[curr_object_number],t0,dt);
00216
00217
00218 if (status_value != SUCCESS)
00219 {
00220 GL_THROW("generators - object:%d %s failed to run the object-level preupdate function",delta_objects[curr_object_number]->id,(delta_objects[curr_object_number]->name ? delta_objects[curr_object_number]->name : "Unnamed"));
00221
00222
00223
00224
00225 }
00226
00227 }
00228
00229 }
00230
00231
00232 return deltamode_timestep;
00233 }
00234 }
00235 else
00236 {
00237 return DT_INFINITY;
00238 }
00239 }
00240
00241
00242
00243
00244
00245 EXPORT SIMULATIONMODE interupdate(MODULE *module, TIMESTAMP t0, unsigned int64 delta_time, unsigned long dt, unsigned int iteration_count_val)
00246 {
00247 int curr_object_number;
00248 SIMULATIONMODE function_status = SM_EVENT;
00249 bool event_driven = true;
00250 bool delta_iter = false;
00251
00252 if (enable_subsecond_models == true)
00253 {
00254
00255 if (deltatimestep_running < 0.0)
00256 {
00257
00258 deltatimestep_running = (double)((double)dt/(double)DT_SECOND);
00259 }
00260
00261
00262
00263 for (curr_object_number=0; curr_object_number<gen_object_count; curr_object_number++)
00264 {
00265
00266 if ((delta_objects[curr_object_number]->in_svc_double <= gl_globaldeltaclock) && (delta_objects[curr_object_number]->out_svc_double >= gl_globaldeltaclock))
00267 {
00268
00269 function_status = ((SIMULATIONMODE (*)(OBJECT *, unsigned int64, unsigned long, unsigned int))(*delta_functions[curr_object_number]))(delta_objects[curr_object_number],delta_time,dt,iteration_count_val);
00270 }
00271 else
00272 function_status = SM_EVENT;
00273
00274
00275 if (function_status == SM_DELTA)
00276 {
00277 gl_verbose("Generator object:%d - %s - requested deltamode to continue",delta_objects[curr_object_number]->id,(delta_objects[curr_object_number]->name ? delta_objects[curr_object_number]->name : "Unnamed"));
00278
00279 event_driven = false;
00280 }
00281 else if (function_status == SM_DELTA_ITER)
00282 {
00283 gl_verbose("Generator object:%d - %s - requested a deltamode reiteration",delta_objects[curr_object_number]->id,(delta_objects[curr_object_number]->name ? delta_objects[curr_object_number]->name : "Unnamed"));
00284
00285 event_driven = false;
00286 delta_iter = true;
00287 }
00288 else if (function_status == SM_ERROR)
00289 {
00290 gl_error("Generator object:%s - deltamode function returned an error!",delta_objects[curr_object_number]->name);
00291
00292
00293
00294
00295 return SM_ERROR;
00296 }
00297
00298 }
00299
00300
00301 if (event_driven == false)
00302 {
00303 if (delta_iter == true)
00304 return SM_DELTA_ITER;
00305 else
00306 return SM_DELTA;
00307 }
00308 else
00309 return SM_EVENT;
00310 }
00311 else
00312 {
00313 return SM_EVENT;
00314 }
00315 }
00316
00317
00318
00319
00320 EXPORT STATUS postupdate(MODULE *module, TIMESTAMP t0, unsigned int64 dt)
00321 {
00322 unsigned int64 seconds_advance, temp_time;
00323 int curr_object_number;
00324 STATUS function_status;
00325 complex temp_complex;
00326 double *extracted_freq;
00327
00328 if (enable_subsecond_models == true)
00329 {
00330
00331 deltamode_starttime = TS_NEVER;
00332
00333
00334 deltatimestep_running = -1.0;
00335
00336
00337 seconds_advance = (unsigned int64)(dt/DT_SECOND);
00338
00339
00340 temp_time = dt - ((unsigned int64)(seconds_advance)*DT_SECOND);
00341
00342
00343
00344 deltamode_supersec_endtime = t0 + seconds_advance;
00345
00346
00347 if (temp_time != 0)
00348 seconds_advance++;
00349
00350
00351 deltamode_endtime = t0 + seconds_advance;
00352 deltamode_endtime_dbl = (double)(t0) + ((double)(dt)/double(DT_SECOND));
00353
00354
00355
00356 extracted_freq = (double *)gl_get_module_var(gl_find_module("powerflow"),"current_frequency");
00357
00358
00359 if (extracted_freq == 0)
00360 {
00361 gl_error("Generator deltamode update - failed to link to powerflow frequency");
00362
00363
00364
00365
00366 return FAILED;
00367 }
00368
00369
00370 temp_complex = complex(*extracted_freq*2.0*PI,0.0);
00371
00372
00373 for (curr_object_number=0; curr_object_number<gen_object_count; curr_object_number++)
00374 {
00375
00376 if (post_delta_functions[curr_object_number] != NULL)
00377 {
00378
00379 if ((delta_objects[curr_object_number]->in_svc_double <= gl_globaldeltaclock) && (delta_objects[curr_object_number]->out_svc_double >= gl_globaldeltaclock))
00380 {
00381
00382 function_status = ((STATUS (*)(OBJECT *, complex *, unsigned int))(*post_delta_functions[curr_object_number]))(delta_objects[curr_object_number],&temp_complex,0);
00383 }
00384 else
00385 function_status = SUCCESS;
00386
00387
00388 if (function_status == FAILED)
00389 {
00390 gl_error("Generator object:%s - failed post-deltamode update",delta_objects[curr_object_number]->name);
00391
00392
00393
00394
00395 return FAILED;
00396 }
00397
00398 }
00399
00400 }
00401
00402
00403 return SUCCESS;
00404 }
00405 else
00406 {
00407 return SUCCESS;
00408 }
00409 }
00410
00411 CDECL int do_kill()
00412 {
00413
00414 return 0;
00415 }
00416
00417 EXPORT int check(){
00418 return 0;
00419 }