network/import.cpp

Go to the documentation of this file.
00001 
00011 #include <stdlib.h>
00012 #include <stdio.h>
00013 #include <errno.h>
00014 #include <math.h>
00015 #include "network.h"
00016 
00017 int import_cdf(char *file)
00018 {
00019     int n_bus=0;
00020     int n_branch=0;
00021     int linenum=0;
00022     int errors = 0; 
00023     OBJECT *bus[10000]; memset(bus,0,sizeof(bus));// CDF does not allow more than 9999 as a bus no
00024     OBJECT *branch[10000]; memset(branch,0,sizeof(branch));// CDF does not allow more than 9999 as a bus no
00025     // allow up to 100 zones
00026     OBJECT *swing[100]; memset(swing,0,sizeof(swing)); 
00027     int count[100]; memset(count,0,sizeof(count)); 
00028     char line[1024];
00029     char *ff = gl_findfile(file,NULL,FF_READ);
00030     FILE *fp = ff?fopen(ff, "r"):NULL;
00031     OBJECT *obj;
00032     enum {LD_INIT, LD_READY, LD_BUS, LD_BRANCH} state = LD_INIT;
00033     // model variables
00034     // branch variables
00035 
00036     if (fp==NULL)
00037         return 0;
00038     while (fgets(line,sizeof(line),fp)!=NULL)
00039     {
00040         linenum++;
00041         switch (state) {
00042         case LD_INIT:
00043             if (sscanf(line+31,"%lg",&mvabase)==1)
00044                 state=LD_READY;
00045             break;
00046         case LD_READY:
00047             if (mvabase>0 && strncmp(line,"BUS",3)==0)
00048                 state = LD_BUS;
00049             else if (mvabase>0 && strncmp(line,"BRANCH",6)==0)
00050                 state = LD_BRANCH;
00051             /* ignore line otherwise */
00052             break;
00053         case LD_BUS:
00054             if (atoi(line)>0)
00055             {   int n, area, zone, type;
00056                 int64 remote;
00057                 char32 name;
00058                 double Vm, Va, Lr, Li, Gr, Gi, bV, dV, Qh, Ql, G, B;
00059                 if (sscanf(line,"%d %12[^\n] %d %d%d %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg %" FMT_INT64 "d", 
00060                     &n, name, &area, &zone, &type, &Vm, &Va, &Lr, &Li, &Gr, &Gi, &bV, &dV, &Qh, &Ql, &G, &B, &remote)==18 && n_bus<10000)
00061                 {
00062                     obj = gl_create_object(node_class,sizeof(node));
00063                     obj->parent = NULL;
00064                     bus[n] = obj;
00065                     node *p = OBJECTDATA(obj,node);
00066                     p->create();
00067                     p->bus_id = n;
00068                     strncpy(p->name,name,sizeof(p->name));
00069                     p->flow_area_num = area;
00070                     p->loss_zone_num = zone;
00071                     p->type = (BUSTYPE)type;
00072                     p->V.SetPolar(Vm,Va*PI/180);
00073                     p->S.SetRect((Gr-Lr)/mvabase,(Gi-Li)/mvabase); /* loads are negative, gen is positive */
00074                     p->base_kV = bV;
00075                     p->desired_kV = dV;
00076                     p->Qmax_MVAR = Qh;
00077                     p->Qmin_MVAR = Ql;
00078                     p->G = G;
00079                     p->B = B;
00080                     p->remote_bus_id = (OBJECT*)remote;
00081                     if (p->type==SWING) swing[area]=obj;
00082                     count[area]++;
00083                     n_bus++;
00084 #ifdef DEBUG_OBS
00085                     if (p->type!=PQ) 
00086                     {
00087                         p->Vstdev = 0.01;
00088                         p->Vobs.Re() = gl_random_normal(p->V.Re(),p->Vstdev);
00089                         p->Vobs.Im() = gl_random_normal(p->V.Im(),p->Vstdev);
00090                     }
00091                     if (p->type!=SWING) 
00092                         p->V = complex(1,0);
00093                     else if (p->Vstdev>0)
00094                         p->V.SetPolar(p->Vobs.Mag(),0);
00095 #endif
00096                 }
00097                 else
00098                 {
00099                     gl_output("%s(%d) : missing bus data", file, linenum);
00100                     errors++;
00101                 }
00102             }
00103             else
00104                 state = LD_READY;
00105             break;
00106         case LD_BRANCH:
00107             if (atoi(line)>0)
00108             {   int from, to, area, zone, type, circuit;
00109                 double R, X, B, n=0;
00110                 if (sscanf(line,"%d %d %d %d %d %d %lg %lg %lg %*lg %*lg %*lg %*d %*d %lg",
00111                     &from,&to,&area,&zone,&type,&circuit,&R,&X,&B, &n)>=9 && n_branch<10000)
00112                 {
00113                     obj = gl_create_object(link_class,sizeof(link));
00114                     obj->parent = NULL;
00115                     branch[n_branch] = obj;
00116                     link *p = OBJECTDATA(obj,link);
00117                     p->create();
00118                     p->from = bus[from];
00119                     p->to = bus[to];
00120                     if (n>0.0)
00121                         p->turns_ratio = n;
00122                     else
00123                         p->turns_ratio = 1.0;
00124                     p->Y = complex(1)/complex(R,X); 
00125                     p->B = B;
00126                     n_branch++;
00127                 }
00128                 else
00129                 {
00130                     gl_output("%s(%d) : missing branch data", file, linenum);
00131                     errors++;
00132                 }
00133             }
00134             else
00135                 state = LD_READY;
00136             break;
00137         default:
00138             break;
00139         }
00140     }
00141     fclose(fp);
00142 
00143     int n;
00144     // check area for swing buses
00145     for (n=0; n<sizeof(count)/sizeof(count[0]); n++)
00146     {
00147         if (count[n]>0 && swing[n]==NULL)
00148         {
00149             gl_output("%s : flow area %d has no swing bus", file, n);
00150             errors++;
00151         }
00152     }
00153 
00154     // fixup parent swing bus and remote bus, if any
00155     for (n=0; n<sizeof(bus)/sizeof(bus[0]); n++)
00156     {
00157         OBJECT *obj = bus[n];
00158         if (obj==NULL) continue;
00159         node *p = OBJECTDATA(obj,node);
00160         if (p->type!=SWING)
00161         {
00162             OBJECT *swingbus = swing[p->flow_area_num];
00163             if (swingbus!=NULL)
00164                 gl_set_parent(obj,swingbus);
00165         }
00166         p->remote_bus_id= bus[(int64)p->remote_bus_id];
00167     }
00168 
00169     // branch parent is bus of lowest rank
00170     for (n=0; n<sizeof(branch)/sizeof(branch[0]); n++)
00171     {
00172         OBJECT *obj = branch[n];
00173         if (obj==NULL) continue;
00174         link *p = OBJECTDATA(obj,link);
00175         if (p->from!=NULL && p->to!=NULL)
00176             gl_set_parent(obj, p->from->rank<p->to->rank ? p->from : p->to);
00177 
00178         // update injections to node
00179         p->sync(TS_NEVER);
00180     }
00181 
00182     return errors>0 ? -errors : n_bus+n_branch;
00183 }
00184 EXPORT int import_file(char *file)
00185 {
00186     char *ext = strrchr(file,'.');
00187     if (ext!=NULL && stricmp(ext,".cdf")==0)
00188         return import_cdf(file);
00189     errno = ENOENT;
00190     return 0;
00191 }
00192 

GridLAB-DTM Version 1.0
An open-source project initiated by the US Department of Energy