TIMESTAMP microwave::sync(TIMESTAMP t0, TIMESTAMP t1) { TIMESTAMP ct = 0; double dt = 0; double val = 0.0; TIMESTAMP t2 = TS_NEVER; if (t0 <= 0) return TS_NEVER; if (pCircuit!=NULL) load.voltage_factor = pCircuit->pV->Mag() / 120; // update voltage factor t2 = residential_enduse::sync(t0,t1); if(shape.type == MT_UNKNOWN){ if(cycle_time > 0){ ct = update_state_cycle(t0, t1); } else { dt = update_state(gl_toseconds(t1-t0)); } load.power.SetPowerFactor( (state==ON ? shape.params.analog.power : standby_power), load.power_factor); } gl_enduse_sync(&(residential_enduse::load),t1); if(shape.type == MT_UNKNOWN){ if(cycle_time == 0) return dt>0?-(TIMESTAMP)(t1 + dt*TS_SECOND) : TS_NEVER; // negative time means soft transition else return ct == TS_NEVER ? TS_NEVER : -ct; } else { return t2; } }
TIMESTAMP refrigerator::sync(TIMESTAMP t0, TIMESTAMP t1) { double nHours = (gl_tohours(t1)- gl_tohours(t0))/TS_SECOND; double t = 0.0, dt = 0.0; const double COP = COPcoef*((-3.5/45)*(Tout-70)+4.5); // change control mode if appropriate if(motor_state == S_ON){ Qr = rated_capacity; } else if(motor_state == S_OFF){ Qr = 0; } else{ throw "refrigerator motor state is ambiguous"; } // calculate power from motor state load.power = Qr * KWPBTUPH * COP; // compute constants const double C1 = Cf/(UAr+UAf); const double C2 = Tout - Qr/UAr; // compute time to next internal event dt = t = -log((Tevent - C2)/(Tair-C2))*C1; if(t == 0){ GL_THROW("refrigerator control logic error, dt = 0"); } else if(t < 0){ GL_THROW("refrigerator control logic error, dt < 0"); } TIMESTAMP t2 = gl_enduse_sync(&(residential_enduse::load),t1); // if fridge is undersized or time exceeds balance of time or external event pending next_time = (TIMESTAMP)(t1 + (t > 0 ? t : -t) * (3600.0/TS_SECOND) + 1); return next_time > TS_NEVER ? TS_NEVER : -next_time; }
TIMESTAMP plugload::sync(TIMESTAMP t0, TIMESTAMP t1) { TIMESTAMP t2 = TS_NEVER; double val = 0.0; if (pCircuit!=NULL) load.voltage_factor = pCircuit->pV->Mag() / 120; // update voltage factor t2 = residential_enduse::sync(t0,t1); if (pCircuit->status==BRK_CLOSED) { if (shape.type == MT_UNKNOWN) { if(shape.load < 0.0){ gl_error("plugload demand cannot be negative, capping"); shape.load = 0.0; } load.power = load.power_fraction * shape.load; load.current = load.current_fraction * shape.load; load.admittance = load.impedance_fraction * shape.load; if(fabs(load.power_factor) < 1 && load.power_factor != 0.0){ val = (load.power_factor < 0 ? -1.0 : 1.0) * load.power.Re() * sqrt(1/(load.power_factor * load.power_factor) - 1); } else { val = 0; } load.power.SetRect(load.power.Re(), val); } } else load.power = load.current = load.admittance = complex(0,0,J); gl_enduse_sync(&(residential_enduse::load),t1); plugs_actual_power = load.power + (load.current + load.admittance * load.voltage_factor) * load.voltage_factor; return t2; }
TIMESTAMP house::sync_hvac_load(TIMESTAMP t1, double nHours) { // compute hvac performance outside_temp = *pTout; const double heating_cop_adj = (-0.0063*(*pTout)+1.5984); const double cooling_cop_adj = -(-0.0108*(*pTout)+2.0389); const double heating_capacity_adj = (-0.0063*(*pTout)+1.5984); const double cooling_capacity_adj = -(-0.0063*(*pTout)+1.5984); double t = 0.0; if (heat_cool_mode == HEAT) { hvac_rated_capacity = design_heating_capacity*floor_area*heating_capacity_adj; hvac_rated_power = hvac_rated_capacity/(heating_COP * heating_cop_adj); } else if (heat_cool_mode == COOL) { hvac_rated_capacity = design_cooling_capacity*floor_area*cooling_capacity_adj; hvac_rated_power = hvac_rated_capacity/(cooling_COP * cooling_cop_adj); } else { hvac_rated_capacity = 0.0; hvac_rated_power = 0.0; } gl_enduse_sync(&(residential_enduse::load),t1); load.power = hvac_rated_power*KWPBTUPH * ((heat_cool_mode == HEAT) && (heat_mode == GASHEAT) ? 0.01 : 1.0); //load.total = load.power; // calculated by sync_enduse() load.heatgain = hvac_rated_capacity; //load.heatgain = hvac_rater_power; /* factored in at netHeatrate */ //hvac_kWh_use = load.power.Mag()*nHours; // this updates the energy usage of the elapsed time since last synch return TS_NEVER; /* we'll figure that out later */ }
TIMESTAMP dishwasher::sync(TIMESTAMP t0, TIMESTAMP t1) { TIMESTAMP t2 = residential_enduse::sync(t0, t1); if (pCircuit!=NULL) load.voltage_factor = pCircuit->pV->Mag() / 120; // update voltage factor if(shape.type == MT_UNKNOWN){ /* requires manual enduse control */ double real = 0.0, imag = 0.0; real = shape.params.analog.power * shape.load; if(fabs(load.power_factor) < 1){ imag = (load.power_factor<0?-1.0:1.0) * real * sqrt(1/(load.power_factor * load.power_factor) - 1); } else { imag = 0; } load.power.SetRect(real, imag); // convert from W to kW } gl_enduse_sync(&(residential_enduse::load), t1); return t2; }