00001
00008 #include <stdlib.h>
00009 #include <stdio.h>
00010 #include <errno.h>
00011 #include <math.h>
00012
00013 #include "link.h"
00014 #include "node.h"
00015
00016 CLASS* link::oclass = NULL;
00017 CLASS* link::pclass = NULL;
00018 link *link::defaults = NULL;
00019
00024 link::link(MODULE *mod) : powerflow_object(mod){
00025
00026
00027 if (oclass==NULL)
00028 {
00029 pclass = powerflow_object::oclass;
00030 oclass = gl_register_class(mod,"link",PC_BOTTOMUP|PC_POSTTOPDOWN);
00031 if (oclass==NULL)
00032 GL_THROW("unable to register object class implemented by %s",__FILE__);
00033
00034 defaults = this;
00035 memset(this,0,sizeof(link));
00036 }
00037 }
00038
00039 int link::isa(char *classname)
00040 {
00041 return strcmp(classname,"link")==0 || powerflow_object::isa(classname);
00042 }
00043
00044 int link::create(void)
00045 {
00046 int result = powerflow_object::create();
00047 memcpy(this,defaults,sizeof(link));
00048 return result;
00049 }
00050
00051 int link::init(void)
00052 {
00053 OBJECT *obj = GETOBJECT(this);
00054
00055 powerflow_object::init();
00056
00057
00058 if (from==NULL)
00059 throw "link from node is not specified";
00060 else if (obj->parent==NULL)
00061 {
00062
00063 if (gl_object_isa(from,"node"))
00064 gl_set_parent(obj, from);
00065 else
00066 throw "link from reference not a node";
00067 }
00068 else
00069
00070
00071 gl_set_rank(from,obj->rank+1);
00072
00073
00074 if (to==NULL)
00075 throw "link to node is not specified";
00076 else if (to->parent==NULL)
00077 {
00078
00079 if (gl_object_isa(to,"node"))
00080 gl_set_parent(to, obj);
00081 else
00082 throw "link to reference not a node";
00083 }
00084 else
00085
00086 gl_set_rank(obj,to->rank+1);
00087
00088 return 1;
00089 }
00090
00091 TIMESTAMP link::sync(TIMESTAMP t0)
00092 {
00093 node *f = OBJECTDATA(from, node);
00094 node *t = OBJECTDATA(to, node);
00095 set nodeconditions = f->condition | t->condition;
00096
00097
00098 if (!is_normal())
00099 {
00100
00101 if (!is_open(PHASE_A))
00102 t->condition = f->condition |= OC_PHASE_A_CONTACT&(nodeconditions|condition);
00103 if (!is_open(PHASE_B))
00104 t->condition = f->condition |= OC_PHASE_B_CONTACT&(nodeconditions|condition);
00105 if (!is_open(PHASE_C))
00106 t->condition = f->condition |= OC_PHASE_C_CONTACT&(nodeconditions|condition);
00107 }
00108
00109
00110 f->phaseA_I_in += c_mat[0][0] * t->phaseA_V +
00111 c_mat[0][1] * t->phaseB_V +
00112 c_mat[0][2] * t->phaseC_V +
00113 d_mat[0][0] * t->phaseA_I_in +
00114 d_mat[0][1] * t->phaseB_I_in +
00115 d_mat[0][2] * t->phaseC_I_in;
00116 f->phaseB_I_in += c_mat[1][0] * t->phaseA_V +
00117 c_mat[1][1] * t->phaseB_V +
00118 c_mat[1][2] * t->phaseC_V +
00119 d_mat[1][0] * t->phaseA_I_in +
00120 d_mat[1][1] * t->phaseB_I_in +
00121 d_mat[1][2] * t->phaseC_I_in;
00122 f->phaseC_I_in += c_mat[2][0] * t->phaseA_V +
00123 c_mat[2][1] * t->phaseB_V +
00124 c_mat[2][2] * t->phaseC_V +
00125 d_mat[2][0] * t->phaseA_I_in +
00126 d_mat[2][1] * t->phaseB_I_in +
00127 d_mat[2][2] * t->phaseC_I_in;
00128
00129 return TS_NEVER;
00130 }
00131
00132 TIMESTAMP link::postsync(TIMESTAMP t0)
00133 {
00134 node *f = OBJECTDATA(from, node);
00135 node *t = OBJECTDATA(to, node);
00136 set nodeconditions = f->condition | t->condition;
00137
00138
00139 if (!(is_normal() && nodeconditions==OC_NORMAL))
00140
00142 memset(d_mat,0,sizeof(d_mat));
00143
00144 t->phaseA_V = A_mat[0][0] * f->phaseA_V +
00145 A_mat[0][1] * f->phaseB_V +
00146 A_mat[0][2] * f->phaseC_V -
00147 B_mat[0][0] * t->phaseA_I_in -
00148 B_mat[0][1] * t->phaseB_I_in -
00149 B_mat[0][2] * t->phaseC_I_in;
00150 t->phaseB_V = A_mat[1][0] * f->phaseA_V +
00151 A_mat[1][1] * f->phaseB_V +
00152 A_mat[1][2] * f->phaseC_V -
00153 B_mat[1][0] * t->phaseA_I_in -
00154 B_mat[1][1] * t->phaseB_I_in -
00155 B_mat[1][2] * t->phaseC_I_in;
00156 t->phaseC_V = A_mat[2][0] * f->phaseA_V +
00157 A_mat[2][1] * f->phaseB_V +
00158 A_mat[2][2] * f->phaseC_V -
00159 B_mat[2][0] * t->phaseA_I_in -
00160 B_mat[2][1] * t->phaseB_I_in -
00161 B_mat[2][2] * t->phaseC_I_in;
00162
00163 return TS_NEVER;
00164 }
00165
00166
00167
00169
00171
00179 EXPORT int create_link(OBJECT **obj, OBJECT *parent)
00180 {
00181 try
00182 {
00183 *obj = gl_create_object(link::oclass,sizeof(link));
00184 if (*obj==NULL)
00185 throw "unable to create v";
00186 gl_set_parent(*obj,parent);
00187 return OBJECTDATA(*obj,link)->create();
00188 }
00189 catch (char *msg)
00190 {
00191 gl_error("create_link: %s", msg);
00192 return 0;
00193 }
00194 }
00195
00196
00197
00204 EXPORT int init_link(OBJECT *obj)
00205 {
00206 link *my = OBJECTDATA(obj,link);
00207 try {
00208 return my->init();
00209 }
00210 catch (char *msg)
00211 {
00212 GL_THROW("%s (link:%d): %s", my->get_name(), my->get_id(), msg);
00213 return 0;
00214 }
00215 }
00216
00224 EXPORT TIMESTAMP sync_link(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
00225 {
00226 link *pLink = OBJECTDATA(obj,link);
00227 try
00228 {
00229 if (pass==PC_BOTTOMUP)
00230 return pLink->sync(t0);
00231 else if (pass==PC_POSTTOPDOWN)
00232 {
00233 TIMESTAMP t1 = pLink->postsync(t0);
00234 obj->clock = t0;
00235 return t1;
00236 }
00237 else
00238 throw "invalid pass request";
00239 }
00240 catch (const char *error)
00241 {
00242 GL_THROW("%s (link:%d): %s", pLink->get_name(), pLink->get_id(), error);
00243 return TS_INVALID;
00244 }
00245 catch (...)
00246 {
00247 GL_THROW("%s (link:%d): unknown exception", pLink->get_name(), pLink->get_id());
00248 return TS_INVALID;
00249 }
00250 }
00251
00252 EXPORT int isa_link(OBJECT *obj, char *classname)
00253 {
00254 return OBJECTDATA(obj,link)->isa(classname);
00255 }
00256
00258
00260
00261 void inverse(complex in[3][3], complex out[3][3])
00262 {
00263 complex x = complex(1.0) / (in[0][0] * in[1][1] * in[2][2] -
00264 in[0][0] * in[1][2] * in[2][1] -
00265 in[0][1] * in[1][0] * in[2][2] +
00266 in[0][1] * in[1][2] * in[2][0] +
00267 in[0][2] * in[1][0] * in[2][1] -
00268 in[0][2] * in[1][1] * in[2][0]);
00269
00270 out[0][0] = x * (in[1][1] * in[2][2] - in[1][2] * in[2][1]);
00271 out[0][1] = x * (in[0][2] * in[2][1] - in[0][1] * in[2][2]);
00272 out[0][2] = x * (in[0][1] * in[1][2] - in[0][2] * in[1][1]);
00273 out[1][0] = x * (in[1][2] * in[2][0] - in[1][0] * in[2][2]);
00274 out[1][1] = x * (in[0][0] * in[2][2] - in[0][2] * in[2][0]);
00275 out[1][2] = x * (in[0][2] * in[1][0] - in[0][0] * in[1][2]);
00276 out[2][0] = x * (in[1][0] * in[2][1] - in[1][1] * in[2][0]);
00277 out[2][1] = x * (in[0][1] * in[2][0] - in[0][0] * in[2][1]);
00278 out[2][2] = x * (in[0][0] * in[1][1] - in[0][1] * in[1][0]);
00279 }
00280
00281 void multiply(double a, complex b[3][3], complex c[3][3])
00282 {
00283 #define MUL(i, j) c[i][j] = b[i][j] * a
00284 MUL(0, 0); MUL(0, 1); MUL(0, 2);
00285 MUL(1, 0); MUL(1, 1); MUL(1, 2);
00286 MUL(2, 0); MUL(2, 1); MUL(2, 2);
00287 #undef MUL
00288 }
00289
00290 void multiply(complex a[3][3], complex b[3][3], complex c[3][3])
00291 {
00292 #define MUL(i, j) c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j]
00293 MUL(0, 0); MUL(0, 1); MUL(0, 2);
00294 MUL(1, 0); MUL(1, 1); MUL(1, 2);
00295 MUL(2, 0); MUL(2, 1); MUL(2, 2);
00296 #undef MUL
00297 }
00298
00299 void subtract(complex a[3][3], complex b[3][3], complex c[3][3])
00300 {
00301 #define SUB(i, j) c[i][j] = a[i][j] - b[i][j]
00302 SUB(0, 0); SUB(0, 1); SUB(0, 2);
00303 SUB(1, 0); SUB(1, 1); SUB(1, 2);
00304 SUB(2, 0); SUB(2, 1); SUB(2, 2);
00305 #undef MUL
00306 }
00307
00308