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