Ejemplo n.º 1
0
void dnsbsd_tmmt( double phi[nvar], double dep[ndep], double F_i[nvar][nvar])
{
   int ivar, idir, iidir;
   
   // density jacobian ----------------
   F_i[Pvar][Pvar] = drdp( phi);
   F_i[Pvar][Tvar] = drdt( phi);

//printf(" %f %f\n", F_i[Pvar][Pvar], F_i[Pvar][Tvar]);

   for (idir=0;idir<ndir;idir++) {
   // momentum jacobian ---------------
      F_i[Uvar+idir][Pvar]      = drdp( phi) * phi[Uvar+idir];
      F_i[Uvar+idir][Uvar+idir] = dep[Rdep];
      F_i[Uvar+idir][Tvar]      = drdt( phi) * phi[Uvar+idir];

   // enthalpy jacobian/1 -------------
      F_i[Tvar][Uvar+idir] = dep[Rdep] * phi[Uvar+idir];
   }

   // enthalpy jacobian/2 -------------
   F_i[Tvar][Pvar] = drdp( phi) - ( 1.0 * dep[Rdep] * dhdp( phi));
   F_i[Tvar][Tvar] = drdt( phi) * enthalpy( phi) + dep[Rdep] * dhdt( phi);

   for (ivar=Tvar+1;ivar<nvar;ivar++)
      F_i[ivar][ivar] = dep[Rdep];
}
inline double waterheater::new_time_2zone(double h0, double h1)
{
	const double c0 = RHOWATER * Cp * area * (/*Tupper*/ Tw - Tlower);
	double dhdt0, dhdt1;

    if (fabs(c0) <= ROUNDOFF || height <= ROUNDOFF)
        return -1.0;    // c0 or height should never be zero.  if one of these is zero, there is no definite time to transition

	const double cb = (tank_UA / height) * (/*Tupper*/ Tw - Tlower) / c0;

    if (fabs(cb) <= ROUNDOFF)
        return -1.0;
	dhdt1 = fabs(dhdt(h1));
	dhdt0 = fabs(dhdt(h0));
	double last_timestep = (log(dhdt1) - log(dhdt0)) / -cb;	// [hr]
	return last_timestep;
}
/** Set the water heater model and tank state based on the estimated
	temperature differential along the height of the water column when it is full, 
	emplty or partial at the current height, given the current water draw.
 **/
