00001
00010 #include <stdlib.h>
00011 #include <stdio.h>
00012 #include <errno.h>
00013 #include <math.h>
00014
00015 #include "node.h"
00016 #include "meter.h"
00017
00018 CLASS* triplex_node::oclass = NULL;
00019 CLASS* triplex_node::pclass = NULL;
00020
00021 triplex_node::triplex_node(MODULE *mod) : node(mod)
00022 {
00023 if(oclass == NULL)
00024 {
00025 pclass = node::oclass;
00026
00027 oclass = gl_register_class(mod,"triplex_node",sizeof(triplex_node),PC_PRETOPDOWN|PC_BOTTOMUP|PC_POSTTOPDOWN|PC_UNSAFE_OVERRIDE_OMIT);
00028 if(oclass == NULL)
00029 GL_THROW("unable to register object class implemented by %s",__FILE__);
00030
00031 if(gl_publish_variable(oclass,
00032 PT_INHERIT, "powerflow_object",
00033 PT_enumeration, "bustype", PADDR(bustype),
00034 PT_KEYWORD, "PQ", PQ,
00035 PT_KEYWORD, "PV", PV,
00036 PT_KEYWORD, "SWING", SWING,
00037 PT_set, "busflags", PADDR(busflags),
00038 PT_KEYWORD, "HASSOURCE", (set)NF_HASSOURCE,
00039 PT_object, "reference_bus", PADDR(reference_bus),
00040 PT_double,"maximum_voltage_error[V]",PADDR(maximum_voltage_error),
00041
00042 PT_complex, "voltage_1[V]", PADDR(voltage1),
00043 PT_complex, "voltage_2[V]", PADDR(voltage2),
00044 PT_complex, "voltage_N[V]", PADDR(voltageN),
00045 PT_complex, "voltage_12[V]", PADDR(voltage12),
00046 PT_complex, "voltage_1N[V]", PADDR(voltage1N),
00047 PT_complex, "voltage_2N[V]", PADDR(voltage2N),
00048 PT_complex, "current_1[A]", PADDR(current1),
00049 PT_complex, "current_2[A]", PADDR(current2),
00050 PT_complex, "current_N[A]", PADDR(currentN),
00051 PT_double, "current_1_real[A]", PADDR(current1.Re()),
00052 PT_double, "current_2_real[A]", PADDR(current2.Re()),
00053 PT_double, "current_N_real[A]", PADDR(currentN.Re()),
00054 PT_double, "current_1_reac[A]", PADDR(current1.Im()),
00055 PT_double, "current_2_reac[A]", PADDR(current2.Im()),
00056 PT_double, "current_N_reac[A]", PADDR(currentN.Im()),
00057 PT_complex, "current_12[A]", PADDR(current12),
00058 PT_double, "current_12_real[A]", PADDR(current12.Re()),
00059 PT_double, "current_12_reac[A]", PADDR(current12.Im()),
00060 PT_complex, "residential_nominal_current_1[A]", PADDR(nom_res_curr[0]),
00061 PT_complex, "residential_nominal_current_2[A]", PADDR(nom_res_curr[1]),
00062 PT_complex, "residential_nominal_current_12[A]", PADDR(nom_res_curr[2]),
00063 PT_double, "residential_nominal_current_1_real[A]", PADDR(nom_res_curr[0].Re()),
00064 PT_double, "residential_nominal_current_1_imag[A]", PADDR(nom_res_curr[0].Im()),
00065 PT_double, "residential_nominal_current_2_real[A]", PADDR(nom_res_curr[1].Re()),
00066 PT_double, "residential_nominal_current_2_imag[A]", PADDR(nom_res_curr[1].Im()),
00067 PT_double, "residential_nominal_current_12_real[A]", PADDR(nom_res_curr[2].Re()),
00068 PT_double, "residential_nominal_current_12_imag[A]", PADDR(nom_res_curr[2].Im()),
00069 PT_complex, "power_1[VA]", PADDR(power1),
00070 PT_complex, "power_2[VA]", PADDR(power2),
00071 PT_complex, "power_12[VA]", PADDR(power12),
00072 PT_double, "power_1_real[W]", PADDR(power1.Re()),
00073 PT_double, "power_2_real[W]", PADDR(power2.Re()),
00074 PT_double, "power_12_real[W]", PADDR(power12.Re()),
00075 PT_double, "power_1_reac[VAr]", PADDR(power1.Im()),
00076 PT_double, "power_2_reac[VAr]", PADDR(power2.Im()),
00077 PT_double, "power_12_reac[VAr]", PADDR(power12.Im()),
00078 PT_complex, "shunt_1[S]", PADDR(pub_shunt[0]),
00079 PT_complex, "shunt_2[S]", PADDR(pub_shunt[1]),
00080 PT_complex, "shunt_12[S]", PADDR(pub_shunt[2]),
00081 PT_complex, "impedance_1[Ohm]", PADDR(impedance[0]),
00082 PT_complex, "impedance_2[Ohm]", PADDR(impedance[1]),
00083 PT_complex, "impedance_12[Ohm]", PADDR(impedance[2]),
00084 PT_double, "impedance_1_real[Ohm]", PADDR(impedance[0].Re()),
00085 PT_double, "impedance_2_real[Ohm]", PADDR(impedance[1].Re()),
00086 PT_double, "impedance_12_real[Ohm]", PADDR(impedance[2].Re()),
00087 PT_double, "impedance_1_reac[Ohm]", PADDR(impedance[0].Im()),
00088 PT_double, "impedance_2_reac[Ohm]", PADDR(impedance[1].Im()),
00089 PT_double, "impedance_12_reac[Ohm]", PADDR(impedance[2].Im()),
00090 PT_bool, "house_present", PADDR(house_present),
00091 PT_bool, "NR_mode", PADDR(NR_mode),
00092 NULL) < 1) GL_THROW("unable to publish properties in %s",__FILE__);
00093 }
00094 }
00095
00096 int triplex_node::isa(char *classname)
00097 {
00098 return strcmp(classname,"triplex_node")==0 || node::isa(classname);
00099 }
00100
00101 int triplex_node::create(void)
00102 {
00103 int result = node::create();
00104 maximum_voltage_error = 0;
00105 pub_shunt[0] = pub_shunt[1] = pub_shunt[2] = 0;
00106 shunt1 = complex(0,0);
00107 shunt2 = complex(0,0);
00108 shunt12 = complex(0,0);
00109 return result;
00110 }
00111
00112 int triplex_node::init(OBJECT *parent)
00113 {
00114 if ((pub_shunt[0] == 0) && (impedance[0] != 0))
00115 shunt[0] = complex(1.0,0)/impedance[0];
00116
00117 if ((pub_shunt[1] == 0) && (impedance[1] != 0))
00118 shunt[1] = complex(1.0,0)/impedance[1];
00119
00120 if ((pub_shunt[2] == 0) && (impedance[2] != 0))
00121 shunt[2] = complex(1.0,0)/impedance[2];
00122
00123 return node::init(parent);
00124 }
00125
00126 TIMESTAMP triplex_node::presync(TIMESTAMP t0)
00127 {
00128 if (solver_method == SM_NR)
00129 NR_mode = NR_cycle;
00130 else
00131 NR_mode = false;
00132
00133
00134 shunt[0] = shunt[1] = shunt[2] = 0.0;
00135
00136 return node::presync(t0);
00137 }
00138
00139 TIMESTAMP triplex_node::sync(TIMESTAMP t0)
00140 {
00141 complex I;
00142 OBJECT *obj = OBJECTHDR(this);
00143
00144
00145
00146 if ((pub_shunt[0] == 0) && (impedance[0] != 0))
00147 shunt[0] += complex(1.0,0)/impedance[0];
00148 else
00149 shunt[0] += pub_shunt[0];
00150
00151 if ((pub_shunt[1] == 0) && (impedance[1] != 0))
00152 shunt[1] += complex(1.0,0)/impedance[1];
00153 else
00154 shunt[1] += pub_shunt[1];
00155
00156 if ((pub_shunt[2] == 0) && (impedance[2] != 0))
00157 shunt[2] += complex(1.0,0)/impedance[2];
00158 else
00159 shunt[2] += pub_shunt[2];
00160
00161 return node::sync(t0);
00162 }
00163
00165
00167
00175 EXPORT int create_triplex_node(OBJECT **obj, OBJECT *parent)
00176 {
00177 try
00178 {
00179 *obj = gl_create_object(triplex_node::oclass);
00180 if (*obj!=NULL)
00181 {
00182 triplex_node *my = OBJECTDATA(*obj,triplex_node);
00183 gl_set_parent(*obj,parent);
00184 return my->create();
00185 }
00186 }
00187 catch (const char *msg)
00188 {
00189 gl_error("create_triplex_node: %s", msg);
00190 }
00191 return 0;
00192 }
00193
00200 EXPORT int init_triplex_node(OBJECT *obj)
00201 {
00202 triplex_node *my = OBJECTDATA(obj,triplex_node);
00203 try {
00204 return my->init();
00205 }
00206 catch (const char *msg)
00207 {
00208 GL_THROW("%s (triplex_node:%d): %s", my->get_name(), my->get_id(), msg);
00209 return 0;
00210 }
00211 }
00212
00221 EXPORT TIMESTAMP sync_triplex_node(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
00222 {
00223 triplex_node *pObj = OBJECTDATA(obj,triplex_node);
00224 try {
00225 TIMESTAMP t1;
00226 switch (pass) {
00227 case PC_PRETOPDOWN:
00228 return pObj->presync(t0);
00229 case PC_BOTTOMUP:
00230 return pObj->sync(t0);
00231 case PC_POSTTOPDOWN:
00232 t1 = pObj->postsync(t0);
00233 obj->clock = t0;
00234 return t1;
00235 default:
00236 throw "invalid pass request";
00237 }
00238 } catch (const char *error) {
00239 GL_THROW("%s (triplex_node:%d): %s", pObj->get_name(), pObj->get_id(), error);
00240 return 0;
00241 } catch (...) {
00242 GL_THROW("%s (triplex_node:%d): %s", pObj->get_name(), pObj->get_id(), "unknown exception");
00243 return 0;
00244 }
00245 }
00246
00247 EXPORT int isa_triplex_node(OBJECT *obj, char *classname)
00248 {
00249 return OBJECTDATA(obj,triplex_node)->isa(classname);
00250 }
00251