示例#1
0
TIMESTAMP node::postsync(TIMESTAMP t0) 
{
	OBJECT *hdr = OBJECTHDR(this);
	node *swing = hdr->parent?OBJECTDATA(hdr->parent,node):this;
	complex dV(0.0);
	complex YY = Ys + complex(G,B);
	// copy values that might get updated while we work on this object
	complex old_YVs = YVs;
#ifdef HYBRID
	swing->del_inj_residual(this);
#endif
	if (!YY.IsZero() || type==SWING)
	{
		switch (type) {
		case PV:
			S.Im() = ((~V*(YY*V-old_YVs)).Im());
			if (Qmin_MVAR<Qmax_MVAR && S.Im()<Qmin_MVAR) 
				S.Im() = Qmin_MVAR;
			else if (Qmax_MVAR>Qmin_MVAR && S.Im()>Qmax_MVAR) 
				S.Im() = Qmax_MVAR;
			//else
			{
				complex Vnew = (-(~S/~V) + old_YVs) / YY;
				Vnew.SetPolar(V.Mag(),Vnew.Arg());
#ifdef HYBRID
				if (Vstdev>0)
				{
					double pr = swing->get_obs_probability();
					swing->del_obs_residual(this);
					dV = Vobs*(1-pr) + (Vnew)*pr - V;
					V += dV;
					swing->add_obs_residual(this);
				}
				else
#endif
				{
					dV = Vnew - V;
					V = Vnew;
				}
				break;
			}
			/* continue with PQ solution */
		case PQ:
			if (!V.IsZero())
			{
				complex Vnew = (-(~S/~V) + old_YVs) / YY;
#ifdef HYBRID
				if (Vstdev>0) // need to consider observation
				{
					double pr = swing->get_obs_probability();
					swing->del_obs_residual(this);
					dV = Vobs*(1-pr) + (Vnew)*pr - V;
					V += dV;
					swing->add_obs_residual(this);
				}
				else // no observation 
#endif
				{
					dV = (Vnew - V)*acceleration_factor;
					V += dV;
				}
				V.Notation() = A;
			}
			break;
		case SWING:
			S = ~(~V*(YY*V - YVs));
			S.Notation() = J;
			break;
		default:
			/* unknown type fails */
			gl_error("invalid bus type");
			return TS_ZERO;
		}
	}
#ifdef HYBRID
	swing->add_inj_residual(this);
#endif

#ifdef _DEBUG
	// node debugging
	if (debug_node>0)
	{
		OBJECT* obj = OBJECTHDR(this);
		static int first=-1;
		if (first==-1) first = obj->id;
		if (obj->id==first)
		{
			printf("\n");
			printf("Node           Type  V                 Vobs              Stdev    Power             G        B        dV       Pr{Vobs} r2     Sr2\n");
			printf("============== ===== ================= ================= ======== ================= ======== ======== ======== ======== ====== ======\n");
		}
		if (((debug_node&1)==1 && dV.Mag()>convergence_limit )  // only on dV
#ifdef HYBRID
			|| ((debug_node&2)==2 && Vstdev>0 ) // only on observation
			|| ((debug_node&4)==4 && get_inj_residual()>0.001)// non-zero power residual
#endif
			)
		{
			printf("%2d (%-9.9s) %5s %+8.4f%+8.3fd %+8.4f%+8.3fd %8.5f %+8.4f%+8.4fj %+8.5f ", 
				obj->id, obj->name, type==SWING?"SWING":(type==PQ?"PQ   ":"PV"),
				V.Mag(),V.Arg()*180/3.1416, 
				Vobs.Mag(), Vobs.Arg()*180/3.1416, Vstdev,
				S.Re(), S.Im(), 
				G, B,
				dV.Mag());
#ifdef HYBRID
			printf("%+8.5f %8.5f ", get_obs_probability(), r2);
			if (Vstdev>0)
				printf("%8.5f %6.3f %6.3f\n", get_obs_probability(), r2, get_inj_residual());
			else
				printf("   --      --   %6.3f\n",get_inj_residual());
#else
			printf("\n");
#endif
		}
	}
#endif // _DEBUG

	// send dV through all links
	LINKLIST *item;
	for (item=linklist; item!=NULL; item=item->next)
		item->data->apply_dV(hdr,dV);

	if (dV.Mag()>convergence_limit)
		return t0; /* did not converge, hold the clock */
	else
		return TS_NEVER; /* converged, no further updates needed */
}
示例#2
0
EXPORT int init_dryer(OBJECT *obj)
{
	dryer *my = OBJECTDATA(obj,dryer);
	return my->init(obj->parent);
}
示例#3
0
/** initialization process
 **/
