00001
00009 #include <stdlib.h>
00010 #include <stdio.h>
00011 #include <errno.h>
00012 #include <math.h>
00013
00014 #define _RESIDENTIAL_CPP
00015 #include "residential.h"
00016 #undef _RESIDENTIAL_CPP
00017
00018
00019 #include "appliance.h"
00020 #include "clotheswasher.h"
00021 #include "dishwasher.h"
00022 #include "lights.h"
00023 #include "microwave.h"
00024 #include "occupantload.h"
00025 #include "plugload.h"
00026 #include "range.h"
00027 #include "refrigerator.h"
00028 #include "waterheater.h"
00029 #include "freezer.h"
00030 #include "dryer.h"
00031 #include "evcharger.h"
00032 #include "zipload.h"
00033 #include "thermal_storage.h"
00034 #include "evcharger_det.h"
00035
00036 #include "residential_enduse.h"
00037 #include "house_e.h"
00038
00039 EXPORT CLASS *init(CALLBACKS *fntable, MODULE *module, int argc, char *argv[])
00040 {
00041 if (set_callback(fntable)==NULL)
00042 {
00043 errno = EINVAL;
00044 return NULL;
00045 }
00046
00047 gl_global_create("residential::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);
00048 gl_global_create("residential::default_outdoor_temperature",PT_double,&default_outdoor_temperature,PT_UNITS,"degF",PT_DESCRIPTION,"outdoor air temperature when no climate data is found",NULL);
00049 gl_global_create("residential::default_humidity",PT_double,&default_humidity,PT_UNITS,"%",PT_DESCRIPTION,"humidity when no climate data is found",NULL);
00050 gl_global_create("residential::default_horizontal_solar",PT_double,&default_horizontal_solar,PT_UNITS,"Btu/sf",PT_DESCRIPTION,"horizontal solar gains when no climate data is found",NULL);
00051 gl_global_create("residential::default_etp_iterations",PT_int64,&default_etp_iterations,PT_DESCRIPTION,"number of iterations ETP solver will run",NULL);
00052 gl_global_create("residential::default_grid_frequency",PT_double,&default_grid_frequency,PT_UNITS,"Hz",PT_DESCRIPTION,"grid frequency when no powerflow attachment is found",NULL);
00053 gl_global_create("residential::ANSI_voltage_check",PT_bool,&ANSI_voltage_check,PT_DESCRIPTION,"enable or disable messages about ANSI voltage limit violations in the house",NULL);
00054 gl_global_create("residential::enable_subsecond_models", PT_bool, &enable_subsecond_models,PT_DESCRIPTION,"Enable deltamode capabilities within the residential module",NULL);
00055 gl_global_create("residential::deltamode_timestep", PT_double, &deltamode_timestep_publish,PT_UNITS,"ns",PT_DESCRIPTION,"Desired minimum timestep for deltamode-related simulations",NULL);
00056 gl_global_create("residential::all_house_delta", PT_bool, &all_house_delta,PT_DESCRIPTION,"Modeling convenient - enables all houses in deltamode",NULL);
00057
00058 new residential_enduse(module);
00059 new appliance(module);
00060
00061 new house_e(module);
00062 new waterheater(module);
00063 new lights(module);
00064 new refrigerator(module);
00065 new clotheswasher(module);
00066 new dishwasher(module);
00067 new occupantload(module);
00068 new plugload(module);
00069 new microwave(module);
00070 new range(module);
00071 new freezer(module);
00072 new dryer(module);
00073 new evcharger(module);
00074 new ZIPload(module);
00075 new thermal_storage(module);
00076 new evcharger_det(module);
00077
00078
00079 return residential_enduse::oclass;
00080 }
00081
00082
00083 void schedule_deltamode_start(TIMESTAMP tstart)
00084 {
00085 if (enable_subsecond_models == true)
00086 {
00087 if ( (tstart<deltamode_starttime) && ((tstart-gl_globalclock)<0x7fffffff ))
00088 deltamode_starttime = tstart;
00089 }
00090 else
00091 {
00092 GL_THROW("residential: a call was made to deltamode functions, but subsecond models are not enabled!");
00093
00094
00095
00096
00097
00098
00099 }
00100 }
00101
00102
00103
00104 void allocate_deltamode_arrays(void)
00105 {
00106 int obj_idx;
00107
00108 if ((res_object_current == -1) || (delta_objects==NULL))
00109 {
00110
00111 delta_objects = (OBJECT**)gl_malloc(res_object_count*sizeof(OBJECT*));
00112
00113
00114 if (delta_objects == NULL)
00115 {
00116 GL_THROW("Failed to allocate deltamode objects array for residential module!");
00117
00118
00119
00120
00121
00122 }
00123
00124
00125 delta_functions = (FUNCTIONADDR*)gl_malloc(res_object_count*sizeof(FUNCTIONADDR));
00126
00127
00128 if (delta_functions == NULL)
00129 {
00130 GL_THROW("Failed to allocate deltamode objects function array for residential module!");
00131
00132
00133
00134
00135
00136 }
00137
00138
00139 post_delta_functions = (FUNCTIONADDR*)gl_malloc(res_object_count*sizeof(FUNCTIONADDR));
00140
00141
00142 if (post_delta_functions == NULL)
00143 {
00144 GL_THROW("Failed to allocate deltamode objects function array for residential module!");
00145
00146 }
00147
00148
00149 for (obj_idx=0; obj_idx<res_object_count; obj_idx++)
00150 {
00151 delta_objects[obj_idx] = NULL;
00152 delta_functions[obj_idx] = NULL;
00153 post_delta_functions[obj_idx] = NULL;
00154 }
00155
00156
00157 res_object_current = 0;
00158 }
00159
00160 }
00161
00162
00163
00164
00165
00166
00167
00168 EXPORT unsigned long deltamode_desired(int *flags)
00169 {
00170 unsigned long dt_val;
00171
00172 if (enable_subsecond_models == true)
00173 {
00174
00175 if ((deltamode_starttime>=gl_globalclock) && (deltamode_starttime<TS_NEVER))
00176 {
00177
00178 *flags |= DMF_SOFTEVENT;
00179
00180
00181 dt_val = (unsigned long)(deltamode_starttime - gl_globalclock);
00182
00183 gl_debug("residential: deltamode desired in %d", dt_val);
00184 return dt_val;
00185 }
00186 else
00187 {
00188
00189 return DT_INFINITY;
00190 }
00191 }
00192 else
00193 {
00194 return DT_INFINITY;
00195 }
00196 }
00197
00198
00199
00200
00201
00202 EXPORT unsigned long preupdate(MODULE *module, TIMESTAMP t0, unsigned int64 dt)
00203 {
00204 if (enable_subsecond_models == true)
00205 {
00206 if (deltamode_timestep_publish<=0.0)
00207 {
00208 gl_error("residential::deltamode_timestep must be a positive, non-zero number!");
00209
00210
00211
00212
00213
00214 return DT_INVALID;
00215 }
00216 else
00217 {
00218
00219 deltamode_timestep = (unsigned long)(deltamode_timestep_publish+0.5);
00220
00221
00222 return deltamode_timestep;
00223 }
00224 }
00225 else
00226 {
00227 return DT_INFINITY;
00228 }
00229 }
00230
00231
00232
00233
00234
00235 EXPORT SIMULATIONMODE interupdate(MODULE *module, TIMESTAMP t0, unsigned int64 delta_time, unsigned long dt, unsigned int iteration_count_val)
00236 {
00237 int curr_object_number;
00238 SIMULATIONMODE function_status = SM_EVENT;
00239 bool event_driven = true;
00240 bool delta_iter = false;
00241
00242 if (enable_subsecond_models == true)
00243 {
00244
00245 for (curr_object_number=0; curr_object_number<res_object_count; curr_object_number++)
00246 {
00247
00248 if ((delta_objects[curr_object_number]->in_svc_double <= gl_globaldeltaclock) && (delta_objects[curr_object_number]->out_svc_double >= gl_globaldeltaclock))
00249 {
00250
00251 try {
00252
00253 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);
00254 }
00255 catch (const char *msg)
00256 {
00257 gl_error("residential:interupdate - pre-pass function call: %s", msg);
00258 function_status = SM_ERROR;
00259 }
00260 catch (...)
00261 {
00262 gl_error("residential:interupdate - pre-pass function call: unknown exception");
00263 function_status = SM_ERROR;
00264 }
00265 }
00266 else
00267 function_status = SM_EVENT;
00268
00269
00270 if (function_status == SM_DELTA)
00271 {
00272 gl_verbose("Residential 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"));
00273
00274 event_driven = false;
00275 }
00276 else if (function_status == SM_DELTA_ITER)
00277 {
00278 gl_verbose("Residential 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"));
00279
00280 event_driven = false;
00281 delta_iter = true;
00282 }
00283 else if (function_status == SM_ERROR)
00284 {
00285 gl_error("Residential object:%d - %s - deltamode function returned an error!",delta_objects[curr_object_number]->id,(delta_objects[curr_object_number]->name ? delta_objects[curr_object_number]->name : "Unnamed"));
00286
00287
00288
00289
00290 return SM_ERROR;
00291 }
00292
00293 }
00294
00295
00296 if (event_driven == false)
00297 {
00298 if (delta_iter == true)
00299 return SM_DELTA_ITER;
00300 else
00301 return SM_DELTA;
00302 }
00303 else
00304 return SM_EVENT;
00305 }
00306 else
00307 {
00308 return SM_EVENT;
00309 }
00310 }
00311
00312
00313
00314
00315 EXPORT STATUS postupdate(MODULE *module, TIMESTAMP t0, unsigned int64 dt)
00316 {
00317 int curr_object_number;
00318 STATUS function_status;
00319
00320 if (enable_subsecond_models == true)
00321 {
00322
00323 for (curr_object_number=0; curr_object_number<res_object_count; curr_object_number++)
00324 {
00325
00326 if (post_delta_functions[curr_object_number] != NULL)
00327 {
00328
00329 if ((delta_objects[curr_object_number]->in_svc_double <= gl_globaldeltaclock) && (delta_objects[curr_object_number]->out_svc_double >= gl_globaldeltaclock))
00330 {
00331
00332 try {
00333
00334 function_status = ((STATUS (*)(OBJECT *))(*post_delta_functions[curr_object_number]))(delta_objects[curr_object_number]);
00335 }
00336 catch (const char *msg)
00337 {
00338 gl_error("residential:postupdate function call: %s", msg);
00339 function_status = FAILED;
00340 }
00341 catch (...)
00342 {
00343 gl_error("residential:postupdate function call: unknown exception");
00344 function_status = FAILED;
00345 }
00346 }
00347 else
00348 function_status = SUCCESS;
00349
00350
00351 if (function_status == FAILED)
00352 {
00353 gl_error("Residential object:%s - failed post-deltamode update",delta_objects[curr_object_number]->name);
00354
00355
00356
00357
00358 return FAILED;
00359 }
00360
00361 }
00362
00363 }
00364
00365
00366 return SUCCESS;
00367 }
00368 else
00369 {
00370 return SUCCESS;
00371 }
00372 }
00373
00374 CDECL int do_kill()
00375 {
00376
00377 return 0;
00378 }
00379
00380 EXPORT int check(){
00381 return 0;
00382 }
00383
00384