00001
00081 #include <stdlib.h>
00082 #include <stdio.h>
00083 #include <errno.h>
00084 #include <math.h>
00085 #include "solvers.h"
00086 #include "house_e.h"
00087 #include "complex.h"
00088
00089 #ifndef WIN32
00090 char *_strlwr(char *s)
00091 {
00092 char *r=s;
00093 while (*s!='\0')
00094 {
00095 *s = (*s>='A'&&*s<='Z') ? (*s-'A'+'a') : *s;
00096 s++;
00097 }
00098 return r;
00099 }
00100 #endif
00101
00102
00103 set house_e::implicit_enduses_active = IEU_ALL;
00104 enumeration house_e::implicit_enduse_source = IES_ELCAP1990;
00105 static double aux_cutin_temperature = 10;
00106
00108
00110 typedef struct s_implicit_enduse_list {
00111 char *implicit_name;
00112 struct {
00113 double breaker_amps;
00114 int circuit_is220;
00115 struct {
00116 double z, i, p;
00117 } fractions;
00118 double power_factor;
00119 double heat_fraction;
00120 } load;
00121 char *shape;
00122 char *schedule_name;
00123 char *schedule_definition;
00124 } IMPLICITENDUSEDATA;
00125 #include "elcap1990.h"
00126 #include "elcap2010.h"
00127 #include "rbsa2014.h"
00128 static IMPLICITENDUSEDATA *implicit_enduse_data = elcap1990;
00129
00130 EXPORT CIRCUIT *attach_enduse_house_e(OBJECT *obj, enduse *target, double breaker_amps, int is220)
00131 {
00132 house_e *pHouse = 0;
00133 CIRCUIT *c = 0;
00134
00135 if(obj == NULL){
00136 GL_THROW("attach_house_a: null object reference");
00137 }
00138 if(target == NULL){
00139 GL_THROW("attach_house_a: null enduse target data");
00140 }
00141 if(breaker_amps < 0 || breaker_amps > 1000){
00142 GL_THROW("attach_house_a: breaker amps of %i unrealistic", breaker_amps);
00143 }
00144
00145 pHouse = OBJECTDATA(obj,house_e);
00146 return pHouse->attach(obj,breaker_amps,is220,target);
00147 }
00148
00150
00152 CLASS* house_e::oclass = NULL;
00153 CLASS* house_e::pclass = NULL;
00154
00155 double house_e::warn_low_temp = 55;
00156 double house_e::warn_high_temp = 95;
00157 bool house_e::warn_control = true;
00158 double house_e::system_dwell_time = 1;
00159
00163 house_e::house_e(MODULE *mod) : residential_enduse(mod)
00164 {
00165
00166 if (oclass==NULL)
00167 {
00168
00169 oclass = gl_register_class(mod,"house",sizeof(house_e),PC_PRETOPDOWN|PC_BOTTOMUP|PC_POSTTOPDOWN|PC_AUTOLOCK);
00170 if (oclass==NULL)
00171 throw "unable to register class house";
00172 else
00173 oclass->trl = TRL_PROVEN;
00174
00175
00176 if (gl_publish_variable(oclass,
00177 PT_INHERIT, "residential_enduse",
00178 PT_object,"weather",PADDR(weather),PT_DESCRIPTION,"reference to the climate object",
00179 PT_double,"floor_area[sf]",PADDR(floor_area),PT_DESCRIPTION,"home conditioned floor area",
00180 PT_double,"gross_wall_area[sf]",PADDR(gross_wall_area),PT_DESCRIPTION,"gross outdoor wall area",
00181 PT_double,"ceiling_height[ft]",PADDR(ceiling_height),PT_DESCRIPTION,"average ceiling height",
00182 PT_double,"aspect_ratio",PADDR(aspect_ratio), PT_DESCRIPTION,"aspect ratio of the home's footprint",
00183 PT_double,"envelope_UA[Btu/degF*h]",PADDR(envelope_UA),PT_DESCRIPTION,"overall UA of the home's envelope",
00184 PT_double,"window_wall_ratio",PADDR(window_wall_ratio),PT_DESCRIPTION,"ratio of window area to wall area",
00185 PT_double,"number_of_doors",PADDR(number_of_doors),PT_DESCRIPTION,"ratio of door area to wall area",
00186 PT_double,"exterior_wall_fraction",PADDR(exterior_wall_fraction),PT_DESCRIPTION,"ratio of exterior wall area to total wall area",
00187 PT_double,"interior_exterior_wall_ratio",PADDR(interior_exterior_wall_ratio),PT_DESCRIPTION,"ratio of interior to exterior walls",
00188 PT_double,"exterior_ceiling_fraction",PADDR(exterior_ceiling_fraction),PT_DESCRIPTION,"ratio of external ceiling sf to floor area",
00189 PT_double,"exterior_floor_fraction",PADDR(exterior_floor_fraction),PT_DESCRIPTION,"ratio of floor area used in UA calculation",
00190 PT_double,"window_shading",PADDR(glazing_shgc),PT_DESCRIPTION,"transmission coefficient through window due to glazing",
00191 PT_double,"window_exterior_transmission_coefficient",PADDR(window_exterior_transmission_coefficient),PT_DESCRIPTION,"coefficient for the amount of energy that passes through window",
00192 PT_double,"solar_heatgain_factor",PADDR(solar_heatgain_factor),PT_ACCESS,PA_REFERENCE,PT_DESCRIPTION,"product of the window area, window transmitivity, and the window exterior transmission coefficient",
00193 PT_double,"airchange_per_hour[unit/h]",PADDR(airchange_per_hour),PT_DESCRIPTION,"number of air-changes per hour",
00194 PT_double,"airchange_UA[Btu/degF*h]",PADDR(airchange_UA),PT_DESCRIPTION,"additional UA due to air infiltration",
00195 PT_double,"UA[Btu/degF*h]",PADDR(UA),PT_DESCRIPTION,"the total UA",
00196 PT_double,"internal_gain[Btu/h]",PADDR(total.heatgain),PT_DESCRIPTION,"internal heat gains",
00197 PT_double,"solar_gain[Btu/h]",PADDR(solar_load),PT_DESCRIPTION,"solar heat gains",
00198 PT_double,"incident_solar_radiation[Btu/h*sf]",PADDR(incident_solar_radiation),PT_DESCRIPTION,"average incident solar radiation hitting the house",
00199 PT_double,"heat_cool_gain[Btu/h]",PADDR(load.heatgain),PT_DESCRIPTION,"system heat gains(losses)",
00200
00201 PT_set,"include_solar_quadrant",PADDR(include_solar_quadrant),PT_DESCRIPTION,"bit set for determining which solar incidence quadrants should be included in the solar heatgain",
00202 PT_KEYWORD,"NONE",(set)NO_SOLAR,
00203 PT_KEYWORD,"H",(set)HORIZONTAL,
00204 PT_KEYWORD,"N",(set)NORTH,
00205 PT_KEYWORD,"E",(set)EAST,
00206 PT_KEYWORD,"S",(set)SOUTH,
00207 PT_KEYWORD,"W",(set)WEST,
00208 PT_double,"horizontal_diffuse_solar_radiation[Btu/h*sf]",PADDR(horizontal_diffuse_solar_radiation),PT_DESCRIPTION,"incident solar radiation hitting the top of the house",
00209 PT_double,"north_incident_solar_radiation[Btu/h*sf]",PADDR(north_incident_solar_radiation),PT_DESCRIPTION,"incident solar radiation hitting the north side of the house",
00210 PT_double,"northwest_incident_solar_radiation[Btu/h*sf]",PADDR(north_west_incident_solar_radiation),PT_DESCRIPTION,"incident solar radiation hitting the northwest side of the house",
00211 PT_double,"west_incident_solar_radiation[Btu/h*sf]",PADDR(west_incident_solar_radiation),PT_DESCRIPTION,"incident solar radiation hitting the west side of the house",
00212 PT_double,"southwest_incident_solar_radiation[Btu/h*sf]",PADDR(south_west_incident_solar_radiation),PT_DESCRIPTION,"incident solar radiation hitting the southwest side of the house",
00213 PT_double,"south_incident_solar_radiation[Btu/h*sf]",PADDR(south_incident_solar_radiation),PT_DESCRIPTION,"incident solar radiation hitting the south side of the house",
00214 PT_double,"southeast_incident_solar_radiation[Btu/h*sf]",PADDR(south_east_incident_solar_radiation),PT_DESCRIPTION,"incident solar radiation hitting the southeast side of the house",
00215 PT_double,"east_incident_solar_radiation[Btu/h*sf]",PADDR(east_incident_solar_radiation),PT_DESCRIPTION,"incident solar radiation hitting the east side of the house",
00216 PT_double,"northeast_incident_solar_radiation[Btu/h*sf]",PADDR(north_east_incident_solar_radiation),PT_DESCRIPTION,"incident solar radiation hitting the northeast side of the house",
00217 PT_enumeration,"heating_cop_curve",PADDR(heating_cop_curve),PT_DESCRIPTION,"Defines the function type to use for the adjusted heating COP as a function of outside air temperature.",
00218 PT_KEYWORD,"DEFAULT",(enumeration)HC_DEFAULT,
00219 PT_KEYWORD,"FLAT",(enumeration)HC_FLAT,
00220 PT_KEYWORD,"LINEAR",(enumeration)HC_LINEAR,
00221 PT_KEYWORD,"CURVED",(enumeration)HC_CURVED,
00222 PT_enumeration,"heating_cap_curve",PADDR(heating_cap_curve),PT_DESCRIPTION,"Defines the function type to use for the adjusted heating capacity as a function of outside air temperature.",
00223 PT_KEYWORD,"DEFAULT",(enumeration)HP_DEFAULT,
00224 PT_KEYWORD,"FLAT",(enumeration)HP_FLAT,
00225 PT_KEYWORD,"LINEAR",(enumeration)HP_LINEAR,
00226 PT_KEYWORD,"CURVED",(enumeration)HP_CURVED,
00227 PT_enumeration,"cooling_cop_curve",PADDR(cooling_cop_curve),PT_DESCRIPTION,"Defines the function type to use for the adjusted cooling COP as a function of outside air temperature.",
00228 PT_KEYWORD,"DEFAULT",(enumeration)CC_DEFAULT,
00229 PT_KEYWORD,"FLAT",(enumeration)CC_FLAT,
00230 PT_KEYWORD,"LINEAR",(enumeration)CC_LINEAR,
00231 PT_KEYWORD,"CURVED",(enumeration)CC_CURVED,
00232 PT_enumeration,"cooling_cap_curve",PADDR(cooling_cap_curve),PT_DESCRIPTION,"Defines the function type to use for the adjusted cooling capacity as a function of outside air temperature.",
00233 PT_KEYWORD,"DEFAULT",(enumeration)CP_DEFAULT,
00234 PT_KEYWORD,"FLAT",(enumeration)CP_FLAT,
00235 PT_KEYWORD,"LINEAR",(enumeration)CP_LINEAR,
00236 PT_KEYWORD,"CURVED",(enumeration)CP_CURVED,
00237 PT_bool,"use_latent_heat",PADDR(use_latent_heat),PT_DESCRIPTION,"Boolean for using the heat latency of the air to the humidity when cooling.",
00238 PT_bool,"include_fan_heatgain",PADDR(include_fan_heatgain),PT_DESCRIPTION,"Boolean to choose whether to include the heat generated by the fan in the ETP model.",
00239
00240 PT_double,"thermostat_deadband[degF]",PADDR(thermostat_deadband),PT_DESCRIPTION,"deadband of thermostat control",
00241 PT_double,"dlc_offset[degF]",PADDR(dlc_offset),PT_DESCRIPTION,"used as a cap to offset the thermostat deadband for direct load control applications",
00242 PT_int16,"thermostat_cycle_time",PADDR(thermostat_cycle_time),PT_DESCRIPTION,"minimum time in seconds between thermostat updates",
00243 PT_int16,"thermostat_off_cycle_time",PADDR(thermostat_off_cycle_time),PT_DESCRIPTION,"the minimum amount of time the thermostat cycle must stay in the off state",
00244 PT_int16,"thermostat_on_cycle_time",PADDR(thermostat_on_cycle_time),PT_DESCRIPTION,"the minimum amount of time the thermostat cycle must stay in the on state",
00245 PT_timestamp,"thermostat_last_cycle_time",PADDR(thermostat_last_cycle_time),PT_ACCESS,PA_REFERENCE,PT_DESCRIPTION,"last time the thermostat changed state",
00246 PT_double,"heating_setpoint[degF]",PADDR(heating_setpoint),PT_DESCRIPTION,"thermostat heating setpoint",
00247 PT_double,"cooling_setpoint[degF]",PADDR(cooling_setpoint),PT_DESCRIPTION,"thermostat cooling setpoint",
00248 PT_double,"design_heating_setpoint[degF]",PADDR(design_heating_setpoint),PT_DESCRIPTION,"system design heating setpoint",
00249 PT_double,"design_cooling_setpoint[degF]",PADDR(design_cooling_setpoint),PT_DESCRIPTION,"system design cooling setpoint",
00250 PT_double,"over_sizing_factor",PADDR(over_sizing_factor),PT_DESCRIPTION,"over sizes the heating and cooling system from standard specifications (0.2 ='s 120% sizing)",
00251
00252 PT_bool,"simulate_window_openings",PADDR(window_openings),PT_DESCRIPTION,"activates a representation of an occupant opening a window and de-activating the HVAC system",
00253 PT_double,"is_window_open",PADDR(window_open),PT_DESCRIPTION,"defines the state of the window opening, 1=open, 2=closed",
00254 PT_double,"window_low_temperature_cutoff[degF]",PADDR(window_low_temp),PT_DESCRIPTION,"lowest temperature at which the window opening might occur",
00255 PT_double,"window_high_temperature_cutoff[degF]",PADDR(window_high_temp),PT_DESCRIPTION,"highest temperature at which the window opening might occur",
00256 PT_double,"window_quadratic_coefficient",PADDR(window_a),PT_DESCRIPTION,"quadratic coefficient for describing function between low and high temperature cutoffs",
00257 PT_double,"window_linear_coefficient",PADDR(window_b),PT_DESCRIPTION,"linear coefficient for describing function between low and high temperature cutoffs",
00258 PT_double,"window_constant_coefficient",PADDR(window_c),PT_DESCRIPTION,"constant coefficient for describing function between low and high temperature cutoffs",
00259 PT_double,"window_temperature_delta",PADDR(window_temp_delta),PT_DESCRIPTION,"change in outdoor temperature required to update the window opening model",
00260
00261 PT_double,"design_heating_capacity[Btu/h]",PADDR(design_heating_capacity),PT_DESCRIPTION,"system heating capacity",
00262 PT_double,"design_cooling_capacity[Btu/h]",PADDR(design_cooling_capacity),PT_DESCRIPTION,"system cooling capacity",
00263 PT_double,"cooling_design_temperature[degF]", PADDR(cooling_design_temperature),PT_DESCRIPTION,"system cooling design temperature",
00264 PT_double,"heating_design_temperature[degF]", PADDR(heating_design_temperature),PT_DESCRIPTION,"system heating design temperature",
00265 PT_double,"design_peak_solar[Btu/h*sf]", PADDR(design_peak_solar),PT_DESCRIPTION,"system design solar load",
00266 PT_double,"design_internal_gains[W/sf]", PADDR(design_internal_gains),PT_DESCRIPTION,"system design internal gains",
00267 PT_double,"air_heat_fraction[pu]", PADDR(air_heat_fraction), PT_DESCRIPTION, "fraction of heat gain/loss that goes to air (as opposed to mass)",
00268 PT_double,"mass_solar_gain_fraction[pu]", PADDR(mass_solar_gain_fraction), PT_DESCRIPTION, "fraction of the heat gain/loss from the solar gains that goes to the mass",
00269 PT_double,"mass_internal_gain_fraction[pu]", PADDR(mass_internal_gain_fraction), PT_DESCRIPTION, "fraction of heat gain/loss from the internal gains that goes to the mass",
00270
00271 PT_double,"auxiliary_heat_capacity[Btu/h]",PADDR(aux_heat_capacity),PT_DESCRIPTION,"installed auxiliary heating capacity",
00272 PT_double,"aux_heat_deadband[degF]",PADDR(aux_heat_deadband),PT_DESCRIPTION,"temperature offset from standard heat activation to auxiliary heat activation",
00273 PT_double,"aux_heat_temperature_lockout[degF]",PADDR(aux_heat_temp_lockout),PT_DESCRIPTION,"temperature at which auxiliary heat will not engage above",
00274 PT_double,"aux_heat_time_delay[s]",PADDR(aux_heat_time_delay),PT_DESCRIPTION,"time required for heater to run until auxiliary heating engages",
00275
00276 PT_double,"cooling_supply_air_temp[degF]",PADDR(cooling_supply_air_temp),PT_DESCRIPTION,"temperature of air blown out of the cooling system",
00277 PT_double,"heating_supply_air_temp[degF]",PADDR(heating_supply_air_temp),PT_DESCRIPTION,"temperature of air blown out of the heating system",
00278 PT_double,"duct_pressure_drop[inH2O]",PADDR(duct_pressure_drop),PT_DESCRIPTION,"end-to-end pressure drop for the ventilation ducts, in inches of water",
00279 PT_double,"fan_design_power[W]",PADDR(fan_design_power),PT_DESCRIPTION,"designed maximum power draw of the ventilation fan",
00280 PT_double,"fan_low_power_fraction[pu]",PADDR(fan_low_power_fraction),PT_DESCRIPTION,"fraction of ventilation fan power draw during low-power mode (two-speed only)",
00281 PT_double,"fan_power[kW]",PADDR(fan_power),PT_ACCESS,PA_REFERENCE,PT_DESCRIPTION,"current ventilation fan power draw",
00282 PT_double,"fan_design_airflow[cfm]",PADDR(fan_design_airflow),PT_DESCRIPTION,"designed airflow for the ventilation system",
00283 PT_double,"fan_impedance_fraction[pu]",PADDR(fan_impedance_fraction),PT_DESCRIPTION,"Impedance component of fan ZIP load",
00284 PT_double,"fan_power_fraction[pu]",PADDR(fan_power_fraction),PT_DESCRIPTION,"Power component of fan ZIP load",
00285 PT_double,"fan_current_fraction[pu]",PADDR(fan_current_fraction),PT_DESCRIPTION,"Current component of fan ZIP load",
00286 PT_double,"fan_power_factor[pu]",PADDR(fan_power_factor),PT_DESCRIPTION,"Power factor of the fan load",
00287
00288 PT_double,"heating_demand[kW]",PADDR(heating_demand),PT_ACCESS,PA_REFERENCE,PT_DESCRIPTION,"the current power draw to run the heating system",
00289 PT_double,"cooling_demand[kW]",PADDR(cooling_demand),PT_ACCESS,PA_REFERENCE,PT_DESCRIPTION,"the current power draw to run the cooling system",
00290 PT_double,"heating_COP[pu]",PADDR(heating_COP),PT_DESCRIPTION,"system heating performance coefficient",
00291 PT_double,"cooling_COP[Btu/kWh]",PADDR(cooling_COP),PT_DESCRIPTION,"system cooling performance coefficient",
00292
00293 PT_double,"air_temperature[degF]",PADDR(Tair),PT_DESCRIPTION,"indoor air temperature",
00294 PT_double,"outdoor_temperature[degF]",PADDR(outside_temperature),PT_DESCRIPTION,"outdoor air temperature",
00295 PT_double,"outdoor_rh[%]",PADDR(outdoor_rh),PT_DESCRIPTION,"outdoor relative humidity",
00296 PT_double,"mass_heat_capacity[Btu/degF]",PADDR(house_content_thermal_mass),PT_DESCRIPTION,"interior mass heat capacity",
00297 PT_double,"mass_heat_coeff[Btu/degF*h]",PADDR(house_content_heat_transfer_coeff),PT_DESCRIPTION,"interior mass heat exchange coefficient",
00298 PT_double,"mass_temperature[degF]",PADDR(Tmaterials),PT_DESCRIPTION,"interior mass temperature",
00299 PT_double,"air_volume[cf]", PADDR(volume), PT_DESCRIPTION,"air volume",
00300 PT_double,"air_mass[lb]",PADDR(air_mass), PT_DESCRIPTION,"air mass",
00301 PT_double,"air_heat_capacity[Btu/degF]", PADDR(air_thermal_mass), PT_DESCRIPTION,"air thermal mass",
00302 PT_double,"latent_load_fraction[pu]", PADDR(latent_load_fraction), PT_DESCRIPTION,"fractional increase in cooling load due to latent heat",
00303 PT_double,"total_thermal_mass_per_floor_area[Btu/degF*sf]",PADDR(total_thermal_mass_per_floor_area),
00304 PT_double,"interior_surface_heat_transfer_coeff[Btu/h*degF*sf]",PADDR(interior_surface_heat_transfer_coeff),
00305 PT_double,"number_of_stories",PADDR(number_of_stories),PT_DESCRIPTION,"number of stories within the structure",
00306
00307 PT_double,"is_AUX_on",PADDR(is_AUX_on),PT_DESCRIPTION,"logic statement to determine population statistics - is the AUX on? 0 no, 1 yes",
00308 PT_double,"is_HEAT_on",PADDR(is_HEAT_on),PT_DESCRIPTION,"logic statement to determine population statistics - is the HEAT on? 0 no, 1 yes",
00309 PT_double,"is_COOL_on",PADDR(is_COOL_on),PT_DESCRIPTION,"logic statement to determine population statistics - is the COOL on? 0 no, 1 yes",
00310
00311 PT_bool,"thermal_storage_present",PADDR(thermal_storage_present),PT_DESCRIPTION,"logic statement for determining if energy storage is present",
00312 PT_bool,"thermal_storage_in_use",PADDR(thermal_storage_inuse),PT_DESCRIPTION,"logic statement for determining if energy storage is being utilized",
00313
00314 PT_enumeration,"thermostat_mode",PADDR(thermostat_mode),PT_DESCRIPTION,"tells the thermostat whether it is even allowed to heat or cool the house.",
00315 PT_KEYWORD, "OFF", (enumeration)TM_OFF,
00316 PT_KEYWORD, "AUTO", (enumeration)TM_AUTO,
00317 PT_KEYWORD, "HEAT", (enumeration)TM_HEAT,
00318 PT_KEYWORD, "COOL", (enumeration)TM_COOL,
00319
00320 PT_set,"system_type",PADDR(system_type),PT_DESCRIPTION,"heating/cooling system type/options",
00321 PT_KEYWORD, "NONE", (set)ST_NONE,
00322 PT_KEYWORD, "GAS", (set)ST_GAS,
00323 PT_KEYWORD, "AIRCONDITIONING", (set)ST_AC,
00324 PT_KEYWORD, "FORCEDAIR", (set)ST_AIR,
00325 PT_KEYWORD, "TWOSTAGE", (set)ST_VAR,
00326 PT_KEYWORD, "RESISTIVE", (set)ST_RST,
00327 PT_set,"auxiliary_strategy",PADDR(auxiliary_strategy),PT_DESCRIPTION,"auxiliary heating activation strategies",
00328 PT_KEYWORD, "NONE", (set)AX_NONE,
00329 PT_KEYWORD, "DEADBAND", (set)AX_DEADBAND,
00330 PT_KEYWORD, "TIMER", (set)AX_TIMER,
00331 PT_KEYWORD, "LOCKOUT", (set)AX_LOCKOUT,
00332 PT_enumeration,"system_mode",PADDR(system_mode),PT_DESCRIPTION,"heating/cooling system operation state",
00333 PT_KEYWORD,"UNKNOWN",(enumeration)SM_UNKNOWN,
00334 PT_KEYWORD,"HEAT",(enumeration)SM_HEAT,
00335 PT_KEYWORD,"OFF",(enumeration)SM_OFF,
00336 PT_KEYWORD,"COOL",(enumeration)SM_COOL,
00337 PT_KEYWORD,"AUX",(enumeration)SM_AUX,
00338 PT_enumeration,"last_system_mode",PADDR(last_system_mode),PT_DESCRIPTION,"heating/cooling system operation state",
00339 PT_KEYWORD,"UNKNOWN",(enumeration)SM_UNKNOWN,
00340 PT_KEYWORD,"HEAT",(enumeration)SM_HEAT,
00341 PT_KEYWORD,"OFF",(enumeration)SM_OFF,
00342 PT_KEYWORD,"COOL",(enumeration)SM_COOL,
00343 PT_KEYWORD,"AUX",(enumeration)SM_AUX,
00344 PT_enumeration,"heating_system_type",PADDR(heating_system_type),
00345 PT_KEYWORD,"NONE",(enumeration)HT_NONE,
00346 PT_KEYWORD,"GAS",(enumeration)HT_GAS,
00347 PT_KEYWORD,"HEAT_PUMP",(enumeration)HT_HEAT_PUMP,
00348 PT_KEYWORD,"RESISTANCE",(enumeration)HT_RESISTANCE,
00349 PT_enumeration,"cooling_system_type",PADDR(cooling_system_type),
00350 PT_KEYWORD,"NONE",(enumeration)CT_NONE,
00351 PT_KEYWORD,"ELECTRIC",(enumeration)CT_ELECTRIC,
00352 PT_KEYWORD,"HEAT_PUMP",(enumeration)CT_ELECTRIC,
00353 PT_enumeration,"auxiliary_system_type",PADDR(auxiliary_system_type),
00354 PT_KEYWORD,"NONE",(enumeration)AT_NONE,
00355 PT_KEYWORD,"ELECTRIC",(enumeration)AT_ELECTRIC,
00356 PT_enumeration,"fan_type",PADDR(fan_type),
00357 PT_KEYWORD,"NONE",(enumeration)FT_NONE,
00358 PT_KEYWORD,"ONE_SPEED",(enumeration)FT_ONE_SPEED,
00359 PT_KEYWORD,"TWO_SPEED",(enumeration)FT_TWO_SPEED,
00360 PT_enumeration,"thermal_integrity_level",PADDR(thermal_integrity_level),PT_DESCRIPTION,"default envelope UA settings",
00361 PT_KEYWORD,"VERY_LITTLE",(enumeration)TI_VERY_LITTLE,
00362 PT_KEYWORD,"LITTLE",(enumeration)TI_LITTLE,
00363 PT_KEYWORD,"BELOW_NORMAL",(enumeration)TI_BELOW_NORMAL,
00364 PT_KEYWORD,"NORMAL",(enumeration)TI_NORMAL,
00365 PT_KEYWORD,"ABOVE_NORMAL",(enumeration)TI_ABOVE_NORMAL,
00366 PT_KEYWORD,"GOOD",(enumeration)TI_GOOD,
00367 PT_KEYWORD,"VERY_GOOD",(enumeration)TI_VERY_GOOD,
00368 PT_KEYWORD,"UNKNOWN",(enumeration)TI_UNKNOWN,
00369 PT_enumeration, "glass_type", PADDR(glass_type), PT_DESCRIPTION, "glass used in the windows",
00370 PT_KEYWORD,"OTHER",(enumeration)GM_OTHER,
00371 PT_KEYWORD,"GLASS",(enumeration)GM_GLASS,
00372 PT_KEYWORD,"LOW_E_GLASS",(enumeration)GM_LOW_E_GLASS,
00373 PT_enumeration, "window_frame", PADDR(window_frame), PT_DESCRIPTION, "type of window frame",
00374 PT_KEYWORD, "NONE", (enumeration)WF_NONE,
00375 PT_KEYWORD, "ALUMINUM", (enumeration)WF_ALUMINUM,
00376 PT_KEYWORD, "ALUMINIUM", (enumeration)WF_ALUMINUM,
00377 PT_KEYWORD, "THERMAL_BREAK", (enumeration)WF_THERMAL_BREAK,
00378 PT_KEYWORD, "WOOD", (enumeration)WF_WOOD,
00379 PT_KEYWORD, "INSULATED", (enumeration)WF_INSULATED,
00380 PT_enumeration, "glazing_treatment", PADDR(glazing_treatment), PT_DESCRIPTION, "the treatment to increase the reflectivity of the exterior windows",
00381 PT_KEYWORD, "OTHER", (enumeration)GT_OTHER,
00382 PT_KEYWORD, "CLEAR", (enumeration)GT_CLEAR,
00383 PT_KEYWORD, "ABS", (enumeration)GT_ABS,
00384 PT_KEYWORD, "REFL", (enumeration)GT_REFL,
00385 PT_KEYWORD, "LOW_S", (enumeration)GT_LOW_S,
00386 PT_KEYWORD, "HIGH_S", (enumeration)GT_HIGH_S,
00387 PT_enumeration, "glazing_layers", PADDR(glazing_layers), PT_DESCRIPTION, "number of layers of glass in each window",
00388 PT_KEYWORD, "ONE", (enumeration)GL_ONE,
00389 PT_KEYWORD, "TWO", (enumeration)GL_TWO,
00390 PT_KEYWORD, "THREE", (enumeration)GL_THREE,
00391 PT_KEYWORD, "OTHER",(enumeration) GL_OTHER,
00392 PT_enumeration, "motor_model", PADDR(motor_model), PT_DESCRIPTION, "indicates the level of detail used in modelling the hvac motor parameters",
00393 PT_KEYWORD, "NONE", (enumeration)MM_NONE,
00394 PT_KEYWORD, "BASIC", (enumeration)MM_BASIC,
00395 PT_KEYWORD, "FULL", (enumeration)MM_FULL,
00396 PT_enumeration, "motor_efficiency", PADDR(motor_efficiency), PT_DESCRIPTION, "when using motor model, describes the efficiency of the motor",
00397 PT_KEYWORD, "VERY_POOR", (enumeration)ME_VERY_POOR,
00398 PT_KEYWORD, "POOR", (enumeration)ME_POOR,
00399 PT_KEYWORD, "AVERAGE", (enumeration)ME_AVERAGE,
00400 PT_KEYWORD, "GOOD", (enumeration)ME_GOOD,
00401 PT_KEYWORD, "VERY_GOOD", (enumeration)ME_VERY_GOOD,
00402 PT_int64, "last_mode_timer", PADDR(last_mode_timer),
00403 PT_double, "hvac_motor_efficiency[unit]", PADDR(hvac_motor_efficiency), PT_DESCRIPTION, "when using motor model, percent efficiency of hvac motor",
00404 PT_double, "hvac_motor_loss_power_factor[unit]", PADDR(hvac_motor_loss_power_factor), PT_DESCRIPTION, "when using motor model, power factor of motor losses",
00405 PT_double, "Rroof[degF*sf*h/Btu]", PADDR(Rroof),PT_DESCRIPTION,"roof R-value",
00406 PT_double, "Rwall[degF*sf*h/Btu]", PADDR(Rwall),PT_DESCRIPTION,"wall R-value",
00407 PT_double, "Rfloor[degF*sf*h/Btu]", PADDR(Rfloor),PT_DESCRIPTION,"floor R-value",
00408 PT_double, "Rwindows[degF*sf*h/Btu]", PADDR(Rwindows),PT_DESCRIPTION,"window R-value",
00409 PT_double, "Rdoors[degF*sf*h/Btu]", PADDR(Rdoors),PT_DESCRIPTION,"door R-value",
00410 PT_double, "hvac_breaker_rating[A]", PADDR(hvac_breaker_rating), PT_DESCRIPTION,"determines the amount of current the HVAC circuit breaker can handle",
00411 PT_double, "hvac_power_factor[unit]", PADDR(hvac_power_factor), PT_DESCRIPTION,"power factor of hvac",
00412
00413 PT_double,"hvac_load[kW]",PADDR(hvac_load),PT_DESCRIPTION,"heating/cooling system load",
00414 PT_double,"last_heating_load[kW]",PADDR(last_heating_load),PT_DESCRIPTION,"stores the previous heating/cooling system load",
00415 PT_double,"last_cooling_load[kW]",PADDR(last_cooling_load),PT_DESCRIPTION,"stores the previous heating/cooling system load",
00416 PT_complex,"hvac_power[kVA]",PADDR(hvac_power),PT_DESCRIPTION,"describes hvac load complex power consumption",
00417 PT_double,"total_load[kW]",PADDR(total_load),
00418 PT_enduse,"panel",PADDR(total),PT_DESCRIPTION,"total panel enduse load",
00419 PT_double,"design_internal_gain_density[W/sf]",PADDR(design_internal_gain_density),PT_DESCRIPTION,"average density of heat generating devices in the house",
00420 PT_bool,"compressor_on",PADDR(compressor_on),
00421 PT_int64,"compressor_count",PADDR(compressor_count),
00422 PT_timestamp,"hvac_last_on",PADDR(hvac_last_on),
00423 PT_timestamp,"hvac_last_off",PADDR(hvac_last_off),
00424 PT_double,"hvac_period_length[s]",PADDR(hvac_period_length),
00425 PT_double,"hvac_duty_cycle",PADDR(hvac_duty_cycle),
00426
00427
00428 PT_double,"a",PADDR(a),PT_ACCESS,PA_HIDDEN,
00429 PT_double,"b",PADDR(b),PT_ACCESS,PA_HIDDEN,
00430 PT_double,"c",PADDR(c),PT_ACCESS,PA_HIDDEN,
00431 PT_double,"d",PADDR(d),PT_ACCESS,PA_HIDDEN,
00432 PT_double,"c1",PADDR(c1),PT_ACCESS,PA_HIDDEN,
00433 PT_double,"c2",PADDR(c2),PT_ACCESS,PA_HIDDEN,
00434 PT_double,"A3",PADDR(A3),PT_ACCESS,PA_HIDDEN,
00435 PT_double,"A4",PADDR(A4),PT_ACCESS,PA_HIDDEN,
00436 PT_double,"k1",PADDR(k1),PT_ACCESS,PA_HIDDEN,
00437 PT_double,"k2",PADDR(k2),PT_ACCESS,PA_HIDDEN,
00438 PT_double,"r1",PADDR(r1),PT_ACCESS,PA_HIDDEN,
00439 PT_double,"r2",PADDR(r2),PT_ACCESS,PA_HIDDEN,
00440 PT_double,"Teq",PADDR(Teq),PT_ACCESS,PA_HIDDEN,
00441 PT_double,"Tevent",PADDR(Tevent),PT_ACCESS,PA_HIDDEN,
00442 PT_double,"Qi",PADDR(Qi),PT_ACCESS,PA_HIDDEN,
00443 PT_double,"Qa",PADDR(Qa),PT_ACCESS,PA_HIDDEN,
00444 PT_double,"Qm",PADDR(Qm),PT_ACCESS,PA_HIDDEN,
00445 PT_double,"Qh",PADDR(load.heatgain),PT_ACCESS,PA_HIDDEN,
00446 PT_double,"Qlatent",PADDR(Qlatent),PT_ACCESS,PA_HIDDEN,
00447 PT_double,"dTair",PADDR(dTair),PT_ACCESS,PA_HIDDEN,
00448 PT_double,"adj_cooling_cap",PADDR(adj_cooling_cap),PT_ACCESS,PA_HIDDEN,
00449 PT_double,"adj_heating_cap",PADDR(adj_heating_cap),PT_ACCESS,PA_HIDDEN,
00450 PT_double,"adj_cooling_cop",PADDR(adj_cooling_cop),PT_ACCESS,PA_HIDDEN,
00451 PT_double,"adj_heating_cop",PADDR(adj_heating_cop),PT_ACCESS,PA_HIDDEN,
00452
00453
00454 PT_complex,"voltage_12",PADDR(value_Circuit_V[0]),PT_ACCESS,PA_HIDDEN,
00455 PT_complex,"voltage_1N",PADDR(value_Circuit_V[1]),PT_ACCESS,PA_HIDDEN,
00456 PT_complex,"voltage_2N",PADDR(value_Circuit_V[2]),PT_ACCESS,PA_HIDDEN,
00457
00458
00459 PT_double,"grid_frequency",PADDR(value_Frequency),PT_ACCESS,PA_HIDDEN,
00460
00461 PT_enumeration,"thermostat_control", PADDR(thermostat_control), PT_DESCRIPTION, "determine level of internal thermostatic control",
00462 PT_KEYWORD, "FULL", (enumeration)TC_FULL,
00463 PT_KEYWORD, "BAND", (enumeration)TC_BAND,
00464 PT_KEYWORD, "NONE", (enumeration)TC_NONE,
00465 NULL)<1)
00466 GL_THROW("unable to publish properties in %s",__FILE__);
00467
00468 gl_publish_function(oclass, "attach_enduse", (FUNCTIONADDR)attach_enduse_house_e);
00469 gl_global_create("residential::implicit_enduses",PT_set,&implicit_enduses_active,
00470 PT_KEYWORD, "LIGHTS", (set)IEU_LIGHTS,
00471 PT_KEYWORD, "PLUGS", (set)IEU_PLUGS,
00472 PT_KEYWORD, "OCCUPANCY", (set)IEU_OCCUPANCY,
00473 PT_KEYWORD, "DISHWASHER", (set)IEU_DISHWASHER,
00474 PT_KEYWORD, "MICROWAVE", (set)IEU_MICROWAVE,
00475 PT_KEYWORD, "FREEZER", (set)IEU_FREEZER,
00476 PT_KEYWORD, "REFRIGERATOR", (set)IEU_REFRIGERATOR,
00477 PT_KEYWORD, "RANGE", (set)IEU_RANGE,
00478 PT_KEYWORD, "EVCHARGER", (set)IEU_EVCHARGER,
00479 PT_KEYWORD, "WATERHEATER", (set)IEU_WATERHEATER,
00480 PT_KEYWORD, "CLOTHESWASHER", (set)IEU_CLOTHESWASHER,
00481 PT_KEYWORD, "DRYER", (set)IEU_DRYER,
00482 PT_KEYWORD, "NONE", (set)0,
00483 PT_DESCRIPTION, "list of implicit enduses that are active in houses",
00484 NULL);
00485 gl_global_create("residential::implicit_enduse_source",PT_enumeration,&implicit_enduse_source,
00486 PT_KEYWORD,"ELCAP1990", (enumeration)IES_ELCAP1990,
00487 PT_KEYWORD,"ELCAP2010", (enumeration)IES_ELCAP2010,
00488 PT_KEYWORD,"RBSA2014", (enumeration)IES_RBSA2014,
00489 NULL);
00490 gl_global_create("residential::house_low_temperature_warning[degF]",PT_double,&warn_low_temp,
00491 PT_DESCRIPTION, "the low house indoor temperature at which a warning will be generated",
00492 NULL);
00493 gl_global_create("residential::house_high_temperature_warning[degF]",PT_double,&warn_high_temp,
00494 PT_DESCRIPTION, "the high house indoor temperature at which a warning will be generated",
00495 NULL);
00496 gl_global_create("residential::thermostat_control_warning",PT_double,&warn_control,
00497 PT_DESCRIPTION, "boolean to indicate whether a warning is generated when indoor temperature is out of control limits",
00498 NULL);
00499 gl_global_create("residential::system_dwell_time[s]",PT_double,&system_dwell_time,
00500 PT_DESCRIPTION, "the heating/cooling system dwell time interval for changing system state",
00501 NULL);
00502 }
00503 gl_global_create("residential::aux_cutin_temperature[degF]",PT_double,&aux_cutin_temperature,
00504 PT_DESCRIPTION, "the outdoor air temperature below which AUX heating is used",
00505 NULL);
00506
00507 if (gl_publish_function(oclass, "interupdate_res_object", (FUNCTIONADDR)interupdate_house_e)==NULL)
00508 GL_THROW("Unable to publish house_e deltamode function");
00509 if (gl_publish_function(oclass, "postupdate_res_object", (FUNCTIONADDR)postupdate_house_e)==NULL)
00510 GL_THROW("Unable to publish house_e deltamode function");
00511
00512 }
00513
00514 int house_e::create()
00515 {
00516 int result=SUCCESS;
00517 char active_enduses[1025];
00518 gl_global_getvar("residential::implicit_enduses",active_enduses,sizeof(active_enduses));
00519 char *token = NULL;
00520 error_flag = 0;
00521
00522
00523
00524 glazing_shgc = 0;
00525 load.power_fraction = 0.8;
00526 load.impedance_fraction = 0.2;
00527 load.current_fraction = 0.0;
00528 design_internal_gain_density = 0.6;
00529 thermal_integrity_level = TI_UNKNOWN;
00530 hvac_breaker_rating = 0;
00531 hvac_power_factor = 0;
00532 Tmaterials = 0.0;
00533
00534 cooling_supply_air_temp = 50.0;
00535 heating_supply_air_temp = 150.0;
00536
00537 heating_system_type = HT_HEAT_PUMP;
00538 cooling_system_type = CT_UNKNOWN;
00539 auxiliary_system_type = AT_UNKNOWN;
00540 fan_type = FT_UNKNOWN;
00541 fan_power_factor = 0.96;
00542 fan_current_fraction = 0.7332;
00543 fan_impedance_fraction = 0.2534;
00544 fan_power_fraction = 0.0135;
00545
00546 glazing_layers = GL_TWO;
00547 glass_type = GM_LOW_E_GLASS;
00548 glazing_treatment = GT_CLEAR;
00549 window_frame = WF_THERMAL_BREAK;
00550 motor_model = MM_NONE;
00551 motor_efficiency = ME_AVERAGE;
00552 hvac_motor_efficiency = 1;
00553 hvac_motor_loss_power_factor = 0.125;
00554 hvac_motor_real_loss = 0;
00555 hvac_motor_reactive_loss = 0;
00556 is_AUX_on = is_HEAT_on = is_COOL_on = 0;
00557
00558
00559 thermal_storage_present = false;
00560 thermal_storage_inuse = false;
00561
00562
00563 implicit_enduse_list = NULL;
00564 if (strcmp(active_enduses,"NONE")!=0)
00565 {
00566 char *eulist[64];
00567 char n_eu=0;
00568
00569
00570 while ((token=strtok(token?NULL:active_enduses,"|"))!=NULL)
00571 eulist[n_eu++] = token;
00572
00573 while (n_eu-->0)
00574 {
00575 char *euname = eulist[n_eu];
00576 _strlwr(euname);
00577
00578
00579 struct s_implicit_enduse_list *eu = NULL;
00580 int found=0;
00581 switch ( implicit_enduse_source ) {
00582 case IES_ELCAP1990:
00583 eu = elcap1990;
00584 break;
00585 case IES_ELCAP2010:
00586 gl_warning("ELCAP2010 implicit enduse data is not valid for individual enduses");
00587 eu = elcap2010;
00588 break;
00589 case IES_RBSA2014:
00590 gl_warning("RBSA2010 implicit enduse data is not valid for individual enduses");
00591 eu = rbsa2014;
00592 break;
00593 default:
00594 gl_error("implicit enduse source '%d' is not recognized, using default ELCAP1990 instead", implicit_enduse_source);
00595 eu = elcap1990;
00596 break;
00597 }
00598 for ( ; eu->implicit_name!=NULL ; eu++)
00599 {
00600 char name[64];
00601 sprintf(name,"residential-%s-default",euname);
00602
00603 if (strcmp(eu->schedule_name,name)==0)
00604 {
00605 SCHEDULE *sched = gl_schedule_find(name);
00606 if (sched==NULL){
00607 sched = gl_schedule_create(eu->schedule_name,eu->schedule_definition);
00608 }
00609 if(sched == NULL){
00610 gl_error("error creating schedule for enduse \'%s\'", eu->schedule_name);
00611 return FAILED;
00612 }
00613 IMPLICITENDUSE *item = (IMPLICITENDUSE*)gl_malloc(sizeof(IMPLICITENDUSE));
00614 memset(item,0,sizeof(IMPLICITENDUSE));
00615 gl_enduse_create(&(item->load));
00616 item->load.shape = gl_loadshape_create(sched);
00617 if (gl_set_value_by_type(PT_loadshape,item->load.shape,eu->shape)==0)
00618 {
00619 gl_error("loadshape '%s' could not be created", name);
00620 result = FAILED;
00621 }
00622 item->load.name = eu->implicit_name;
00623 item->next = implicit_enduse_list;
00624 item->amps = eu->load.breaker_amps;
00625 item->is220 = eu->load.circuit_is220;
00626 item->load.impedance_fraction = eu->load.fractions.z;
00627 item->load.current_fraction = eu->load.fractions.i;
00628 item->load.power_fraction = eu->load.fractions.p;
00629 item->load.power_factor = eu->load.power_factor;
00630 item->load.heatgain_fraction = eu->load.heat_fraction;
00631 implicit_enduse_list = item;
00632 found=1;
00633 break;
00634 }
00635 }
00636 if (found==0)
00637 {
00638 gl_error("house_e data for '%s' implicit enduse not found", euname);
00639 result = FAILED;
00640 }
00641 }
00642 }
00643 total.name = "panel";
00644 load.name = "system";
00645
00646
00647 include_solar_quadrant = 0x001e;
00648 UA = -1;
00649 airchange_per_hour = -1;
00650 heating_cop_curve = HC_DEFAULT;
00651 heating_cap_curve = HP_DEFAULT;
00652 cooling_cop_curve = CC_DEFAULT;
00653 cooling_cap_curve = CP_DEFAULT;
00654 thermostat_off_cycle_time = -1;
00655 thermostat_on_cycle_time = -1;
00656 use_latent_heat = true;
00657 include_fan_heatgain = true;
00658 fan_design_power = -1;
00659 heating_setpoint = 0.0;
00660 cooling_setpoint = 0.0;
00661 panel.max_amps = 0.0;
00662 system_type = 0;
00663 heating_COP = 0;
00664 cooling_COP = 0;
00665 number_of_stories = 0;
00666 aspect_ratio = 0;
00667 floor_area = 0;
00668 gross_wall_area = 0;
00669 window_wall_ratio = 0;
00670 window_roof_ratio = 0;
00671 interior_exterior_wall_ratio = 0;
00672 exterior_wall_fraction = 0;
00673 exterior_ceiling_fraction = 0;
00674 exterior_floor_fraction = 0;
00675 window_exterior_transmission_coefficient = 0;
00676 Rroof = 0;
00677 Rwall = 0;
00678 Rwindows = 0;
00679 Rdoors = 0;
00680 volume = 0;
00681 air_mass = 0;
00682 air_thermal_mass = 0;
00683 air_heat_fraction = 0;
00684 mass_solar_gain_fraction = 0;
00685 mass_internal_gain_fraction = 0;
00686 total_thermal_mass_per_floor_area = 0;
00687 interior_surface_heat_transfer_coeff = 0;
00688 airchange_UA = 0;
00689 envelope_UA = 0;
00690 design_cooling_setpoint = 0;
00691 design_heating_setpoint = 0;
00692 design_peak_solar = 0;
00693 thermostat_deadband = 0;
00694 thermostat_cycle_time = 0;
00695 Tair = 0;
00696 over_sizing_factor = 0;
00697 cooling_design_temperature = 0;
00698 design_internal_gains = 0;
00699 latent_load_fraction = 0;
00700 design_cooling_capacity = 0;
00701 design_heating_capacity = 0;
00702 system_mode = SM_UNKNOWN;
00703 last_system_mode = SM_UNKNOWN;
00704 last_mode_timer = 0;
00705 aux_heat_capacity = 0;
00706 aux_heat_deadband = 0;
00707 aux_heat_temp_lockout = 0;
00708 aux_heat_time_delay = 0;
00709 duct_pressure_drop = 0;
00710 fan_design_airflow = 0;
00711 fan_low_power_fraction = 0;
00712 fan_power = 0;
00713 house_content_thermal_mass = 0;
00714 house_content_heat_transfer_coeff = 0;
00715
00716
00717 window_openings = FALSE;
00718 window_open = 0;
00719 window_low_temp = 60;
00720 window_high_temp = 80;
00721 window_a = 0;
00722 window_b = 0;
00723 window_c = 1;
00724 window_temp_delta = 5;
00725 last_temperature = 75;
00726 thermostat_mode = TM_AUTO;
00727
00728
00729 deltamode_inclusive = false;
00730 deltamode_registered = false;
00731
00732
00733 pCircuit_V[0] = pCircuit_V[1] = pCircuit_V[2] = NULL;
00734 pLine_I[0] = pLine_I[1] = pLine_I[2] = NULL;
00735 pShunt[0] = pShunt[1] = pShunt[2] = NULL;
00736 pPower[0] = pPower[1] = pPower[2] = NULL;
00737 pMeterStatus = NULL;
00738 pFrequency = NULL;
00739
00740
00741 value_Circuit_V[0] = complex(2.0*default_line_voltage,0.0);
00742 value_Circuit_V[1] = complex(default_line_voltage,0.0);
00743 value_Circuit_V[2] = complex(default_line_voltage,0.0);
00744 value_Line_I[0] = value_Line_I[1] = value_Line_I[2] = complex(0.0,0.0);
00745 value_Shunt[0] = value_Shunt[1] = value_Shunt[2] = complex(0.0,0.0);
00746 value_Power[0] = value_Power[1] = value_Power[2] = complex(0.0,0.0);
00747 value_MeterStatus = 1;
00748 value_Frequency = 60.0;
00749
00750 proper_meter_parent = false;
00751 proper_climate_found = false;
00752
00753
00754 pTout = NULL;
00755 pRhout = NULL;
00756 pSolar[0] = pSolar[1] = pSolar[2] = pSolar[3] = pSolar[4] = NULL;
00757 pSolar[5] = pSolar[6] = pSolar[7] = pSolar[8] = NULL;
00758
00759
00760 value_Tout = 74.0;
00761 value_Rhout = 75.0;
00762 value_Solar[0] = value_Solar[1] = value_Solar[2] = value_Solar[3] = value_Solar[4] = 0.0;
00763 value_Solar[5] = value_Solar[6] = value_Solar[7] = value_Solar[8] = 0.0;
00764
00765 return result;
00766 }
00767
00772 int house_e::init_climate()
00773 {
00774 gld_property *temp_property = NULL;
00775 OBJECT *hdr = OBJECTHDR(this);
00776
00777
00778 FINDLIST *climates = NULL;
00779 int not_found = 0;
00780 if (climates==NULL && not_found==0)
00781 {
00782 climates = gl_find_objects(FL_NEW,FT_CLASS,SAME,"climate",FT_END);
00783 if (climates==NULL)
00784 {
00785 not_found = 1;
00786 gl_warning("house_e: no climate data found, using static data");
00787
00788
00789 value_Tout = default_outdoor_temperature;
00790 value_Rhout = default_humidity;
00791 value_Solar[0] = default_horizontal_solar;
00792
00793
00794 proper_climate_found = false;
00795 }
00796 else if (climates->hit_count>1 && weather != 0)
00797 {
00798 gl_warning("house_e: %d climates found, using first one defined", climates->hit_count);
00799 }
00800 }
00801 if (climates!=NULL)
00802 {
00803 if (climates->hit_count==0)
00804 {
00805
00806 gl_warning("house_e: no climate data found, using static data");
00807
00808 value_Tout = default_outdoor_temperature;
00809 value_Rhout = default_humidity;
00810 value_Solar[0] = default_horizontal_solar;
00811
00812
00813 proper_climate_found = false;
00814 }
00815 else
00816 {
00817
00818 OBJECT *obj = NULL;
00819 if(weather == NULL){
00820 obj = gl_find_next(climates,NULL);
00821 weather = obj;
00822 } else {
00823 obj = weather;
00824 }
00825 if (obj->rank<=hdr->rank)
00826 gl_set_dependent(obj,hdr);
00827
00828
00829 pTout = map_double_value(obj,"temperature");
00830 pRhout = map_double_value(obj,"humidity");
00831 pSolar[0] = map_double_value(obj,"solar_horiz");
00832 pSolar[1] = map_double_value(obj,"solar_north");
00833 pSolar[2] = map_double_value(obj,"solar_northeast");
00834 pSolar[3] = map_double_value(obj,"solar_east");
00835 pSolar[4] = map_double_value(obj,"solar_southeast");
00836 pSolar[5] = map_double_value(obj,"solar_south");
00837 pSolar[6] = map_double_value(obj,"solar_southwest");
00838 pSolar[7] = map_double_value(obj,"solar_west");
00839 pSolar[8] = map_double_value(obj,"solar_northwest");
00840
00841
00842 proper_climate_found = true;
00843
00844
00845 temp_property = map_double_value(obj,"record.high");
00846
00847
00848 cooling_design_temperature = temp_property->get_double();
00849
00850
00851 delete temp_property;
00852
00853
00854 temp_property = map_double_value(obj,"record.low");
00855
00856
00857 heating_design_temperature = temp_property->get_double();
00858
00859
00860 delete temp_property;
00861
00862 if((obj->flags & OF_INIT) != OF_INIT){
00863 char objname[256];
00864 gl_verbose("house::init(): deferring initialization on %s", gl_name(obj, objname, 255));
00865 return 0;
00866 }
00867 }
00868 }
00869 return 1;
00870 }
00871
00872 int house_e::isa(char *classname)
00873 {
00874 return (strcmp(classname,"house")==0 || residential_enduse::isa(classname));
00875 }
00876
00877 void house_e::set_thermal_integrity(){
00878 switch (thermal_integrity_level) {
00879 case TI_VERY_LITTLE:
00880 if(Rroof <= 0.0) Rroof = 11;
00881 if(Rwall <= 0.0) Rwall = 4;
00882 if(Rfloor <= 0.0) Rfloor = 4;
00883 if(Rdoors <= 0.0) Rdoors = 3;
00884 if(Rwindows <= 0.0) Rwindows = 1/1.27;
00885 if(airchange_per_hour < 0.0) airchange_per_hour = 1.5;
00886 break;
00887 case TI_LITTLE:
00888 if(Rroof <= 0.0) Rroof = 19;
00889 if(Rwall <= 0.0) Rwall = 11;
00890 if(Rfloor <= 0.0) Rfloor = 4;
00891 if(Rdoors <= 0.0) Rdoors = 3;
00892 if(Rwindows <= 0.0) Rwindows = 1/0.81;
00893 if(airchange_per_hour < 0.0) airchange_per_hour = 1.5;
00894 break;
00895 case TI_BELOW_NORMAL:
00896 if(Rroof <= 0.0) Rroof = 19;
00897 if(Rwall <= 0.0) Rwall = 11;
00898 if(Rfloor <= 0.0) Rfloor = 11;
00899 if(Rdoors <= 0.0) Rdoors = 3;
00900 if(Rwindows <= 0.0) Rwindows = 1/0.81;
00901 if(airchange_per_hour < 0.0) airchange_per_hour = 1.0;
00902 break;
00903 case TI_NORMAL:
00904 if(Rroof <= 0.0) Rroof = 30;
00905 if(Rwall <= 0.0) Rwall = 11;
00906 if(Rfloor <= 0.0) Rfloor = 19;
00907 if(Rdoors <= 0.0) Rdoors = 3;
00908 if(Rwindows <= 0.0) Rwindows = 1/0.6;
00909 if(airchange_per_hour < 0.0) airchange_per_hour = 1.0;
00910 break;
00911 case TI_ABOVE_NORMAL:
00912 if(Rroof <= 0.0) Rroof = 30;
00913 if(Rwall <= 0.0) Rwall = 19;
00914 if(Rfloor <= 0.0) Rfloor = 11;
00915 if(Rdoors <= 0.0) Rdoors = 3;
00916 if(Rwindows <= 0.0) Rwindows = 1/0.6;
00917 if(airchange_per_hour < 0.0) airchange_per_hour = 1.0;
00918 break;
00919 case TI_GOOD:
00920 if(Rroof <= 0.0) Rroof = 30;
00921 if(Rwall <= 0.0) Rwall = 19;
00922 if(Rfloor <= 0.0) Rfloor = 22;
00923 if(Rdoors <= 0.0) Rdoors = 5;
00924 if(Rwindows <= 0.0) Rwindows = 1/0.47;
00925 if(airchange_per_hour < 0.0) airchange_per_hour = 0.5;
00926 break;
00927 case TI_VERY_GOOD:
00928 if(Rroof <= 0.0) Rroof = 48;
00929 if(Rwall <= 0.0) Rwall = 22;
00930 if(Rfloor <= 0.0) Rfloor = 30;
00931 if(Rdoors <= 0.0) Rdoors = 11;
00932 if(Rwindows <= 0.0) Rwindows = 1/0.31;
00933 if(airchange_per_hour < 0.0) airchange_per_hour = 0.5;
00934 break;
00935 case TI_UNKNOWN:
00936
00937 break;
00938 default:
00939
00940 break;
00941 }
00942 }
00943
00944
00945 void house_e::set_window_shgc(){
00946 switch(glazing_layers){
00947 case GL_ONE:
00948 switch(glazing_treatment){
00949 case GT_CLEAR:
00950 switch(window_frame){
00951 case WF_NONE:
00952 glazing_shgc = 0.86;
00953 break;
00954 case WF_ALUMINUM:
00955 case WF_THERMAL_BREAK:
00956 glazing_shgc = 0.75;
00957 break;
00958 case WF_WOOD:
00959 case WF_INSULATED:
00960 glazing_shgc = 0.64;
00961 break;
00962 }
00963 break;
00964 case GT_ABS:
00965 switch(window_frame){
00966 case WF_NONE:
00967 glazing_shgc = 0.73;
00968 break;
00969 case WF_ALUMINUM:
00970 case WF_THERMAL_BREAK:
00971 glazing_shgc = 0.64;
00972 break;
00973 case WF_WOOD:
00974 case WF_INSULATED:
00975 glazing_shgc = 0.54;
00976 break;
00977 }
00978 break;
00979 case GT_REFL:
00980 switch(window_frame){
00981 case WF_NONE:
00982 glazing_shgc = 0.31;
00983 break;
00984 case WF_ALUMINUM:
00985 case WF_THERMAL_BREAK:
00986 glazing_shgc = 0.28;
00987 break;
00988 case WF_WOOD:
00989 case WF_INSULATED:
00990 glazing_shgc = 0.24;
00991 break;
00992 }
00993 break;
00994 }
00995 break;
00996 case GL_TWO:
00997 switch(glazing_treatment){
00998 case GT_CLEAR:
00999 switch(window_frame){
01000 case WF_NONE:
01001 glazing_shgc = 0.76;
01002 break;
01003 case WF_ALUMINUM:
01004 case WF_THERMAL_BREAK:
01005 glazing_shgc = 0.67;
01006 break;
01007 case WF_WOOD:
01008 case WF_INSULATED:
01009 glazing_shgc = 0.57;
01010 break;
01011 }
01012 break;
01013 case GT_ABS:
01014 switch(window_frame){
01015 case WF_NONE:
01016 glazing_shgc = 0.62;
01017 break;
01018 case WF_ALUMINUM:
01019 case WF_THERMAL_BREAK:
01020 glazing_shgc = 0.55;
01021 break;
01022 case WF_WOOD:
01023 case WF_INSULATED:
01024 glazing_shgc = 0.46;
01025 break;
01026 }
01027 break;
01028 case GT_REFL:
01029 switch(window_frame){
01030 case WF_NONE:
01031 glazing_shgc = 0.29;
01032 break;
01033 case WF_ALUMINUM:
01034 case WF_THERMAL_BREAK:
01035 glazing_shgc = 0.27;
01036 break;
01037 case WF_WOOD:
01038 case WF_INSULATED:
01039 glazing_shgc = 0.22;
01040 break;
01041 }
01042 break;
01043 case GT_LOW_S:
01044 switch(window_frame){
01045 case WF_NONE:
01046 glazing_shgc = 0.41;
01047 break;
01048 case WF_ALUMINUM:
01049 case WF_THERMAL_BREAK:
01050 glazing_shgc = 0.37;
01051 break;
01052 case WF_WOOD:
01053 case WF_INSULATED:
01054 glazing_shgc = 0.31;
01055 break;
01056 }
01057 break;
01058 case GT_HIGH_S:
01059 switch(window_frame){
01060 case WF_NONE:
01061 glazing_shgc = 0.70;
01062 break;
01063 case WF_ALUMINUM:
01064 case WF_THERMAL_BREAK:
01065 glazing_shgc = 0.62;
01066 break;
01067 case WF_WOOD:
01068 case WF_INSULATED:
01069 glazing_shgc = 0.52;
01070 break;
01071 }
01072 break;
01073 }
01074 break;
01075 case GL_THREE:
01076 switch(glazing_treatment){
01077 case GT_CLEAR:
01078 switch(window_frame){
01079 case WF_NONE:
01080 glazing_shgc = 0.68;
01081 break;
01082 case WF_ALUMINUM:
01083 case WF_THERMAL_BREAK:
01084 glazing_shgc = 0.60;
01085 break;
01086 case WF_WOOD:
01087 case WF_INSULATED:
01088 glazing_shgc = 0.51;
01089 break;
01090 }
01091 break;
01092 case GT_ABS:
01093 switch(window_frame){
01094 case WF_NONE:
01095 glazing_shgc = 0.34;
01096 break;
01097 case WF_ALUMINUM:
01098 case WF_THERMAL_BREAK:
01099 glazing_shgc = 0.31;
01100 break;
01101 case WF_WOOD:
01102 case WF_INSULATED:
01103 glazing_shgc = 0.26;
01104 break;
01105 }
01106 break;
01107 case GT_REFL:
01108 switch(window_frame){
01109 case WF_NONE:
01110 glazing_shgc = 0.34;
01111 break;
01112 case WF_ALUMINUM:
01113 case WF_THERMAL_BREAK:
01114 glazing_shgc = 0.31;
01115 break;
01116 case WF_WOOD:
01117 case WF_INSULATED:
01118 glazing_shgc = 0.26;
01119 break;
01120 }
01121 break;
01122 case GT_LOW_S:
01123 switch(window_frame){
01124 case WF_NONE:
01125 glazing_shgc = 0.27;
01126 break;
01127 case WF_ALUMINUM:
01128 case WF_THERMAL_BREAK:
01129 glazing_shgc = 0.25;
01130 break;
01131 case WF_WOOD:
01132 case WF_INSULATED:
01133 glazing_shgc = 0.21;
01134 break;
01135 }
01136 break;
01137 case GT_HIGH_S:
01138 switch(window_frame){
01139 case WF_NONE:
01140 glazing_shgc = 0.62;
01141 break;
01142 case WF_ALUMINUM:
01143 case WF_THERMAL_BREAK:
01144 glazing_shgc = 0.55;
01145 break;
01146 case WF_WOOD:
01147 case WF_INSULATED:
01148 glazing_shgc = 0.46;
01149 break;
01150 }
01151 break;
01152 }
01153 break;
01154 }
01155 }
01156
01157 void house_e::set_window_Rvalue(){
01158 if(glass_type == GM_LOW_E_GLASS){
01159 switch(glazing_layers){
01160 case GL_ONE:
01161 gl_error("no value for one pane of low-e glass");
01162 break;
01163 case GL_TWO:
01164 switch(window_frame){
01165 case WF_NONE:
01166 Rwindows = 1.0/0.30;
01167 break;
01168 case WF_ALUMINUM:
01169 Rwindows = 1.0/0.67;
01170 break;
01171 case WF_THERMAL_BREAK:
01172 Rwindows = 1.0/0.47;
01173 break;
01174 case WF_WOOD:
01175 Rwindows = 1.0/0.41;
01176 break;
01177 case WF_INSULATED:
01178 Rwindows = 1.0/0.33;
01179 break;
01180 }
01181 break;
01182 case GL_THREE:
01183 switch(window_frame){
01184 case WF_NONE:
01185 Rwindows = 1/0.27;
01186 break;
01187 case WF_ALUMINUM:
01188 Rwindows = 1/0.64;
01189 break;
01190 case WF_THERMAL_BREAK:
01191 Rwindows = 1/0.43;
01192 break;
01193 case WF_WOOD:
01194 Rwindows = 1/0.37;
01195 break;
01196 case WF_INSULATED:
01197 Rwindows = 1/0.31;
01198 break;
01199 }
01200 break;
01201 }
01202 } else if(glass_type == GM_GLASS){
01203 switch(glazing_layers){
01204 case GL_ONE:
01205 switch(window_frame){
01206 case WF_NONE:
01207 Rwindows = 1/1.04;
01208 break;
01209 case WF_ALUMINUM:
01210 Rwindows = 1/1.27;
01211 break;
01212 case WF_THERMAL_BREAK:
01213 Rwindows = 1/1.08;
01214 break;
01215 case WF_WOOD:
01216 Rwindows = 1/0.90;
01217 break;
01218 case WF_INSULATED:
01219 Rwindows = 1/0.81;
01220 break;
01221 }
01222 break;
01223 case GL_TWO:
01224 switch(window_frame){
01225 case WF_NONE:
01226 Rwindows = 1/0.48;
01227 break;
01228 case WF_ALUMINUM:
01229 Rwindows = 1/0.81;
01230 break;
01231 case WF_THERMAL_BREAK:
01232 Rwindows = 1/0.60;
01233 break;
01234 case WF_WOOD:
01235 Rwindows = 1/0.53;
01236 break;
01237 case WF_INSULATED:
01238 Rwindows = 1/0.44;
01239 break;
01240 }
01241 break;
01242 case GL_THREE:
01243 switch(window_frame){
01244 case WF_NONE:
01245 Rwindows = 1/0.31;
01246 break;
01247 case WF_ALUMINUM:
01248 Rwindows = 1/0.67;
01249 break;
01250 case WF_THERMAL_BREAK:
01251 Rwindows = 1/0.46;
01252 break;
01253 case WF_WOOD:
01254 Rwindows = 1/0.40;
01255 break;
01256 case WF_INSULATED:
01257 Rwindows = 1/0.34;
01258 break;
01259 }
01260 break;
01261 }
01262 } else {
01263 Rwindows = 2.0;
01264 }
01265 }
01270 int house_e::init(OBJECT *parent)
01271 {
01272 gld_property *meter_house_present;
01273 gld_wlock *test_rlock;
01274 bool temp_bool_val;
01275
01276 if(parent != NULL){
01277 if((parent->flags & OF_INIT) != OF_INIT){
01278 char objname[256];
01279 gl_verbose("house::init(): deferring initialization on %s", gl_name(parent, objname, 255));
01280 return 2;
01281 }
01282 }
01283 OBJECT *hdr = OBJECTHDR(this);
01284 hdr->flags |= OF_SKIPSAFE;
01285
01286 heat_start = false;
01287
01288
01289 OBJECT *obj = OBJECTHDR(this);
01290 if (parent!=NULL && (gl_object_isa(parent,"triplex_meter","powerflow") || gl_object_isa(obj->parent,"triplex_node","powerflow")))
01291 {
01292
01293 meter_house_present = new gld_property(parent,"house_present");
01294
01295
01296 if ((meter_house_present->is_valid() != true) || (meter_house_present->is_bool() != true))
01297 {
01298 gl_error("house:%d - %s - Failed to map powerflow variable",obj->id,(obj->name ? obj->name : "Unnamed"));
01299
01300
01301
01302
01303
01304 return 0;
01305 }
01306
01307
01308 temp_bool_val = true;
01309 meter_house_present->setp<bool>(temp_bool_val,*test_rlock);
01310
01311
01312 delete meter_house_present;
01313
01314
01315 pCircuit_V[0] = map_complex_value(parent,"voltage_12");
01316 pCircuit_V[1] = map_complex_value(parent,"voltage_1N");
01317 pCircuit_V[2] = map_complex_value(parent,"voltage_2N");
01318
01319
01320 pLine_I[0] = map_complex_value(parent,"residential_nominal_current_1");
01321 pLine_I[1] = map_complex_value(parent,"residential_nominal_current_2");
01322 pLine_I[2] = map_complex_value(parent,"residential_nominal_current_12");
01323
01324
01325 pShunt[0] = map_complex_value(parent,"shunt_1");
01326 pShunt[1] = map_complex_value(parent,"shunt_2");
01327 pShunt[2] = map_complex_value(parent,"shunt_12");
01328
01329
01330 pPower[0] = map_complex_value(parent,"power_1");
01331 pPower[1] = map_complex_value(parent,"power_2");
01332 pPower[2] = map_complex_value(parent,"power_12");
01333
01334
01335 pMeterStatus = new gld_property(parent,"service_status");
01336
01337
01338 if ((pMeterStatus->is_valid() != true) || (pMeterStatus->is_enumeration() != true))
01339 {
01340 GL_THROW("house:%d - %s - Failed to map meter status variable from parent",obj->id,(obj->name ? obj->name : "Unnamed"));
01341
01342
01343
01344
01345 }
01346
01347
01348 pFrequency = map_double_value(parent,"measured_frequency");
01349
01350
01351 proper_meter_parent = true;
01352 }
01353 else
01354 {
01355 gl_warning("house_e:%d %s; using static voltages", obj->id, parent==NULL?"has no parent triplex_meter defined":"parent is not a triplex_meter");
01356
01357
01358 value_Circuit_V[0] = complex(2.0*default_line_voltage,0.0);
01359 value_Circuit_V[1] = complex(default_line_voltage,0.0);
01360 value_Circuit_V[2] = complex(default_line_voltage,0.0);
01361
01362
01363 pCircuit_V[0] = map_complex_value(obj,"voltage_12");
01364 pCircuit_V[1] = map_complex_value(obj,"voltage_1N");
01365 pCircuit_V[2] = map_complex_value(obj,"voltage_2N");
01366
01367
01368 proper_meter_parent = false;
01369
01370
01371 value_Frequency = default_grid_frequency;
01372
01373
01374 pFrequency = map_double_value(obj,"grid_frequency");
01375 }
01376
01377
01378 simulation_beginning_time = gl_globalclock;
01379
01380
01381 if (panel.max_amps==0) panel.max_amps = 200;
01382 load.power = complex(0,0,J);
01383
01384
01385
01386 if(system_type & ST_GAS) heating_system_type = HT_GAS;
01387 else if (system_type & ST_RST) heating_system_type = HT_RESISTANCE;
01388 if(system_type & ST_AC) cooling_system_type = CT_ELECTRIC;
01389 if(system_type & ST_AIR) fan_type = FT_ONE_SPEED;
01390 if(system_type & ST_VAR) fan_type = FT_TWO_SPEED;
01391
01392 if(heating_system_type == HT_HEAT_PUMP && fan_type == FT_NONE){
01393 fan_type = FT_ONE_SPEED;
01394 }
01395
01396 if(system_type != 0){
01397 if(heating_system_type == HT_UNKNOWN) heating_system_type = HT_NONE;
01398 if(cooling_system_type == CT_UNKNOWN) cooling_system_type = CT_NONE;
01399 if(fan_type == FT_UNKNOWN) fan_type = FT_NONE;
01400 if(auxiliary_system_type == AT_UNKNOWN){
01401 auxiliary_system_type = AT_NONE;
01402 auxiliary_strategy = 0;
01403 }
01404 }
01405 if(system_type == 0){
01406 if(heating_system_type == HT_UNKNOWN) heating_system_type = HT_HEAT_PUMP;
01407 if(cooling_system_type == CT_UNKNOWN) cooling_system_type = CT_ELECTRIC;
01408 if(fan_type == FT_UNKNOWN) fan_type = FT_ONE_SPEED;
01409 if(auxiliary_system_type == AT_UNKNOWN && heating_system_type == HT_HEAT_PUMP){
01410 auxiliary_system_type = AT_ELECTRIC;
01411 auxiliary_strategy = AX_DEADBAND;
01412 }
01413 } else if(!(system_type & ST_GAS) && !(system_type & ST_RST)){
01414
01415 auxiliary_system_type = AT_ELECTRIC;
01416 auxiliary_strategy = AX_DEADBAND;
01417 }
01418
01419 if(heating_system_type == HT_HEAT_PUMP) {
01420 if(cooling_system_type == CT_NONE)
01421 gl_warning("A HEAT_PUMP heating_system_type with no air conditioning does not make a lot of sense. You may encounter odd behavior with house %s",obj->name);
01422 else if(cooling_system_type == CT_UNKNOWN) {
01423 gl_warning("A HEAT_PUMP heating_system_type with no air conditioning does not make a lot of sense. Setting cooling_system_type to ELECTRIC.");
01424 cooling_system_type = CT_ELECTRIC;
01425 }
01426 }
01427
01428
01429 set_thermal_integrity();
01430
01431
01432 if (heating_COP==0.0) heating_COP = 2.5;
01433 if (heating_COP < 0.0) heating_COP = -heating_COP;
01434 if (cooling_COP==0.0) cooling_COP = 3.5;
01435 if (cooling_COP < 0.0) cooling_COP = -cooling_COP;
01436
01437 if (number_of_stories < 1.0)
01438 number_of_stories = 1.0;
01439 if (fmod(number_of_stories, 1.0) != 0.0){
01440 number_of_stories = floor(number_of_stories);
01441
01442 }
01443 if (aspect_ratio==0.0) aspect_ratio = 1.5;
01444 if (floor_area==0) floor_area = 2500.0;
01445 if (ceiling_height==0) ceiling_height = 8.0;
01446 if (gross_wall_area==0) gross_wall_area = 2.0 * number_of_stories * (aspect_ratio + 1.0) * ceiling_height * sqrt(floor_area/aspect_ratio/number_of_stories);
01447 if (window_wall_ratio==0) window_wall_ratio = 0.15;
01448 if (window_roof_ratio==0) window_roof_ratio = 0.0;
01449 if (number_of_doors==0) number_of_doors = 4.0;
01450 else number_of_doors = floor(number_of_doors);
01451 if (interior_exterior_wall_ratio == 0) interior_exterior_wall_ratio = 1.5;
01452 if (exterior_wall_fraction==0) exterior_wall_fraction = 1.0;
01453 if (exterior_ceiling_fraction==0) exterior_ceiling_fraction = 1.0;
01454 if (exterior_floor_fraction==0) exterior_floor_fraction = 1.0;
01455 if (window_exterior_transmission_coefficient<=0) window_exterior_transmission_coefficient = 0.60;
01456
01457 if (glazing_shgc <= 0.0) set_window_shgc();
01458 if (Rroof<=0) Rroof = 30.0;
01459 if (Rwall<=0) Rwall = 19.0;
01460 if (Rfloor<=0) Rfloor = 22.0;
01461 if (Rwindows<=0) set_window_Rvalue();
01462 if (Rdoors<=0) Rdoors = 5.0;
01463
01464 air_density = 0.0735;
01465 air_heat_capacity = 0.2402;
01466
01467
01468 if (volume==0) volume = ceiling_height*floor_area;
01469 if (air_mass==0) air_mass = air_density*volume;
01470 if (air_thermal_mass==0) air_thermal_mass = 3*air_heat_capacity*air_mass;
01471
01472 if (air_heat_fraction!=0) {
01473 gl_warning("The air_heat_fraction is no longer used to determine heat gain/loss to the air. Setting mass_solar_gain_fraction and mass_internal_gain_fraction to 1-air_heat_fraction specified for house %s.", obj->name);
01474 mass_solar_gain_fraction=1-air_heat_fraction;
01475 mass_internal_gain_fraction=1-air_heat_fraction;
01476 }
01477 if (mass_solar_gain_fraction==0) mass_solar_gain_fraction=0.5;
01478 if (mass_internal_gain_fraction==0) mass_internal_gain_fraction=0.5;
01479 if (air_heat_fraction<0.0 || air_heat_fraction>1.0) throw "air heat fraction is not between 0 and 1";
01480 if (mass_solar_gain_fraction<0.0 || mass_solar_gain_fraction>1.0) throw "the solar gain fraction to mass is not between 0 and 1";
01481 if (mass_internal_gain_fraction<0.0 || mass_internal_gain_fraction>1.0) throw "the internal gain fraction to mass is not between 0 and 1";
01482 if (total_thermal_mass_per_floor_area <= 0.0) total_thermal_mass_per_floor_area = 2.0;
01483 if (interior_surface_heat_transfer_coeff <= 0.0) interior_surface_heat_transfer_coeff = 1.46;
01484
01485 if (airchange_per_hour<0) airchange_per_hour = 0.5;
01486 if (airchange_UA <= 0) airchange_UA = airchange_per_hour * volume * air_density * air_heat_capacity;
01487
01488 double door_area = number_of_doors * 3.0 * 78.0 / 12.0;
01489 double window_area = gross_wall_area * window_wall_ratio * exterior_wall_fraction;
01490 double net_exterior_wall_area = exterior_wall_fraction * gross_wall_area - window_area - door_area;
01491 double exterior_ceiling_area = floor_area * exterior_ceiling_fraction / number_of_stories;
01492 double exterior_floor_area = floor_area * exterior_floor_fraction / number_of_stories;
01493
01494 if (envelope_UA==0) envelope_UA = exterior_ceiling_area/Rroof + exterior_floor_area/Rfloor + net_exterior_wall_area/Rwall + window_area/Rwindows + door_area/Rdoors;
01495 if(UA < 0){
01496 UA = envelope_UA + airchange_UA;
01497 }
01498 solar_heatgain_factor = window_area * glazing_shgc * window_exterior_transmission_coefficient;
01499
01500
01501 if (heating_setpoint==0.0) heating_setpoint = 70.0;
01502 if (cooling_setpoint==0.0) cooling_setpoint = 75.0;
01503 if (design_cooling_setpoint==0.0) design_cooling_setpoint = 75.0;
01504 if (design_heating_setpoint==0.0) design_heating_setpoint = 70.0;
01505 if (design_peak_solar<=0.0) design_peak_solar = 195.0;
01506
01507 if (thermostat_deadband<=0.0) thermostat_deadband = 2.0;
01508 if (thermostat_cycle_time<=0.0) thermostat_cycle_time = 120;
01509 if (Tair==0.0){
01510
01511 double Thigh = cooling_setpoint+thermostat_deadband/2.0;
01512 double Tlow = heating_setpoint-thermostat_deadband/2.0;
01513 Thigh = clip(Thigh, 60.0, 140.0);
01514 Tlow = clip(Tlow, 60.0, 140.0);
01515 Tair = gl_random_uniform(RNGSTATE,Tlow, Thigh);
01516 }
01517 if (over_sizing_factor<=0.0) over_sizing_factor = 0.0;
01518 if (cooling_design_temperature == 0.0) cooling_design_temperature = 95.0;
01519 if (design_internal_gains<=0.0) design_internal_gains = 167.09 * pow(floor_area,0.442);
01520 if (latent_load_fraction<=0.0) latent_load_fraction = 0.30;
01521
01522 double round_value = 0.0;
01523 if (design_cooling_capacity<=0.0 && cooling_system_type != CT_NONE)
01524 {
01525 round_value = 0.0;
01526 design_cooling_capacity = (1.0 + over_sizing_factor) * (1.0 + latent_load_fraction) * ((UA) * (cooling_design_temperature - design_cooling_setpoint) + design_internal_gains + (design_peak_solar * solar_heatgain_factor));
01527 round_value = (design_cooling_capacity) / 6000.0;
01528 design_cooling_capacity = ceil(round_value) * 6000.0;
01529 }
01530
01531 if(auxiliary_system_type != AT_NONE && heating_system_type == HT_NONE)
01532 {
01533 static int aux_for_rst = 0;
01534 if(aux_for_rst == 0){
01535 gl_warning("house_e heating strategies with auxiliary heat but without normal heating modes are converted"
01536 "to resistively heated houses, see house %s",obj->name);
01537 aux_for_rst = 1;
01538 }
01539 heating_system_type = HT_RESISTANCE;
01540 }
01541
01542 if (design_heating_capacity<=0 && heating_system_type != HT_NONE)
01543 {
01544 double round_value = 0.0;
01545 if(heating_system_type == HT_HEAT_PUMP){
01546 design_heating_capacity = design_cooling_capacity;
01547 } else {
01548 design_heating_capacity = (1.0 + over_sizing_factor) * (UA) * (design_heating_setpoint - heating_design_temperature);
01549 round_value = (design_heating_capacity) / 10000.0;
01550 design_heating_capacity = ceil(round_value) * 10000.0;
01551 }
01552 }
01553
01554 if (system_mode==SM_UNKNOWN) system_mode = SM_OFF;
01555 if (last_system_mode == SM_UNKNOWN) last_system_mode = SM_OFF;
01556 if (last_mode_timer == 0) last_mode_timer = 3600*6;
01557
01558 if (aux_heat_capacity<=0.0 && auxiliary_system_type != AT_NONE)
01559 {
01560 double round_value = 0.0;
01561 aux_heat_capacity = (1.0 + over_sizing_factor) * (UA) * (design_heating_setpoint - heating_design_temperature);
01562 round_value = (aux_heat_capacity) / 10000.0;
01563 aux_heat_capacity = ceil(round_value) * 10000.0;
01564 }
01565
01566 if (aux_heat_deadband<=0.0) aux_heat_deadband = thermostat_deadband;
01567 if (aux_heat_temp_lockout<=0.0) aux_heat_temp_lockout = 10;
01568 if (aux_heat_time_delay<=0.0) aux_heat_time_delay = 300.0;
01569
01570 if (duct_pressure_drop<=0.0) duct_pressure_drop = 0.5;
01571 if (fan_design_airflow<=0.0){
01572 double design_heating_cfm;
01573 double design_cooling_cfm;
01574 double gtr_cfm;
01575
01576 design_heating_cfm = (design_heating_capacity > aux_heat_capacity ? design_heating_capacity : aux_heat_capacity) / (air_density * air_heat_capacity * (heating_supply_air_temp - design_heating_setpoint)) / 60.0;
01577 design_cooling_cfm = design_cooling_capacity / (1.0 + latent_load_fraction) / (air_density * air_heat_capacity * (design_cooling_setpoint - cooling_supply_air_temp)) / 60.0;
01578 gtr_cfm = (design_heating_cfm > design_cooling_cfm ? design_heating_cfm : design_cooling_cfm);
01579 fan_design_airflow = gtr_cfm;
01580 }
01581
01582 if (fan_design_power<0.0){
01583 double roundval;
01584
01585 roundval = ceil((0.117 * duct_pressure_drop * fan_design_airflow / 0.42 / 745.7)*8);
01586 fan_design_power = roundval / 8.0 * 745.7 / 0.88;
01587 }
01588
01589 if (fan_low_power_fraction<=0.0 && fan_type == FT_TWO_SPEED)
01590 fan_low_power_fraction = 0.5;
01591 if (fan_power <= 0.0) fan_power = 0.0;
01592
01593 if (house_content_thermal_mass==0) house_content_thermal_mass = total_thermal_mass_per_floor_area*floor_area - 2 * air_heat_capacity*air_mass;
01594 if (house_content_heat_transfer_coeff==0) house_content_heat_transfer_coeff =
01595 interior_surface_heat_transfer_coeff * (
01596
01597 (gross_wall_area - window_area - door_area)
01598 + gross_wall_area * interior_exterior_wall_ratio + number_of_stories * exterior_ceiling_area / exterior_ceiling_fraction);
01599
01600 if(Tair == 0){
01601 if (system_mode==SM_OFF)
01602 Tair = gl_random_uniform(RNGSTATE,heating_setpoint,cooling_setpoint);
01603 else if (system_mode==SM_HEAT || system_mode==SM_AUX)
01604 Tair = gl_random_uniform(RNGSTATE,heating_setpoint-thermostat_deadband/2,heating_setpoint+thermostat_deadband/2);
01605 else if (system_mode==SM_COOL)
01606 Tair = gl_random_uniform(RNGSTATE,cooling_setpoint-thermostat_deadband/2,cooling_setpoint+thermostat_deadband/2);
01607 }
01608
01609 if (Tmaterials == 0.0)
01610 Tmaterials = Tair;
01611
01612
01613 if (motor_model != MM_NONE)
01614 {
01615 if ( hvac_motor_loss_power_factor > 1 || hvac_motor_loss_power_factor < -1 )
01616 GL_THROW("hvac_motor_power_factor must have a value between -1 and 1");
01617 if ( hvac_motor_efficiency > 1 || hvac_motor_efficiency < 0 )
01618 GL_THROW("hvac_motor_efficiency must have a value between 0 and 1");
01619 switch(motor_efficiency){
01620 case ME_VERY_POOR:
01621 hvac_motor_efficiency = 0.8236;
01622 break;
01623 case ME_POOR:
01624 hvac_motor_efficiency = 0.8488;
01625 break;
01626 case ME_AVERAGE:
01627 hvac_motor_efficiency = 0.8740;
01628 break;
01629 case ME_GOOD:
01630 hvac_motor_efficiency = 0.9020;
01631 break;
01632 case ME_VERY_GOOD:
01633 hvac_motor_efficiency = 0.9244;
01634 break;
01635 default:
01636 gl_warning("Unknown motor_efficiency setting. Setting to AVERAGE.");
01637 hvac_motor_efficiency = 0.8740;
01638 motor_efficiency = ME_AVERAGE;
01639 break;
01640 }
01641 }
01642
01643
01644
01645 #define Ca (air_thermal_mass)
01646 #define Tout (outside_temperature)
01647 #define Cm (house_content_thermal_mass)
01648 #define Ua (UA)
01649 #define Hm (house_content_heat_transfer_coeff)
01650 #define Qs (solar_load)
01651 #define Qh (load.heatgain)
01652 #define Ta (Tair)
01653 #define dTa (dTair)
01654 #define Tm (Tmaterials)
01655
01656 if (Ca<=0)
01657 throw "air_thermal_mass must be positive";
01658 if (Cm<=0)
01659 throw "house_content_thermal_mass must be positive";
01660 if(Hm <= 0)
01661 throw "house_content_heat_transfer_coeff must be positive";
01662 if(Ua < 0)
01663 throw "UA must be positive";
01664
01665 a = Cm*Ca/Hm;
01666 b = Cm*(Ua+Hm)/Hm+Ca;
01667 c = Ua;
01668 c1 = -(Ua + Hm)/Ca;
01669 c2 = Hm/Ca;
01670 double rr = sqrt(b*b-4*a*c)/(2*a);
01671 double r = -b/(2*a);
01672 r1 = r+rr;
01673 r2 = r-rr;
01674 A3 = Ca/Hm * r1 + (Ua+Hm)/Hm;
01675 A4 = air_thermal_mass/Hm * r2 + (Ua+Hm)/Hm;
01676
01677
01678 outside_temperature = default_outdoor_temperature;
01679
01680 if (hvac_power_factor == 0)
01681 load.power_factor = 0.97;
01682 else
01683 load.power_factor = hvac_power_factor;
01684
01685
01686 attach_implicit_enduses();
01687 update_system();
01688 if(error_flag == 1){
01689 return 0;
01690 }
01691 update_model();
01692
01693
01694 if (hvac_breaker_rating == 0)
01695 {
01696 load.breaker_amps = 200;
01697 hvac_breaker_rating = 200;
01698 }
01699 else
01700 load.breaker_amps = hvac_breaker_rating;
01701 load.config = EUC_IS220;
01702 attach(OBJECTHDR(this),hvac_breaker_rating, true, &load);
01703
01704 if(include_fan_heatgain == TRUE){
01705 fan_heatgain_fraction = 1;
01706 } else {
01707 fan_heatgain_fraction = 0;
01708 }
01709
01710
01711 if ((all_house_delta == true) && (enable_subsecond_models==true))
01712 {
01713 obj->flags |= OF_DELTAMODE;
01714 }
01715
01716
01717 if ((obj->flags & OF_DELTAMODE) == OF_DELTAMODE)
01718 {
01719 deltamode_inclusive = true;
01720 }
01721
01722
01723 if (deltamode_inclusive)
01724 {
01725
01726 if (enable_subsecond_models!=true)
01727 {
01728 gl_warning("house_e:%s indicates it wants to run deltamode, but the module-level flag is not set!",obj->name?obj->name:"unnamed");
01729
01730
01731
01732
01733
01734
01735 deltamode_inclusive = false;
01736 }
01737 else
01738 {
01739 res_object_count++;
01740 }
01741 }
01742 else
01743 {
01744 if (enable_subsecond_models == true)
01745 {
01746 gl_warning("house_e:%d %s - Deltamode is enabled for the module, but not this house!",obj->id,(obj->name ? obj->name : "Unnamed"));
01747
01748
01749
01750
01751
01752 }
01753 }
01754
01755 return 1;
01756 }
01757
01758 void house_e::attach_implicit_enduses()
01759 {
01760 IMPLICITENDUSE *item;
01761 for (item=implicit_enduse_list; item!=NULL; item=item->next){
01762 attach(NULL,item->amps,item->is220,&(item->load));
01763 if (item->is220)
01764 item->load.config |= EUC_IS220;
01765 }
01766
01767 return;
01768 }
01769
01774 CIRCUIT *house_e::attach(OBJECT *obj,
01775 double breaker_amps,
01776 int is220,
01777 enduse *pLoad)
01778 {
01779
01780 CIRCUIT *c = new CIRCUIT;
01781 if (c==NULL)
01782 {
01783 gl_error("memory allocation failure");
01784 return 0;
01785
01786
01787 }
01788 c->next = panel.circuits;
01789 c->id = panel.circuits ? panel.circuits->id+1 : 1;
01790
01791
01792 c->max_amps = breaker_amps;
01793
01794
01795 if (pLoad)
01796 c->pLoad = pLoad;
01797 else if (obj)
01798 {
01799 c->pLoad = (enduse*)gl_get_addr(obj,"enduse_load");
01800 if (c->pLoad==NULL)
01801 GL_THROW("end-use load %s couldn't be connected because it does not publish 'enduse_load' property", c->pLoad->name);
01802 }
01803 else
01804 GL_THROW("end-use load couldn't be connected neither an object nor a enduse property was given");
01805
01806
01807 if (is220 == 1)
01808 {
01809 c->type = X12;
01810 c->id++;
01811 }
01812 else if (c->id&0x01)
01813 c->type = X13;
01814 else
01815 c->type = X23;
01816
01817
01818 panel.circuits = c;
01819
01820
01821 c->pV = pCircuit_V[(int)c->type];
01822
01823
01824 c->pfrequency;
01825
01826
01827 c->status = BRK_CLOSED;
01828
01829
01830
01831 c->tripsleft = 100;
01832
01833 return c;
01834 }
01835
01836 void house_e::update_model(double dt)
01837 {
01838
01839
01840 incident_solar_radiation = 0;
01841 horizontal_diffuse_solar_radiation = 0;
01842 north_incident_solar_radiation = 0;
01843 north_west_incident_solar_radiation = 0;
01844 west_incident_solar_radiation = 0;
01845 south_west_incident_solar_radiation = 0;
01846 south_incident_solar_radiation = 0;
01847 south_east_incident_solar_radiation = 0;
01848 east_incident_solar_radiation = 0;
01849 north_east_incident_solar_radiation = 0;
01850 double number_of_quadrants = 0;
01851
01852
01853 if (Ca<=0)
01854 throw "air_thermal_mass must be positive";
01855 if (Cm<=0)
01856 throw "house_content_thermal_mass must be positive";
01857 if(Hm <= 0)
01858 throw "house_content_heat_transfer_coeff must be positive";
01859 if(Ua < 0)
01860 throw "UA must be positive";
01861
01862 a = Cm*Ca/Hm;
01863
01864 if (window_open == 1)
01865 {
01866 b = Cm*(10*Ua+Hm)/Hm+Ca;
01867 c = 10*Ua;
01868 c1 = -(10*Ua + Hm)/Ca;
01869 }
01870 else
01871 {
01872 b = Cm*(Ua+Hm)/Hm+Ca;
01873 c = Ua;
01874 c1 = -(Ua + Hm)/Ca;
01875 }
01876
01877 c2 = Hm/Ca;
01878 double rr = sqrt(b*b-4*a*c)/(2*a);
01879 double r = -b/(2*a);
01880 r1 = r+rr;
01881 r2 = r-rr;
01882
01883 if (window_open == 1)
01884 {
01885 A3 = Ca/Hm * r1 + (10*Ua+Hm)/Hm;
01886 A4 = Ca/Hm * r2 + (10*Ua+Hm)/Hm;
01887 }
01888 else
01889 {
01890 A3 = Ca/Hm * r1 + (Ua+Hm)/Hm;
01891 A4 = Ca/Hm * r2 + (Ua+Hm)/Hm;
01892 }
01893
01894
01895 if (proper_climate_found == true)
01896 {
01897 pull_climate_values();
01898 }
01899
01900 horizontal_diffuse_solar_radiation = 3.412*value_Solar[0];
01901 north_incident_solar_radiation = 3.412*value_Solar[1];
01902 north_east_incident_solar_radiation = 3.412*value_Solar[2];
01903 east_incident_solar_radiation = 3.412*value_Solar[3];
01904 south_east_incident_solar_radiation = 3.412*value_Solar[4];
01905 south_incident_solar_radiation = 3.412*value_Solar[5];
01906 south_west_incident_solar_radiation = 3.412*value_Solar[6];
01907 west_incident_solar_radiation = 3.412*value_Solar[7];
01908 north_west_incident_solar_radiation = 3.412*value_Solar[8];
01909
01910
01911 if((include_solar_quadrant & 0x0002) == 0x0002){
01912 incident_solar_radiation += value_Solar[1];
01913 incident_solar_radiation += value_Solar[2]/2;
01914 incident_solar_radiation += value_Solar[8]/2;
01915 if((include_solar_quadrant & 0x0001) == 0x0001){
01916 incident_solar_radiation += 2*value_Solar[0];
01917 }
01918 }
01919 if((include_solar_quadrant & 0x0004) == 0x0004){
01920 incident_solar_radiation += value_Solar[3];
01921 incident_solar_radiation += value_Solar[2]/2;
01922 incident_solar_radiation += value_Solar[4]/2;
01923 if((include_solar_quadrant & 0x0001) == 0x0001){
01924 incident_solar_radiation += 2*value_Solar[0];
01925 }
01926 }
01927 if((include_solar_quadrant & 0x0008) == 0x0008){
01928 incident_solar_radiation += value_Solar[5];
01929 incident_solar_radiation += value_Solar[4]/2;
01930 incident_solar_radiation += value_Solar[6]/2;
01931 if((include_solar_quadrant & 0x0001) == 0x0001){
01932 incident_solar_radiation += 2*value_Solar[0];
01933 }
01934 }
01935 if((include_solar_quadrant & 0x0010) == 0x0010){
01936 incident_solar_radiation += value_Solar[7];
01937 incident_solar_radiation += value_Solar[6]/2;
01938 incident_solar_radiation += value_Solar[8]/2;
01939 if((include_solar_quadrant & 0x0001) == 0x0001){
01940 incident_solar_radiation += 2*value_Solar[0];
01941 }
01942 }
01943
01944 incident_solar_radiation *= 3.412/8;
01945 Qs = incident_solar_radiation*solar_heatgain_factor;
01946
01947
01948
01949
01950 if (Qs<0)
01951 throw "solar gain is negative";
01952
01953
01954 Qi = total.heatgain - load.heatgain;
01955 Qa = Qh + (1-mass_internal_gain_fraction)*Qi + (1-mass_solar_gain_fraction)*Qs;
01956 Qm = mass_internal_gain_fraction*Qi + mass_solar_gain_fraction*Qs;
01957
01958 if (window_open == 1)
01959 d = Qa + Qm + (10*Ua)*Tout;
01960 else
01961 d = Qa + Qm + (Ua)*Tout;
01962 Teq = d/c;
01963
01964
01965 dTa = c2*Tm + c1*Ta - (c1+c2)*Tout + Qa/Ca;
01966 k1 = (r2*Tair - r2*Teq - dTa)/(r2-r1);
01967 k2 = Tair - Teq - k1;
01968
01969
01970 }
01971
01979 void house_e::update_system(double dt)
01980 {
01981
01983
01984 double heating_cop_adj=0;
01985 double cooling_cop_adj=0;
01986 double temp_temperature=0;
01987 double heating_capacity_adj=0;
01988 double cooling_capacity_adj=0;
01989 double temp_c;
01990
01991
01992 if (proper_climate_found == true)
01993 {
01994 pull_climate_values();
01995 }
01996
01997 temp_c = 5*(value_Tout - 32)/9;
01998
01999 if(heating_cop_curve == HC_DEFAULT){
02000 if(value_Tout > 80){
02001 temp_temperature = 80;
02002 heating_cop_adj = heating_COP / (2.03914613 - 0.03906753*temp_temperature + 0.00045617*temp_temperature*temp_temperature - 0.00000203*temp_temperature*temp_temperature*temp_temperature);
02003 } else {
02004 heating_cop_adj = heating_COP / (2.03914613 - 0.03906753*value_Tout + 0.00045617*value_Tout*value_Tout - 0.00000203*value_Tout*value_Tout*value_Tout);
02005 }
02006 }
02007 if(heating_cop_curve == HC_FLAT){
02008 heating_cop_adj = heating_COP;
02009 }
02010 if(heating_cop_curve == HC_LINEAR){
02011 if(value_Tout >= 47){
02012 heating_cop_adj = heating_COP;
02013 } else {
02014 heating_cop_adj = heating_COP*(value_Tout/47);
02015 }
02016 }
02017 if(heating_cop_curve == HC_CURVED){
02018 gl_error("CURVED heating_cop_curve is not supported yet.");
02019 error_flag = 1;
02020 }
02021
02022 if(cooling_cop_curve == CC_DEFAULT){
02023 if(value_Tout < 40){
02024 temp_temperature = 40;
02025 cooling_cop_adj = cooling_COP / (-0.01363961 + 0.01066989*temp_temperature);
02026 } else {
02027 cooling_cop_adj = cooling_COP / (-0.01363961 + 0.01066989*value_Tout);
02028 }
02029 }
02030 if(cooling_cop_curve == CC_FLAT){
02031 cooling_cop_adj = cooling_COP;
02032 }
02033 if(cooling_cop_curve == CC_LINEAR){
02034 if(temp_c <= 35){
02035 cooling_cop_adj = cooling_COP;
02036 } else {
02037 cooling_cop_adj = cooling_COP*35/temp_c;
02038 }
02039 }
02040 if(cooling_cop_curve == CC_CURVED){
02041 gl_error("CURVE cooling_cop_curve is not supported yet.");
02042 error_flag = 1;
02043 }
02044
02045 adj_cooling_cop = cooling_cop_adj;
02046 adj_heating_cop = heating_cop_adj;
02047
02048 if(heating_cap_curve == HP_DEFAULT){
02049 heating_capacity_adj = design_heating_capacity*(0.34148808 + 0.00894102*value_Tout + 0.00010787*value_Tout*value_Tout);
02050 }
02051 if(heating_cap_curve == HP_FLAT){
02052 heating_capacity_adj = design_heating_capacity;
02053 }
02054 if(heating_cap_curve == HP_LINEAR){
02055 gl_error("LINEAR heating_cap_curve is not supported at this time");
02056 error_flag = 1;
02057 }
02058 if(heating_cap_curve == HP_CURVED){
02059 gl_error("CURVED heating _cap_curve is not supported at this time");
02060 error_flag = 1;
02061 }
02062
02063 if(cooling_cap_curve == CP_DEFAULT){
02064 cooling_capacity_adj = design_cooling_capacity*(1.48924533 - 0.00514995*value_Tout);
02065 }
02066 if(cooling_cap_curve == CP_FLAT){
02067 cooling_capacity_adj = design_cooling_capacity;
02068 }
02069 if(cooling_cap_curve == CP_LINEAR){
02070 gl_error("LINEAR cooling_cap_curve is not supported at this time");
02071 error_flag = 1;
02072 }
02073 if(cooling_cap_curve == CP_CURVED){
02074 gl_error("CURVED cooling_cap_curve is not supported at this time");
02075 error_flag = 1;
02076 }
02077
02078
02079 adj_cooling_cap = cooling_capacity_adj;
02080 adj_heating_cap = heating_capacity_adj;
02081 #pragma warning("house_e: add update_system voltage adjustment for heating")
02082 double voltage_adj = (((value_Circuit_V[0]).Mag() * (value_Circuit_V[0]).Mag()) / (240.0 * 240.0) * load.impedance_fraction + ((value_Circuit_V[0]).Mag() / 240.0) * load.current_fraction + load.power_fraction);
02083 double voltage_adj_resistive = ((value_Circuit_V[0]).Mag() * (value_Circuit_V[0]).Mag()) / (240.0 * 240.0);
02084
02085
02086 if (value_MeterStatus!=0)
02087 {
02088
02089 Qlatent = 0;
02090
02091
02092 switch(heating_system_type){
02093 case HT_NONE:
02094 case HT_GAS:
02095 heating_demand = 0.0;
02096 break;
02097 case HT_RESISTANCE:
02098 heating_demand = design_heating_capacity*KWPBTUPH;
02099 break;
02100 case HT_HEAT_PUMP:
02101 if(system_mode == SM_AUX){
02102 heating_demand = aux_heat_capacity*KWPBTUPH;
02103 } else {
02104 heating_demand = heating_capacity_adj / heating_cop_adj * KWPBTUPH;
02105 }
02106 break;
02107 }
02108 switch(cooling_system_type){
02109 case CT_NONE:
02110 cooling_demand = 0.0;
02111 break;
02112 case CT_ELECTRIC:
02113 if (thermal_storage_present == false)
02114 {
02115 cooling_demand = cooling_capacity_adj / cooling_cop_adj * KWPBTUPH;
02116 }
02117 else
02118 {
02119 cooling_demand = 0.0;
02120 }
02121 break;
02122 }
02123
02124 switch (system_mode) {
02125 case SM_HEAT:
02126
02127 if(fan_type != FT_NONE)
02128 fan_power = fan_design_power/1000.0;
02129 else
02130 fan_power = 0.0;
02131
02132
02133 thermal_storage_inuse = false;
02134
02135
02136
02137 switch(heating_system_type){
02138 case HT_NONE:
02139
02140 system_rated_capacity = 0.0;
02141 system_rated_power = 0.0;
02142 fan_power = 0.0;
02143 break;
02144 case HT_RESISTANCE:
02145
02146 system_rated_capacity = design_heating_capacity*voltage_adj_resistive + fan_power*BTUPHPKW*fan_heatgain_fraction;
02147 system_rated_power = heating_demand;
02148 break;
02149 case HT_HEAT_PUMP:
02150
02151 system_rated_capacity = heating_capacity_adj*voltage_adj + fan_power*BTUPHPKW*fan_heatgain_fraction;
02152 system_rated_power = heating_demand;
02153 break;
02154 case HT_GAS:
02155 heating_demand = 0.0;
02156 system_rated_capacity = design_heating_capacity + fan_power*BTUPHPKW*fan_heatgain_fraction;
02157 system_rated_power = heating_demand;
02158 break;
02159 }
02160 break;
02161 case SM_AUX:
02162
02163 if(fan_type != FT_NONE)
02164 fan_power = fan_design_power/1000.0;
02165 else
02166 fan_power = 0.0;
02167
02168
02169 thermal_storage_inuse = false;
02170
02171 switch(auxiliary_system_type){
02172 case AT_NONE:
02173
02174 system_rated_capacity = 0.0;
02175 system_rated_power = 0.0;
02176 break;
02177 case AT_ELECTRIC:
02178
02179 system_rated_capacity = aux_heat_capacity*voltage_adj_resistive + fan_power*BTUPHPKW*fan_heatgain_fraction;
02180 system_rated_power = heating_demand;
02181 break;
02182 }
02183 break;
02184 case SM_COOL:
02185
02186 if(fan_type != FT_NONE)
02187 fan_power = fan_design_power/1000.0;
02188 else
02189 fan_power = 0.0;
02190
02191
02192
02193 switch(cooling_system_type){
02194 case CT_NONE:
02195
02196 system_rated_capacity = 0.0;
02197 system_rated_power = 0.0;
02198 fan_power = 0.0;
02199 thermal_storage_inuse = false;
02200 break;
02201 case CT_ELECTRIC:
02202 if (thermal_storage_present == false)
02203 {
02204
02205
02206 if(use_latent_heat == TRUE){
02207 system_rated_capacity = -cooling_capacity_adj / (1 + 0.1 + latent_load_fraction/(1 + exp(4-10*value_Rhout)))*voltage_adj + fan_power*BTUPHPKW*fan_heatgain_fraction;
02208 Qlatent = -cooling_capacity_adj*voltage_adj*((1/(1 + 0.1 + latent_load_fraction/(1 + exp(4-10*value_Rhout))))-1);
02209 } else {
02210 system_rated_capacity = -cooling_capacity_adj*voltage_adj + fan_power*BTUPHPKW*fan_heatgain_fraction;
02211 Qlatent = 0;
02212 }
02213 system_rated_power = cooling_demand;
02214 thermal_storage_inuse = false;
02215 }
02216 else
02217 {
02218 system_rated_capacity = fan_power*BTUPHPKW*fan_heatgain_fraction;
02219 system_rated_power = cooling_demand;
02220 thermal_storage_inuse = true;
02221 }
02222 break;
02223 }
02224 break;
02225 default:
02226
02227 if(fan_type == FT_TWO_SPEED){
02228 fan_power = fan_design_power * fan_low_power_fraction / 1000.0;
02229 } else {
02230 fan_power = 0.0;
02231 }
02232 system_rated_capacity = fan_power*BTUPHPKW*fan_heatgain_fraction;
02233 system_rated_power = 0.0;
02234 thermal_storage_inuse = false;
02235
02236 }
02237
02238
02239 if(include_fan_heatgain == TRUE){
02240 load.total = system_rated_power + fan_power;
02241 } else {
02242 load.total = system_rated_power;
02243 }
02244 load.heatgain = system_rated_capacity;
02245
02246 if( (cooling_system_type == CT_ELECTRIC && system_mode == SM_COOL) ||
02247 (heating_system_type == HT_HEAT_PUMP && system_mode == SM_HEAT)) {
02248 load.power.SetRect(load.power_fraction * load.total.Re() , load.power_fraction * load.total.Re() * sqrt( 1 / (load.power_factor*load.power_factor) - 1) );
02249 load.admittance.SetRect(load.impedance_fraction * load.total.Re() , load.impedance_fraction * load.total.Re() * sqrt( 1 / (load.power_factor*load.power_factor) - 1) );
02250 load.current.SetRect(load.current_fraction * load.total.Re(), load.current_fraction * load.total.Re() * sqrt( 1 / (load.power_factor*load.power_factor) - 1) );
02251
02252
02253
02254 if (motor_model == MM_BASIC)
02255 {
02256 if (system_mode == SM_HEAT)
02257 {
02258 hvac_motor_real_loss = hvac_motor_loss_power_factor*(1 - hvac_motor_efficiency) * sqrt( design_heating_capacity*KWPBTUPH*design_heating_capacity*KWPBTUPH / (load.power_factor*load.power_factor*heating_COP*heating_COP) );
02259 hvac_motor_reactive_loss = sqrt( 1 / (hvac_motor_loss_power_factor*hvac_motor_loss_power_factor) - 1) * hvac_motor_real_loss;
02260 }
02261 else if (system_mode == SM_COOL)
02262 {
02263 hvac_motor_real_loss = hvac_motor_loss_power_factor*(1 - hvac_motor_efficiency) * sqrt( design_cooling_capacity*KWPBTUPH*design_cooling_capacity*KWPBTUPH / (load.power_factor*load.power_factor*cooling_COP*cooling_COP) );
02264 hvac_motor_reactive_loss = sqrt( 1 / (hvac_motor_loss_power_factor*hvac_motor_loss_power_factor) - 1) * hvac_motor_real_loss;
02265 }
02266
02267 load.admittance += complex(hvac_motor_real_loss,hvac_motor_reactive_loss);
02268 }
02269 else if (motor_model == MM_FULL)
02270 gl_warning("FULL motor model is not yet supported. No losses are assumed.");
02271
02272 } else {
02273
02274
02275 load.power.SetRect(fan_power * fan_power_fraction, fan_power * fan_power_fraction * sqrt( 1 / (fan_power_factor * fan_power_factor) - 1));
02276 load.admittance.SetRect(system_rated_power + fan_power * fan_impedance_fraction, fan_power * fan_impedance_fraction * sqrt( 1 / (fan_power_factor * fan_power_factor) - 1));
02277 load.current.SetRect(fan_power * fan_current_fraction, fan_power * fan_current_fraction * sqrt( 1 / (fan_power_factor * fan_power_factor) - 1));
02278 }
02279 }
02280 else
02281 {
02282 load.total = 0.0;
02283 load.power = 0.0;
02284 load.admittance = 0.0;
02285 load.current = 0.0;
02286 load.heatgain = 0.0;
02287 }
02288
02289
02290 hvac_load = load.total.Re() * (load.power_fraction + load.voltage_factor*(load.current_fraction + load.impedance_fraction*load.voltage_factor));
02291 if (system_mode == SM_COOL)
02292 last_cooling_load = hvac_load;
02293 else if (system_mode == SM_AUX || system_mode == SM_HEAT)
02294 last_heating_load = hvac_load;
02295 hvac_power = load.power + load.admittance*load.voltage_factor*load.voltage_factor + load.current*load.voltage_factor;
02296
02297 if(compressor_on){
02298
02299 if(system_mode == SM_AUX || system_mode == SM_OFF){
02300 compressor_on = false;
02301 }
02302 } else {
02303 if( (system_mode == SM_HEAT && heating_system_type == HT_HEAT_PUMP) ||
02304 (system_mode == SM_COOL && cooling_system_type == CT_ELECTRIC)){
02305 compressor_on = true;
02306 ++compressor_count;
02307 }
02308 }
02309 }
02310
02313 TIMESTAMP house_e::presync(TIMESTAMP t0, TIMESTAMP t1)
02314 {
02315 OBJECT *obj = OBJECTHDR(this);
02316 const double dt = (double)((t1-t0)*TS_SECOND)/3600;
02317 CIRCUIT *c;
02318
02319 extern bool enable_subsecond_models;
02320 extern OBJECT **delta_objects;
02321 extern FUNCTIONADDR *delta_functions;
02322 extern FUNCTIONADDR *post_delta_functions;
02323 extern int res_object_count;
02324 extern int res_object_current;
02325 extern void allocate_deltamode_arrays(void);
02326
02327
02328 value_Power[0] = value_Power[1] = value_Power[2] = complex(0.0,0.0);
02329 value_Line_I[0] = value_Line_I[1] = value_Line_I[2] = complex(0.0,0.0);
02330 value_Shunt[0] = value_Shunt[1] = value_Shunt[2] = complex(0.0,0.0);
02331
02332
02333 if (t0>0 && dt>0)
02334 {
02335
02336 if (c2!=0)
02337 {
02338
02339 const double e1 = k1*exp(r1*dt);
02340 const double e2 = k2*exp(r2*dt);
02341 Tair = e1 + e2 + Teq;
02342 if (window_open == 1)
02343 Tmaterials = A3*e1 + A4*e2 + Qm/Hm + (Qm+Qa)/(10*Ua) + Tout;
02344 else
02345 Tmaterials = A3*e1 + A4*e2 + Qm/Hm + (Qm+Qa)/(Ua) + Tout;
02346 }
02347 }
02348
02349 if (window_openings == TRUE)
02350 {
02351 if (window_high_temp <= window_low_temp)
02352 {
02353 gl_error("The high window temperature cutoff must be greater than the low window temperature cutoff.");
02354
02355
02356
02357
02358
02359 }
02360 if (Tout >= window_low_temp && Tout <= window_high_temp)
02361 {
02362
02363 if ( window_first_time_through == 1 )
02364 {
02365 window_first_time_through = 0;
02366
02367 double random_val = gl_random_uniform(RNGSTATE,0,1);
02368 double calc_val = window_a * Tout * Tout + window_b * Tout + window_c;
02369
02370 if (calc_val > 1.0)
02371 {
02372 gl_verbose("Function value for window_opening calculation was greater than 1 (%.2f). Capping value at 1.", calc_val);
02373
02374
02375
02376
02377
02378
02379 calc_val = 1.01;
02380 }
02381 else if (calc_val < 0.)
02382 {
02383 gl_verbose("Function value for window_opening calculation was less than 0 (%.2f). Capping value at 0.", calc_val);
02384
02385
02386
02387
02388
02389
02390 calc_val = -0.01;
02391 }
02392
02393 if (random_val <= calc_val)
02394 {
02395 window_open = 1;
02396 last_temperature = Tout;
02397 }
02398 else
02399 {
02400 window_open = 0;
02401 }
02402 }
02403
02404 else if ( abs(last_temperature - Tout) > window_temp_delta )
02405 {
02406 double random_val = gl_random_uniform(RNGSTATE,0,1);
02407 double calc_val = window_a * Tout * Tout + window_b * Tout + window_c;
02408
02409 if (calc_val > 1.0)
02410 {
02411 gl_verbose("Function value for window_opening calculation was greater than 1 or less than 0 (%.2f). Limiting to that range", calc_val);
02412 calc_val = 1.01;
02413 }
02414 else if (calc_val < 0.)
02415 {
02416 gl_verbose("Function value for window_opening calculation was greater than 1 or less than 0 (%.2f). Limiting to that range", calc_val);
02417 calc_val = -0.01;
02418 }
02419
02420 if (random_val <= calc_val)
02421 {
02422 window_open = 1;
02423 last_temperature = Tout;
02424 }
02425 else
02426 {
02427 window_open = 0;
02428 last_temperature = Tout;
02429 }
02430 }
02431 }
02432 else
02433 {
02434 window_open = 0;
02435 last_temperature = Tout;
02436 window_first_time_through = 1;
02437 }
02438 }
02439
02440
02441 if (proper_meter_parent == true)
02442 {
02443 pull_complex_powerflow_values();
02444 }
02445
02446
02447 for (c=panel.circuits; c!=NULL; c=c->next)
02448 {
02449
02450 int n = (int)c->type;
02451 if (n<0 || n>2)
02452 GL_THROW("%s:%d circuit %d has an invalid circuit type (%d)", obj->oclass->name, obj->id, c->id, (int)c->type);
02453
02454
02455 c->pLoad->voltage_factor = value_Circuit_V[(int)c->type].Mag() / ((c->pLoad->config&EUC_IS220) ? (2.0* default_line_voltage) : default_line_voltage);
02456 if ((c->pLoad->voltage_factor > 1.06 || c->pLoad->voltage_factor < 0.88) && (ANSI_voltage_check==true))
02457 gl_warning("%s - %s:%d is outside of ANSI standards (voltage = %.0f percent of nominal 120/240)", obj->name, obj->oclass->name,obj->id,c->pLoad->voltage_factor*100);
02458 }
02459
02460
02461 if (deltamode_inclusive == true)
02462 {
02463
02464 if (deltamode_registered == false)
02465 {
02466 if ((res_object_current == -1) && (delta_objects==NULL) && (enable_subsecond_models==true))
02467 {
02468
02469 allocate_deltamode_arrays();
02470 }
02471
02472
02473 if (res_object_current>=res_object_count)
02474 {
02475 GL_THROW("Too many objects tried to populate deltamode objects array in the residential module!");
02476
02477
02478
02479
02480
02481 }
02482
02483
02484 delta_objects[res_object_current] = obj;
02485
02486
02487 delta_functions[res_object_current] = (FUNCTIONADDR)(gl_get_function(obj,"interupdate_res_object"));
02488
02489
02490 if (delta_functions[res_object_current] == NULL)
02491 {
02492 GL_THROW("Failure to map deltamode function for device:%s",obj->name);
02493
02494
02495
02496
02497
02498 }
02499
02500
02501 post_delta_functions[res_object_current] = (FUNCTIONADDR)(gl_get_function(obj,"postupdate_res_object"));
02502
02503
02504 if (post_delta_functions[res_object_current] == NULL)
02505 {
02506 GL_THROW("Failure to map post-deltamode function for device:%s",obj->name);
02507
02508
02509
02510
02511
02512 }
02513
02514
02515 res_object_current++;
02516
02517
02518 deltamode_registered = true;
02519
02520 }
02521 }
02522
02523 return TS_NEVER;
02524 }
02525
02529 TIMESTAMP house_e::sync(TIMESTAMP t0, TIMESTAMP t1)
02530 {
02531 OBJECT *obj = OBJECTHDR(this);
02532 TIMESTAMP t2 = TS_NEVER, t;
02533 const double dt1 = (double)(t1-t0)*TS_SECOND;
02534
02535
02536 if (proper_climate_found == true)
02537 {
02538 pull_climate_values();
02539 }
02540
02541 if(!heat_start){
02542
02543 outside_temperature = value_Tout;
02544 outdoor_rh = value_Rhout*100;
02545 }
02546
02547 if (t0==simulation_beginning_time || t1>t0){
02548 outside_temperature = value_Tout;
02549 outdoor_rh = value_Rhout*100;
02550
02551
02552 update_system(dt1);
02553 if(error_flag == 1){
02554 return TS_INVALID;
02555 }
02556 }
02557
02558 t2 = sync_enduses(t0, t1);
02559 #ifdef _DEBUG
02560
02561 #endif
02562
02563
02564
02565
02566
02567 t = sync_panel(t0,t1);
02568 if (t < t2) {
02569 t2 = t;
02570 #ifdef _DEBUG
02571
02572 #endif
02573 }
02574
02575 if ((t0==simulation_beginning_time || t1>t0) || (!heat_start)){
02576
02577
02578 update_model(dt1);
02579 heat_start = true;
02580
02581 }
02582
02583
02584 update_Tevent();
02585
02586
02587 double dt2;
02588
02589
02590
02591
02592 if(re_override == OV_NORMAL){
02593 if(thermostat_off_cycle_time == -1 && thermostat_on_cycle_time == -1){
02594
02595 if(t < thermostat_last_cycle_time + thermostat_cycle_time){
02596 dt2 = (double)(thermostat_last_cycle_time + thermostat_cycle_time);
02597 } else {
02598 dt2 = e2solve(k1,r1,k2,r2,Teq-Tevent)*3600.0;
02599 }
02600 } else if(thermostat_off_cycle_time >= 0 && thermostat_on_cycle_time >= 0){
02601 if(thermostat_last_off_cycle_time > thermostat_last_on_cycle_time){
02602 if(t < thermostat_last_off_cycle_time + thermostat_off_cycle_time){
02603 dt2 = (double)(thermostat_last_off_cycle_time + thermostat_off_cycle_time);
02604 } else {
02605 dt2 = e2solve(k1,r1,k2,r2,Teq-Tevent)*3600;
02606 }
02607 } else if(thermostat_last_off_cycle_time < thermostat_last_on_cycle_time){
02608 if(t < thermostat_last_on_cycle_time + thermostat_on_cycle_time){
02609 dt2 = (double)(thermostat_last_on_cycle_time + thermostat_on_cycle_time);
02610 } else {
02611 dt2 = e2solve(k1,r1,k2,r2,Teq-Tevent)*3600;
02612 }
02613 } else {
02614 if(t < thermostat_last_cycle_time + thermostat_cycle_time){
02615 dt2 = (double)(thermostat_last_cycle_time + thermostat_cycle_time);
02616 } else {
02617 dt2 = e2solve(k1,r1,k2,r2,Teq-Tevent)*3600;
02618 }
02619 }
02620 } else {
02621 gl_error("Both the thermostat_off_cycle_time and the thermostat_on_cycle_time must be greater than zero.");
02622 return TS_INVALID;
02623 }
02624 } else {
02625 dt2 = TS_NEVER;
02626 }
02627
02628
02629 if (isnan(dt2) || !isfinite(dt2) || dt2<0)
02630 {
02631 #ifdef _DEBUG
02632
02633 #endif
02634 }
02635
02636
02637 else if (dt2<TS_SECOND)
02638 {
02639
02640 t = t1+1; if (t<t2) t2 = t;
02641 #ifdef _DEBUG
02642
02643 #endif
02644 }
02645 else
02646 {
02647
02648 t = t1+(TIMESTAMP)(ceil(dt2)*TS_SECOND); if (t<t2) t2 = t;
02649 #ifdef _DEBUG
02650
02651 #endif
02652 }
02653
02654 #ifdef _DEBUG
02655 char tbuf[64];
02656 gl_printtime(t2, tbuf, 64);
02657
02658 #endif
02659
02660
02661 if (t2!=TS_NEVER)
02662 {
02663 TIMESTAMP t = (TIMESTAMP)(ceil((t2<0 ? -t2 : t2)/system_dwell_time)*system_dwell_time);
02664 t2 = (t2<0 ? t : -t);
02665 }
02666
02667
02668 return t2;
02669 }
02670
02672 TIMESTAMP house_e::postsync(TIMESTAMP t0, TIMESTAMP t1)
02673 {
02674 OBJECT *obj = OBJECTHDR(this);
02675
02676
02677 if (proper_meter_parent == true)
02678 {
02679
02680
02681 value_Power[0] = complex(-1.0,0.0) * value_Power[0];
02682 value_Power[1] = complex(-1.0,0.0) * value_Power[1];
02683 value_Power[2] = complex(-1.0,0.0) * value_Power[2];
02684
02685
02686 value_Line_I[0] = complex(-1.0,0.0) * value_Line_I[0];
02687 value_Line_I[1] = complex(-1.0,0.0) * value_Line_I[1];
02688 value_Line_I[2] = complex(-1.0,0.0) * value_Line_I[2];
02689
02690
02691
02692 value_Shunt[0] = complex(-1.0,0.0) * value_Shunt[0];
02693 value_Shunt[1] = complex(-1.0,0.0) * value_Shunt[1];
02694 value_Shunt[2] = complex(-1.0,0.0) * value_Shunt[2];
02695
02696
02697 push_complex_powerflow_values();
02698 }
02699
02700 return TS_NEVER;
02701 }
02702
02703
02704 void house_e::update_Tevent()
02705 {
02706 OBJECT *obj = OBJECTHDR(this);
02707
02708
02709 switch(system_mode) {
02710
02711 case SM_HEAT:
02712 if (dTair > 0)
02713 Tevent = TheatOff;
02714 else if (auxiliary_strategy == AX_DEADBAND)
02715 Tevent = TauxOn;
02716 break;
02717 case SM_AUX:
02718 Tevent = TheatOff;
02719 break;
02720 case SM_COOL:
02721 Tevent = TcoolOff;
02722 break;
02723
02724 default:
02725 if (dTair<0)
02726 Tevent = TheatOn;
02727 else if (dTair>0)
02728
02729 Tevent = ( cooling_system_type != CT_NONE ? TcoolOn : warn_high_temp );
02730 else
02731 Tevent = Tair;
02732 break;
02733 }
02734 }
02735
02740 TIMESTAMP house_e::sync_thermostat(TIMESTAMP t0, TIMESTAMP t1)
02741 {
02742 double terr = dTair/3600;
02743 bool turned_on = false, turned_off = false;
02744
02745
02746 if (proper_climate_found == true)
02747 {
02748 pull_climate_values();
02749 }
02750
02751
02752 if (thermostat_control==TC_FULL)
02753 {
02754 double tdead = thermostat_deadband/2;
02755 TcoolOn = cooling_setpoint+tdead;
02756 TcoolOff = cooling_setpoint-tdead;
02757 TheatOn = heating_setpoint-tdead;
02758 TheatOff = heating_setpoint+tdead;
02759 TauxOn = TheatOn-aux_heat_deadband;
02760 }
02761
02762
02763 if(thermostat_off_cycle_time == -1 && thermostat_on_cycle_time == -1){
02764 if(t1 < thermostat_last_cycle_time + thermostat_cycle_time){
02765 return (thermostat_last_cycle_time + thermostat_cycle_time);
02766 }
02767 } else if(thermostat_off_cycle_time >=0 && thermostat_on_cycle_time >=0){
02768 if(thermostat_last_off_cycle_time > thermostat_last_on_cycle_time){
02769 if(t1 < thermostat_last_off_cycle_time + thermostat_off_cycle_time){
02770 return (thermostat_last_off_cycle_time + thermostat_off_cycle_time);
02771 }
02772 } else if(thermostat_last_off_cycle_time < thermostat_last_on_cycle_time){
02773 if(t1 < thermostat_last_on_cycle_time + thermostat_on_cycle_time){
02774 return (thermostat_last_on_cycle_time + thermostat_on_cycle_time);
02775 }
02776 } else {
02777 if(t1 < thermostat_last_cycle_time + thermostat_cycle_time){
02778 return (thermostat_last_cycle_time + thermostat_cycle_time);
02779 }
02780 }
02781 }
02782
02783 if (window_openings == TRUE)
02784 {
02785 if (window_open == 1)
02786 {
02787 this->re_override = OV_OFF;
02788 dlc_offset = 20;
02789 }
02790 else
02791 {
02792 dlc_offset = 0;
02793 }
02794 }
02795
02796
02797 if (this->re_override == OV_ON){
02798 if (dlc_offset == 0.0)
02799 {
02800 TcoolOn = TcoolOff;
02801 TheatOn = TheatOff;
02802 re_override = OV_NORMAL;
02803 }
02804 else
02805 {
02806 switch(last_system_mode){
02807 case SM_HEAT:
02808 case SM_AUX:
02809 TcoolOn = TcoolOn + dlc_offset;
02810 TcoolOff = TcoolOff + dlc_offset;
02811 TheatOn = TheatOff + dlc_offset;
02812 TheatOff = TheatOff + dlc_offset;
02813 break;
02814 case SM_OFF:
02815 case SM_COOL:
02816 TcoolOn = TcoolOff - dlc_offset;
02817 TcoolOff = TcoolOff - dlc_offset;
02818 TheatOn = TheatOn - dlc_offset;
02819 TheatOff = TheatOff - dlc_offset;
02820 break;
02821 }
02822 }
02823
02824 } else if(this->re_override == OV_OFF){
02825 if (dlc_offset == 0.0)
02826 {
02827 TcoolOff = TcoolOn;
02828 TheatOff = TheatOn;
02829 re_override = OV_NORMAL;
02830 }
02831 else
02832 {
02833 TcoolOn = TcoolOn + dlc_offset;
02834 TcoolOff = TcoolOn + dlc_offset;
02835 TheatOn = TheatOff - dlc_offset;
02836 TheatOff = TheatOn - dlc_offset;
02837 }
02838
02839 }
02840
02841 if(t0 < thermostat_last_cycle_time + last_mode_timer){
02842 last_system_mode = SM_OFF;
02843 }
02844
02845 switch(last_system_mode){
02846 case SM_HEAT:
02847 case SM_AUX:
02848 if (TcoolOff<TheatOff)
02849 TcoolOff = TheatOff;
02850 if (TcoolOn<TcoolOff+thermostat_deadband)
02851 TcoolOn = TcoolOff+thermostat_deadband;
02852 break;
02853 case SM_OFF:
02854 case SM_COOL:
02855 if (TcoolOff<TheatOff)
02856 TheatOff = TcoolOff;
02857 if (TheatOff<TheatOn-thermostat_deadband)
02858 TheatOff = TheatOn-thermostat_deadband;
02859 if (TauxOn<TheatOn-aux_heat_deadband)
02860 TauxOn = TheatOn-aux_heat_deadband;
02861 break;
02862 }
02863
02864
02865 if (TcoolOff<TheatOff && cooling_system_type!=CT_NONE)
02866 {
02867 char buffer[64];
02868 gl_error("%s: thermostat setpoints deadbands overlap (TcoolOff=%.1f < TheatOff=%.1f)", gl_name(OBJECTHDR(this),buffer,sizeof(buffer)), TcoolOff, TheatOff);
02869 return TS_INVALID;
02870 }
02871
02872
02873 if(system_mode == SM_UNKNOWN)
02874 {
02875 char buffer[64];
02876 gl_warning("%s: system_mode was unknown, changed to off", gl_name(OBJECTHDR(this),buffer,sizeof(buffer)));
02877 system_mode = SM_OFF;
02878 }
02879
02880
02881
02882
02883
02884
02885
02886
02887 DATETIME t_next;
02888 gl_localtime(t1,&t_next);
02889
02890 if (thermostat_control!=TC_NONE)
02891 {
02892 switch(system_mode) {
02893 case SM_HEAT:
02894
02895 if(thermostat_mode == TM_HEAT || thermostat_mode == TM_AUTO){
02896 if(re_override == OV_NORMAL){
02897 if ( auxiliary_system_type != AT_NONE &&
02898 ((auxiliary_strategy & AX_DEADBAND && Tair < TauxOn)
02899 || (auxiliary_strategy & AX_TIMER && t0 >= thermostat_last_cycle_time + aux_heat_time_delay))
02900 || (auxiliary_strategy & AX_LOCKOUT && value_Tout <= aux_heat_temp_lockout)
02901 ){
02902 last_system_mode = system_mode = SM_AUX;
02903 power_state = PS_ON;
02904 thermostat_last_cycle_time = t1;
02905 } else if(Tair > TheatOff - terr/2){
02906 system_mode = SM_OFF;
02907 power_state = PS_OFF;
02908 thermostat_last_cycle_time = t1;
02909 thermostat_last_off_cycle_time = t1;
02910 turned_off = true;
02911 }
02912 } else if(re_override == OV_OFF){
02913 system_mode = SM_OFF;
02914 power_state = PS_OFF;
02915 thermostat_last_cycle_time = t1;
02916 thermostat_last_off_cycle_time = t1;
02917 turned_off = true;
02918 }
02919 } else {
02920 system_mode = SM_OFF;
02921 power_state = PS_OFF;
02922 thermostat_last_cycle_time = t1;
02923 thermostat_last_off_cycle_time = t1;
02924 turned_off = true;
02925 }
02926 break;
02927 case SM_AUX:
02928 if(thermostat_mode == TM_HEAT || thermostat_mode == TM_AUTO){
02929 if((Tair > TheatOff - terr/2 && re_override == OV_NORMAL) || (re_override == OV_OFF)){
02930 system_mode = SM_OFF;
02931 power_state = PS_OFF;
02932 thermostat_last_cycle_time = t1;
02933 thermostat_last_off_cycle_time = t1;
02934 turned_off = true;
02935 } else if(re_override == OV_OFF){
02936 system_mode = SM_OFF;
02937 power_state = PS_OFF;
02938 thermostat_last_cycle_time = t1;
02939 thermostat_last_off_cycle_time = t1;
02940 turned_off = true;
02941 }
02942 } else {
02943 system_mode = SM_OFF;
02944 power_state = PS_OFF;
02945 thermostat_last_cycle_time = t1;
02946 thermostat_last_off_cycle_time = t1;
02947 turned_off = true;
02948 }
02949 break;
02950 case SM_COOL:
02951 if(thermostat_mode == TM_COOL || thermostat_mode == TM_AUTO){
02952 if((Tair < TcoolOff - terr/2 && re_override == OV_NORMAL) || (re_override == OV_OFF)){
02953 system_mode = SM_OFF;
02954 power_state = PS_OFF;
02955 thermostat_last_cycle_time = t1;
02956 thermostat_last_off_cycle_time = t1;
02957 turned_off = true;
02958 }
02959 } else {
02960 system_mode = SM_OFF;
02961 power_state = PS_OFF;
02962 thermostat_last_cycle_time = t1;
02963 thermostat_last_off_cycle_time = t1;
02964 turned_off = true;
02965 }
02966 break;
02967 case SM_OFF:
02968 if((Tair > TcoolOn - terr/2) && (cooling_system_type != CT_NONE) && (thermostat_mode == TM_AUTO || thermostat_mode == TM_COOL))
02969 {
02970 last_system_mode = system_mode = SM_COOL;
02971 power_state = PS_ON;
02972 thermostat_last_cycle_time = t1;
02973 thermostat_last_on_cycle_time = t1;
02974 turned_on = true;
02975 }
02976 else if(Tair < TheatOn - terr/2 && (thermostat_mode == TM_AUTO || thermostat_mode == TM_HEAT))
02977 {
02978
02979 if (Tair < TauxOn &&
02980 (auxiliary_system_type != AT_NONE) &&
02981 ((auxiliary_strategy & AX_DEADBAND) ||
02982 (auxiliary_strategy & AX_LOCKOUT && value_Tout <= aux_heat_temp_lockout)))
02983 {
02984 last_system_mode = system_mode = SM_AUX;
02985 power_state = PS_ON;
02986 thermostat_last_cycle_time = t1;
02987 thermostat_last_on_cycle_time = t1;
02988 turned_on = true;
02989 }
02990 else
02991 {
02992 last_system_mode = system_mode = SM_HEAT;
02993 power_state = PS_ON;
02994 thermostat_last_cycle_time = t1;
02995 thermostat_last_off_cycle_time = t1;
02996 turned_on = true;
02997 }
02998 }
02999 break;
03000 }
03001 }
03002
03003 if(turned_on){
03004 if(hvac_last_off != 0){
03005 hvac_period_off = (double)(t1 - hvac_last_off)/60.0;
03006 }
03007 hvac_last_on = t1;
03008 }
03009 if(turned_off){
03010 if(hvac_last_on != 0){
03011 hvac_period_on = (double)(t1 - hvac_last_on)/60.0;
03012 }
03013 hvac_last_off = t1;
03014 }
03015 if(hvac_period_on != 0.0 && hvac_period_off != 0){
03016 hvac_period_length = hvac_period_on + hvac_period_off;
03017 hvac_duty_cycle = (double)hvac_period_on / (double)hvac_period_length;
03018 }
03019
03020 if ( system_mode == SM_HEAT && (heating_system_type == HT_HEAT_PUMP || heating_system_type == HT_RESISTANCE || heating_system_type == HT_GAS) )
03021 {
03022 is_AUX_on = is_COOL_on = 0;
03023 is_HEAT_on = 1;
03024 }
03025 else if ( system_mode == SM_COOL && cooling_system_type == CT_ELECTRIC)
03026 {
03027 is_AUX_on = is_HEAT_on = 0;
03028 is_COOL_on = 1;
03029 }
03030 else if ( system_mode == SM_AUX && auxiliary_system_type == AT_ELECTRIC)
03031 {
03032 is_COOL_on = is_HEAT_on = 0;
03033 is_AUX_on = 1;
03034 }
03035 else
03036 is_COOL_on = is_HEAT_on = is_AUX_on = 0;
03037
03038 return TS_NEVER;
03039 }
03040
03041 TIMESTAMP house_e::sync_panel(TIMESTAMP t0, TIMESTAMP t1)
03042 {
03043 TIMESTAMP t2 = TS_NEVER;
03044 OBJECT *obj = OBJECTHDR(this);
03045
03046
03047 if((t0 >= simulation_beginning_time && t1 > t0) || (!heat_start)){
03048 total.heatgain = 0;
03049 }
03050 total.total = total.power = total.current = total.admittance = complex(0,0);
03051
03052
03053 if (proper_meter_parent == true)
03054 {
03055 pull_complex_powerflow_values();
03056 }
03057
03058
03059 CIRCUIT *c;
03060 for (c=panel.circuits; c!=NULL; c=c->next)
03061 {
03062
03063 int n = (int)c->type;
03064 if (n<0 || n>2)
03065 GL_THROW("%s:%d circuit %d has an invalid circuit type (%d)", obj->oclass->name, obj->id, c->id, (int)c->type);
03066
03067
03068 if (c->status==BRK_OPEN && t1>=c->reclose)
03069 {
03070 c->status = BRK_CLOSED;
03071 c->reclose = TS_NEVER;
03072 t2 = t1;
03073 gl_debug("house_e:%d panel breaker %d closed", obj->id, c->id);
03074 }
03075
03076
03077 if (c->status==BRK_CLOSED)
03078 {
03079
03080 if ((value_Circuit_V[(int)c->type].Mag() == 0) || (value_MeterStatus==0))
03081 {
03082 gl_debug("house_e:%d circuit %d (enduse %s) voltage is zero", obj->id, c->id, c->pLoad->name);
03083
03084 if (value_MeterStatus==0)
03085 {
03086 if((t0 >= simulation_beginning_time && t1 > t0) || (!heat_start)){
03087 total.heatgain += c->pLoad->heatgain;
03088 }
03089 }
03090 continue;
03091 }
03092
03093
03094 complex actual_power = c->pLoad->power + (c->pLoad->current + c->pLoad->admittance * c->pLoad->voltage_factor)* c->pLoad->voltage_factor;
03095 complex current = ~(actual_power*1000 / value_Circuit_V[(int)c->type]);
03096
03097
03098 if (current.Mag()>c->max_amps)
03099 {
03100
03101 if (c->tripsleft>0 && gl_random_bernoulli(RNGSTATE,1/(c->tripsleft--))==0)
03102 {
03103
03104 c->status = BRK_OPEN;
03105
03106
03107 c->reclose = t1 + (TIMESTAMP)(gl_random_exponential(RNGSTATE,1/300.0)*TS_SECOND);
03108 gl_debug("house_e:%d circuit breaker %d tripped - enduse %s overload at %.0f A", obj->id, c->id,
03109 c->pLoad->name, current.Mag());
03110 }
03111
03112
03113 else
03114 {
03115 c->status = BRK_FAULT;
03116 c->reclose = TS_NEVER;
03117 gl_warning("house_e:%d, %s circuit breaker %d failed - enduse %s is no longer running", obj->id, obj->name, c->id, c->pLoad->name);
03118 }
03119
03120
03121 t2 = t1;
03122 }
03123
03124
03125 else
03126 {
03127
03128
03129
03130 if (n==0)
03131 {
03132 value_Power[2] += c->pLoad->power * 1000.0;
03133 value_Line_I[2] += ~(c->pLoad->current * 1000.0 / (2.0 * default_line_voltage));
03134 value_Shunt[2] += ~(c->pLoad->admittance * 1000.0 / (4.0 * default_line_voltage * default_line_voltage));
03135 }
03136 else if (n==1)
03137 {
03138 value_Power[1] += c->pLoad->power * 1000.0;
03139 value_Line_I[1] += ~(c->pLoad->current * 1000.0 / default_line_voltage);
03140 value_Shunt[1] += ~(c->pLoad->admittance * 1000.0 / (default_line_voltage * default_line_voltage));
03141 }
03142 else
03143 {
03144 value_Power[0] += c->pLoad->power * 1000.0;
03145 value_Line_I[0] += ~(c->pLoad->current * 1000.0 / default_line_voltage);
03146 value_Shunt[0] += ~(c->pLoad->admittance * 1000.0 / (default_line_voltage * default_line_voltage));
03147 }
03148
03149 total.total += c->pLoad->total;
03150 total.power += c->pLoad->power;
03151 total.current += c->pLoad->current;
03152 total.admittance += c->pLoad->admittance;
03153 if((t0 != 0 && t1 > t0) || (!heat_start)){
03154 total.heatgain += c->pLoad->heatgain;
03155 }
03156 c->reclose = TS_NEVER;
03157 }
03158 }
03159
03160
03161 if (t2 > c->reclose)
03162 t2 = c->reclose;
03163 }
03164
03165
03166
03167
03168 total_load = total.total.Mag();
03169
03170
03171
03172 if (proper_meter_parent == true)
03173 {
03174 push_complex_powerflow_values();
03175 }
03176
03177 return t2;
03178 }
03179
03180 TIMESTAMP house_e::sync_enduses(TIMESTAMP t0, TIMESTAMP t1)
03181 {
03182 TIMESTAMP t2 = TS_NEVER;
03183 IMPLICITENDUSE *eu;
03184
03185
03186 for (eu=implicit_enduse_list; eu!=NULL; eu=eu->next)
03187 {
03188 TIMESTAMP t = 0;
03189 t = gl_enduse_sync(&(eu->load),t1);
03190 if (t<t2) t2 = t;
03191 }
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201 return t2;
03202 }
03203
03204 void house_e::check_controls(void)
03205 {
03206 char buffer[256];
03207 if (warn_control)
03208 {
03209 OBJECT *obj = OBJECTHDR(this);
03210
03211 if (Tair<warn_low_temp || Tair>warn_high_temp)
03212 {
03213 gl_warning("house_e:%d (%s) air temperature excursion (%.1f degF) at %s",
03214 obj->id, obj->name?obj->name:"anonymous", Tair, gl_strftime(obj->clock, buffer, 255));
03215 }
03216
03217
03218 if (Tmaterials<warn_low_temp || Tmaterials>warn_high_temp)
03219 {
03220 gl_warning("house_e:%d (%s) mass temperature excursion (%.1f degF) at %s",
03221 obj->id, obj->name?obj->name:"anonymous", Tmaterials, gl_strftime(obj->clock, buffer, 255));
03222 }
03223
03224
03225 if ((system_mode==SM_HEAT || system_mode==SM_AUX) && Teq<heating_setpoint)
03226 {
03227 gl_warning("house_e:%d (%s) heating equipement undersized at %s",
03228 obj->id, obj->name?obj->name:"anonymous", gl_strftime(obj->clock, buffer, 255));
03229 }
03230
03231
03232 else if (system_mode==SM_COOL &&
03233
03234 (cooling_system_type != CT_NONE) &&
03235 Teq>cooling_setpoint)
03236 {
03237 gl_warning("house_e:%d (%s) cooling equipement undersized at %s",
03238 obj->id, obj->name?obj->name:"anonymous", gl_strftime(obj->clock, buffer, 255));
03239 }
03240
03241
03242 if ((dTair>0 && Tevent<Tair) || (dTair<0 && Tevent>Tair))
03243 {
03244 char mode_buffer[1024];
03245 gl_warning("house_e:%d (%s) possible control problem (system_mode %s) -- Tevent-Tair mismatch with dTair (Tevent=%.1f, Tair=%.1f, dTair=%.1f) at %s",
03246 obj->id, obj->name?obj->name:"anonymous", gl_getvalue(obj,"system_mode", mode_buffer, 1023)==NULL?"ERR":mode_buffer, Tevent, Tair, dTair, gl_strftime(obj->clock, buffer, 255));
03247 }
03248 }
03249 }
03250
03251
03252 gld_property *house_e::map_complex_value(OBJECT *obj, char *name)
03253 {
03254 gld_property *pQuantity;
03255 OBJECT *objhdr = OBJECTHDR(this);
03256
03257
03258 pQuantity = new gld_property(obj,name);
03259
03260
03261 if ((pQuantity->is_valid() != true) || (pQuantity->is_complex() != true))
03262 {
03263 GL_THROW("house_e:%d %s - Unable to map property %s from object:%d %s",objhdr->id,(objhdr->name ? objhdr->name : "Unnamed"),name,obj->id,(obj->name ? obj->name : "Unnamed"));
03264
03265
03266
03267
03268 }
03269
03270
03271 return pQuantity;
03272 }
03273
03274
03275 gld_property *house_e::map_double_value(OBJECT *obj, char *name)
03276 {
03277 gld_property *pQuantity;
03278 OBJECT *objhdr = OBJECTHDR(this);
03279
03280
03281 pQuantity = new gld_property(obj,name);
03282
03283
03284 if ((pQuantity->is_valid() != true) || (pQuantity->is_double() != true))
03285 {
03286 GL_THROW("house_e:%d %s - Unable to map property %s from object:%d %s",objhdr->id,(objhdr->name ? objhdr->name : "Unnamed"),name,obj->id,(obj->name ? obj->name : "Unnamed"));
03287
03288
03289
03290
03291 }
03292
03293
03294 return pQuantity;
03295 }
03296
03297
03298 void house_e::pull_complex_powerflow_values(void)
03299 {
03300
03301 value_Circuit_V[0] = pCircuit_V[0]->get_complex();
03302 value_Circuit_V[1] = pCircuit_V[1]->get_complex();
03303 value_Circuit_V[2] = pCircuit_V[2]->get_complex();
03304 value_MeterStatus = pMeterStatus->get_enumeration();
03305 value_Frequency = pFrequency->get_double();
03306 }
03307
03308
03309 void house_e::push_complex_powerflow_values(void)
03310 {
03311 complex temp_complex_val;
03312 gld_wlock *test_rlock;
03313 int indexval;
03314
03315 for (indexval=0; indexval<3; indexval++)
03316 {
03317
03318
03319 temp_complex_val = pLine_I[indexval]->get_complex();
03320
03321
03322 temp_complex_val += value_Line_I[indexval];
03323
03324
03325 pLine_I[indexval]->setp<complex>(temp_complex_val,*test_rlock);
03326
03327
03328
03329 temp_complex_val = pShunt[indexval]->get_complex();
03330
03331
03332 temp_complex_val += value_Shunt[indexval];
03333
03334
03335 pShunt[indexval]->setp<complex>(temp_complex_val,*test_rlock);
03336
03337
03338
03339 temp_complex_val = pPower[indexval]->get_complex();
03340
03341
03342 temp_complex_val += value_Power[indexval];
03343
03344
03345 pPower[indexval]->setp<complex>(temp_complex_val,*test_rlock);
03346 }
03347 }
03348
03349
03350 void house_e::pull_climate_values(void)
03351 {
03352 int index_loop;
03353
03354
03355 value_Tout = pTout->get_double();
03356
03357
03358 value_Rhout = pRhout->get_double();
03359
03360
03361 for (index_loop=0; index_loop<9; index_loop++)
03362 {
03363 value_Solar[index_loop] = pSolar[index_loop]->get_double();
03364 }
03365 }
03366
03368
03370
03371 SIMULATIONMODE house_e::inter_deltaupdate(unsigned int64 delta_time, unsigned long dt, unsigned int iteration_count_val)
03372 {
03373 OBJECT *obj = OBJECTHDR(this);
03374
03375
03376
03377
03378
03379 if ((iteration_count_val == 0) && (delta_time == 0))
03380 {
03381
03382 if (proper_meter_parent == true)
03383 {
03384
03385 push_complex_powerflow_values();
03386 }
03387 }
03388
03389
03390
03391 return SM_EVENT;
03392 }
03393
03394
03395 STATUS house_e::post_deltaupdate(void)
03396 {
03397
03398
03399
03400
03401 if (proper_meter_parent == true)
03402 {
03403
03404
03405 value_Power[0] = complex(-1.0,0.0) * value_Power[0];
03406 value_Power[1] = complex(-1.0,0.0) * value_Power[1];
03407 value_Power[2] = complex(-1.0,0.0) * value_Power[2];
03408
03409
03410 value_Line_I[0] = complex(-1.0,0.0) * value_Line_I[0];
03411 value_Line_I[1] = complex(-1.0,0.0) * value_Line_I[1];
03412 value_Line_I[2] = complex(-1.0,0.0) * value_Line_I[2];
03413
03414
03415
03416 value_Shunt[0] = complex(-1.0,0.0) * value_Shunt[0];
03417 value_Shunt[1] = complex(-1.0,0.0) * value_Shunt[1];
03418 value_Shunt[2] = complex(-1.0,0.0) * value_Shunt[2];
03419
03420
03421 push_complex_powerflow_values();
03422 }
03423
03424 return SUCCESS;
03425 }
03426
03428
03430
03431 EXPORT int create_house(OBJECT **obj, OBJECT *parent)
03432 {
03433 try
03434 {
03435 *obj = gl_create_object(house_e::oclass);
03436 if (*obj!=NULL)
03437 {
03438 house_e *my = OBJECTDATA(*obj,house_e);;
03439 gl_set_parent(*obj,parent);
03440 my->create();
03441 return 1;
03442 }
03443 else
03444 return 0;
03445 }
03446 CREATE_CATCHALL(house);
03447 }
03448
03449 EXPORT int init_house(OBJECT *obj)
03450 {
03451 try {
03452 house_e *my = OBJECTDATA(obj,house_e);
03453 int rv = my->init_climate();
03454 if(rv == 0){
03455 return 2;
03456 } else {
03457 return my->init(obj->parent);
03458 }
03459 }
03460 INIT_CATCHALL(house);
03461 }
03462
03463 EXPORT int isa_house(OBJECT *obj, char *classname)
03464 {
03465 if(obj != 0 && classname != 0){
03466 return OBJECTDATA(obj,house_e)->isa(classname);
03467 } else {
03468 return 0;
03469 }
03470 }
03471
03472 EXPORT TIMESTAMP sync_house(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
03473 {
03474
03475 try {
03476 house_e *my = OBJECTDATA(obj,house_e);
03477 TIMESTAMP t1 = TS_NEVER;
03478 if (obj->clock <= ROUNDOFF)
03479 obj->clock = t0;
03480 switch (pass)
03481 {
03482 case PC_PRETOPDOWN:
03483 t1 = my->presync(obj->clock, t0);
03484 break;
03485
03486 case PC_BOTTOMUP:
03487 t1 = my->sync(obj->clock, t0);
03488 obj->clock = t0;
03489 break;
03490 case PC_POSTTOPDOWN:
03491 t1 = my->postsync(obj->clock, t0);
03492 obj->clock = t0;
03493 break;
03494 default:
03495 gl_error("house_e::sync- invalid pass configuration");
03496 t1 = TS_INVALID;
03497 }
03498 return t1;
03499 }
03500 SYNC_CATCHALL(house);
03501 }
03502
03503 EXPORT TIMESTAMP plc_house(OBJECT *obj, TIMESTAMP t0)
03504 {
03505
03506 if (obj->clock <= ROUNDOFF)
03507 obj->clock = t0;
03508
03509 house_e *my = OBJECTDATA(obj,house_e);
03510 return my->sync_thermostat(obj->clock, t0);
03511 }
03512
03513
03514 EXPORT SIMULATIONMODE interupdate_house_e(OBJECT *obj, unsigned int64 delta_time, unsigned long dt, unsigned int iteration_count_val)
03515 {
03516 house_e *my = OBJECTDATA(obj,house_e);
03517 SIMULATIONMODE status = SM_ERROR;
03518 try
03519 {
03520 status = my->inter_deltaupdate(delta_time,dt,iteration_count_val);
03521 return status;
03522 }
03523 catch (char *msg)
03524 {
03525 gl_error("interupdate_house_e(obj=%d;%s): %s", obj->id, obj->name?obj->name:"unnamed", msg);
03526 return status;
03527 }
03528 }
03529
03530 EXPORT STATUS postupdate_house_e(OBJECT *obj)
03531 {
03532 house_e *my = OBJECTDATA(obj,house_e);
03533 STATUS status = FAILED;
03534 try
03535 {
03536 status = my->post_deltaupdate();
03537 return status;
03538 }
03539 catch (char *msg)
03540 {
03541 gl_error("postupdate_house_e(obj=%d;%s): %s", obj->id, obj->name?obj->name:"unnamed", msg);
03542 return status;
03543 }
03544 }
03545