int waterheater::create() 
{
	int res = residential_enduse::create();

	// initialize public values
	tank_volume = 50.0;
	tank_UA = 0.0;
	tank_diameter	= 1.5;  // All heaters are 1.5-ft wide for now...
	Tinlet = 60.0;		// default set here, but published by the model for users to set this value
	water_demand = 0.0;	// in gpm
	heating_element_capacity = 0.0;
	heat_needed = FALSE;
	location = GARAGE;
	heat_mode = ELECTRIC;
	tank_setpoint = 0.0;
	thermostat_deadband = 0.0;
	is_waterheater_on = 0;
//	power_kw = complex(0,0);
	Tw = 0.0;

	// location...mostly in garage, a few inside...
	location = gl_random_bernoulli(RNGSTATE,0.80) ? GARAGE : INSIDE;

	// initialize randomly distributed values
	tank_setpoint 		= clip(gl_random_normal(RNGSTATE,130,10),100,160);
	thermostat_deadband	= clip(gl_random_normal(RNGSTATE,5, 1),1,10);

	/* initialize water tank thermostat */
	tank_setpoint = gl_random_normal(RNGSTATE,125,5);
	if (tank_setpoint<90) tank_setpoint = 90;
	if (tank_setpoint>160) tank_setpoint = 160;

	/* initialize water tank deadband */
	thermostat_deadband = fabs(gl_random_normal(RNGSTATE,2,1))+1;
	if (thermostat_deadband>10)
		thermostat_deadband = 10;

	tank_UA = clip(gl_random_normal(RNGSTATE,2.0, 0.20),0.1,10) * tank_volume/50;  
	if(tank_UA <= 1.0)
		tank_UA = 2.0;	// "R-13"

	// name of enduse
	load.name = oclass->name;

	load.breaker_amps = 30;
	load.config = EUC_IS220;
	load.power_fraction = 0.0;
	load.impedance_fraction = 1.0;
	load.heatgain_fraction = 0.0; /* power has no effect on heat loss */

	gas_fan_power = -1.0;
	gas_standby_power = -1.0;

	return res;

}
int refrigerator::init(OBJECT *parent)
{
	OBJECT *hdr = OBJECTHDR(this);
	hdr->flags |= OF_SKIPSAFE;

	// defaults for unset values */
	if (size==0)				size = gl_random_uniform(RNGSTATE,20,40); // cf
	if (thermostat_deadband==0) thermostat_deadband = gl_random_uniform(RNGSTATE,2,3);
	if (Tset==0)				Tset = gl_random_uniform(RNGSTATE,35,39);
	if (UA == 0)				UA = 0.6;
	if (UAr==0)					UAr = UA+size/40*gl_random_uniform(RNGSTATE,0.9,1.1);
	if (UAf==0)					UAf = gl_random_uniform(RNGSTATE,0.9,1.1);
	if (COPcoef==0)				COPcoef = gl_random_uniform(RNGSTATE,0.9,1.1);
	if (Tout==0)				Tout = 59.0;
	if (load.power_factor==0)		load.power_factor = 0.95;

	pTout = (double*)gl_get_addr(parent, "air_temperature");
	if (pTout==NULL)
	{
		static double default_air_temperature = 72;
		gl_warning("%s (%s:%d) parent object lacks air temperature, using %0f degF instead", hdr->name, hdr->oclass->name, hdr->id, default_air_temperature);
		pTout = &default_air_temperature;
	}

	/* derived values */
	Tair = gl_random_uniform(RNGSTATE,Tset-thermostat_deadband/2, Tset+thermostat_deadband/2);

	// size is used to couple Cw and Qrated
	Cf = size/10.0 * RHOWATER * CWATER;  // cf * lb/cf * BTU/lb/degF = BTU / degF

	rated_capacity = BTUPHPW * size*10; // BTU/h ... 10 BTU.h / cf (34W/cf, so ~700 for a full-sized refrigerator)

	// duty cycle estimate for initial condition
	if (gl_random_bernoulli(RNGSTATE,0.1)){
		Qr = rated_capacity;
	} else {
		Qr = 0;
	}

	// initial demand
	load.total = Qr * KWPBTUPH;

	return residential_enduse::init(parent);
}
Beispiel #3
0
TIMESTAMP house::sync_panel(TIMESTAMP t0, TIMESTAMP t1)
{
	TIMESTAMP sync_time = TS_NEVER;
	OBJECT *obj = OBJECTHDR(this);

	// clear accumulators for panel currents
	complex I[3]; I[X12] = I[X23] = I[X13] = complex(0,0);

	// clear heatgain accumulator
	double heatgain = 0;

	// gather load power and compute current for each circuit
	CIRCUIT *c;
	for (c=panel.circuits; c!=NULL; c=c->next)
	{
		// get circuit type
		int n = (int)c->type;
		if (n<0 || n>2)
			GL_THROW("%s:%d circuit %d has an invalid circuit type (%d)", obj->oclass->name, obj->id, c->id, (int)c->type);
		/*	TROUBLESHOOT
			Invalid circuit types are an internal error for the house panel.  Please report this error.  The likely causes
			include an object that is not a house is being processed by the house model, or the panel was not correctly
			initialized.
		*/

		// if breaker is open and reclose time has arrived
		if (c->status==BRK_OPEN && t1>=c->reclose)
		{
			c->status = BRK_CLOSED;
			c->reclose = TS_NEVER;
			sync_time = t1; // must immediately reevaluate devices affected
			gl_debug("house:%d panel breaker %d closed", obj->id, c->id);
		}

		// if breaker is closed
		if (c->status==BRK_CLOSED)
		{
			// compute circuit current
			if ((c->pV)->Mag() == 0)
			{
				gl_debug("house:%d circuit %d (enduse %s) voltage is zero", obj->id, c->id, c->pLoad->name);
				break;
			}
			
			complex current = ~(c->pLoad->total*1000 / *(c->pV)); 

			// check breaker
			if (c->max_amps>0 && current.Mag()>c->max_amps)
			{
				// probability of breaker failure increases over time
				if (c->tripsleft>0 && gl_random_bernoulli(RNGSTATE,1/(c->tripsleft--))==0)
				{
					// breaker opens
					c->status = BRK_OPEN;

					// average five minutes before reclosing, exponentially distributed
					c->reclose = t1 + (TIMESTAMP)(gl_random_exponential(RNGSTATE,1/300.0)*TS_SECOND); 
					gl_debug("house:%d circuit breaker %d tripped - enduse %s overload at %.0f A", obj->id, c->id,
						c->pLoad->name, current.Mag());
				}

				// breaker fails from too frequent operation
				else
				{
					c->status = BRK_FAULT;
					c->reclose = TS_NEVER;
					gl_debug("house:%d circuit breaker %d failed", obj->id, c->id);
				}

				// must immediately reevaluate everything
				sync_time = t1; 
			}

			// add to panel current
			else
			{
				tload.power += c->pLoad->power;	// reminder: |a| + |b| != |a+b|
				tload.current += c->pLoad->current;
				tload.admittance += c->pLoad->admittance; // should this be additive? I don't buy t.a = c->pL->a ... -MH
				tload.total += c->pLoad->total;
				tload.heatgain += c->pLoad->heatgain;
				tload.energy += c->pLoad->power * gl_tohours(t1-t0);
				I[n] += current;
				c->reclose = TS_NEVER;
			}
		}

		// sync time
		if (sync_time > c->reclose)
			sync_time = c->reclose;
	}

	// compute line currents and post to meter
	if (obj->parent != NULL)
		LOCK_OBJECT(obj->parent);

	pLine_I[0] = I[X13];
	pLine_I[1] = I[X23];
	pLine_I[2] = 0;
	*pLine12 = I[X12];

	if (obj->parent != NULL)
		UNLOCK_OBJECT(obj->parent);

	return sync_time;
}
Beispiel #4
0
int range::create() 
{

	OBJECT *hdr = OBJECTHDR(this);
	int res = residential_enduse::create();

	// initialize public values
	
	
	oven_diameter = 1.5;  // All heaters are 1.5-ft wide for now...
	Tinlet = 60.0;		// default set here, but published by the model for users to set this value
	oven_demand = 0.0;	
	
	heat_needed = FALSE;	
	heat_mode = ELECTRIC;
	is_range_on = 0;
	Tw = 0.0;
	time_oven_operation = 0;
	oven_check = false;
	remainon = false;
	cooktop_check = false;
	time_cooktop_operation = 0;
	oven_volume = 5;
	heating_element_capacity = 1;
	oven_setpoint = 100;
	Tw = 70;
	thermostat_deadband = 8;
	location = INSIDE;
	oven_UA = 2.9;
	oven_demand = 0.01;
	food_density = 5;
	specificheat_food = 1;
	time_oven_setting = 3600;
	

	enduse_queue_oven = 0.85;


	// location...mostly in garage, a few inside...
	location = gl_random_bernoulli(&hdr->rng_state,0.80) ? GARAGE : INSIDE;

	// initialize randomly distributed values
	oven_setpoint 		= clip(gl_random_normal(&hdr->rng_state,130,10),100,160);
	thermostat_deadband	= clip(gl_random_normal(&hdr->rng_state,5, 1),1,10);

	/* initialize oven thermostat */
	oven_setpoint = gl_random_normal(&hdr->rng_state,125,5);
	if (oven_setpoint<90) oven_setpoint = 90;
	if (oven_setpoint>160) oven_setpoint = 160;

	/* initialize oven deadband */
	thermostat_deadband = fabs(gl_random_normal(&hdr->rng_state,2,1))+1;
	if (thermostat_deadband>10)
		thermostat_deadband = 10;

	oven_UA = clip(gl_random_normal(&hdr->rng_state,2.0, 0.20),0.1,10) * oven_volume/50;  
	if(oven_UA <= 1.0)
		oven_UA = 2.0;	// "R-13"

	// name of enduse
	load.name = oclass->name;

	load.breaker_amps = 30;
	load.config = EUC_IS220;
	load.power_fraction = 0.0;
	load.impedance_fraction = 1.0;
	load.heatgain_fraction = 0.0; /* power has no effect on heat loss */

	state_cooktop = CT_STOPPED;
	TSTAT_PRECISION= 0.01;

	cooktop_energy_baseline = 0.5;
           		  
	cooktop_coil_power[0] = 2;
    cooktop_coil_power[1] = 1.0;
    cooktop_coil_power[2] = 1.7;
           
    cooktop_interval[0] = 240;
    cooktop_interval[1] = 900;
    cooktop_interval[2] = 120;
           
    time_cooktop_setting = 2000;

	enduse_queue_cooktop = 0.99;

	return res;

}