int controller::init(OBJECT *parent){
	OBJECT *hdr = OBJECTHDR(this);
	char tname[32];
	char *namestr = (hdr->name ? hdr->name : tname);
//	double high, low;

	sprintf(tname, "controller:%i", hdr->id);

	cheat();

	if(parent == NULL){
		gl_error("%s: controller has no parent, therefore nothing to control", namestr);
		return 0;
	}

	if(pMarket == NULL){
		gl_error("%s: controller has no market, therefore no price signals", namestr);
		return 0;
	}

	if(gl_object_isa(pMarket, "auction")){
		gl_set_dependent(hdr, pMarket);
		market = OBJECTDATA(pMarket, auction);
	} else {
		gl_error("controllers only work when attached to an 'auction' object");
		return 0;
	}

	if(dPeriod == 0.0){
		period = market->period;
	} else {
		period = (TIMESTAMP)floor(dPeriod + 0.5);
	}

	if(bid_delay < 0){
		bid_delay = -bid_delay;
	}
	if(bid_delay > period){
		gl_warning("Bid delay is greater than the controller period. Resetting bid delay to 0.");
		bid_delay = 0;
	}

	if(target[0] == 0){
		GL_THROW("controller: %i, target property not specified", hdr->id);
	}
	if(setpoint[0] == 0 && control_mode == CN_RAMP){
		GL_THROW("controller: %i, setpoint property not specified", hdr->id);;
	}
	if(demand[0] == 0 && control_mode == CN_RAMP){
		GL_THROW("controller: %i, demand property not specified", hdr->id);
	}
	if(total[0] == 0){
		GL_THROW("controller: %i, total property not specified", hdr->id);
	}
	if(load[0] == 0){
		GL_THROW("controller: %i, load property not specified", hdr->id);
	}

	if(heating_setpoint[0] == 0 && control_mode == CN_DOUBLE_RAMP){
		GL_THROW("controller: %i, heating_setpoint property not specified", hdr->id);;
	}
	if(heating_demand[0] == 0 && control_mode == CN_DOUBLE_RAMP){
		GL_THROW("controller: %i, heating_demand property not specified", hdr->id);
	}

	if(cooling_setpoint[0] == 0 && control_mode == CN_DOUBLE_RAMP){
		GL_THROW("controller: %i, cooling_setpoint property not specified", hdr->id);;
	}
	if(cooling_demand[0] == 0 && control_mode == CN_DOUBLE_RAMP){
		GL_THROW("controller: %i, cooling_demand property not specified", hdr->id);
	}

	if(deadband[0] == 0 && control_mode == CN_DOUBLE_RAMP){
		GL_THROW("controller: %i, deadband property not specified", hdr->id);
	}

	fetch(&pMonitor, target, parent);
	if(control_mode == CN_RAMP){
		fetch(&pSetpoint, setpoint, parent);
		fetch(&pDemand, demand, parent);
		fetch(&pTotal, total, parent);
		fetch(&pLoad, load, parent);
	} else if(control_mode == CN_DOUBLE_RAMP){
		sprintf(aux_state, "is_AUX_on");
		sprintf(heat_state, "is_HEAT_on");
		sprintf(cool_state, "is_COOL_on");
		fetch(&pHeatingSetpoint, heating_setpoint, parent);
		fetch(&pHeatingDemand, heating_demand, parent);
		fetch(&pHeatingTotal, total, parent);
		fetch(&pHeatingLoad, total, parent);
		fetch(&pCoolingSetpoint, cooling_setpoint, parent);
		fetch(&pCoolingDemand, cooling_demand, parent);
		fetch(&pCoolingTotal, total, parent);
		fetch(&pCoolingLoad, load, parent);
		fetch(&pDeadband, deadband, parent);
		fetch(&pAuxState, aux_state, parent);
		fetch(&pHeatState, heat_state, parent);
		fetch(&pCoolState, cool_state, parent);
	}
	fetch(&pAvg, avg_target, pMarket);
	fetch(&pStd, std_target, pMarket);


	if(dir == 0){
		double high = ramp_high * range_high;
		double low = ramp_low * range_low;
		if(high > low){
			dir = 1;
		} else if(high < low){
			dir = -1;
		} else if((high == low) && (fabs(ramp_high) > 0.001 || fabs(ramp_low) > 0.001)){
			dir = 0;
			gl_warning("%s: controller has no price ramp", namestr);
			/* occurs given no price variation, or no control width (use a normal thermostat?) */
		}
		if(ramp_low * ramp_high < 0){
			gl_warning("%s: controller price curve is not injective and may behave strangely");
			/* TROUBLESHOOTING
				The price curve 'changes directions' at the setpoint, which may create odd
				conditions in a number of circumstances.
			 */
		}
	}
	if(setpoint0==0)
		setpoint0 = -1; // key to check first thing

	if(heating_setpoint0==0)
		heating_setpoint0 = -1;

	if(cooling_setpoint0==0)
		cooling_setpoint0 = -1;

//	double period = market->period;
//	next_run = gl_globalclock + (TIMESTAMP)(period - fmod(gl_globalclock+period,period));
	next_run = gl_globalclock;// + (market->period - gl_globalclock%market->period);
	time_off = TS_NEVER;
	if(sliding_time_delay < 0 )
		dtime_delay = 21600; // default sliding_time_delay of 6 hours
	else
		dtime_delay = (int64)sliding_time_delay;

	if(state[0] != 0){
		// grab state pointer
		pState = gl_get_enum_by_name(parent, state);
		last_pState = 0;
		if(pState == 0){
			gl_error("state property name \'%s\' is not published by parent class", state);
			return 0;
		}
	}

	if(heating_state[0] != 0){
		// grab state pointer
		pHeatingState = gl_get_enum_by_name(parent, heating_state);
		if(pHeatingState == 0){
			gl_error("heating_state property name \'%s\' is not published by parent class", heating_state);
			return 0;
		}
	}

	if(cooling_state[0] != 0){
		// grab state pointer
		pCoolingState = gl_get_enum_by_name(parent, cooling_state);
		if(pCoolingState == 0){
			gl_error("cooling_state property name \'%s\' is not published by parent class", cooling_state);
			return 0;
		}
	}
	// get override, if set
	if(re_override[0] != 0){
		pOverride = gl_get_enum_by_name(parent, re_override);
	}
	if((pOverride == 0) && (use_override == OU_ON)){
		gl_error("use_override is ON but no valid override property name is given");
		return 0;
	}

	if(control_mode == CN_RAMP){
		if(slider_setting < 0.0){
			gl_warning("slider_setting is negative, reseting to 0.0");
			slider_setting = 0.0;
		}
		if(slider_setting > 1.0){
			gl_warning("slider_setting is greater than 1.0, reseting to 1.0");
			slider_setting = 1.0;
		}
	}
	if(control_mode == CN_DOUBLE_RAMP){
		if(slider_setting_heat < 0.0){
			gl_warning("slider_setting_heat is negative, reseting to 0.0");
			slider_setting_heat = 0.0;
		}
		if(slider_setting_cool < 0.0){
			gl_warning("slider_setting_cool is negative, reseting to 0.0");
			slider_setting_cool = 0.0;
		}
		if(slider_setting_heat > 1.0){
			gl_warning("slider_setting_heat is greater than 1.0, reseting to 1.0");
			slider_setting_heat = 1.0;
		}
		if(slider_setting_cool > 1.0){
			gl_warning("slider_setting_cool is greater than 1.0, reseting to 1.0");
			slider_setting_cool = 1.0;
		}
		// get override, if set
	}
	last_p = market->init_price;
	return 1;
}
int thermal_storage::init(OBJECT *parent)
{
	if(parent != NULL){
		if((parent->flags & OF_INIT) != OF_INIT){
			char objname[256];
			gl_verbose("thermal_storage::init(): deferring initialization on %s", gl_name(parent, objname, 255));
			return 2; // defer
		}
	}
	OBJECT *hdr = OBJECTHDR(this);
	hdr->flags |= OF_SKIPSAFE;
	double *design_cooling_capacity;

	//Make sure the parent is a house
	if (!(gl_object_isa(parent,"house","residential")))
	{
		GL_THROW("thermal_storage:%s must be parented to a house!",hdr->name);
		/*  TROUBLESHOOT
		The thermal_storage model is only valid for house objects.  Please parent it appropriately.
		*/
	}

	//Pull a house link, we'll use it for addresses
	house_e *house_lnk = OBJECTDATA(parent,house_e);

	//Link the variables to the parent values (house values)
	design_cooling_capacity = &house_lnk->design_cooling_capacity;
	outside_temperature = &house_lnk->outside_temperature;
	thermal_storage_available = &house_lnk->thermal_storage_present;
	thermal_storage_active = &house_lnk->thermal_storage_inuse;

	//Check the cooling capacity
	if (*design_cooling_capacity == NULL)
	{
		gl_warning("\'design_cooling_capacity\' not specified in parent ~ default to 5 ton or 60,000 Btu/hr");
		/* TROUBLESHOOT
			The thermal_storage did not reference a parent object that publishes design_cooling_capacity, so 5 ton was assumed.
			Confirm or change the parent reference and try again.
		*/
		discharge_rate = 5 * 12000; //Btu/hr, is set to 5 ton when not defined
		water_capacity = 1.7413;	//m^3, is set to the same as a 5 ton unit
	} else {
		discharge_rate = *design_cooling_capacity;
		water_capacity = 1.7413 * (discharge_rate / (5 * 12000));
	}

	surface_area = 6 * pow(water_capacity, 0.6667); //suface area of a cube calculated from volume

	if (total_capacity == 0)			total_capacity = (30 / 5) * discharge_rate; //Btu

	if (state_of_charge < 0 && stored_capacity < 0) //Btu
	{
		stored_capacity = total_capacity;
		state_of_charge = 100;
	} else if (state_of_charge < 0 && stored_capacity >= 0)
	{
		state_of_charge = stored_capacity / total_capacity;
	} else if (state_of_charge >= 0 && stored_capacity < 0)
	{
		stored_capacity = (state_of_charge / 100) * total_capacity;
	} else if (state_of_charge >= 0 && stored_capacity >= 0)
	{
		stored_capacity = (state_of_charge / 100) * total_capacity;
		gl_warning("stored_capacity and SOC are both defined, SOC being used for initial energy state");
		/*  TROUBLESHOOT
		During the initialization of the system, a value was specified for both the stored_capacity and SOC (state of charge).
		The thermal energy storage object gives precedence to the SOC variable, so the initial stored_capacity will be the SOC
		percentage of the total_capacity.
		*/
	}

	if (recharge_power == 0)			recharge_power = (3.360 * discharge_rate) / (5 * 12000); //kW
	if (discharge_power == 0)			discharge_power = (0.300 * discharge_rate) / (5 * 12000); //kW
	if (recharge_power_factor == 0)		recharge_power_factor = 0.97; //same as used for HVAC compressor in house_e
	if (discharge_power_factor == 0)	discharge_power_factor = 1; //assume ideal pump
	if (k < 0)							k = 0; //assume no thermal conductivity
	k = k * 0.00052667;				//convert k from W/m/K to BTU/sec/m/degF

	//Determine how to read the scheduling information - charging
	if (recharge_schedule_type==INTERNAL)
	{
		//See if someone else has already created such a schedule
		recharge_schedule_vals = gl_schedule_find(thermal_default_schedule_list[1].schedule_name);

		//If not found, create
		if (recharge_schedule_vals == NULL)
		{
			//Populate schedules - charging
			recharge_schedule_vals = gl_schedule_create(thermal_default_schedule_list[1].schedule_name,thermal_default_schedule_list[1].schedule_definition);

			//Make sure it worked
			if (recharge_schedule_vals==NULL)
			{
				GL_THROW("Failure to create default charging schedule");
				/*  TROUBLESHOOT
				While attempting to create the default charging schedule in the thermal_storage object, an error occurred.  Please try again.
				If the error persists, please submit your code and a bug report via the track website.
				*/
			}
		}

		gl_verbose("thermal_storage charging defaulting to internal schedule");
		/*  TROUBLESHOOT
		recharge_schedule_type was not set to EXTERNAL, so the internal schedule definition will be used
		for the recharging schedule.
		*/

		//Assign to the schedule value
		recharge_time_ptr = &recharge_schedule_vals->value;
	}
	else
	{
		//Assign the to published property
		recharge_time_ptr = &recharge_time;
	}

	//Determine how to read the scheduling information - discharging
	if (discharge_schedule_type==INTERNAL)
	{
		//See if someone else has already created such a schedule
		discharge_schedule_vals = gl_schedule_find(thermal_default_schedule_list[0].schedule_name);

		//If not found, create
		if (discharge_schedule_vals == NULL)
		{
			//Populate schedules - discharging
			discharge_schedule_vals = gl_schedule_create(thermal_default_schedule_list[0].schedule_name,thermal_default_schedule_list[0].schedule_definition);

			//Make sure it worked
			if (discharge_schedule_vals==NULL)
			{
				GL_THROW("Failure to create default discharging schedule");
				/*  TROUBLESHOOT
				While attempting to create the default discharging schedule in the thermal_storage object, an error occurred.  Please try again.
				If the error persists, please submit your code and a bug report via the track website.
				*/
			}
		}

		gl_verbose("thermal_storage discharging defaulting to internal schedule");
		/*  TROUBLESHOOT
		discharge_schedule_type was not set to EXTERNAL, so the internal schedule definition will be used
		for the discharging availability schedule.
		*/

		//Assign to the schedule value
		discharge_time_ptr = &discharge_schedule_vals->value;
	}
	else
	{
		//Assigned to the published property
		discharge_time_ptr = &discharge_time;
	}

	// waiting this long to initialize the parent class is normal
	return residential_enduse::init(parent);
}
示例#5
0
文件: pqload.cpp 项目: ryuever/sgrid
EXPORT int isa_pqload(OBJECT *obj, char *classname)
{
	return OBJECTDATA(obj,pqload)->isa(classname);
}
示例#6
0
//Solar radiation calcuation based on solpos and Perez tilt models
EXPORT int64 calc_solar_solpos_shading_rad(OBJECT *obj, double tilt, double orientation, double shading_value, double *value)
{
	static SolarAngles sa; // just for the functions
	double ghr, dhr, dnr;
	double cos_incident;
	double temp_value;
	DATETIME dt;
	TIMESTAMP offsetclock;

	climate *cli;
	if(obj == 0 || value == 0){
		return 0;
	}
	cli = OBJECTDATA(obj, climate);
	if(gl_object_isa(obj, "climate", "climate") == 0){
		return 0;
	}
	ghr = cli->solar_global;
	dhr = cli->solar_diffuse;
	dnr = cli->solar_direct;

	if (cli->reader_type==cli->RT_TMY2)
	{
		//Adjust time by half an hour - adjusts per TMY "reading" intervals - what they really represent
		offsetclock = obj->clock + 1800;
	}
	else	//Just pass it in
	{
		offsetclock = obj->clock;
	}
	
	gl_localtime(offsetclock, &dt);

	//Convert temperature back to centrigrade - since we seem to like imperial units
	temp_value = ((cli->temperature - 32.0)*5.0/9.0);

	//Initialize solpos algorithm
	sa.S_init(&sa.solpos_vals);

	//Assign in values
	sa.solpos_vals.longitude = obj->longitude;
	sa.solpos_vals.latitude = RAD(obj->latitude);
	if (dt.is_dst == 1)
	{
		sa.solpos_vals.timezone = cli->tz_offset_val-1.0;
	}
	else
	{
		sa.solpos_vals.timezone = cli->tz_offset_val;
	}
	sa.solpos_vals.year = dt.year;
	sa.solpos_vals.daynum = (dt.yearday+1);
	sa.solpos_vals.hour = dt.hour;
	sa.solpos_vals.minute = dt.minute;
	sa.solpos_vals.second = dt.second;
	sa.solpos_vals.temp = temp_value;
	sa.solpos_vals.press = cli->pressure;

	// Solar constant associated with extraterrestrial DNI, 1367 W/sq m - pull from TMY for now
	//sa.solpos_vals.solcon = 126.998456;	//Use constant value for direct normal extraterrestrial irradiance - doesn't seem right to me
	sa.solpos_vals.solcon = cli->direct_normal_extra;	//Use weather-read version (TMY)

	sa.solpos_vals.aspect = orientation;
	sa.solpos_vals.tilt = tilt;
	sa.solpos_vals.diff_horz = dhr;
	sa.solpos_vals.dir_norm = dnr;

	//Calculate different solar position values
	sa.S_solpos(&sa.solpos_vals);

	//Pull off new cosine of incidence
	if (sa.solpos_vals.cosinc >= 0.0)
		cos_incident = sa.solpos_vals.cosinc;
	else
		cos_incident = 0.0;

	//Apply the adjustment
	*value = (shading_value*dnr*cos_incident) + dhr*sa.solpos_vals.perez_horz + ghr*((1 - cos(tilt))*cli->ground_reflectivity/2.0);

	return 1;
}
示例#7
0
TIMESTAMP climate::presync(TIMESTAMP t0) /* called in presync */
{
	TIMESTAMP rv = 0;
	if(t0 > TS_ZERO && reader_type == RT_CSV){
		DATETIME now;
		gl_localtime(t0, &now);
		//OBJECT *obj = OBJECTHDR(this);
		csv_reader *cr = OBJECTDATA(reader,csv_reader);
		rv = cr->get_data(t0, &temperature, &humidity, &solar_direct, &solar_diffuse, &solar_global, &wind_speed, &rainfall, &snowdepth, &pressure);
		// calculate the solar radiation
		double sol_time = sa->solar_time((double)now.hour+now.minute/60.0+now.second/3600.0 + (now.is_dst ? -1:0),now.yearday,RAD(tz_meridian),RAD(reader->longitude));
		double sol_rad = 0.0;

		for(COMPASS_PTS c_point = CP_H; c_point < CP_LAST;c_point=COMPASS_PTS(c_point+1)){
			if(c_point == CP_H)
				sol_rad = file.calc_solar(CP_E,now.yearday,RAD(reader->latitude),sol_time,solar_direct,solar_diffuse,solar_global,ground_reflectivity,0.0);//(double)dnr * cos_incident + dhr;
			else
				sol_rad = file.calc_solar(c_point,now.yearday,RAD(reader->latitude),sol_time,solar_direct,solar_diffuse,solar_global,ground_reflectivity);//(double)dnr * cos_incident + dhr;
			/* TMY2 solar radiation data is in Watt-hours per square meter. */
			solar_flux[c_point] = sol_rad;
		}
		return rv;
	}
	if (t0>TS_ZERO && tmy!=NULL)
	{
		DATETIME ts;
		int localres = gl_localtime(t0,&ts);
		int hoy;
		double now, hoy0, hoy1, hoy2;
		if(localres == 0){
			GL_THROW("climate::sync -- unable to resolve localtime!");
		}
		int doy = sa->day_of_yr(ts.month,ts.day);
		hoy = (doy - 1) * 24 + (ts.hour);
		switch(interpolate){
			case CI_NONE:
				temperature = tmy[hoy].temp;
				temperature_raw = tmy[hoy].temp_raw;
				humidity = tmy[hoy].rh;
				solar_direct = tmy[hoy].dnr;
				solar_diffuse = tmy[hoy].dhr;
				solar_global = tmy[hoy].ghr;
				solar_raw = tmy[hoy].solar_raw;
				solar_azimuth = tmy[hoy].solar_azimuth;
				solar_elevation = tmy[hoy].solar_elevation;

				pressure = tmy[hoy].pressure;
				direct_normal_extra = tmy[hoy].direct_normal_extra;

				this->wind_speed = tmy[hoy].windspeed;
				this->rainfall = tmy[hoy].rainfall;
				this->snowdepth = tmy[hoy].snowdepth;

				if(memcmp(solar_flux,tmy[hoy].solar,CP_LAST*sizeof(double)))
					memcpy(solar_flux,tmy[hoy].solar,CP_LAST*sizeof(double));
				break;
			case CI_LINEAR:
				now = hoy+ts.minute/60.0;
				hoy0 = hoy;
				hoy1 = hoy+1.0;
				temperature = gl_lerp(now, hoy0, tmy[hoy].temp, hoy1, tmy[hoy+1%8760].temp);
				temperature_raw = gl_lerp(now, hoy0, tmy[hoy].temp_raw, hoy1, tmy[hoy+1%8760].temp_raw);
				humidity = gl_lerp(now, hoy0, tmy[hoy].rh, hoy1, tmy[hoy+1%8760].rh);
				solar_direct = gl_lerp(now, hoy0, tmy[hoy].dnr, hoy1, tmy[hoy+1%8760].dnr);
				solar_diffuse = gl_lerp(now, hoy0, tmy[hoy].dhr, hoy1, tmy[hoy+1%8760].dhr);
				solar_global = gl_lerp(now, hoy0, tmy[hoy].ghr, hoy1, tmy[hoy+1%8760].ghr);
				solar_azimuth = gl_lerp(now, hoy0, tmy[hoy].solar_azimuth, hoy1, tmy[hoy+1%8760].solar_azimuth);
				solar_elevation = gl_lerp(now, hoy0, tmy[hoy].solar_elevation, hoy1, tmy[hoy+1%8760].solar_elevation);
				wind_speed = gl_lerp(now, hoy0, tmy[hoy].windspeed, hoy1, tmy[hoy+1%8760].windspeed);
				rainfall = gl_lerp(now, hoy0, tmy[hoy].rainfall, hoy1, tmy[hoy+1%8760].rainfall);
				snowdepth = gl_lerp(now, hoy0, tmy[hoy].snowdepth, hoy1, tmy[hoy+1%8760].snowdepth);
				solar_raw = gl_lerp(now, hoy0, tmy[hoy].solar_raw, hoy1, tmy[hoy+1%8760].solar_raw);
				pressure = gl_lerp(now, hoy0, tmy[hoy].pressure, hoy1, tmy[hoy+1%8760].pressure);
				direct_normal_extra = gl_lerp(now, hoy0, tmy[hoy].direct_normal_extra, hoy1, tmy[hoy+1%8760].direct_normal_extra);
				for(int pt = 0; pt < CP_LAST; ++pt){
					solar_flux[pt] = gl_lerp(now, hoy0, tmy[hoy].solar[pt], hoy1, tmy[hoy+1%8760].solar[pt]);
				}
				break;
			case CI_QUADRATIC:
				now = hoy+ts.minute/60.0;
				hoy0 = hoy;
				hoy1 = hoy+1.0;
				hoy2 = hoy+2.0;
				temperature = gl_qerp(now, hoy0, tmy[hoy].temp, hoy1, tmy[hoy+1%8760].temp, hoy2, tmy[hoy+2%8760].temp);
				temperature_raw = gl_qerp(now, hoy0, tmy[hoy].temp_raw, hoy1, tmy[hoy+1%8760].temp_raw, hoy2, tmy[hoy+2%8760].temp_raw);
				humidity = gl_qerp(now, hoy0, tmy[hoy].rh, hoy1, tmy[hoy+1%8760].rh, hoy2, tmy[hoy+2%8760].rh);
				if(humidity < 0.0){
					humidity = 0.0;
					gl_verbose("Setting humidity to zero. Quadratic interpolation caused the humidity to drop below zero.");
				}
				solar_direct = gl_qerp(now, hoy0, tmy[hoy].dnr, hoy1, tmy[hoy+1%8760].dnr, hoy2, tmy[hoy+2%8760].dnr);
				if(solar_direct < 0.0){
					solar_direct = 0.0;
					gl_verbose("Setting solar_direct to zero. Quadratic interpolation caused the solar_direct to drop below zero.");
				}
				solar_diffuse = gl_qerp(now, hoy0, tmy[hoy].dhr, hoy1, tmy[hoy+1%8760].dhr, hoy2, tmy[hoy+2%8760].dhr);
				if(solar_diffuse < 0.0){
					solar_diffuse = 0.0;
					gl_verbose("Setting solar_diffuse to zero. Quadratic interpolation caused the solar_diffuse to drop below zero.");
				}
				solar_global = gl_qerp(now, hoy0, tmy[hoy].ghr, hoy1, tmy[hoy+1%8760].ghr, hoy2, tmy[hoy+2%8760].ghr);
				if(solar_global < 0.0){
					solar_global = 0.0;
					gl_verbose("Setting solar_global to zero. Quadratic interpolation caused the solar_global to drop below zero.");
				}
				solar_azimuth = gl_qerp(now, hoy0, tmy[hoy].solar_azimuth, hoy1, tmy[hoy+1%8760].solar_azimuth, hoy2, tmy[hoy+2%8760].solar_azimuth);
				solar_elevation = gl_qerp(now, hoy0, tmy[hoy].solar_elevation, hoy1, tmy[hoy+1%8760].solar_elevation, hoy2, tmy[hoy+2%8760].solar_elevation);
				wind_speed = gl_qerp(now, hoy0, tmy[hoy].windspeed, hoy1, tmy[hoy+1%8760].windspeed, hoy2, tmy[hoy+2%8760].windspeed);
				if(wind_speed < 0.0){
					wind_speed = 0.0;
					gl_verbose("Setting wind_speed to zero. Quadratic interpolation caused the wind_speed to drop below zero.");
				}
				rainfall = gl_qerp(now, hoy0, tmy[hoy].rainfall, hoy1, tmy[hoy+1%8760].rainfall, hoy2, tmy[hoy+2%8760].rainfall);
				if(rainfall < 0.0){
					rainfall = 0.0;
					gl_verbose("Setting rainfall to zero. Quadratic interpolation caused the rainfall to drop below zero.");
				}
				snowdepth = gl_qerp(now, hoy0, tmy[hoy].snowdepth, hoy1, tmy[hoy+1%8760].snowdepth, hoy2, tmy[hoy+2%8760].snowdepth);
				if(snowdepth < 0.0){
					snowdepth = 0.0;
					gl_verbose("Setting snowdepth to zero. Quadratic interpolation caused the snowdepth to drop below zero.");
				}
				solar_raw = gl_qerp(now, hoy0, tmy[hoy].solar_raw, hoy1, tmy[hoy+1%8760].solar_raw, hoy2, tmy[hoy+2%8760].solar_raw);
				if(solar_raw < 0.0){
					solar_raw = 0.0;
					gl_verbose("Setting solar_raw to zero. Quadratic interpolation caused the solar_raw to drop below zero.");
				}
				pressure = gl_qerp(now, hoy0, tmy[hoy].pressure, hoy1, tmy[hoy+1%8760].pressure, hoy2, tmy[hoy+2%8760].pressure);
				if(pressure < 0.0){
					pressure = 0.0;
					gl_verbose("Setting pressure to zero. Quadratic interpolation caused the pressure to drop below zero.");
				}
				direct_normal_extra = gl_qerp(now, hoy0, tmy[hoy].direct_normal_extra, hoy1, tmy[hoy+1%8760].direct_normal_extra, hoy2, tmy[hoy+2%8760].direct_normal_extra);
				if(direct_normal_extra < 0.0){
					direct_normal_extra = 0.0;
					gl_verbose("Setting extraterrestrial_direct_normal to zero. Quadratic interpolation caused the extraterrestrial_direct_normal to drop below zero.");
				}
				for(int pt = 0; pt < CP_LAST; ++pt){
					if(tmy[hoy].solar[pt] == tmy[hoy+1].solar[pt]){
						solar_flux[pt] = tmy[hoy].solar[pt];
					} else {
						solar_flux[pt] = gl_qerp(now, hoy0, tmy[hoy].solar[pt], hoy1, tmy[hoy+1%8760].solar[pt], hoy2, tmy[hoy+2%8760].solar[pt]);
						if(solar_flux[pt] < 0.0)
							solar_flux[pt] = 0.0; /* quadratic isn't always cooperative... */
					}
				}
				break;
			default:
				GL_THROW("climate::sync -- unrecognize interpolation mode!");
		}
		update_forecasts(t0);
		return -(t0+(3600*TS_SECOND-t0%(3600 *TS_SECOND))); /// negative means soft event
	}
	return TS_NEVER;
}
示例#8
0
//Function to change recloser states - just call underlying switch routine
EXPORT double change_recloser_state(OBJECT *thisobj, unsigned char phase_change, bool state)
{
	double count_values;
	char desA, desB, desC;
	recloser *reclobj;
	switch_object *swtchobj;
	FUNCTIONADDR funadd = NULL;

	//Init
	count_values = 0.0;

	//Map us as a recloser - just so we can get our count
	reclobj = OBJECTDATA(thisobj,recloser);

	//Set count
	if (state == false)
		count_values = reclobj->ntries;	//Opening, so must have "tried" all times
	else
		count_values = 1.0;	//Just a non-zero value

	//Map the switch
	swtchobj = OBJECTDATA(thisobj,switch_object);

	if (swtchobj->switch_banked_mode == switch_object::BANKED_SW)	//Banked mode - all become "state", just cause
	{
		swtchobj->set_switch(state);
	}
	else	//Must be individual
	{
		//Figure out what we need to call
		if ((phase_change & 0x04) == 0x04)
		{
			if (state==true)
				desA=1;	//Close it
			else
				desA=0;	//Open it
		}
		else	//Nope, no A
			desA=2;		//I don't care

		//Phase B
		if ((phase_change & 0x02) == 0x02)
		{
			if (state==true)
				desB=1;	//Close it
			else
				desB=0;	//Open it
		}
		else	//Nope, no B
			desB=2;		//I don't care

		//Phase C
		if ((phase_change & 0x01) == 0x01)
		{
			if (state==true)
				desC=1;	//Close it
			else
				desC=0;	//Open it
		}
		else	//Nope, no A
			desC=2;		//I don't care

		//Perform the switching!
		swtchobj->set_switch_full(desA,desB,desC);
	}//End individual adjustments

	return count_values;
}
示例#9
0
EXPORT int init_plugload(OBJECT *obj)
{
	plugload *my = OBJECTDATA(obj,plugload);
	return my->init(obj->parent);
}
示例#10
0
EXPORT int init_schedule(OBJECT *obj)
{
	schedule *my = OBJECTDATA(obj,schedule);
	return my->init(obj->parent);
}
示例#11
0
EXPORT int isa_recloser(OBJECT *obj, char *classname)
{
	return OBJECTDATA(obj,recloser)->isa(classname);
}
/** initialization process
 **/
