00001
00051 #include <stdlib.h>
00052 #include <stdio.h>
00053 #include <errno.h>
00054 #include <math.h>
00055
00056 #include "house.h"
00057 #include "refrigerator.h"
00058
00060
00062 CLASS* refrigerator::oclass = NULL;
00063 refrigerator *refrigerator::defaults = NULL;
00064
00065
00066
00067 refrigerator::refrigerator(MODULE *module)
00068 {
00069
00070 if (oclass == NULL)
00071 {
00072 oclass = gl_register_class(module,"refrigerator",PC_BOTTOMUP);
00073 if (oclass==NULL)
00074 GL_THROW("unable to register object class implemented by %s",__FILE__);
00075
00076
00077 if (gl_publish_variable(oclass,
00078 PT_double, "size [cf]", PADDR(size),
00079 PT_double, "rated_capacity [Btu/h]", PADDR(rated_capacity),
00080 NULL) < 1)
00081 GL_THROW("unable to publish properties in %s", __FILE__);
00082
00083
00084 defaults = this;
00085 size = gl_random_uniform(20,40);
00086
00087
00088 thermostat_deadband = gl_random_uniform(2,3);
00089 Tset = gl_random_uniform(35,39);
00090 UAr = 1.5+size/40*gl_random_uniform(0.9,1.1);
00091 UAf = gl_random_uniform(0.9,1.1);
00092 COPcoef = gl_random_uniform(0.9,1.1);
00093
00094
00095 Cf = 8.43 * size/10;
00096 rated_capacity = BTUPHPW * size*10;
00097
00098
00099 if (gl_random_uniform(0,1)<0.04)
00100 Qr = rated_capacity;
00101 else
00102 Qr = 0;
00103
00104
00105 Tair = gl_random_uniform(Tset-thermostat_deadband,Tset+thermostat_deadband);
00106
00107 Tout = 59.0;
00108 power_factor = 0.95;
00109
00110 }
00111 }
00112
00113 refrigerator::~refrigerator()
00114 {
00115 }
00116
00117 int refrigerator::init(OBJECT *parent)
00118 {
00119 if (parent==NULL)
00120 {
00121 gl_error("refrigerator must have a parent house");
00122 return 0;
00123 }
00124 pHouse = OBJECTDATA(parent,house);
00125
00126
00127 pVoltage = (pHouse->attach(OBJECTHDR(this),20,false))->pV;
00128
00129
00130 power_kw = rated_capacity*KWPBTUPH;
00131
00132 return 1;
00133 }
00134
00135 int refrigerator::create()
00136 {
00137 memcpy(this, defaults, sizeof(*this));
00138 return 1;
00139 }
00140
00141
00142 TIMESTAMP refrigerator::sync(TIMESTAMP t0, TIMESTAMP t1)
00143 {
00144 double nHours = (gl_tohours(t1)- gl_tohours(t0))/TS_SECOND;
00145
00146
00147 Tout = pHouse->get_Tair();
00148
00149
00150 const double Ton = Tset+thermostat_deadband;
00151 const double Toff = Tset-thermostat_deadband;
00152
00153
00154 const double C1 = Cf/(UAr*UAf);
00155 const double COP = COPcoef*((-3.5/45)*(Tout-70)+4.5);
00156
00157
00158 kwh_meter = Qr*KWPBTUPH*COP*nHours;
00159 power_kw = kwh_meter/nHours;
00160
00161
00162
00163 if (ANE(Qr,0,0.1) && ALT(Tair,Toff,0.1))
00164 Qr = 0;
00165 else if (AEQ(Qr,0,0.1) && AGT(Tair,Ton,0.1))
00166 Qr = rated_capacity;
00167
00168
00169 const double C2 = Tout - Qr/UAf;
00170
00171
00172 double Tevent;
00173 if (AEQ(Qr,0,0.1))
00174 Tevent = Ton;
00175 else
00176 Tevent = Toff;
00177
00178
00179 double t = -log((Tevent - C2)/(Tair-C2))*C1;
00180 double dt = t;
00181 if (t==0)
00182 throw "refrigerator control logic error";
00183
00184
00185 if (t<0 || t>=nHours)
00186 {
00187 dt = ((t<0||t>=nHours)?nHours:t);
00188
00189
00190 Tair = (Tair-C2)*exp(-dt/C1)+C2;
00191 if (Tair < 32 || Tair > 55)
00192 throw "refrigerator air temperature out of control";
00193
00194 return (TIMESTAMP)(t1+dt*3600.0/TS_SECOND);
00195 }
00196
00197 else
00198 {
00199 Tair = Tevent;
00200 return TS_NEVER;
00201 }
00202 }
00203
00204
00206
00208 EXPORT int create_refrigerator(OBJECT **obj, OBJECT *parent)
00209 {
00210 *obj = gl_create_object(refrigerator::oclass,sizeof(refrigerator));
00211 if (*obj!=NULL)
00212 {
00213 refrigerator *my = OBJECTDATA(*obj,refrigerator);;
00214 gl_set_parent(*obj,parent);
00215 my->create();
00216 return 1;
00217 }
00218 return 0;
00219 }
00220
00221 EXPORT int init_refrigerator(OBJECT *obj)
00222 {
00223 refrigerator *my = OBJECTDATA(obj,refrigerator);
00224 return my->init(obj->parent);
00225 }
00226
00227 EXPORT TIMESTAMP sync_refrigerator(OBJECT *obj, TIMESTAMP t0)
00228 {
00229 TIMESTAMP t1 = ((refrigerator*)(obj+1))->sync(obj->clock, t0);
00230 obj->clock = t0;
00231 return t1;
00232 }
00233