00001
00080 #include <stdlib.h>
00081 #include <stdio.h>
00082 #include <errno.h>
00083 #include <math.h>
00084
00085 #include "powerflow.h"
00086 #include "node.h"
00087 #include "link.h"
00088
00090
00092 CLASS* powerflow_object::oclass = NULL;
00093 CLASS* powerflow_object::pclass = NULL;
00094
00095 powerflow_object::powerflow_object(MODULE *mod)
00096 {
00097 if (oclass==NULL)
00098 {
00099 #ifdef SUPPORT_OUTAGES
00100 oclass = gl_register_class(mod,"powerflow_object",sizeof(powerflow_object),PC_ABSTRACTONLY|PC_POSTTOPDOWN|PC_UNSAFE_OVERRIDE_OMIT|PC_AUTOLOCK);
00101 #else
00102 oclass = gl_register_class(mod,"powerflow_object",sizeof(powerflow_object),PC_ABSTRACTONLY|PC_NOSYNC|PC_AUTOLOCK);
00103 #endif
00104 if (oclass==NULL)
00105 throw "unable to register class powerflow_object";
00106 else
00107 oclass->trl = TRL_PROVEN;
00108
00109 if(gl_publish_variable(oclass,
00110 PT_set, "phases", PADDR(phases),
00111 PT_KEYWORD, "G", (set)GROUND,
00112 PT_KEYWORD, "S", (set)PHASE_S,
00113 PT_KEYWORD, "N", (set)PHASE_N,
00114 PT_KEYWORD, "D", (set)PHASE_D,
00115 PT_KEYWORD, "C", (set)PHASE_C,
00116 PT_KEYWORD, "B", (set)PHASE_B,
00117 PT_KEYWORD, "A", (set)PHASE_A,
00118 PT_double,"nominal_voltage[V]",PADDR(nominal_voltage),
00119 PT_enumeration, "inrush_integration_method",PADDR(inrush_integration_method),PT_DESCRIPTION,"Integration method for in-rush",
00120 PT_KEYWORD,"NONE",(enumeration)IRM_NONE,
00121 PT_KEYWORD,"TRAPEZOIDAL",(enumeration)IRM_TRAPEZOIDAL,
00122 PT_KEYWORD,"BACKWARD_EULER",(enumeration)IRM_BACKEULER,
00123 #ifdef SUPPORT_OUTAGES
00124 PT_set, "condition", PADDR(condition),
00125 PT_KEYWORD, "OPEN", (set)OC_OPEN,
00126 PT_KEYWORD, "CONTACT", (set)OC_CONTACT,
00127 PT_KEYWORD, "NORMAL", (set)OC_NORMAL,
00128 PT_KEYWORD, "SN", (set)PHASE_SN,
00129 PT_KEYWORD, "S2", (set)PHASE_S2,
00130 PT_KEYWORD, "S1", (set)PHASE_S1,
00131 PT_KEYWORD, "G", (set)GROUND,
00132 PT_KEYWORD, "N", (set)PHASE_N,
00133 PT_KEYWORD, "C", (set)PHASE_C,
00134 PT_KEYWORD, "B", (set)PHASE_B,
00135 PT_KEYWORD, "A", (set)PHASE_A,
00136 PT_enumeration, "solution", PADDR(solution),
00137 PT_KEYWORD, "NORMAL", PS_NORMAL,
00138 PT_KEYWORD, "OUTAGE", PS_OUTAGE,
00139 #endif
00140 NULL) < 1) GL_THROW("unable to publish powerflow_object properties in %s",__FILE__);
00141
00142
00143 }
00144 }
00145
00146 powerflow_object::powerflow_object(CLASS *oclass)
00147 {
00148 gl_create_foreign((OBJECT*)this);
00149 }
00150
00151 int powerflow_object::isa(char *classname)
00152 {
00153 return strcmp(classname,"powerflow_object")==0;
00154 }
00155
00156 int powerflow_object::create(void)
00157 {
00158 OBJECT *obj = OBJECTHDR(this);
00159 phases = NO_PHASE;
00160 nominal_voltage = 0.0;
00161
00162
00163 if (all_powerflow_delta == true)
00164 obj->flags |= OF_DELTAMODE;
00165
00166
00167 inrush_integration_method = default_inrush_integration_method;
00168
00169 #ifdef SUPPORT_OUTAGES
00170 condition = OC_NORMAL;
00171 solution = PS_NORMAL;
00172 #endif
00173 return 1;
00174 }
00175
00176 int powerflow_object::init(OBJECT *parent)
00177 {
00178
00179 if (parent && gl_object_isa(parent,"powerflow_object"))
00180 {
00181 powerflow_object *pParent = OBJECTDATA(parent,powerflow_object);
00182 if (phases==NO_PHASE)
00183 phases = pParent->phases;
00184 }
00185
00186
00187 if (phases==0)
00188 throw "phases not specified";
00189
00190
00191 if (has_phase(PHASE_S) && !(has_phase(PHASE_A) || has_phase(PHASE_B) || has_phase(PHASE_C)))
00192 throw "split connection is missing A,B, or C phase connection";
00193
00194
00195 if (has_phase(PHASE_S) && (
00196 (has_phase(PHASE_A) && has_phase(PHASE_B)) ||
00197 (has_phase(PHASE_B) && has_phase(PHASE_C)) ||
00198 (has_phase(PHASE_C) && has_phase(PHASE_A))))
00199 throw "split connection is connected to two phases simultaneously";
00200
00201
00202 if (has_phase(PHASE_S) && has_phase(PHASE_D))
00203 throw "split and delta connection cannot occur simultaneously";
00204
00205
00206 if (has_phase(PHASE_N) && has_phase(PHASE_S))
00207 {
00208 gl_warning("neutral phase ignored on split connection.");
00209 phases ^= PHASE_N;
00210 }
00211
00212 return 1;
00213 }
00214
00215 TIMESTAMP powerflow_object::presync(TIMESTAMP t0)
00216 {
00217
00218 return TS_NEVER;
00219 }
00220
00221 TIMESTAMP powerflow_object::sync(TIMESTAMP t0)
00222 {
00223
00224 return TS_NEVER;
00225 }
00226
00227 TIMESTAMP powerflow_object::postsync(TIMESTAMP t0)
00228 {
00229 #ifdef SUPPORT_OUTAGES
00230 OBJECT *obj = OBJECTHDR(this);
00231 if (condition!=OC_NORMAL && solution==PS_NORMAL)
00232 {
00233 char buffer[1024]="???";
00234 gl_get_value_by_name(obj,"condition",buffer,sizeof(buffer));
00235 gl_debug("powerflow_object %s (%s:%d): abnormal condition detected (condition=%s), switching solver to OUTAGE method", obj->name, obj->oclass->name, obj->id, buffer);
00236 solution = PS_OUTAGE;
00237 return t0;
00238 }
00239 else if (condition==OC_NORMAL && solution==PS_OUTAGE)
00240 {
00241 gl_debug("powerflow_object %s (%s:%d): normal condition restored, switching solver to NORMAL method", obj->name, obj->oclass->name, obj->id);
00242 solution = PS_NORMAL;
00243 return t0;
00244 }
00245 #endif
00246 return TS_NEVER;
00247 }
00248
00249 int powerflow_object::kmldump(FILE *fp)
00250 {
00251 return 1;
00252 }
00254
00256
00264 EXPORT int create_powerflow_object(OBJECT **obj, OBJECT *parent)
00265 {
00266 try
00267 {
00268 *obj = gl_create_object(powerflow_object::oclass);
00269 if (*obj!=NULL)
00270 {
00271 powerflow_object *my = OBJECTDATA(*obj,powerflow_object);
00272 gl_set_parent(*obj,parent);
00273 return my->create();
00274 }
00275 else
00276 return 0;
00277 }
00278 CREATE_CATCHALL(powerflow_object);
00279 }
00280
00287 EXPORT int init_powerflow_object(OBJECT *obj)
00288 {
00289 try {
00290 powerflow_object *my = OBJECTDATA(obj,powerflow_object);
00291 return my->init(obj->parent);
00292 }
00293 INIT_CATCHALL(powerflow_object);
00294 }
00295
00304 EXPORT TIMESTAMP sync_powerflow_object(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
00305 {
00306 powerflow_object *pObj = OBJECTDATA(obj,powerflow_object);
00307 try {
00308 TIMESTAMP t1 = TS_NEVER;
00309 switch (pass) {
00310 case PC_PRETOPDOWN:
00311 return pObj->presync(t0);
00312 case PC_BOTTOMUP:
00313 return pObj->sync(t0);
00314 case PC_POSTTOPDOWN:
00315 t1 = pObj->postsync(t0);
00316 obj->clock = t0;
00317 return t1;
00318 default:
00319 throw "invalid pass request";
00320 }
00321 }
00322 SYNC_CATCHALL(powerflow_object);
00323 }
00324
00325 EXPORT int isa_powerflow_object(OBJECT *obj, char *classname)
00326 {
00327 return OBJECTDATA(obj,powerflow_object)->isa(classname);
00328 }
00329