Skip to content
This repository has been archived by the owner on Sep 27, 2023. It is now read-only.

Added realtime IEEE 123 model to models folder #41

Merged
merged 8 commits into from
Nov 10, 2018
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 23 additions & 22 deletions climate/climate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,7 @@ int climate::create(void)
cloud_num_layers = 40;
cloud_alpha = 400;
cloud_aerosol_transmissivity = 0.95;
file = new tmy2_reader;
return 1;
}

Expand Down Expand Up @@ -777,7 +778,7 @@ int climate::init(OBJECT *parent)
}

// implicit if(reader_type == RT_TMY2) ~ do the following
if( file.open(found_file) < 3 ){
if( file->open(found_file) < 3 ){
gl_error("climate::init() -- weather file header improperly formed");
return 0;
}
Expand All @@ -798,7 +799,7 @@ int climate::init(OBJECT *parent)
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);
file->header_info(NULL,NULL,&lat_deg,&lat_min,&long_deg,&long_min);

//Handle hemispheres
if (lat_deg<0)
Expand Down Expand Up @@ -847,15 +848,15 @@ int climate::init(OBJECT *parent)
gl_error("climate::init unable to gl_convert() 'm' to 'ft'!");
return 0;
}
file.elevation = (int)(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->elevation = (int)(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())
{
while (isdigit(file.buf[1]) == 0) {
file.next();
while (isdigit(file->buf[1]) == 0) {
file->next();
}
file.read_data(&dnr,&dhr,&ghr,&temperature,&humidity,&month,&day,&hour,&wspeed,&wdir,&precip,&snowdepth,&pressure,&extra_dni,&extra_ghi,&tot_sky_cov,&opq_sky_cov);
file->read_data(&dnr,&dhr,&ghr,&temperature,&humidity,&month,&day,&hour,&wspeed,&wdir,&precip,&snowdepth,&pressure,&extra_dni,&extra_ghi,&tot_sky_cov,&opq_sky_cov);

int doy = sa->day_of_yr(month,day);
int hoy = (doy - 1) * 24 + (hour-1);
Expand Down Expand Up @@ -918,9 +919,9 @@ int climate::init(OBJECT *parent)

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(get_latitude()),sol_time,dnr,dhr,ghr,ground_reflectivity,0.0);//(double)dnr * cos_incident + dhr;
sol_rad = file->calc_solar(CP_E,doy,RAD(get_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(get_latitude()),sol_time,dnr,dhr,ghr,ground_reflectivity);//(double)dnr * cos_incident + dhr;
sol_rad = file->calc_solar(c_point,doy,RAD(get_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;

Expand All @@ -944,7 +945,7 @@ int climate::init(OBJECT *parent)

line++;
}
file.close();
file->close();

/* initialize climate to starttime */
presync(gl_globalclock);
Expand Down Expand Up @@ -1892,21 +1893,21 @@ void climate::build_cloud_pattern(int col_min, int col_max, int row_min, int row


int climate::calc_cloud_pattern_size(std::vector< std::vector<double> > &location_list){
double lat_max = location_list[0][0];
double lat_min = location_list[0][0];
double long_max = location_list[0][1];
double long_min = location_list[0][1];
double lat_max = (location_list)[0][0];
double lat_min = (location_list)[0][0];
double long_max = (location_list)[0][1];
double long_min = (location_list)[0][1];
double lat_delta = 0;
double long_delta = 0;
double degree_range_lat = 0;
double degree_range_lon = 0;
int num_tile_edge = 1; //Minimum size (1 on-screen tile with 1 off-screen on all sides; 9 tiles total).
if (location_list.size() > 1) {
for (int i=1; i<location_list.size(); i++) {
lat_max = std::max(lat_max,location_list[i][0]);
lat_min = std::min(lat_min,location_list[i][0]);
long_max = std::max(long_max,location_list[i][1]);
long_min = std::min(long_min,location_list[i][1]);
lat_max = std::max(lat_max,(location_list)[i][0]);
lat_min = std::min(lat_min,(location_list)[i][0]);
long_max = std::max(long_max,(location_list)[i][1]);
long_min = std::min(long_min,(location_list)[i][1]);
}
lat_delta = fabs(lat_max - lat_min);
long_delta = fabs(long_max - long_min);
Expand Down Expand Up @@ -2010,9 +2011,9 @@ TIMESTAMP climate::presync(TIMESTAMP t0) /* called in presync */

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.get_yearday(),RAD(reader->latitude),sol_time,solar_direct,solar_diffuse,solar_global,ground_reflectivity,0.0);//(double)dnr * cos_incident + dhr;
sol_rad = file->calc_solar(CP_E,now.get_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.get_yearday(),RAD(reader->latitude),sol_time,solar_direct,solar_diffuse,solar_global,ground_reflectivity);//(double)dnr * cos_incident + dhr;
sol_rad = file->calc_solar(c_point,now.get_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;
}
Expand Down
2 changes: 1 addition & 1 deletion climate/climate.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ class climate : public gld_object {
// data not shared with classes in this module (no locks needed)
private:
SolarAngles *sa;
tmy2_reader file;
tmy2_reader *file;
weather_reader *reader_hndl;
TMYDATA *tmy;
public:
Expand Down
32 changes: 16 additions & 16 deletions generators/inverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -921,9 +921,9 @@ int inverter::init(OBJECT *parent)
VoltVArSchedInput = volt_var_sched;
gl_warning(VoltVArSchedInput.c_str());
if(VoltVArSchedInput.length() == 0) {
VoltVArSched.push_back(std::make_pair (119.5,0));
VoltVArSched->push_back(std::make_pair (119.5,0));
//put two random things on the schedule with Q values of zero, all scheduled Qs will then be zero
VoltVArSched.push_back(std::make_pair (120.5,0));
VoltVArSched->push_back(std::make_pair (120.5,0));
gl_warning("Volt/VAr schedule unspecified. Setting inverter for constant power factor of 1.0");
}
else
Expand All @@ -943,25 +943,25 @@ int inverter::init(OBJECT *parent)
else
{
if(cntr % 2 == 1){
VoltVArSched.push_back(std::make_pair (atof(tempV.c_str()),atof(tempQ.c_str())));
VoltVArSched->push_back(std::make_pair (atof(tempV.c_str()),atof(tempQ.c_str())));
tempQ = "";
tempV = "";
}
cntr++;
}
}
if(cntr % 2 == 1)
VoltVArSched.push_back(std::make_pair (atof(tempV.c_str()),atof(tempQ.c_str())));
VoltVArSched->push_back(std::make_pair (atof(tempV.c_str()),atof(tempQ.c_str())));
} //end VoltVArSchedInput


//checks for freq-power schedule
freq_pwrSchedInput = freq_pwr_sched;
warning(freq_pwrSchedInput.c_str());
if(freq_pwrSchedInput.length() == 0) {
freq_pwrSched.push_back(std::make_pair (f_nominal*0.9,0));
freq_pwrSched->push_back(std::make_pair (f_nominal*0.9,0));
//make both power values equal to zero, then all scheduled powers will be zero
freq_pwrSched.push_back(std::make_pair (f_nominal*1.1,0));
freq_pwrSched->push_back(std::make_pair (f_nominal*1.1,0));
warning("Frequency-Power schedule unspecified. Setting power for frequency regulation to zero.");
}
else
Expand All @@ -980,15 +980,15 @@ int inverter::init(OBJECT *parent)
else
{
if(cntr % 2 == 1) {
freq_pwrSched.push_back(std::make_pair (atof(tempf.c_str()),atof(tempP.c_str())));
freq_pwrSched->push_back(std::make_pair (atof(tempf.c_str()),atof(tempP.c_str())));
tempf = "";
tempP = "";
}
cntr++;
}
}
if(cntr % 2 == 1)
freq_pwrSched.push_back(std::make_pair (atof(tempf.c_str()),atof(tempP.c_str())));
freq_pwrSched->push_back(std::make_pair (atof(tempf.c_str()),atof(tempP.c_str())));
} //end freq_pwrSchedInput

} //end VOLT_VAR_FREQ_PWR control mode
Expand Down Expand Up @@ -3307,19 +3307,19 @@ TIMESTAMP inverter::sync(TIMESTAMP t0, TIMESTAMP t1)
//currently only compares to the phase A inverter AC voltage,
//TODO: need to address for non-3phase inv? include support for a remote voltage input?

double Qo = VoltVArSched.back().second; //set the scheduled Q for highest voltage range, handles the last case with the loop below (will be overwritten if needed)
double Qo = VoltVArSched->back().second; //set the scheduled Q for highest voltage range, handles the last case with the loop below (will be overwritten if needed)
double prevV = 0; //setup for first loop iter to handle lowest voltage range
double prevQ = VoltVArSched.front().second; //setup for first loop iter to handle lowest voltage range
for (size_t i = 0; i < VoltVArSched.size(); i++)
double prevQ = VoltVArSched->front().second; //setup for first loop iter to handle lowest voltage range
for (size_t i = 0; i < VoltVArSched->size(); i++)
{ //iterate over all specified voltage ranges, find where current voltage value lies and set Qo as linear interpolation between endpoints
if(phaseA_V_Out.Mag() <= VoltVArSched[i].first) {
double m = (VoltVArSched[i].second - prevQ)/(VoltVArSched[i].first - prevV);
double b = VoltVArSched[i].second - (m * VoltVArSched[i].first);
if(phaseA_V_Out.Mag() <= (*VoltVArSched)[i].first) {
double m = ((*VoltVArSched)[i].second - prevQ)/((*VoltVArSched)[i].first - prevV);
double b = (*VoltVArSched)[i].second - (m * (*VoltVArSched)[i].first);
Qo = m * phaseA_V_Out.Mag() + b;
break;
}
prevV = VoltVArSched[i].first;
prevQ = VoltVArSched[i].second;
prevV = (*VoltVArSched)[i].first;
prevQ = (*VoltVArSched)[i].second;
}

double Po = (P_in * net_eff) - fabs(Qo) * (1 - net_eff)/net_eff;
Expand Down
4 changes: 2 additions & 2 deletions generators/inverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,8 @@ class inverter: public power_electronics
double max_pwr_slew_rate; //maximum rate at which inverter can change its power output for frequency regulation (W/second) *not sure if this is defined anywhere else i.e. power electronics classes
char volt_var_sched[1024]; //user input Volt/VAr Schedule
char freq_pwr_sched[1024]; //user input freq-power Schedule
std::vector<std::pair<double,double> > VoltVArSched; //Volt/VAr schedule -- i realize I'm using goofball data types, what would be the GridLABD-esque way of implementing this data type?
std::vector<std::pair<double,double> > freq_pwrSched; //freq-power schedule -- i realize I'm using goofball data types, what would be the GridLABD-esque way of implementing this data type?
std::vector<std::pair<double,double> > *VoltVArSched; //Volt/VAr schedule -- i realize I'm using goofball data types, what would be the GridLABD-esque way of implementing this data type?
std::vector<std::pair<double,double> > *freq_pwrSched; //freq-power schedule -- i realize I'm using goofball data types, what would be the GridLABD-esque way of implementing this data type?
private:
//load following variables
FUNCTIONADDR powerCalc; //Address for power_calculate in link object, if it is a link
Expand Down
8 changes: 4 additions & 4 deletions gldcore/load_xml_handle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -910,7 +910,7 @@ void gld_loadHndl::startElement(const XMLCh* const uri, const XMLCh* const local
*/
char *gld_loadHndl::build_object_vect(int start, int end){
int count = 0, i = 0;
obj_vect.clear();
obj_vect->clear();
if(start == end){
if((*oclass->create)(&obj, NULL) == 0){
//output_error("XML_Load: Unable to create a lone object with ID = %i.", start);
Expand Down Expand Up @@ -941,11 +941,11 @@ char *gld_loadHndl::build_object_vect(int start, int end){
return errmsg;
}
}
obj_vect.reserve(count);
obj_vect->reserve(count);
for(i = (start == -1) ? 0 : start; i <= last; ++i){ /* "if start == -1, use 0, else use start" */
if((*oclass->create)((obj_vect[i]), NULL) != 0){
if((*oclass->create)(((*obj_vect)[i]), NULL) != 0){
if(start != -1){
if(load_set_index(obj_vect[i], (OBJECTNUM)i) == 0){
if(load_set_index((*obj_vect)[i], (OBJECTNUM)i) == 0){
sprintf(errmsg, "Unable to index a batch item in build_object_vect(%i, %i)", start, end);
load_state = false;
// cleanup all items?
Expand Down
2 changes: 1 addition & 1 deletion gldcore/load_xml_handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,6 @@ private :
bool load_state;
int object_count, class_count;

vector<OBJECT *> obj_vect;
vector<OBJECT *> *obj_vect;
gldStack *stack_ptr;
};
15 changes: 15 additions & 0 deletions models/ieee123/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Using the IEEE-123 model

This model is designed to operated either as a real-time simulation or as a normal simulation with a start and stop time. The options are controlled by the file `config/local.glm`, which you may edit manually if you wish, provided you are not using the web-server interface.

If you wish to run in real-time, you should comment out the STARTTIME and STOPTIME definitions in `config/local.glm`.

If you are saving data to a MySQL data, the you enable MySQL by uncommenting `MYSQL_ENABLE=on`.

To run the simulation, do the following:

~~~
localhost% cd ieee123
localhost% gridlabd model/ieee123.glm
~~~

44 changes: 44 additions & 0 deletions models/ieee123/config/default.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!-- default_config.php
Copyright (C) 2016, Stanford University
Author: dchassin@slac.stanford.edu
-->
<?php

// gridlabd
$gridlabd_prefix = "/usr/local";
$gridlabd_bin = "$gridlabd_prefix/bin";
$gridlabd_lib = "$gridlabd_prefix/lib/gridlabd";
$gridlabd_share = "$gridlabd_prefix/share/gridlabd";
$gridlabd_server = gethostname();
$gridlabd_port = "6267";

// web server
$www_modelpath = "model";

// location
$glm_weather = "CA-Bakersfield.tmy3";
$glm_timezone = "US/CA/Los Angeles";
$glm_modelname = "ieee123.glm";

// model features
$glm_loads = 0;
$glm_solar = 0;
$glm_storage = 0;
$glm_demand = 0;
$glm_hvac = "none";
$glm_waterheater = "none";
$glm_dishwasher = "none";
$glm_washer = "none";
$glm_dryer = "none";

// MySQL configuration
$mysql = 0;
$my_server = gethostname();
$my_user = "gridlabd_ro";
$my_pwd = "gridlabd";
$my_name = "ieee123";
$my_scada = 0;
$my_ami = 0;
$my_model = 0;
$my_graph = 0;
?>
5 changes: 5 additions & 0 deletions models/ieee123/config/graph.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php
$my_server = '127.0.0.1:3306';
$my_user = 'gridlabd_ro';
$my_pwd = 'gridlabd';
?>
22 changes: 22 additions & 0 deletions models/ieee123/config/local.glm
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// do not edit -- updated automatically by 'save' action to setup.php at Tue, 09 Jan 2018 20:05:18 +0000
#define DOCROOT=/ieee123
#define HOSTNAME=localhost
#define MYSQLHOST=${HOSTNAME}
#define NAME=ieee123.glm
#define PORT=3306
#define WEATHER=CA-Bakersfield_Meadows_Field.tmy3
#define TIMEZONE=US/CA/Los Angeles
#define LOADS=on
#define SOLAR=on
#define DR_HVAC=none
#define DR_WATERHEATER=none
#define DR_DISHWASHER=none
#define DR_WASHER=none
#define DR_DRYER=none
#define MYSQL_ENABLE='on'
#define MYSQL_NAME=ieee123
#define MYSQL_SCADA=on
#define MYSQL_AMI=on

#define STARTTIME=2018-01-01 00:00:00 PST
#define STOPTIME=2019-01-01 00:00:00 PST
19 changes: 19 additions & 0 deletions models/ieee123/config/local.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php // do not edit -- updated automatically by 'save' action to setup.php at Tue, 09 Jan 2018 20:05:18 +0000
$gridlabd_docroot='/ieee123';
$gridlabd_server='localhost';
$glm_modelname='ieee123.glm';
$gridlabd_port='6267';
$glm_weather='CA-Bakersfield_Meadows_Field.tmy3';
$glm_timezone='US/CA/Los Angeles';
$glm_loads='on';
$glm_solar='on';
$glm_hvac='none';
$glm_waterheater='none';
$glm_dishwasher='none';
$glm_washer='none';
$glm_dryer='none';
$mysql='off';
$my_name='ieee123';
$my_scada='on';
$my_ami='on';
?>
Loading