00001
00049 #include <stdlib.h>
00050 #include <stdio.h>
00051 #include <errno.h>
00052 #include <math.h>
00053 #include "network.h"
00054
00056
00058
00059 CLASS* link::oclass = NULL;
00060 CLASS* link::pclass = NULL;
00061 link *link::defaults = NULL;
00062 CLASS *link_class = (NULL);
00063 OBJECT *last_link = (NULL);
00064
00065 link::link(MODULE *mod)
00066 {
00067
00068 if (oclass==NULL)
00069 {
00070
00071 link_class = oclass = gl_register_class(mod,"link",sizeof(link),PC_BOTTOMUP|PC_UNSAFE_OVERRIDE_OMIT);
00072 if (oclass==NULL)
00073 throw "unable to register class link";
00074 else
00075 oclass->trl = TRL_STANDALONE;
00076
00077
00078 if (gl_publish_variable(oclass,
00079 PT_complex, "Y", PADDR(Y),
00080 PT_complex, "I", PADDR(I),
00081 PT_double, "B", PADDR(B),
00082 PT_object, "from", PADDR(from),
00083 PT_object, "to", PADDR(to),
00084 NULL)<1) GL_THROW("unable to publish properties in %s",__FILE__);
00085
00086
00087 defaults = this;
00088 Y = complex(0,0);
00089 B = 0.0;
00090 I = complex(0,0);
00091 from = NULL;
00092 to = NULL;
00093 turns_ratio = 1.0;
00094 }
00095 }
00096
00097 int link::create()
00098 {
00099 memcpy(this,defaults,sizeof(*this));
00100 return 1;
00101 }
00102
00103 int link::init(node *parent)
00104 {
00105 node *f = OBJECTDATA(from,node);
00106 if (f==NULL)
00107 throw "from node not specified";
00108 f->attach(this);
00109
00110 node *t = OBJECTDATA(to,node);
00111 if (t==NULL)
00112 throw "to node not specified";
00113 t->attach(this);
00114
00115
00116 Yeff = Y + complex(0,B/2);
00117
00118
00119 c = 1/turns_ratio;
00120
00121
00122 Yc = Yeff*c;
00123
00124 return 1;
00125 }
00126
00127 TIMESTAMP link::sync(TIMESTAMP t0)
00128 {
00129 node *f = OBJECTDATA(from,node);
00130 node *t = OBJECTDATA(to,node);
00131
00132
00133
00134 complex Ifrom = t->V * Yc;
00135 complex Ito = f->V * Yc;
00136
00137
00138
00139 complex Ys = Yc + Yc*(c-1);
00140 LOCK_OBJECT(from);
00141 f->Ys += Ys;
00142 f->YVs += Ifrom;
00143 UNLOCK_OBJECT(from);
00144
00145 Ys = Yc + Yeff*(1-c);
00146 LOCK_OBJECT(to);
00147 t->YVs += Ito;
00148 t->Ys += Ys;
00149 UNLOCK_OBJECT(to);
00150
00151
00152 I = Ito - Ifrom;
00153
00154
00155 #ifdef _DEBUG
00156
00157 if (debug_link==1)
00158 {
00159 OBJECT* obj = OBJECTHDR(this);
00160 static int first=-1;
00161 if (first==-1) first = obj->id;
00162 if (obj->id==first)
00163 {
00164 printf("\n");
00165 printf("Link From -> To R X B Y Ifrom Ito I \n");
00166 printf("===== ====================== ======== ======== ======== ================= ================= ================= =================\n");
00167 }
00168 printf("%2d-%2d %-9.9s -> %-9.9s %+8.4f %+8.4f %+8.4f %+8.4f%+8.4fj %+8.4f%+8.4fj %+8.4f%+8.4fj %+8.4f%+8.4fj\n",
00169 from->id, to->id,
00170 from->name,to->name,
00171 (complex(1,0)/Y).Re(),(complex(1,0)/Y).Im(), B,
00172 Y.Re(), Y.Im(),
00173 Ifrom.Re(), Ifrom.Im(),
00174 Ito.Re(), Ito.Im(),
00175 I.Re(), I.Im());
00176 }
00177 #endif // _DEBUG
00178
00179 return TS_NEVER;
00180 }
00181
00182 void link::apply_dV(OBJECT *source, complex dV)
00183 {
00184 complex dI = dV * Y * c;
00185 OBJECT *obj;
00186 node *n;
00187 if (source==from)
00188 n = OBJECTDATA(obj=to,node);
00189 else if (source==to)
00190 n = OBJECTDATA(obj=from,node);
00191 else
00192 throw "apply_dV() - source is not valid";
00193 LOCKED(obj,n->YVs += dI);
00194 }
00195
00197
00199
00200 EXPORT int create_link(OBJECT **obj, OBJECT *parent)
00201 {
00202 *obj = gl_create_object(link_class);
00203 if (*obj!=NULL)
00204 {
00205 last_link = *obj;
00206 link *my = OBJECTDATA(*obj,link);
00207 gl_set_parent(*obj,parent);
00208 my->create();
00209 return 1;
00210 }
00211 return 0;
00212 }
00213
00214 EXPORT TIMESTAMP sync_link(OBJECT *obj, TIMESTAMP t0)
00215 {
00216 TIMESTAMP t1 = OBJECTDATA(obj,link)->sync(t0);
00217 obj->clock = t0;
00218 return t1;
00219 }
00220
00221 EXPORT int init_link(OBJECT *obj)
00222 {
00223
00224 return OBJECTDATA(obj,link)->init(OBJECTDATA(obj->parent,node));
00225 }
00226
00227