network/export.cpp

Go to the documentation of this file.
00001 
00009 #include <stdlib.h>
00010 #include <stdio.h>
00011 #include <errno.h>
00012 #include <math.h>
00013 #include <float.h>
00014 #include "network.h"
00015 
00016 static int save_cdf(char *file)
00017 {
00018     FILE *fp=fopen(file,"w");
00019     if (fp==NULL) return 0;
00020     time_t now = time(NULL);
00021     char timestamp[32];
00022     int count=0;
00023     /* TODO: these should be set as module parameters */
00024     double mvabase=100.0;
00025     char system_name[32]="GridLAB-D Network";
00026     
00027     strftime(timestamp,sizeof(timestamp),"%m/%d/%y",gmtime(&now));
00028 
00029     count += fprintf(fp," %s %-20.20s %5.1f  %4d %c %s\n", timestamp, system_name, mvabase, model_year, model_case, model_name);
00030 
00031     // process nodes
00032     FINDLIST *found = gl_find_objects(FL_NEW,FT_CLASS,SAME,"node",FT_END);
00033     count += fprintf(fp,"%-38.38s %d ITEMS\n","BUS DATA FOLLOWS",found->hit_count);
00034     OBJECT *obj=NULL;
00035     while ((obj=gl_find_next(found,obj))!=NULL)
00036     {
00037         node *my = (node*)(obj+1);
00038         char name[32];
00039         sprintf(name,"Bus %d", obj->id+1);
00040         count += fprintf(fp,"%4d %-12.12s %2d %2d %2d %5.3f %6.2f %7.1f %8.1f %7.1f %7.1f %6.1f %6.1f %6.1f %6.1f %8.5f %8.5f %d\n", obj->id+1,name,
00041             my->flow_area_num, my->loss_zone_num, my->type, my->V.Mag(), 
00042             my->V.Arg()*180/PI, 
00043             my->S.Re()<0?-my->S.Re()*mvabase:0, my->S.Re()<0?-my->S.Im()*mvabase:0,
00044             my->S.Re()>0?my->S.Re()*mvabase:0, my->S.Re()>0?my->S.Im()*mvabase:0,
00045             my->base_kV, my->desired_kV, my->Qmax_MVAR, my->Qmin_MVAR, my->G, my->B, my->remote_bus_id?my->remote_bus_id->id+1:0);
00046     }
00047     count += fprintf(fp,"-999\n");
00048     gl_free(found);
00049 
00050     // process links
00051     found = gl_find_objects(FL_NEW,FT_CLASS,SAME,"link",FT_END);
00052     count += fprintf(fp,"%-38.38s %d ITEMS\n","BRANCH DATA FOLLOWS",found->hit_count);
00053     obj=NULL;
00054     while ((obj=gl_find_next(found,obj))!=NULL)
00055     {
00056         link *my = (link*)(obj+1);
00057         node *from = my->from?(node*)(((OBJECT*)my->from)+1):NULL;
00058         node *to= my->to?(node*)(((OBJECT*)my->to)+1):NULL;
00059         if (from==NULL||to==NULL) /* ignore badly connected nodes */
00060             continue;
00061         double R = (complex(1)/my->Y).Re();
00062         double X = (complex(1)/my->Y).Im();
00063         count += fprintf(fp,"%4d %4d %2d %2d 1 0 %9.5f %11.5f %9.4f %4d %4d %4d %4d %1d  %6.3f %7.2f %5f %5f %5f %5f %5f\n", 
00064             my->from->id+1, my->to->id+1, from->flow_area_num, from->loss_zone_num, R,X,0.0,
00065             0,0,0,0, 0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0);
00066     }
00067     count += fprintf(fp,"-999\n");
00068     gl_free(found);
00069 
00070     count += fprintf(fp,"LOSS ZONES FOLLOWS                    1 ITEMS\n  1 %s\n-99\n",model_name);
00071     count += fprintf(fp,"INTERCHANGE DATA FOLLOWS              0 ITEMS\n-9\n");
00072     count += fprintf(fp,"TIE LINES FOLLOWS                     0 ITEMS\n-999\n");
00073 
00074     count += fprintf(fp,"END OF DATA\n");
00075 
00076     return count;
00077 }
00078 
00079 EXPORT int export_file(char *file)
00080 {
00081     if (file==NULL) file="network.cdf";
00082 
00083     char *ext = strrchr(file,'.');
00084     if (ext!=NULL && stricmp(ext,".cdf")==0)
00085         return save_cdf(file);
00086     errno = ENOENT;
00087     return 0;
00088 }
00089 
00090 EXPORT int kmldump(FILE *fp, OBJECT *obj)
00091 {
00092     if (obj==NULL) /* dump document styles */
00093     {
00094         /* line styles */
00095         fprintf(fp,"    <Style id=\"TransmissionLine\">\n");
00096         fprintf(fp,"      <LineStyle>\n"
00097                 "        <color>7f00ffff</color>\n"
00098                 "        <width>4</width>\n"
00099                 "      </LineStyle>\n"
00100                 "      <PolyStyle>\n"
00101                 "        <color>7f00ff00</color>\n"
00102                 "      </PolyStyle>\n"
00103                 "    </Style>\n");
00104     }
00105     else if (strcmp(obj->oclass->name,"node")==0)
00106     {
00107             node *pNode = (node*)OBJECTDATA(obj,node);
00108         if (isnan(obj->latitude) || isnan(obj->longitude))
00109             return 0;
00110         fprintf(fp,"    <Placemark>\n");
00111         if (obj->name)
00112             fprintf(fp,"      <name>%s</name>\n", obj->name);
00113         else if (strcmp(pNode->name,"")!=0)
00114             fprintf(fp,"      <name>%s</name>\n", pNode->name);
00115         else if (pNode->bus_id>0)
00116             fprintf(fp,"      <name>Bus %d</name>\n", pNode->bus_id);
00117         else
00118             fprintf(fp,"      <name>%s %d</name>\n", obj->oclass->name, obj->id);
00119         fprintf(fp,"      <description>\n");
00120         fprintf(fp,"        <![CDATA[\n");
00121         fprintf(fp,"          <TABLE><TR>\n");
00122         switch (pNode->type) {
00123         case SWING:
00124             fprintf(fp,"            <TR><TH ALIGN=LEFT>Type</TH><TD ALIGN=RIGHT STYLE=\"font-family:courier;\">SWING&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD></TR>\n");
00125             break;          
00126         case PV:
00127             fprintf(fp,"            <TR><TH ALIGN=LEFT>Type</TH><TD ALIGN=RIGHT STYLE=\"font-family:courier;\">PV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD></TR>\n");
00128             break;          
00129         case PQ:
00130             fprintf(fp,"            <TR><TH ALIGN=LEFT>Type</TH><TD ALIGN=RIGHT STYLE=\"font-family:courier;\">PQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD></TR>\n");
00131             break;          
00132         }
00133         fprintf(fp,"            <TR><TH ALIGN=LEFT>Voltage</TH><TD ALIGN=RIGHT STYLE=\"font-family:courier;\">%.3f&nbsp;kV&nbsp;&nbsp;<BR>%.3f&nbsp;&ang;&nbsp;&nbsp;&nbsp;</TD></TR>\n",
00134             pNode->V.Mag()*pNode->base_kV,pNode->V.Arg()*180/3.1416);
00135         if (pNode->S.Mag()>0)
00136             fprintf(fp,"            <TR><TH ALIGN=LEFT>%s</TH><TD ALIGN=RIGHT STYLE=\"font-family:courier;\">%.3f&nbsp;MW&nbsp;&nbsp;<BR>%.3f&nbsp;MVAR</TD></TR>\n",
00137                 pNode->S.Re()<0?"Demand":"Supply",fabs(pNode->S.Re())*mvabase,pNode->S.Im()*mvabase);
00138         fprintf(fp,"          </TR></TABLE>\n");
00139         fprintf(fp,"        ]]>\n");
00140         fprintf(fp,"      </description>\n");
00141         fprintf(fp,"      <Point>\n");
00142         fprintf(fp,"        <coordinates>%f,%f</coordinates>\n",obj->longitude,obj->latitude);
00143         fprintf(fp,"      </Point>\n");
00144         fprintf(fp,"    </Placemark>\n");
00145     }
00146     else if (strcmp(obj->oclass->name,"link")==0)
00147     {
00148         link *pLink = (link*)OBJECTDATA(obj,link);
00149         OBJECT *from = pLink->from;
00150         OBJECT *to = pLink->to;
00151         if (isnan(from->latitude) || isnan(to->latitude) || isnan(from->longitude) || isnan(to->longitude))
00152             return 0;
00153         fprintf(fp,"    <Placemark>\n");
00154         if (obj->name)
00155             fprintf(fp,"      <name>%s</name>\n", obj->name);
00156         else
00157             fprintf(fp,"      <name>%s ==> %s</name>\n", from->name?from->name:"unnamed", to->name?to->name:"unnamed");
00158             fprintf(fp,"      <description>\n");
00159             fprintf(fp,"        <![CDATA[\n");
00160             fprintf(fp,"          <TABLE><TR>\n");
00161             complex flow;
00162             node *pFrom = OBJECTDATA(from,node);
00163             node *pTo = OBJECTDATA(to,node);
00164             if (pLink->I.Re()<0)
00165                 flow = pFrom->V * pLink->I;
00166             else
00167                 flow = pTo->V * pLink->I;
00168             complex loss = pLink->I*pLink->I / pLink->Y;
00169             complex imp = complex(1,0)/pLink->Y;
00170             double current_base = mvabase/pFrom->base_kV*1000;
00171             fprintf(fp,"            <TR><TH ALIGN=LEFT>Flow</TH><TD ALIGN=RIGHT STYLE=\"font-family:courier;\">%.3f&nbsp;&nbsp;MW&nbsp;&nbsp;<BR>%.3f&nbsp;&nbsp;MVAR</TD></TR>\n",
00172                 flow.Re()*mvabase, flow.Im()*mvabase);
00173             fprintf(fp,"            <TR><TH ALIGN=LEFT>Current</TH><TD ALIGN=RIGHT STYLE=\"font-family:courier;\">%.3f&nbsp;&nbsp;Amps</TD></TR>\n",
00174                 pLink->I.Mag()*current_base);
00175             fprintf(fp,"            <TR><TH ALIGN=LEFT>Impedance</TH><TD ALIGN=RIGHT STYLE=\"font-family:courier;\">%.4f&nbsp;R&nbsp;&nbsp;&nbsp;<BR>%.4f&nbsp;X&nbsp;&nbsp;&nbsp;</TD></TR>\n",
00176                 imp.Re(),imp.Im());
00177             fprintf(fp,"            <TR><TH ALIGN=LEFT>Losses</TH><TD ALIGN=RIGHT STYLE=\"font-family:courier;\">%.2f&nbsp;&nbsp;&nbsp;%%P&nbsp;&nbsp;<BR>%.2f&nbsp;&nbsp;&nbsp;%%Q&nbsp;&nbsp;</TD></TR>\n",
00178                 loss.Re()/flow.Re()*100,loss.Im()/flow.Im()*100);
00179             fprintf(fp,"          </TR></TABLE>\n");
00180             fprintf(fp,"        ]]>\n");
00181             fprintf(fp,"      </description>\n");
00182         fprintf(fp,"      <styleUrl>#TransmissionLine</styleUrl>>\n");
00183         fprintf(fp,"      <coordinates>%f,%f</coordinates>\n",
00184             (from->longitude+to->longitude)/2,(from->latitude+to->latitude)/2);
00185         fprintf(fp,"      <LineString>\n");         
00186         fprintf(fp,"        <extrude>0</extrude>\n");
00187         fprintf(fp,"        <tessellate>0</tessellate>\n");
00188         fprintf(fp,"        <altitudeMode>relative</altitudeMode>\n");
00189         fprintf(fp,"        <coordinates>%f,%f,50 %f,%f,50</coordinates>\n",
00190             from->longitude,from->latitude,to->longitude,to->latitude);
00191         fprintf(fp,"      </LineString>\n");            
00192         fprintf(fp,"    </Placemark>\n");
00193     }
00194     return 0;
00195 }
00196 

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