residential/lights.cpp

Go to the documentation of this file.
00001 
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041 #include <errno.h>
00042 #include <math.h>
00043 #include "lock.h"
00044 #include "house.h"
00045 #include "lights.h"
00046 
00048 // lights CLASS FUNCTIONS
00050 CLASS* lights::oclass = NULL;
00051 lights *lights::defaults = NULL;
00052 
00053 double lights::power_factor[_MAXTYPES];
00054 
00055 // the constructor registers the class and properties and sets the defaults
00056 lights::lights(MODULE *mod) 
00057 {
00058     // first time init
00059     if (oclass==NULL)
00060     {
00061         // register the class definition
00062         oclass = gl_register_class(mod,"lights",PC_BOTTOMUP);
00063         if (oclass==NULL)
00064             GL_THROW("unable to register object class implemented by %s",__FILE__);
00065 
00066         // publish the class properties
00067         if (gl_publish_variable(oclass,
00068             PT_enumeration,"type",PADDR(type),
00069                 PT_KEYWORD,"INCANDESCENT",INCANDESCENT,
00070                 PT_KEYWORD,"FLUORESCENT",FLUORESCENT,
00071                 PT_KEYWORD,"CFL",CFL,
00072                 PT_KEYWORD,"SSL",SSL,
00073                 PT_KEYWORD,"HID",HID,
00074             PT_enumeration,"placement",PADDR(placement),
00075                 PT_KEYWORD,"INDOOR",INDOOR,
00076                 PT_KEYWORD,"OUTDOOR",OUTDOOR,
00077             PT_double,"installed_power[W]",PADDR(installed_power),
00078             PT_double,"circuit_split",PADDR(circuit_split),
00079             PT_double,"demand[%]",PADDR(demand),
00080             PT_complex,"power[kW]",PADDR(power_kw),
00081             PT_double,"internal_heat",PADDR(internal_heat),
00082             PT_double,"external_heat",PADDR(external_heat),
00083             PT_complex,"meter[kWh]",PADDR(kwh_meter),       //< local meter variable to keep track of energy
00084             NULL)<1) GL_THROW("unable to publish properties in %s",__FILE__);
00085 
00086         // default global values
00087         power_factor[INCANDESCENT]  = 1.00;
00088         power_factor[FLUORESCENT]   = 0.93;
00089         power_factor[CFL]           = 0.86;
00090         power_factor[SSL]           = 0.75;
00091         power_factor[HID]           = 0.97;
00092 
00093         // setup the default values
00094         defaults = this;
00095         type = INCANDESCENT;
00096         placement = INDOOR;
00097         circuit_split = 0;
00098         power_density = 0;
00099         installed_power = 0;
00100         demand = 0.0;
00101         power_kw = 0;
00102         kwh_meter = 0.0;
00103         internal_heat = 0.0;
00104         external_heat = 0.0;
00105         pVoltage = NULL;
00106     }
00107 }
00108 
00109 // create is called every time a new object is loaded
00110 int lights::create(void) 
00111 {
00112     // copy the defaults
00113     memcpy(this,defaults,sizeof(*this));
00114 
00115     // set basic properties
00116     circuit_split = gl_random_uniform(-1,1); // @todo circuit_split is ignored and should be delete; the split is done automatically by panel.attach()
00117     power_density = gl_random_normal(1.0, 0.075);  // W/sf
00118     
00119     // other initial conditions
00120     demand = 1.0;
00121     return 1;
00122 }
00123 
00124 int lights::init(OBJECT *parent)
00125 {
00126     // lights must have a parent house
00127     if (parent==NULL)
00128     {
00129         gl_error("lights must have a parent house");
00130         return 0;
00131     }
00132     house *pHouse = OBJECTDATA(parent,house);
00133 
00134     // attach object to house panel
00135     pVoltage = (pHouse->attach(OBJECTHDR(this),20,false))->pV;
00136 
00137     // installed power intially overrides use of power density
00138     if (installed_power==0) 
00139         installed_power = power_density * pHouse->floor_area;
00140 
00141     // initial demand (assume power factor is 1.0
00142     power_kw = installed_power * demand / 1000;
00143 
00144     return 1;
00145 }
00146 
00147 TIMESTAMP lights::sync(TIMESTAMP t0, TIMESTAMP t1) 
00148 {
00149     // compute nominal power consumption (adjust with power factor)
00150     power_kw.SetPolar(installed_power/power_factor[type] * demand / 1000.0, acos(power_factor[type]),J);
00151 
00152     // adjust power based on lamp type's response to voltage
00153     double puV = pVoltage->Mag()/120.0;
00154     switch (type) {
00155     case INCANDESCENT:
00156         if (puV<0.25)
00157             power_kw = 0;
00158         else
00159             power_kw *= puV; // proportional to voltage
00160         break;
00161     case FLUORESCENT:
00162     case CFL:
00163     case SSL:
00164         if (puV<0.1)
00165             power_kw = 0;
00166         else
00167         {   
00168             power_kw.Re() *= puV; 
00169             power_kw.Im() *= sqrt(puV);
00170         }
00171         break;
00172     case HID:
00173         if (puV<0.75)
00174             power_kw = 0;
00175         else
00176             power_kw *= pow(puV,-2); 
00177         break;
00178     default:
00179         break;
00180     }
00181 
00182     // update energy if clock is started
00183     if (t0>0)
00184     {
00185         double energy = power_kw.Mag()*(gl_tohours(t1)-gl_tohours(t0));
00186         internal_heat = (placement==INDOOR ? (energy * BTUPHPKW) : 0);
00187         external_heat = (placement==OUTDOOR ? (energy * BTUPHPKW) : 0);
00188         kwh_meter += energy;
00189     }
00190 
00191     // update parent house 
00192     OBJECT *parent = (OBJECTHDR(this))->parent;
00193     house *pHouse = OBJECTDATA(parent,house);
00194     LOCK_OBJECT(parent);
00195     pHouse->lights_heat_energy += internal_heat;
00196     UNLOCK_OBJECT(parent);
00197 
00198     return TS_NEVER; 
00199 }
00200 
00202 // IMPLEMENTATION OF CORE LINKAGE
00204 
00205 EXPORT int create_lights(OBJECT **obj, OBJECT *parent)
00206 {
00207     *obj = gl_create_object(lights::oclass,sizeof(lights));
00208     if (*obj!=NULL)
00209     {
00210         lights *my = OBJECTDATA(*obj,lights);
00211         gl_set_parent(*obj,parent);
00212         my->create();
00213         return 1;
00214     }
00215     return 0;
00216 }
00217 
00218 EXPORT int init_lights(OBJECT *obj)
00219 {
00220     lights *my = OBJECTDATA(obj,lights);
00221     return my->init(obj->parent);
00222 }
00223 
00224 EXPORT TIMESTAMP sync_lights(OBJECT *obj, TIMESTAMP t0)
00225 {
00226     lights *my = OBJECTDATA(obj,lights);
00227     TIMESTAMP t1 = my->sync(obj->clock, t0);
00228     obj->clock = t0;
00229     return t1;
00230 }
00231 

GridLAB-DTM Version 1.0
An open-source project initiated by the US Department of Energy