00001
00013 #include <stdlib.h>
00014 #include <stdio.h>
00015 #include <errno.h>
00016 #include <math.h>
00017
00018 #include "house_a.h"
00019 #include "range.h"
00020
00022
00024 CLASS* range::oclass = NULL;
00025 CLASS* range::pclass = NULL;
00026
00027 range::range(MODULE *module) : residential_enduse(module)
00028 {
00029
00030 if (oclass==NULL)
00031 {
00032
00033 oclass = gl_register_class(module,"range",sizeof(range),PC_BOTTOMUP);
00034 if (oclass==NULL)
00035 GL_THROW("unable to register object class implemented by %s",__FILE__);
00036
00037
00038 if (gl_publish_variable(oclass,
00039 PT_INHERIT, "residential_enduse",
00040 PT_double,"installed_power[kW]",PADDR(shape.params.analog.power),
00041 PT_double,"circuit_split",PADDR(circuit_split),
00042 PT_double,"demand[unit]",PADDR(shape.load),
00043 PT_complex,"energy_meter[kWh]",PADDR(load.energy),
00044 NULL)<1)
00045 GL_THROW("unable to publish properties in %s",__FILE__);
00046
00047
00048 }
00049 }
00050
00051 range::~range()
00052 {
00053 }
00054
00055 int range::create()
00056 {
00057 int res = residential_enduse::create();
00058
00059
00060 load.name = oclass->name;
00061 load.power = load.admittance = load.current = load.total = complex(0,0,J);
00062
00063 return res;
00064 }
00065
00066 int range::init(OBJECT *parent)
00067 {
00068 if(shape.params.analog.power < 0){
00069 gl_warning("range installed power is negative, using random default");
00070 installed_power = 0;
00071 }
00072 if(load.heatgain_fraction < 0.0 || load.heatgain_fraction > 1.0){
00073 gl_warning("range heat_fraction out of bounds, restoring default");
00074 heat_fraction = 0;
00075 }
00076
00077 if (shape.params.analog.power==0) shape.params.analog.power = gl_random_uniform(8,15);
00078 if (load.power_factor==0) load.power_factor = 1.0;
00079 if (load.heatgain_fraction==0) load.heatgain_fraction = 0.9;
00080 if (load.voltage_factor==0) load.voltage_factor = 1.0;
00081
00082 load.config = EUC_IS220;
00083 load.breaker_amps = 30;
00084
00085 load.total = complex(shape.params.analog.power*shape.load,0,J);
00086 load.admittance = load.total*(240/240);
00087 load.heatgain = load.total.Mag()*load.heatgain_fraction;
00088
00089 return residential_enduse::init(parent);
00090 }
00091
00092 int range::isa(char *classname)
00093 {
00094 return (strcmp(classname,"range")==0 || residential_enduse::isa(classname));
00095 }
00096
00097 TIMESTAMP range::sync(TIMESTAMP t0, TIMESTAMP t1)
00098 {
00099 double val = 0.0;
00100 TIMESTAMP t2 = TS_NEVER;
00101
00102 if (pCircuit!=NULL)
00103 load.voltage_factor = pCircuit->pV->Mag() / 240;
00104
00105 if(shape.load < 0.0){
00106 GL_THROW("range demand is negative");
00107 }
00108 if(shape.load > 1.0){
00109 GL_THROW("range demand is greater than 1.0 and out of bounds");
00110 }
00111
00112 t2 = residential_enduse::sync(t0,t1);
00113
00114 if(shape.type == MT_UNKNOWN){
00115 double frac = shape.load;
00116 if(shape.load < 0){
00117 gl_warning("range shape demand is negative, capping to 0");
00118 shape.load = 0.0;
00119 } else if (shape.load > 1.0){
00120 gl_warning("range shape demand exceeds installed lighting power, capping to 100%%");
00121 shape.load = 1.0;
00122 }
00123 load.power = shape.params.analog.power * shape.load;
00124 if(fabs(load.power_factor) < 1){
00125 val = (load.power_factor<0?-1.0:1.0) * load.power.Re() * sqrt(1/(load.power_factor * load.power_factor) - 1);
00126 } else {
00127 val = 0;
00128 }
00129 load.power.SetRect(load.power.Re(), val);
00130 }
00131
00132 gl_enduse_sync(&(residential_enduse::load),t1);
00133
00134 return t2;
00135 }
00136
00138
00140
00141
00142 EXPORT int create_range(OBJECT **obj, OBJECT *parent)
00143 {
00144 *obj = gl_create_object(range::oclass);
00145 if (*obj!=NULL)
00146 {
00147 range *my = OBJECTDATA(*obj,range);;
00148 gl_set_parent(*obj,parent);
00149 my->create();
00150 return 1;
00151 }
00152 return 0;
00153 }
00154
00155 EXPORT int init_range(OBJECT *obj)
00156 {
00157 range *my = OBJECTDATA(obj,range);
00158 return my->init(obj->parent);
00159 }
00160
00161 EXPORT int isa_range(OBJECT *obj, char *classname)
00162 {
00163 if(obj != 0 && classname != 0){
00164 return OBJECTDATA(obj,range)->isa(classname);
00165 } else {
00166 return 0;
00167 }
00168 }
00169
00170 EXPORT TIMESTAMP sync_range(OBJECT *obj, TIMESTAMP t0)
00171 {
00172 range *my = OBJECTDATA(obj, range);
00173 TIMESTAMP t1 = my->sync(obj->clock, t0);
00174 obj->clock = t0;
00175 return t1;
00176 }
00177