int irrigation_controller::init(OBJECT *parent){
	OBJECT *hdr = OBJECTHDR(this);
	char tname[32];
	parent2=parent;
	insync=0;


	initial_zipload_power=gl_get_double_by_name(parent,"base_power");

	char *namestr = (hdr->name ? hdr->name : tname);

	sprintf(tname, "irrigation_controller:%i", hdr->id);
	first=0;
	cheat();

	if(parent == NULL){
		gl_error("%s: irrigation_controller has no parent, therefore nothing to control", namestr);
		return 0;
	}

	if(pMarket == NULL){
		gl_error("%s: irrigation_controller has no market, therefore no price signals", namestr);
		return 0;
	}

	if(gl_object_isa(pMarket, "auction")){
		gl_set_dependent(hdr, pMarket);
		market = OBJECTDATA(pMarket, auction);
	} else {
		gl_error("irrigation_controllers only work when attached to an 'auction' object");
		return 0;
	}

	if(dPeriod == 0.0){
		if((pMarket->flags & OF_INIT) != OF_INIT){
			char objname[256];
			gl_verbose("irrigation_controller::init(): deferring initialization on %s", gl_name(pMarket, objname, 255));
			return 2; // defer
		}
		period = market->period;
	} else {
		period = (TIMESTAMP)floor(dPeriod + 0.5);
	}

	if(bid_delay < 0){
		bid_delay = -bid_delay;
	}
	if(bid_delay > period){
		gl_warning("Bid delay is greater than the irrigation_controller period. Resetting bid delay to 0.");
		bid_delay = 0;
	}

	if(target[0] == 0){
		GL_THROW("irrigation_controller: %i, target property not specified", hdr->id);
	}
	if(setpoint[0] == 0 && control_mode == CN_RAMP){
		GL_THROW("irrigation_controller: %i, setpoint property not specified", hdr->id);;
	}
	if(demand[0] == 0 && control_mode == CN_RAMP){
		GL_THROW("irrigation_controller: %i, demand property not specified", hdr->id);
	}
	if(deadband[0] == 0 && use_predictive_bidding == TRUE && control_mode == CN_RAMP){
		GL_THROW("irrigation_controller: %i, deadband property not specified", hdr->id);
	}
	if(total[0] == 0){
		GL_THROW("irrigation_controller: %i, total property not specified", hdr->id);
	}
	if(load[0] == 0){
		GL_THROW("irrigation_controller: %i, load property not specified", hdr->id);
	}

	
	fetch(&pMonitor, target, parent); // auto tha einai to soil hmidit tha to pairnei apo to soil_SENSOR
	if(control_mode == CN_RAMP){
		fetch(&pSetpoint, setpoint, parent);
		fetch(&pDemand, demand, parent);
		fetch(&pTotal, total, parent);
		fetch(&pLoad, load, parent);
		if(use_predictive_bidding == TRUE){
			fetch(&pDeadband, deadband.get_string(), parent);
		}
	} 
	fetch(&pAvg, avg_target.get_string(), pMarket);
	fetch(&pStd, std_target.get_string(), pMarket);


	if(dir == 0){
		double high = ramp_high * range_high;
		double low = ramp_low * range_low;
			//printf("high:%f, low:%f, rh:%f, rl:%f,gh:%f,gl:%f\n\n\n\n",high,low,ramp_high,ramp_low,range_high,range_low);
		if(high > low){
			dir = 1;
		} else if(high < low){
			dir = -1;
		} else if((high == low) && (fabs(ramp_high) > 0.001 || fabs(ramp_low) > 0.001)){
			dir = 0;
			if(ramp_high > 0){
				direction = 1;
			} else {
				direction = -1;
			}
			gl_warning("%s: irrigation_controller has no price ramp", namestr);
			/* occurs given no price variation, or no control width (use a normal thermostat?) */
		}
		if(ramp_low * ramp_high < 0){
			gl_warning("%s: irrigation_controller price curve is not injective and may behave strangely");
			/* TROUBLESHOOT
				The price curve 'changes directions' at the setpoint, which may create odd
				conditions in a number of circumstances.
			 */
		}
	}
	if(setpoint0==0)
		setpoint0 = -1; // key to check first thing

//	double period = market->period;
//	next_run = gl_globalclock + (TIMESTAMP)(period - fmod(gl_globalclock+period,period));
	next_run = gl_globalclock;// + (market->period - gl_globalclock%market->period);
	init_time = gl_globalclock;
	time_off = TS_NEVER;
	if(sliding_time_delay < 0 )
		dtime_delay = 21600; // default sliding_time_delay of 6 hours
	else
		dtime_delay = (int64)sliding_time_delay;

	if(state[0] != 0){
		// grab state pointer
		pState = gl_get_enum_by_name(parent, state);
		last_pState = 0;
		if(pState == 0){
			gl_error("state property name \'%s\' is not published by parent class", state);
			return 0;
		}
	}

	
	// get override, if set
	if(re_override[0] != 0){
		pOverride = gl_get_enum_by_name(parent, re_override);
	}
	if((pOverride == 0) && (use_override == OU_ON)){
		gl_error("use_override is ON but no valid override property name is given");
		return 0;
	}

	if(control_mode == CN_RAMP){
		if(slider_setting < -0.001){
			gl_warning("slider_setting is negative, reseting to 0.0");
			slider_setting = 0.0;
		}
		if(slider_setting > 1.0){
			gl_warning("slider_setting is greater than 1.0, reseting to 1.0");
			slider_setting = 1.0;
		}
	}
	
	last_p = market->init_price;

	/////////////////search for virtual_battery///////////////////////
	/*
				 static FINDLIST *xt1=NULL;
				 xt1=gl_find_objects(FL_NEW,FT_CLASS,SAME,"virtual_battery",FT_END);
				 OBJECT *firstt1= gl_find_next(xt1,NULL);
				 OBJECT *it1;
				 for(it1=firstt1;it1!=NULL;it1=it1->next)
				 {
				
					 if(gl_object_isa(it1,"virtual_battery"))
				     {

						
						 virtual_battery_object=it1;
						
					 }
					 else
					 {
					 
					// virtual_battery_object=NULL;
					 
					 }


				 }

	*/
	//////////////////////////////////////////////////////////////////
	return 1;
}
示例#13
0
//int solver_matpower(double *rbus, unsigned int nbus, double *rgen, unsigned int ngen, 
//	double *rbranch, unsigned int nbranch, double *rgencost, unsigned int ngencost,
//	double *rareas,	unsigned int nareas)
int solver_matpower(vector<unsigned int> bus_BUS_I, vector<unsigned int> branch_F_BUS, vector<unsigned int> branch_T_BUS, vector<unsigned int> gen_GEN_BUS, vector<unsigned int> gen_NCOST,unsigned int BASEMVA)
{	
	unsigned int nbus = 0;
	unsigned int ngen = 0;
	unsigned int nbranch = 0;
	//unsigned int ngencost = 0;
	//unsigned int nareas = 0;
	//unsigned int nbaseMVA = 0;

	vector<bus> vec_bus;
	vector<gen> vec_gen;
	vector<branch> vec_branch;
	//vector<areas> vec_areas;
	//vector<gen_cost> vec_gencost;
	//vector<baseMVA> vec_baseMVA;
	

	
	//printf("========Getting Data=============\n");

	// Get Bus objects
	OBJECT *temp_obj = NULL;
	bus *list_bus;
	FINDLIST *bus_list = gl_find_objects(FL_NEW,FT_CLASS,SAME,"bus",FT_END);
	while (gl_find_next(bus_list,temp_obj)!=NULL)
	{
		
		temp_obj = gl_find_next(bus_list,temp_obj);
		list_bus = OBJECTDATA(temp_obj,bus);
		vec_bus.push_back(*list_bus);
		
        };

	// Get Generator objects
	gen *list_gen;
	FINDLIST *gen_list = gl_find_objects(FL_NEW,FT_CLASS,SAME,"gen",FT_END);
	temp_obj = NULL;
	
	while (gl_find_next(gen_list,temp_obj)!=NULL)
	{
		temp_obj = gl_find_next(gen_list,temp_obj);
		list_gen = OBJECTDATA(temp_obj,gen);
		vec_gen.push_back(*list_gen);
        };

	// Get Line/Branch Objects
	branch *list_branch;
	FINDLIST *branch_list = gl_find_objects(FL_NEW,FT_CLASS,SAME,"branch",FT_END);
	temp_obj = NULL;

	while (gl_find_next(branch_list,temp_obj)!=NULL)	
	{
		temp_obj = gl_find_next(branch_list,temp_obj);
		list_branch = OBJECTDATA(temp_obj,branch);
		vec_branch.push_back(*list_branch);
	}

	// Get Area Objects
/*
	areas *list_areas;
	FINDLIST *areas_list = gl_find_objects(FL_NEW,FT_CLASS,SAME,"areas",FT_END);
	temp_obj = NULL;
	
	while (gl_find_next(areas_list,temp_obj) != NULL)
	{
		temp_obj = gl_find_next(areas_list,temp_obj);
		list_areas = OBJECTDATA(temp_obj,areas);
		vec_areas.push_back(*list_areas);
	}
*/
	
	// Get Generator Cost objects
	/*
	gen_cost *list_gen_cost;
	FINDLIST *gen_cost_list = gl_find_objects(FL_NEW,FT_CLASS,SAME,"gen_cost",FT_END);
	temp_obj = NULL;

	while (gl_find_next(gen_cost_list,temp_obj)!=NULL)
	{
		temp_obj = gl_find_next(gen_cost_list,temp_obj);
		list_gen_cost = OBJECTDATA(temp_obj,gen_cost);
		vec_gencost.push_back(*list_gen_cost);

	}
	*/
	// Get Base Information object
	//baseMVA *list_baseMVA;
	//FINDLIST *baseMVA_list = gl_find_objects(FL_NEW,FT_CLASS,SAME,"baseMVA",FT_END);
	//temp_obj = NULL;
	//temp_obj = gl_find_next(baseMVA_list,temp_obj);
	//list_baseMVA = OBJECTDATA(temp_obj,baseMVA);
	//vec_baseMVA.push_back(*list_baseMVA);

	// Get the size of each class
	nbus = vec_bus.size();
	ngen = vec_gen.size();
	nbranch = vec_branch.size();
	//ngencost = vec_gencost.size();
	//nareas = vec_areas.size();
	//nbaseMVA = vec_baseMVA.size();


	// create arrays for input and allocate memory
	double *rbus;
	rbus = (double *) calloc(nbus*BUS_ATTR,sizeof(double));

	double *rgen;
	rgen = (double *) calloc(ngen*GEN_ATTR,sizeof(double));	

	double *rbranch;
	rbranch = (double *) calloc(nbranch*BRANCH_ATTR,sizeof(double));

	double *rareas;
	rareas = (double *) calloc(AREA_ATTR,sizeof(double));

	double rbaseMVA;

	double *rgencost; // allocation of memory is in the following part
	
	

	
	// insert bus data for rbus
	vector<bus>::iterator iter_bus = vec_bus.begin();
	if (nbus > 1)
	{
		for (unsigned int i=0; i < nbus; i++)
		{
			//rbus[i+0*nbus] = (double)iter_bus->BUS_I;
			rbus[i+0*nbus] = bus_BUS_I[i];
			rbus[i+1*nbus] = (double)iter_bus->BUS_TYPE;
			rbus[i+2*nbus] = iter_bus->PD;
			rbus[i+3*nbus] = iter_bus->QD;
			rbus[i+4*nbus] = iter_bus->GS;
			rbus[i+5*nbus] = iter_bus->BS;
			//rbus[i+6*nbus] = (double)iter_bus->BUS_AREA;
			rbus[i+6*nbus] = 1;
			rbus[i+7*nbus] = iter_bus->VM;
			rbus[i+8*nbus] = iter_bus->VA;
			rbus[i+9*nbus] = iter_bus->BASE_KV;
			rbus[i+10*nbus] = (double)iter_bus->ZONE;
			rbus[i+11*nbus] = iter_bus->VMAX;
			rbus[i+12*nbus] = iter_bus->VMIN;
			iter_bus++;
		}
	}

	
	// insert data for rgen
	vector<gen>::iterator iter_gen = vec_gen.begin();
	unsigned int max_order = 0;
	for (unsigned int i =0; i< ngen; i++)
	{
		if (gen_NCOST[i] > max_order)
			max_order = gen_NCOST[i];
		iter_gen++;
	}
	rgencost = (double *) calloc(ngen*(GENCOST_ATTR+max_order),sizeof(double));

	iter_gen = vec_gen.begin();

	for (unsigned int i = 0; i < ngen; i++)
	{
		//rgen[i+0*ngen] = (double) iter_gen->GEN_BUS;
		rgen[i+0*ngen] = gen_GEN_BUS[i];
		rgen[i+1*ngen] = iter_gen->PG;
		rgen[i+2*ngen] = iter_gen->QG;
		rgen[i+3*ngen] = iter_gen->QMAX;
		rgen[i+4*ngen] = iter_gen->QMIN;
		rgen[i+5*ngen] = iter_gen->VG;
		rgen[i+6*ngen] = iter_gen->MBASE;
		rgen[i+7*ngen] = iter_gen->GEN_STATUS;
		rgen[i+8*ngen] = iter_gen->PMAX;
		rgen[i+9*ngen] = iter_gen->PMIN;
		rgen[i+10*ngen] = iter_gen->PC1;
		rgen[i+11*ngen] = iter_gen->PC2;
		rgen[i+12*ngen] = iter_gen->QC1MIN;
		rgen[i+13*ngen] = iter_gen->QC1MAX;
		rgen[i+14*ngen] = iter_gen->QC2MIN;
		rgen[i+15*ngen] = iter_gen->QC2MAX;
		rgen[i+16*ngen] = iter_gen->RAMP_AGC;
		rgen[i+17*ngen] = iter_gen->RAMP_10;
		rgen[i+18*ngen] = iter_gen->RAMP_30;
		rgen[i+19*ngen] = iter_gen->RAMP_Q;
		rgen[i+20*ngen] = iter_gen->APF;

		// Cost info
		rgencost[i+0*ngen] = iter_gen->MODEL;
		rgencost[i+1*ngen] = iter_gen->STARTUP;
		rgencost[i+2*ngen] = iter_gen->SHUTDOWN;
		//rgencost[i+3*ngen] = (double)iter_gen->NCOST;
		rgencost[i+3*ngen] = gen_NCOST[i];
		string double_string(iter_gen->COST);
		vector<string> v;
		v = split(double_string,',');
		for (unsigned int j=0; j<v.size();j++)
		{
			rgencost[i+(4+j)*ngen] = atof(v[j].c_str());
		}
		if (gen_NCOST[i] != max_order)
		{
			for (unsigned int j = gen_NCOST[i]; j< max_order; j++)
			{
				rgencost[i+(4+j)*ngen] = 0.0;
			}
		}

		iter_gen++;
	}	



	// insert data for rbranch
	vector<branch>::iterator iter_branch = vec_branch.begin();
	for (unsigned int i = 0; i < nbranch; i++)
	{
		//rbranch[i+0*nbranch] = (double)iter_branch->F_BUS;
		rbranch[i+0*nbranch] = branch_F_BUS[i];
		//rbranch[i+1*nbranch] = (double)iter_branch->T_BUS;
		rbranch[i+1*nbranch] = branch_T_BUS[i];
		rbranch[i+2*nbranch] = iter_branch->BR_R;
		rbranch[i+3*nbranch] = iter_branch->BR_X;
		rbranch[i+4*nbranch] = iter_branch->BR_B;
		rbranch[i+5*nbranch] = iter_branch->RATE_A;
		rbranch[i+6*nbranch] = iter_branch->RATE_B;		
		rbranch[i+7*nbranch] = iter_branch->RATE_C;
		rbranch[i+8*nbranch] = iter_branch->TAP;
		rbranch[i+9*nbranch] = iter_branch->SHIFT;
		rbranch[i+10*nbranch] = (double)iter_branch->BR_STATUS;
		rbranch[i+11*nbranch] = iter_branch->ANGMIN;
		rbranch[i+12*nbranch] = iter_branch->ANGMAX;
		iter_branch++;
	}

	
	// insert data for rareas
	//vector<areas>::const_iterator iter_areas = vec_areas.begin();
	//for (unsigned int i = 0; i < nareas; i++)
	//{
		rareas[0] = 1;
		rareas[1] = 1;
	//	iter_areas++;
	//} 

	// insert data for rbaseMVA
	//vector<baseMVA>::const_iterator iter_baseMVA = vec_baseMVA.begin();
	//rbaseMVA = iter_baseMVA->BASEMVA;
	rbaseMVA = BASEMVA;

	// insert data for rgencost
	/*
	vector<gen_cost>::const_iterator iter_gencost = vec_gencost.begin();

	unsigned int max_order = 0;
	for (unsigned int i = 0; i<ngencost; i++)
	{
		if (iter_gencost->NCOST > max_order)
			max_order = iter_gencost->NCOST;
		iter_gencost++;
		
	}
	
	rgencost = (double *) calloc(ngencost*(GENCOST_ATTR+max_order),sizeof(double));
	
	iter_gencost = vec_gencost.begin();
	for (unsigned int i = 0; i<ngencost; i++)
	{
		// Only support model 2: ticket 4
		if (iter_gencost -> MODEL != 2)
			GL_THROW("Unsupported model for generation cost\n");

		rgencost[i+0*ngencost] = iter_gencost->MODEL;
		rgencost[i+1*ngencost] = iter_gencost->STARTUP;
		rgencost[i+2*ngencost] = iter_gencost->SHUTDOWN;
		rgencost[i+3*ngencost] = (double)iter_gencost->NCOST;
		string double_string(iter_gencost->COST);
		vector<string> v;
		v = split(double_string,',');
		for (unsigned int j = 0; j<v.size();j++)
		{
			rgencost[i+(4+j)*ngencost] = atof(v[j].c_str());
		}
		if (iter_gencost->NCOST != max_order)
		{
			for (unsigned int j = iter_gencost->NCOST; j < max_order; j++)
				rgencost[i+(4+j)*ngencost] = 0.0;
		}
		iter_gencost++;
	}
	*/



	// Run the Solver function
	//printf("Running Test\n");
        libopfInitialize();
	//mxArray* basemva = initArray(rbaseMVA,nbaseMVA,BASEMVA_ATTR);
	mxArray* basemva_array = mxCreateDoubleMatrix(1,1,mxREAL);
	*mxGetPr(basemva_array) = rbaseMVA;

	// change to MATLAB MAT format
	mxArray* bus_array = initArray(rbus, nbus, BUS_ATTR);	
	mxArray* gen_array = initArray(rgen, ngen, GEN_ATTR);
	mxArray* branch_array = initArray(rbranch, nbranch, BRANCH_ATTR);
	mxArray* gencost_array = initArray(rgencost, ngen, GENCOST_ATTR+max_order);
	//mxArray* areas_array = initArray(rareas, nareas, AREA_ATTR);
	mxArray* areas_array = initArray(rareas, 1, AREA_ATTR);

	mxArray* busout;
	mxArray* genout;
	mxArray* branchout;
	mxArray* f;
	mxArray* success;



	mxArray* plhs[5];
	mxArray* prhs[6];
	plhs[0] = busout;
	plhs[1] = genout;
	plhs[2] = branchout;
	plhs[3] = f;
	plhs[4] = success;

	prhs[0] = basemva_array;
	prhs[1] = bus_array;
	prhs[2] = gen_array;
	prhs[3] = branch_array;
	prhs[4] = areas_array;
	prhs[5] = gencost_array;

	mlxOpf(5, plhs, 6, prhs); // cout if first parameter is 0;
	//mlxOpf(0,plhs,6,prhs);


	// Get data from array
	double *obus = getArray(plhs[0]);
	double *ogen = getArray(plhs[1]);
	double *obranch = getArray(plhs[2]);

	// Update class bus

	temp_obj = NULL;
	for (unsigned int i=0; i < nbus; i++)
	{
		/*		
		iter_bus->PD = obus[i+2*nbus];
		iter_bus->QD = obus[i+3*nbus];
		iter_bus->GS = obus[i+4*nbus];
		iter_bus->BS = obus[i+5*nbus];
		iter_bus->VM = obus[i+7*nbus];		
		iter_bus->VA = obus[i+8*nbus];
		iter_bus->VMAX = obus[i+11*nbus];
		iter_bus->VMIN = obus[i+12*nbus];
		iter_bus->LAM_P = obus[i+13*nbus];
		iter_bus->LAM_Q = obus[i+14*nbus];
		iter_bus->MU_VMAX = obus[i+15*nbus];
		iter_bus->MU_VMIN = obus[i+16*nbus];
		//iter_bus++;
		*/
		//printf("====Before Test part VM %f; %f\n",iter_bus->VM,obus[i+7*nbus]);
		
		temp_obj = gl_find_next(bus_list,temp_obj);

		
		//Matpower does not overwrite the generator power in bus class
		setObjectValue_Double(temp_obj,"PD",obus[i+2*nbus]);
		setObjectValue_Double(temp_obj,"QD",obus[i+3*nbus]);
		setObjectValue_Double(temp_obj,"GS",obus[i+4*nbus]);
		setObjectValue_Double(temp_obj,"BS",obus[i+5*nbus]);
		setObjectValue_Double(temp_obj,"VM",obus[i+7*nbus]);
		setObjectValue_Double(temp_obj,"VA",obus[i+8*nbus]);
		setObjectValue_Double(temp_obj,"VMAX",obus[i+11*nbus]);
		setObjectValue_Double(temp_obj,"VMIN",obus[i+12*nbus]);
		setObjectValue_Double(temp_obj,"LAM_P",obus[i+13*nbus]);
		setObjectValue_Double(temp_obj,"LAM_Q",obus[i+14*nbus]);
		setObjectValue_Double(temp_obj,"MU_VMAX",obus[i+15*nbus]);
		setObjectValue_Double(temp_obj,"MU_VMIN",obus[i+16*nbus]);

		// obus[i+9*nbus] is BASE_KV. The unit is KV.
		setObjectValue_Double2Complex_inDegree(temp_obj,"CVoltageA",obus[i+7*nbus]*obus[i+9*nbus]*1000,obus[i+8*nbus]);
		setObjectValue_Double2Complex_inDegree(temp_obj,"CVoltageB",obus[i+7*nbus]*obus[i+9*nbus]*1000,obus[i+8*nbus]+2/3*PI);
		setObjectValue_Double2Complex_inDegree(temp_obj,"CVoltageC",obus[i+7*nbus]*obus[i+9*nbus]*1000,obus[i+8*nbus]-2/3*PI);
		setObjectValue_Double(temp_obj,"V_nom",obus[i+7*nbus]*obus[i+9*nbus]*1000);
		
		//printf("BUS: %f LAM_P %f\n",obus[i+0*nbus],obus[i+13*nbus]);
		//cout<<"BUS "<<obus[i+0*nbus]<<"LAM_P "<<obus[i+13*nbus]<<endl;
	}
/*
	unsigned int NumOfElement = mxGetNumberOfElements(plhs[0]);
	for (unsigned int i =0; i<NumOfElement; i++)
	{
		printf("%f ",obus[i]);
		if ((i+1)%nbus == 0)
			printf("\n");
	}
	

	printf("========================\n");

	iter_bus = vec_bus.begin();
	for (unsigned int i=0;i< nbus; i++)
	{
		printf("Bus %d; PD %f; QD %f; VM %f; VA %f;\n",iter_bus->BUS_I,iter_bus->PD,iter_bus->QD,iter_bus->VM,iter_bus->VA);
		iter_bus++;
	}
*/	
	// Update class gen
	
	iter_gen = vec_gen.begin();
	temp_obj = NULL;
	for (unsigned int i = 0; i < ngen; i++)
	{
/*		
		iter_gen->PG = ogen[i+1*ngen];
		iter_gen->QG = ogen[i+2*ngen];
		iter_gen->QMAX = ogen[i+3*ngen];
		iter_gen->QMIN = ogen[i+4*ngen];
		iter_gen->VG = ogen[i+5*ngen];
		iter_gen->PC1 = ogen[i+10*ngen];
		iter_gen->PC2 = ogen[i+11*ngen];
		iter_gen->RAMP_AGC = ogen[i+16*ngen];
		iter_gen->RAMP_10 = ogen[i+17*ngen];
		iter_gen->RAMP_30 = ogen[i+18*ngen];
		iter_gen->RAMP_Q = ogen[i+19*ngen];
		iter_gen->APF = ogen[i+20*ngen];
		iter_gen->MU_PMAX = ogen[i+21*ngen];
		iter_gen->MU_PMIN = ogen[i+22*ngen];
		iter_gen->MU_QMAX = ogen[i+23*ngen];
		iter_gen->MU_QMIN = ogen[i+24*ngen];
		iter_gen++;
*/
		temp_obj = gl_find_next(gen_list,temp_obj);
		setObjectValue_Double(temp_obj,"PG",ogen[i+1*ngen]);
		setObjectValue_Double(temp_obj,"QG",ogen[i+2*ngen]);
		setObjectValue_Double(temp_obj,"QMAX",ogen[i+3*ngen]);
		setObjectValue_Double(temp_obj,"QMIN",ogen[i+4*ngen]);
		setObjectValue_Double(temp_obj,"VG",ogen[i+5*ngen]);
		setObjectValue_Double(temp_obj,"PC1",ogen[i+10*ngen]);
		setObjectValue_Double(temp_obj,"PC2",ogen[i+11*ngen]);
		setObjectValue_Double(temp_obj,"RAMP_AGC",ogen[i+16*ngen]);
		setObjectValue_Double(temp_obj,"RAMP_10",ogen[i+17*ngen]);
		setObjectValue_Double(temp_obj,"RAMP_30",ogen[i+18*ngen]);
		setObjectValue_Double(temp_obj,"RAMP_Q",ogen[i+19*ngen]);
		setObjectValue_Double(temp_obj,"APF",ogen[i+20*ngen]);
		setObjectValue_Double(temp_obj,"MU_PMAX",ogen[i+21*ngen]);
		setObjectValue_Double(temp_obj,"MU_PMIN",ogen[i+22*ngen]);
		setObjectValue_Double(temp_obj,"MU_QMAX",ogen[i+23*ngen]);
		setObjectValue_Double(temp_obj,"MU_QMIN",ogen[i+24*ngen]);



		// Calculate Price
		double price = 0;
		unsigned int NCOST = (unsigned int)rgencost[i+3*ngen];
		//printf("Bus %d, order %d ",i,NCOST);
		for (unsigned int j = 0; j < NCOST; j++)
		{
			price += pow(ogen[i+1*ngen],NCOST-1-j)*rgencost[i+(4+j)*ngen];
			//printf("Coeff %d: %f and price %f",j,rgencost[i+(4+j)*ngencost],price);
		}

		setObjectValue_Double(temp_obj,"Price",price);
		//printf("\nBus %d, Price %f\n",i,price);
		
		iter_gen++;
	}

	// Update class branch	
	
	
	//iter_branch = vec_branch.begin();
	temp_obj = NULL;
	for (unsigned int i = 0; i<nbranch; i++)
	{
/*
		iter_branch->PF = obranch[i+13*nbranch];
		iter_branch->QF = obranch[i+14*nbranch];
		iter_branch->PT = obranch[i+15*nbranch];
		iter_branch->QT = obranch[i+16*nbranch];
		iter_branch->MU_SF = obranch[i+17*nbranch];
		iter_branch->MU_ST = obranch[i+18*nbranch];
		iter_branch->MU_ANGMIN = obranch[i+19*nbranch];
		iter_branch->MU_ANGMAX = obranch[i+20*nbranch];
		iter_branch++;
*/

		temp_obj = gl_find_next(branch_list,temp_obj);
		setObjectValue_Double(temp_obj,"PF",obranch[i+13*nbranch]);
		setObjectValue_Double(temp_obj,"QF",obranch[i+14*nbranch]);
		setObjectValue_Double(temp_obj,"PT",obranch[i+15*nbranch]);
		setObjectValue_Double(temp_obj,"QT",obranch[i+16*nbranch]);
		setObjectValue_Double(temp_obj,"MU_SF",obranch[i+17*nbranch]);
		setObjectValue_Double(temp_obj,"MU_ST",obranch[i+18*nbranch]);
		setObjectValue_Double(temp_obj,"MU_ANGMIN",obranch[i+19*nbranch]);
		setObjectValue_Double(temp_obj,"MU_ANGMAX",obranch[i+20*nbranch]);
	}
	
	// free space
	//printf("Free r..\n");
	free(rbus);
	free(rgen);
	free(rbranch);
	free(rareas);
	//free(rbaseMVA);
	free(rgencost);
	
	//printf("Free o..\n");	
	free(obus);
	free(ogen);
	free(obranch);

	vec_bus.clear();
	vec_gen.clear();
	vec_branch.clear();
	//vec_gencost.clear();
	//vec_baseMVA.clear();


	short ifsuccess = (short)*getArray(plhs[3]);
	//printf("suceess %f\n",*getArray(plhs[4]));
	return ifsuccess;

}
示例#14
0
EXPORT int init_node(OBJECT *obj)
{
	return OBJECTDATA(obj,node)->init(obj->parent);
}
示例#15
0
EXPORT TIMESTAMP sync_capbank(OBJECT *obj, TIMESTAMP t0)
{
	TIMESTAMP t1 = OBJECTDATA(obj,capbank)->sync(t0);
	obj->clock = t0;
	return t1;
}
示例#16
0
EXPORT int commit_range(OBJECT *obj)
{
	range *my = OBJECTDATA(obj,range);
	return my->commit();
}
示例#17
0
EXPORT int isa_powerflow_library(OBJECT *obj, char *classname)
{
	return OBJECTDATA(obj,powerflow_library)->isa(classname);
}
示例#18
0
//Function to change sectionalizer states - just call underlying switch routine
EXPORT double change_sectionalizer_state(OBJECT *thisobj, unsigned char phase_change, bool state)
{
	double count_values, recloser_count;
	char desA, desB, desC;
	switch_object *swtchobj;
	sectionalizer *sectionobj;
	FUNCTIONADDR funadd = NULL;
	bool perform_operation;

	//Init
	count_values = 0.0;

	if (state == false)	//Check routine to find a recloser
	{
		//Map us up as a proper object
		sectionobj = OBJECTDATA(thisobj,sectionalizer);

		//Call to see if a recloser is present
		if (fault_check_object == NULL)
		{
			GL_THROW("Reliability call made without fault_check object present!");
			/*  TROUBLESHOOT
			A sectionalizer attempted to call a reliability-related function.  However, this function
			requires a fault_check object to be present in the system.  Please add the appropriate object.
			If the error persists, please submit your code and a bug report via the trac website.
			*/
		}

		//map the function
		funadd = (FUNCTIONADDR)(gl_get_function(fault_check_object,"handle_sectionalizer"));

		//make sure it worked
		if (funadd==NULL)
		{
			GL_THROW("Failed to find sectionalizer checking method on object %s",fault_check_object->name);
			/*  TROUBLESHOOT
			While attempting to find the fault check method, or its subfunction to handle sectionalizers,
			an error was encountered.  Please ensure a proper fault_check object is present in the system.
			If the error persists, please submit your code and a bug report via the trac website.
			*/
		}

		//Function call
		recloser_count = ((double (*)(OBJECT *, int))(*funadd))(fault_check_object,sectionobj->NR_branch_reference);

		if (recloser_count == 0.0)	//Failed :(
		{
			GL_THROW("Failed to handle sectionalizer check on %s",thisobj->name);
			/*  TROUBLESHOOT
			While attempting to handle sectionalizer actions for the specified device, an error occurred.  Please
			try again and ensure all parameters are correct.  If the error persists, please submit your code and a
			bug report via the trac website.
			*/
		}

		//Error check
		if (recloser_count < 0)	//No recloser found, get us out of here
		{
			count_values = recloser_count;
			perform_operation = false;	//Flag as no change allowed
		}
		else	//Recloser found - pass the count out and flag a change allowed
		{
			perform_operation = true;
			count_values = recloser_count;
		}
	}
	else	//No check required for reconneciton
	{
		perform_operation = true;	//Flag operation as ok
		count_values = 1.0;			//Arbitrary non-zero value so fail check doesn't go off
	}

	if (perform_operation==true)	//Either is a "replace" or a recloser was found - operation is a go
	{
		//Map the switch
		swtchobj = OBJECTDATA(thisobj,switch_object);

		if (swtchobj->switch_banked_mode == switch_object::BANKED_SW)	//Banked mode - all become "state", just cause
		{
			swtchobj->set_switch(state);
		}
		else	//Must be individual
		{
			//Figure out what we need to call
			if ((phase_change & 0x04) == 0x04)
			{
				if (state==true)
					desA=1;	//Close it
				else
					desA=0;	//Open it
			}
			else	//Nope, no A
				desA=2;		//I don't care

			//Phase B
			if ((phase_change & 0x02) == 0x02)
			{
				if (state==true)
					desB=1;	//Close it
				else
					desB=0;	//Open it
			}
			else	//Nope, no B
				desB=2;		//I don't care

			//Phase C
			if ((phase_change & 0x01) == 0x01)
			{
				if (state==true)
					desC=1;	//Close it
				else
					desC=0;	//Open it
			}
			else	//Nope, no A
				desC=2;		//I don't care

			//Perform the switching!
			swtchobj->set_switch_full(desA,desB,desC);
		}//End individual adjustments
	}

	return count_values;
}
示例#19
0
int climate::init(OBJECT *parent)
{
	char *dot = 0;
	OBJECT *obj=OBJECTHDR(this);
	double meter_to_feet = 1.0;
	double tz_num_offset;

	reader_type = RT_NONE;

	// ignore "" files ~ manual climate control is a feature
	if (strcmp(tmyfile,"")==0)
		return 1;

	// open access to the TMY file
	char *found_file;
	found_file = gl_findfile(tmyfile, NULL, FF_READ);
	if (found_file == NULL) // TODO: get proper values for solar
	{
		gl_error("weather file '%s' access failed", tmyfile);
		return 0;
	}

	
	//dot = strchr(tmyfile, '.');
	//while(strchr(dot+1, '.')){ /* init time, doesn't have to be fast -MH */
	//	dot = strchr(dot, '.');
	//}
	if(strstr(tmyfile, ".tmy2") || strstr(tmyfile,".tmy")){
		reader_type = RT_TMY2;
	} else if(strstr(tmyfile, ".csv")){
		reader_type = RT_CSV;
	} else {
		gl_warning("climate: unrecognized filetype, assuming TMY2");
	}

	if(reader_type == RT_CSV){
		// may or may not have an object,
		// have not called open()
		int rv = 0;

		if(reader == NULL){
			csv_reader *creader = new csv_reader();
			reader_hndl = creader;
			rv = creader->open(found_file);
//			creader->get_data(t0, &temperature, &humidity, &solar_direct, &solar_diffuse, &wind_speed, &rainfall, &snowdepth);
		} else {
			csv_reader *my = OBJECTDATA(reader,csv_reader);
			reader_hndl = my;
			rv = my->open(my->filename);
//			my->get_data(t0, &temperature, &humidity, &solar_direct, &solar_diffuse, &wind_speed, &rainfall, &snowdepth);
			//Pull timezone information
			tz_num_offset = my->tz_numval;
			tz_offset_val = tz_num_offset;

			//Copy latitude and longitude information from CSV reader
			obj->latitude = reader->latitude;
			obj->longitude = reader->longitude;

			//CSV Reader validity check
			if (fabs(obj->latitude) > 90)
			{
				gl_error("climate:%s - Latitude is outside +/-90!",obj->name);
				//Defined below
				return 0;
			}

			if (fabs(obj->longitude) > 180)
			{
				gl_error("climate:%s - Longitude is outside +/-180!",obj->name);
				//Defined below
				return 0;
			}

			//Generic warning about southern hemisphere and Duffie-Beckman usage
			if (obj->latitude<0)
			{
				gl_warning("climate:%s - Southern hemisphere solar position model may have issues",obj->name);
				/*  TROUBLESHOOT
				The default solar position model was built around a northern hemisphere assumption.  As such,
				it doesn't always produce completely accurate results for southern hemisphere locations.  Calculated
				insolation values are approximately correct, but may show discrepancies against measured data.  If
				this climate is associated with a solar object, use the SOLAR_TILT_MODEL SOLPOS to ensure proper
				results (this warning will still pop up).
				*/
			}

			//Set the timezone offset - stolen from TMY code below
			tz_meridian =  15 * tz_num_offset;//std_meridians[-file.tz_offset-5];
		}

		return rv;
	}

	// implicit if(reader_type == RT_TMY2) ~ do the following
	if( file.open(found_file) < 3 ){
		gl_error("climate::init() -- weather file header improperly formed");
		return 0;
	}
	
	// begin parsing the TMY file
	int line=0;
	tmy = (TMYDATA*)malloc(sizeof(TMYDATA)*8760);
	if (tmy==NULL)
	{
		gl_error("TMY buffer allocation failed");
		return 0;
	}

	int month, day, hour;//, year;
	double dnr,dhr,ghr,wspeed,precip,snowdepth,pressure,extra_dni;
	//char cty[50];
	//char st[3];
	int lat_deg,lat_min,long_deg,long_min;
	/* The city/state data isn't used anywhere.  -mhauer */
	//file.header_info(cty,st,&lat_deg,&lat_min,&long_deg,&long_min);
	file.header_info(NULL,NULL,&lat_deg,&lat_min,&long_deg,&long_min);

	//Handle hemispheres
	if (lat_deg<0)
		obj->latitude = (double)lat_deg - (((double)lat_min) / 60);
	else
		obj->latitude = (double)lat_deg + (((double)lat_min) / 60);

	if (long_deg<0)
		obj->longitude = (double)long_deg - (((double)long_min) / 60);
	else
		obj->longitude = (double)long_deg + (((double)long_min) / 60);

	//Generic check for TMY files
	if (fabs(obj->latitude) > 90)
	{
		gl_error("climate:%s - Latitude is outside +/-90!",obj->name);
		/*  TROUBLESHOOT
		The value read from the weather data indicates a latitude of greater
		than 90 or less than -90 degrees.  This is not a valid value.  Please specify
		the latitude in this range, with positive values representing the northern hemisphere
		and negative values representing the southern hemisphere.
		*/
		return 0;
	}

	if (fabs(obj->longitude) > 180)
	{
		gl_error("climate:%s - Longitude is outside +/-180!",obj->name);
		/*  TROUBLESHOOT
		The value read from the weather data indicates a longitude of greater
		than 180 or less than -180 degrees.  This is not a valid value.  Please specify
		the longitude in this range, with positive values representing the eastern hemisphere
		and negative values representing the western hemisphere.
		*/
		return 0;
	}

	//Generic warning about southern hemisphere and Duffie-Beckman usage
	if (obj->latitude<0)
	{
		gl_warning("climate:%s - Southern hemisphere solar position model may have issues",obj->name);
		//Defined above
	}

	if(0 == gl_convert("m", "ft", &meter_to_feet)){
		gl_error("climate::init unable to gl_convert() 'm' to 'ft'!");
		return 0;
	}
	file.elevation *= meter_to_feet;
	tz_meridian =  15 * file.tz_offset;//std_meridians[-file.tz_offset-5];
	tz_offset_val = file.tz_offset;
	while (line<8760 && file.next())
	{

		file.read_data(&dnr,&dhr,&ghr,&temperature,&humidity,&month,&day,&hour,&wspeed,&precip,&snowdepth,&pressure,&extra_dni);

		int doy = sa->day_of_yr(month,day);
		int hoy = (doy - 1) * 24 + (hour-1);
		if (hoy>=0 && hoy<8760){
			// pre-conversion of solar data from W/m^2 to W/sf
			if(0 == gl_convert("W/m^2", "W/sf", &(dnr))){
				gl_error("climate::init unable to gl_convert() 'W/m^2' to 'W/sf'!");
				return 0;
			}
			if(0 == gl_convert("W/m^2", "W/sf", &(dhr))){
				gl_error("climate::init unable to gl_convert() 'W/m^2' to 'W/sf'!");
				return 0;
			}
			if(0 == gl_convert("W/m^2", "W/sf", &(ghr))){
				gl_error("climate::init unable to gl_convert() 'W/m^2' to 'W/sf'!");
				return 0;
			}
			if(0 == gl_convert("W/m^2", "W/sf", &(extra_dni))){
				gl_error("climate::init unable to gl_convert() 'W/m^2' to 'W/sf'!");
				return 0;
			}
			if(0 == gl_convert("mps", "mph", &(wspeed))){
				gl_error("climate::init unable to gl_convert() 'm/s' to 'miles/h'!");
				return 0;
			}
			tmy[hoy].temp_raw = temperature;
			tmy[hoy].temp = temperature;
			// post-conversion of copy of temperature from C to F
			if(0 == gl_convert("degC", "degF", &(tmy[hoy].temp))){
				gl_error("climate::init unable to gl_convert() 'degC' to 'degF'!");
				return 0;
			}
			tmy[hoy].windspeed=wspeed;
			tmy[hoy].rh = humidity;
			tmy[hoy].dnr = dnr;
			tmy[hoy].dhr = dhr;
			tmy[hoy].ghr = ghr;
			tmy[hoy].rainfall = precip;
			tmy[hoy].snowdepth = snowdepth;
			tmy[hoy].solar_raw = dnr;

			tmy[hoy].direct_normal_extra = extra_dni;
			tmy[hoy].pressure = pressure;
			
			// calculate the solar radiation - hour on here may need a -1 application (hour-1) - unsure how TMYs really code things
			double sol_time = sa->solar_time((double)hour,doy,RAD(tz_meridian),RAD(obj->longitude));
			double sol_rad = 0.0;

			tmy[hoy].solar_elevation = sa->altitude(doy, RAD(obj->latitude), sol_time);
			tmy[hoy].solar_azimuth = sa->azimuth(doy, RAD(obj->latitude), sol_time);

			for(COMPASS_PTS c_point = CP_H; c_point < CP_LAST;c_point=COMPASS_PTS(c_point+1)){
				if(c_point == CP_H)
					sol_rad = file.calc_solar(CP_E,doy,RAD(obj->latitude),sol_time,dnr,dhr,ghr,ground_reflectivity,0.0);//(double)dnr * cos_incident + dhr;
				else
					sol_rad = file.calc_solar(c_point,doy,RAD(obj->latitude),sol_time,dnr,dhr,ghr,ground_reflectivity);//(double)dnr * cos_incident + dhr;
				/* TMY2 solar radiation data is in Watt-hours per square meter. */
				tmy[hoy].solar[c_point] = sol_rad;

				/* track records */
				if (sol_rad>record.solar || record.solar==0) record.solar = sol_rad;
				if (tmy[hoy].temp>record.high || record.high==0)
				{
					record.high = tmy[hoy].temp;
					record.high_day = doy;
				}
				if (tmy[hoy].temp<record.low || record.low==0)
				{
					record.low = tmy[hoy].temp;
					record.low_day = doy;
				}
			}

		}
		else
			gl_error("%s(%d): day %d, hour %d is out of allowed range 0-8759 hours", tmyfile,line,day,hour);

		line++;
	}
	file.close();

	/* initialize climate to starttime */
	presync(gl_globalclock);

	/* enable forecasting if specified */
#if 0
	if ( strcmp(forecast,"")!=0 && gl_forecast_create(obj,"")==NULL )
	{
		char buf[1024];
		gl_error("%s: forecast '%s' is not valid", gl_name(obj,buf,sizeof(buf))?buf:"(object?)", forecast);
		return 0;
	}
	else if (obj->forecast)
	{	/* initialize the forecast data entity */
		FORECAST *fc = obj->forecast;
		fc->propref = gl_find_property(obj->oclass,"temperature");
		gl_forecast_save(fc,obj->clock,3600,0,NULL);
		obj->flags |= OF_FORECAST;
	}
#endif
	return 1;
}
示例#20
0
EXPORT int isa_sectionalizer(OBJECT *obj, char *classname)
{
	return OBJECTDATA(obj,sectionalizer)->isa(classname);
}
示例#21
0
EXPORT int isa_powerflow_object(OBJECT *obj, char *classname)
{
	return OBJECTDATA(obj,powerflow_object)->isa(classname);
}
示例#22
0
EXPORT int commit_waterheater(OBJECT *obj)
{
	waterheater *my = OBJECTDATA(obj,waterheater);
	return my->commit();
}
示例#23
0
EXPORT int isa_voltdump(OBJECT *obj, char *classname)
{
	return OBJECTDATA(obj,voltdump)->isa(classname);
}
/**
* Sync is called when the clock needs to advance on the bottom-up pass (PC_BOTTOMUP)
*
* @param obj the object we are sync'ing
* @param t0 this objects current timestamp
* @param pass the current pass for this sync call
* @return t1, where t1>t0 on success, t1=t0 for retry, t1<t0 on failure
*/
EXPORT TIMESTAMP sync_powerflow_library(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
{
	powerflow_library *pObj = OBJECTDATA(obj,powerflow_library);
	gl_error("%s (powerflow_library:%d): sync should never be called", pObj->get_name(), pObj->get_id());
	return TS_INVALID;
}
EXPORT int isa_triplex_meter(OBJECT *obj, char *classname)
{
	return OBJECTDATA(obj,triplex_meter)->isa(classname);
}
EXPORT int isa_group_recorder(OBJECT *obj, char *classname)
{
	return OBJECTDATA(obj, group_recorder)->isa(classname);
}
示例#27
0
EXPORT int isa_power_metrics(OBJECT *obj, char *classname)
{
	return OBJECTDATA(obj,power_metrics)->isa(classname);
}
示例#28
0
EXPORT int isa_switch(OBJECT *obj, char *classname)
{
	return OBJECTDATA(obj,switch_object)->isa(classname);
}
示例#29
0
// meter reset function
EXPORT int64 triplex_meter_reset(OBJECT *obj)
{
	triplex_meter *pMeter = OBJECTDATA(obj,triplex_meter);
	pMeter->measured_demand = 0;
	return 0;
}
示例#30
0
/**
* Allows the core to discover whether obj is a subtype of this class.
*
* @param obj a pointer to this object
* @param classname the name of the object the core is testing
*
* @return true (1) if obj is a subtype of this class
*/
EXPORT int isa_histogram(OBJECT *obj, char *classname)
{
	return OBJECTDATA(obj,histogram)->isa(classname);
}