enumeration waterheater::set_current_model_and_load_state(void)
{
	double dhdt_now = dhdt(h);
	double dhdt_full = dhdt(height);
	double dhdt_empty = dhdt(0.0);
	current_model = NONE;		// by default set it to onenode
	load_state = STABLE;		// by default

	enumeration tank_status = tank_state();

	switch(tank_status) 
	{
		case EMPTY:
			if (dhdt_empty <= 0.0) 
			{
				// If the tank is empty, a negative dh/dt means we're still
				// drawing water, so we'll be switching to the 1-zone model...
				
				/* original plan */
				//current_model = NONE;
				//load_state = DEPLETING;
				
				current_model = ONENODE;
				load_state = DEPLETING;
				Tw = Tupper = Tinlet + HEIGHT_PRECISION;
				Tlower = Tinlet;
				h = height;
				/* empty of hot water? full of cold water! */
				/* it is reconized that this causes a discontinuous jump in the water temperature.
				 * despite that, energy is mostly conserved, since Q => dh until h = 0 (thus no heat in the water).
				 * the +0.01 degF fudge factor for the dhdt() T_diff=0 catch adds about 0.05% of a tank of heat,
				 * less than expected errors from other sources. */
			}
			else if (dhdt_full > 0)
			{
				// overriding the plc code ignoring thermostat logic
				// heating will always be on while in two zone model
				heat_needed = TRUE;
				current_model = TWONODE;
				load_state = RECOVERING;
			}
			else
				load_state = STABLE;
			break;

		case FULL:
			// If the tank is full, a negative dh/dt means we're depleting, so
			// we'll also be switching to the 2-zone model...
			if (dhdt_full < 0)
			{
				// overriding the plc code ignoring thermostat logic
				// heating will always be on while in two zone model
				bool cur_heat_needed = heat_needed;
				heat_needed = TRUE;
				double dhdt_full_temp = dhdt(height);
				if (re_override == OV_OFF)
				{
					current_model = ONENODE;
					load_state = DEPLETING;
					heat_needed = FALSE;
				}
				else if (dhdt_full_temp < 0)
				{
					current_model = TWONODE;
					load_state = DEPLETING;
				}
				else
				{
					current_model = ONENODE;
					
					heat_needed = cur_heat_needed;
					load_state = heat_needed ? RECOVERING : DEPLETING;
				}
			}
			else if (dhdt_empty > 0)
			{
				current_model = ONENODE;
				load_state = RECOVERING;
			}
			else
				load_state = STABLE;
			break;

		case PARTIAL:
			// We're definitely in 2-zone mode.  We have to watch for the
			// case where h's movement stalls out...
			current_model = TWONODE;
			// overriding the plc code ignoring thermostat logic
			// heating will always be on while in two zone model
			heat_needed = TRUE;

			if (dhdt_now < 0 && (dhdt_now * dhdt_empty) >= 0)
				load_state = DEPLETING;
			else if (dhdt_now > 0 && (dhdt_now * dhdt_full) >= 0) 
				load_state = RECOVERING;
			else 
			{
				// dhdt_now is 0, so nothing's happening...
				current_model = NONE;
				load_state = STABLE;
			}
			break;
	}

	return load_state;
}
Ejemplo n.º 4
0
/** Set the oven model and its state based on the estimated
	temperature differential along the height of the food column when it is full, 
	emplty or partial at the current height.
 **/
enumeration range::set_current_model_and_load_state(void)
{
	double dhdt_now = dhdt(h);
	double dhdt_full = dhdt(height);
	double dhdt_empty = dhdt(0.0);
	current_model = NONE;		// by default set it to onenode
	load_state = STABLE;		// by default

	enumeration oven_status = range_state();

	switch(oven_status) 
	{
		case EMPTY:
			if (dhdt_empty <= 0.0) 
			{
				current_model = ONENODE;
				load_state = DEPLETING;
				Tw = Tupper = Tinlet + HEIGHT_PRECISION;
				Tlower = Tinlet;
				h = height;

			}
			else if (dhdt_full > 0)
			{
				// overriding the plc code ignoring thermostat logic
				// heating will always be on while in two zone model
				heat_needed = TRUE;
				//current_model = TWONODE;//
				current_model = ONENODE;
				load_state = RECOVERING;
			}
			else
				load_state = STABLE;
			break;

		case FULL:

			if (dhdt_full < 0)
			{

				bool cur_heat_needed = heat_needed;
				heat_needed = TRUE;
				double dhdt_full_temp = dhdt(height);
				if (dhdt_full_temp < 0)
				{
					current_model = ONENODE;
					load_state = DEPLETING;
				}
				else
				{
					current_model = ONENODE;
					
					heat_needed = cur_heat_needed;
					load_state = heat_needed ? RECOVERING : DEPLETING;
				}
			}
			else if (dhdt_empty > 0)
			{
				current_model = ONENODE;
				load_state = RECOVERING;
			}
			else
				load_state = STABLE;
			break;

		case PARTIAL:

			current_model = ONENODE;

			heat_needed = TRUE;

			if (dhdt_now < 0 && (dhdt_now * dhdt_empty) >= 0)
				load_state = DEPLETING;
			else if (dhdt_now > 0 && (dhdt_now * dhdt_full) >= 0) 
				load_state = RECOVERING;
			else 
			{
				current_model = NONE;
				load_state = STABLE;
			}
			break;
	}

	return load_state;
}