Actual source code: PFReadData.c

      1: #include "petscmat.h"
      2: #include "power.h"
      3: #include <string.h>
      4: #include <ctype.h>

      6: PetscErrorCode PFReadMatPowerData(PFDATA *pf, char *filename)
      7: {
      8:   FILE        *fp;
      9:   VERTEX_Power Bus;
     10:   LOAD         Load;
     11:   GEN          Gen;
     12:   EDGE_Power   Branch;
     13:   PetscInt     line_counter   = 0;
     14:   PetscInt     bus_start_line = -1, bus_end_line = -1; /* xx_end_line points to the next line after the record ends */
     15:   PetscInt     gen_start_line = -1, gen_end_line = -1;
     16:   PetscInt     br_start_line = -1, br_end_line = -1;
     17:   char         line[MAXLINE];
     18:   PetscInt     loadi = 0, geni = 0, bri = 0, busi = 0, i, j;
     19:   int          extbusnum, bustype_i;
     20:   double       Pd, Qd;
     21:   PetscInt     maxbusnum = -1, intbusnum, *busext2intmap, genj, loadj;
     22:   GEN          newgen;
     23:   LOAD         newload;

     25:   PetscFunctionBegin;
     26:   fp = fopen(filename, "r");
     27:   /* Check for valid file */
     28:   PetscCheck(fp, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Can't open Matpower data file %s", filename);
     29:   pf->nload = 0;
     30:   while (fgets(line, MAXLINE, fp)) {
     31:     if (strstr(line, "mpc.bus = [")) bus_start_line = line_counter + 1;                     /* Bus data starts from next line */
     32:     if (strstr(line, "mpc.gen") && gen_start_line == -1) gen_start_line = line_counter + 1; /* Generator data starts from next line */
     33:     if (strstr(line, "mpc.branch")) br_start_line = line_counter + 1;                       /* Branch data starts from next line */
     34:     if (strstr(line, "];")) {
     35:       if (bus_start_line != -1 && bus_end_line == -1) bus_end_line = line_counter;
     36:       if (gen_start_line != -1 && gen_end_line == -1) gen_end_line = line_counter;
     37:       if (br_start_line != -1 && br_end_line == -1) br_end_line = line_counter;
     38:     }

     40:     /* Count the number of pq loads */
     41:     if (bus_start_line != -1 && line_counter >= bus_start_line && bus_end_line == -1) {
     42:       sscanf(line, "%d %d %lf %lf", &extbusnum, &bustype_i, &Pd, &Qd);
     43:       if (!((Pd == 0.0) && (Qd == 0.0))) pf->nload++;
     44:       if (extbusnum > maxbusnum) maxbusnum = extbusnum;
     45:     }
     46:     line_counter++;
     47:   }
     48:   fclose(fp);

     50:   pf->nbus    = bus_end_line - bus_start_line;
     51:   pf->ngen    = gen_end_line - gen_start_line;
     52:   pf->nbranch = br_end_line - br_start_line;

     54:   PetscCall(PetscCalloc1(pf->nbus, &pf->bus));
     55:   PetscCall(PetscCalloc1(pf->ngen, &pf->gen));
     56:   PetscCall(PetscCalloc1(pf->nload, &pf->load));
     57:   PetscCall(PetscCalloc1(pf->nbranch, &pf->branch));
     58:   Bus    = pf->bus;
     59:   Gen    = pf->gen;
     60:   Load   = pf->load;
     61:   Branch = pf->branch;

     63:   /* Setting pf->sbase to 100 */
     64:   pf->sbase = 100.0;

     66:   PetscCall(PetscMalloc1(maxbusnum + 1, &busext2intmap));
     67:   for (i = 0; i < maxbusnum + 1; i++) busext2intmap[i] = -1;

     69:   fp = fopen(filename, "r");
     70:   /* Reading data */
     71:   for (i = 0; i < line_counter; i++) {
     72:     PetscCheck(fgets(line, MAXLINE, fp), PETSC_COMM_SELF, PETSC_ERR_SUP, "File is incorrectly formatted");

     74:     if ((i >= bus_start_line) && (i < bus_end_line)) {
     75:       double gl, bl, vm, va, basekV;
     76:       int    bus_i, ide, area;
     77:       /* Bus data */
     78:       sscanf(line, "%d %d %lf %lf %lf %lf %d %lf %lf %lf", &bus_i, &ide, &Pd, &Qd, &gl, &bl, &area, &vm, &va, &basekV);
     79:       Bus[busi].bus_i                = bus_i;
     80:       Bus[busi].ide                  = ide;
     81:       Bus[busi].area                 = area;
     82:       Bus[busi].gl                   = gl;
     83:       Bus[busi].bl                   = bl;
     84:       Bus[busi].vm                   = vm;
     85:       Bus[busi].va                   = va;
     86:       Bus[busi].basekV               = basekV;
     87:       Bus[busi].internal_i           = busi;
     88:       busext2intmap[Bus[busi].bus_i] = busi;

     90:       if (!((Pd == 0.0) && (Qd == 0.0))) {
     91:         Load[loadi].bus_i                 = Bus[busi].bus_i;
     92:         Load[loadi].status                = 1;
     93:         Load[loadi].pl                    = Pd;
     94:         Load[loadi].ql                    = Qd;
     95:         Load[loadi].area                  = Bus[busi].area;
     96:         Load[loadi].internal_i            = busi;
     97:         Bus[busi].lidx[Bus[busi].nload++] = loadi;
     98:         PetscCheck(Bus[busi].nload <= NLOAD_AT_BUS_MAX, PETSC_COMM_SELF, PETSC_ERR_SUP, "Exceeded maximum number of loads allowed at bus");
     99:         loadi++;
    100:       }
    101:       busi++;
    102:     }

    104:     /* Read generator data */
    105:     if (i >= gen_start_line && i < gen_end_line) {
    106:       double pg, qg, qt, qb, vs, mbase, pt, pb;
    107:       int    bus_i, status;
    108:       sscanf(line, "%d %lf %lf %lf %lf %lf %lf %d %lf %lf", &bus_i, &pg, &qg, &qt, &qb, &vs, &mbase, &status, &pt, &pb);
    109:       Gen[geni].bus_i  = bus_i;
    110:       Gen[geni].status = status;
    111:       Gen[geni].pg     = pg;
    112:       Gen[geni].qg     = qg;
    113:       Gen[geni].qt     = qt;
    114:       Gen[geni].qb     = qb;
    115:       Gen[geni].vs     = vs;
    116:       Gen[geni].mbase  = mbase;
    117:       Gen[geni].pt     = pt;
    118:       Gen[geni].pb     = pb;

    120:       intbusnum                                  = busext2intmap[Gen[geni].bus_i];
    121:       Gen[geni].internal_i                       = intbusnum;
    122:       Bus[intbusnum].gidx[Bus[intbusnum].ngen++] = geni;

    124:       Bus[intbusnum].vm = Gen[geni].vs;

    126:       PetscCheck(Bus[intbusnum].ngen <= NGEN_AT_BUS_MAX, PETSC_COMM_SELF, PETSC_ERR_SUP, "Exceeded maximum number of generators allowed at bus");
    127:       geni++;
    128:     }

    130:     if (i >= br_start_line && i < br_end_line) {
    131:       PetscScalar R, X, Bc, B, G, Zm, tap, shift, tap2, tapr, tapi;
    132:       double      r, x, b, rateA, rateB, rateC, tapratio, phaseshift;
    133:       int         fbus, tbus, status;
    134:       sscanf(line, "%d %d %lf %lf %lf %lf %lf %lf %lf %lf %d", &fbus, &tbus, &r, &x, &b, &rateA, &rateB, &rateC, &tapratio, &phaseshift, &status);
    135:       Branch[bri].fbus       = fbus;
    136:       Branch[bri].tbus       = tbus;
    137:       Branch[bri].status     = status;
    138:       Branch[bri].r          = r;
    139:       Branch[bri].x          = x;
    140:       Branch[bri].b          = b;
    141:       Branch[bri].rateA      = rateA;
    142:       Branch[bri].rateB      = rateB;
    143:       Branch[bri].rateC      = rateC;
    144:       Branch[bri].tapratio   = tapratio;
    145:       Branch[bri].phaseshift = phaseshift;

    147:       if (Branch[bri].tapratio == 0.0) Branch[bri].tapratio = 1.0;
    148:       Branch[bri].phaseshift *= PETSC_PI / 180.0;

    150:       intbusnum              = busext2intmap[Branch[bri].fbus];
    151:       Branch[bri].internal_i = intbusnum;

    153:       intbusnum              = busext2intmap[Branch[bri].tbus];
    154:       Branch[bri].internal_j = intbusnum;

    156:       /* Compute self and transfer admittances */
    157:       R  = Branch[bri].r;
    158:       X  = Branch[bri].x;
    159:       Bc = Branch[bri].b;

    161:       Zm = R * R + X * X;
    162:       G  = R / Zm;
    163:       B  = -X / Zm;

    165:       tap   = Branch[bri].tapratio;
    166:       shift = Branch[bri].phaseshift;
    167:       tap2  = tap * tap;
    168:       tapr  = tap * PetscCosScalar(shift);
    169:       tapi  = tap * PetscSinScalar(shift);

    171:       Branch[bri].yff[0] = G / tap2;
    172:       Branch[bri].yff[1] = (B + Bc / 2.0) / tap2;

    174:       Branch[bri].yft[0] = -(G * tapr - B * tapi) / tap2;
    175:       Branch[bri].yft[1] = -(B * tapr + G * tapi) / tap2;

    177:       Branch[bri].ytf[0] = -(G * tapr + B * tapi) / tap2;
    178:       Branch[bri].ytf[1] = -(B * tapr - G * tapi) / tap2;

    180:       Branch[bri].ytt[0] = G;
    181:       Branch[bri].ytt[1] = B + Bc / 2.0;

    183:       bri++;
    184:     }
    185:   }
    186:   fclose(fp);

    188:   /* Reorder the generator data structure according to bus numbers */
    189:   genj  = 0;
    190:   loadj = 0;
    191:   PetscCall(PetscMalloc1(pf->ngen, &newgen));
    192:   PetscCall(PetscMalloc1(pf->nload, &newload));
    193:   for (i = 0; i < pf->nbus; i++) {
    194:     for (j = 0; j < pf->bus[i].ngen; j++) PetscCall(PetscMemcpy(&newgen[genj++], &pf->gen[pf->bus[i].gidx[j]], sizeof(struct _p_GEN)));
    195:     for (j = 0; j < pf->bus[i].nload; j++) PetscCall(PetscMemcpy(&newload[loadj++], &pf->load[pf->bus[i].lidx[j]], sizeof(struct _p_LOAD)));
    196:   }
    197:   PetscCall(PetscFree(pf->gen));
    198:   PetscCall(PetscFree(pf->load));
    199:   pf->gen  = newgen;
    200:   pf->load = newload;

    202:   PetscCall(PetscFree(busext2intmap));
    203:   PetscFunctionReturn(PETSC_SUCCESS);
    204: }