00001 #include "GridWise2.h"
00002 #include <iostream>
00003 using namespace std;
00004 using namespace adevs;
00005
00006 const int GridFriendly2Load::sensor_input = 1;
00007 const int GridFriendly2Load::base_load = 2;
00008 double GridFriendly2Load::base_interval = 0.01/60.0;
00009 double GridFriendly2Load::droop = 1.0/0.05;
00010 double GridFriendly2Load::gfl_fraction = 1.0;
00011 double GridFriendly2Load::control_exponent = 1.0;
00012 GridFriendly2Load::ControlType GridFriendly2Load::ctype = PROP;
00013
00014 adevs::rv GridFriendly2Load::r;
00015
00016 void GridFriendly2Load::setControlParams(double R, double freq_interval,
00017 double gfl_frac, ControlType control_type, double control_exp)
00018 {
00019 ctype = control_type;
00020 base_interval = freq_interval / 60.0;
00021 droop = 1.0/R;
00022 gfl_fraction = gfl_frac;
00023 control_exponent = control_exp;
00024 }
00025
00026 GridFriendly2Load::GridFriendly2Load(unsigned BusID,
00027 ElectricalData* init_data):
00028 Atomic<PortValue<BasicEvent*> >(),
00029 BusID(BusID),
00030 ybase(init_data->getAdmittance(BusID)),
00031 phase(WAIT),
00032 freq_pos(0)
00033 {
00034 localDroop = droop;
00035 trip_interval = base_interval;
00036 load_sig[0] = load_sig[1] = real(ybase);
00037 }
00038
00039 void GridFriendly2Load::delta_int()
00040 {
00041 phase = WAIT;
00042 }
00043
00044 void GridFriendly2Load::delta_ext(double e, const Bag<PortValue<BasicEvent*> >& xb)
00045 {
00046 Bag<PortValue<BasicEvent*> >::const_iterator iter = xb.begin();
00047 for (; iter != xb.end(); iter++)
00048 {
00049 if ((*iter).port == sensor_input)
00050 {
00051 SensorEvent* event = dynamic_cast<SensorEvent*>((*iter).value);
00052 GridFriendly2Sensor* sensor = dynamic_cast<GridFriendly2Sensor*>(event->getCause());
00053 if (sensor->getDirection() == GridFriendly2Sensor::UP) freq_pos++;
00054 else freq_pos--;
00055 phase = ADJUST;
00056
00057 load_sig[1] = load_sig[0];
00058 double dP = gfl_fraction*localDroop*freq_pos*trip_interval;
00059
00060 if (ctype == NONLIP)
00061 {
00062 dP = pow(fabs(dP),control_exponent);
00063 if (freq_pos < 0) dP = -dP;
00064 }
00065 load_sig[0] = real(ybase)+dP;
00069 if (load_sig[0] < 0.0) load_sig[0] = 0.0;
00070 }
00071 else if ((*iter).port == base_load)
00072 {
00073 LoadEvent* load_event = dynamic_cast<LoadEvent*>((*iter).value);
00074 if (load_event->getBusID() == BusID)
00075 {
00076 ybase = load_event->getAdmittance();
00077 load_sig[1] = real(ybase);
00078 }
00079 }
00080 }
00081 }
00082
00083 void GridFriendly2Load::delta_conf(const Bag<PortValue<BasicEvent*> >& xb)
00084 {
00085 delta_int();
00086 delta_ext(0.0,xb);
00087 }
00088
00089 void GridFriendly2Load::output_func(Bag<PortValue<BasicEvent*> >& yb)
00090 {
00091
00092 if (load_sig[0] != load_sig[1])
00093 {
00094
00095 LoadEvent* load_event =
00096 new LoadEvent(BusID,Complex(load_sig[0],imag(ybase)));
00097 yb.insert(PortValue<BasicEvent*>(
00098 GridFriendly2Network::load_change,load_event));
00099 }
00100 }
00101
00102 double GridFriendly2Load::ta()
00103 {
00104 if (phase == ADJUST) return 0.0;
00105 else return DBL_MAX;
00106 }
00107
00108 void GridFriendly2Load::gc_output(Bag<PortValue<BasicEvent*> >& g)
00109 {
00110 Bag<PortValue<BasicEvent*> >::iterator iter = g.begin();
00111 for (; iter != g.end(); iter++)
00112 {
00113 delete (*iter).value;
00114 }
00115 }