00001
00012 #include <stdlib.h>
00013 #include <stdio.h>
00014 #include <errno.h>
00015 #include <math.h>
00016
00017 #include "node.h"
00018 #include "meter.h"
00019
00020 CLASS* load::oclass = NULL;
00021 CLASS* load::pclass = NULL;
00022
00023 load::load(MODULE *mod) : node(mod)
00024 {
00025 if(oclass == NULL)
00026 {
00027 pclass = node::oclass;
00028
00029 oclass = gl_register_class(mod,"load",sizeof(load),PC_PRETOPDOWN|PC_BOTTOMUP|PC_POSTTOPDOWN|PC_UNSAFE_OVERRIDE_OMIT);
00030 if(oclass == NULL)
00031 GL_THROW("unable to register object class implemented by %s",__FILE__);
00032
00033 if(gl_publish_variable(oclass,
00034 PT_INHERIT, "node",
00035 PT_enumeration, "load_class", PADDR(load_class),
00036 PT_KEYWORD, "U", LC_UNKNOWN,
00037 PT_KEYWORD, "R", LC_RESIDENTIAL,
00038 PT_KEYWORD, "C", LC_COMMERCIAL,
00039 PT_KEYWORD, "I", LC_INDUSTRIAL,
00040 PT_KEYWORD, "A", LC_AGRICULTURAL,
00041 PT_complex, "constant_power_A[VA]", PADDR(constant_power[0]),
00042 PT_complex, "constant_power_B[VA]", PADDR(constant_power[1]),
00043 PT_complex, "constant_power_C[VA]", PADDR(constant_power[2]),
00044 PT_double, "constant_power_A_real[W]", PADDR(constant_power[0].Re()),
00045 PT_double, "constant_power_B_real[W]", PADDR(constant_power[1].Re()),
00046 PT_double, "constant_power_C_real[W]", PADDR(constant_power[2].Re()),
00047 PT_double, "constant_power_A_reac[VAr]", PADDR(constant_power[0].Im()),
00048 PT_double, "constant_power_B_reac[VAr]", PADDR(constant_power[1].Im()),
00049 PT_double, "constant_power_C_reac[VAr]", PADDR(constant_power[2].Im()),
00050 PT_complex, "constant_current_A[A]", PADDR(constant_current[0]),
00051 PT_complex, "constant_current_B[A]", PADDR(constant_current[1]),
00052 PT_complex, "constant_current_C[A]", PADDR(constant_current[2]),
00053 PT_double, "constant_current_A_real[A]", PADDR(constant_current[0].Re()),
00054 PT_double, "constant_current_B_real[A]", PADDR(constant_current[1].Re()),
00055 PT_double, "constant_current_C_real[A]", PADDR(constant_current[2].Re()),
00056 PT_double, "constant_current_A_reac[A]", PADDR(constant_current[0].Im()),
00057 PT_double, "constant_current_B_reac[A]", PADDR(constant_current[1].Im()),
00058 PT_double, "constant_current_C_reac[A]", PADDR(constant_current[2].Im()),
00059 PT_complex, "constant_impedance_A[Ohm]", PADDR(constant_impedance[0]),
00060 PT_complex, "constant_impedance_B[Ohm]", PADDR(constant_impedance[1]),
00061 PT_complex, "constant_impedance_C[Ohm]", PADDR(constant_impedance[2]),
00062 PT_double, "constant_impedance_A_real[Ohm]", PADDR(constant_impedance[0].Re()),
00063 PT_double, "constant_impedance_B_real[Ohm]", PADDR(constant_impedance[1].Re()),
00064 PT_double, "constant_impedance_C_real[Ohm]", PADDR(constant_impedance[2].Re()),
00065 PT_double, "constant_impedance_A_reac[Ohm]", PADDR(constant_impedance[0].Im()),
00066 PT_double, "constant_impedance_B_reac[Ohm]", PADDR(constant_impedance[1].Im()),
00067 PT_double, "constant_impedance_C_reac[Ohm]", PADDR(constant_impedance[2].Im()),
00068 PT_complex, "measured_voltage_A",PADDR(measured_voltage_A),
00069 PT_complex, "measured_voltage_B",PADDR(measured_voltage_B),
00070 PT_complex, "measured_voltage_C",PADDR(measured_voltage_C),
00071 PT_complex, "measured_voltage_AB",PADDR(measured_voltage_AB),
00072 PT_complex, "measured_voltage_BC",PADDR(measured_voltage_BC),
00073 PT_complex, "measured_voltage_CA",PADDR(measured_voltage_CA),
00074
00075 NULL) < 1) GL_THROW("unable to publish properties in %s",__FILE__);
00076 }
00077 }
00078
00079 int load::isa(char *classname)
00080 {
00081 return strcmp(classname,"load")==0 || node::isa(classname);
00082 }
00083
00084 int load::create(void)
00085 {
00086 int res = node::create();
00087
00088 maximum_voltage_error = 0;
00089 load_class = LC_UNKNOWN;
00090
00091 return res;
00092 }
00093
00094 TIMESTAMP load::presync(TIMESTAMP t0)
00095 {
00096 if ((solver_method!=SM_FBS) && (SubNode==PARENT))
00097 {
00098 shunt[0] = shunt[1] = shunt[2] = 0.0;
00099 power[0] = power[1] = power[2] = 0.0;
00100 current[0] = current[1] = current[2] = 0.0;
00101 }
00102
00103
00104 TIMESTAMP result = node::presync(t0);
00105
00106 return result;
00107 }
00108
00109 TIMESTAMP load::sync(TIMESTAMP t0)
00110 {
00111 if ((solver_method!=SM_FBS) && (SubNode==PARENT))
00112 {
00113
00114 if (!(constant_impedance[0].IsZero()))
00115 shunt[0] += complex(1.0)/constant_impedance[0];
00116
00117 if (!(constant_impedance[1].IsZero()))
00118 shunt[1] += complex(1.0)/constant_impedance[1];
00119
00120 if (!(constant_impedance[2].IsZero()))
00121 shunt[2] += complex(1.0)/constant_impedance[2];
00122
00123 power[0] += constant_power[0];
00124 power[1] += constant_power[1];
00125 power[2] += constant_power[2];
00126 current[0] += constant_current[0];
00127 current[1] += constant_current[1];
00128 current[2] += constant_current[2];
00129 }
00130 else
00131 {
00132 if(constant_impedance[0].IsZero())
00133 shunt[0] = 0.0;
00134 else
00135 shunt[0] = complex(1)/constant_impedance[0];
00136
00137 if(constant_impedance[1].IsZero())
00138 shunt[1] = 0.0;
00139 else
00140 shunt[1] = complex(1)/constant_impedance[1];
00141
00142 if(constant_impedance[2].IsZero())
00143 shunt[2] = 0.0;
00144 else
00145 shunt[2] = complex(1)/constant_impedance[2];
00146
00147 power[0] = constant_power[0];
00148 power[1] = constant_power[1];
00149 power[2] = constant_power[2];
00150 current[0] = constant_current[0];
00151 current[1] = constant_current[1];
00152 current[2] = constant_current[2];
00153 }
00154
00155
00156 TIMESTAMP result = node::sync(t0);
00157
00158 return result;
00159 }
00160 TIMESTAMP load::postsync(TIMESTAMP t0)
00161 {
00162
00163 TIMESTAMP t1 = node::postsync(t0);
00164
00165
00166 measured_voltage_A.SetPolar(voltageA.Mag(),voltageA.Arg());
00167 measured_voltage_B.SetPolar(voltageB.Mag(),voltageB.Arg());
00168 measured_voltage_C.SetPolar(voltageC.Mag(),voltageC.Arg());
00169 measured_voltage_AB = measured_voltage_A-measured_voltage_B;
00170 measured_voltage_BC = measured_voltage_B-measured_voltage_C;
00171 measured_voltage_CA = measured_voltage_C-measured_voltage_A;
00172
00173 return t1;
00174 }
00175
00177
00179
00187 EXPORT int create_load(OBJECT **obj, OBJECT *parent)
00188 {
00189 try
00190 {
00191 *obj = gl_create_object(load::oclass);
00192 if (*obj!=NULL)
00193 {
00194 load *my = OBJECTDATA(*obj,load);
00195 gl_set_parent(*obj,parent);
00196 return my->create();
00197 }
00198 }
00199 catch (const char *msg)
00200 {
00201 gl_error("create_load: %s", msg);
00202 }
00203 return 0;
00204 }
00205
00212 EXPORT int init_load(OBJECT *obj)
00213 {
00214 int result = 1;
00215 try {
00216 result = ((load*) (obj + 1))->init();
00217 } catch (const char *error) {
00218 GL_THROW("%s:%d: %s", obj->oclass->name, obj->id, error);
00219 return 0;
00220 } catch (...) {
00221 GL_THROW("%s:%d: %s", obj->oclass->name, obj->id, "unknown exception");
00222 return 0;
00223 }
00224 return result;
00225 }
00226
00235 EXPORT TIMESTAMP sync_load(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
00236 {
00237 try {
00238 load *pObj = OBJECTDATA(obj,load);
00239 TIMESTAMP t1 = TS_NEVER;
00240 switch (pass) {
00241 case PC_PRETOPDOWN:
00242 return pObj->presync(t0);
00243 case PC_BOTTOMUP:
00244 return pObj->sync(t0);
00245 case PC_POSTTOPDOWN:
00246 t1 = pObj->postsync(t0);
00247 obj->clock = t0;
00248 return t1;
00249 default:
00250 throw "invalid pass request";
00251 }
00252 } catch (const char *error) {
00253 GL_THROW("%s (load:%d): %s", obj->name, obj->oclass->name, obj->id, error);
00254 return 0;
00255 } catch (...) {
00256 GL_THROW("%s (load:%d): %s", obj->name, obj->oclass->name, obj->id, "unknown exception");
00257 return 0;
00258 }
00259 }
00260
00261 EXPORT int isa_load(OBJECT *obj, char *classname)
00262 {
00263 return OBJECTDATA(obj,load)->isa(classname);
00264 }
00265