Actual source code: pffunctions.c
1: /* function subroutines used by power.c */
3: #include "power.h"
5: PetscErrorCode GetListofEdges_Power(PFDATA *pfdata, PetscInt *edgelist)
6: {
7: PetscInt i, fbus, tbus, nbranches = pfdata->nbranch;
8: EDGE_Power branch = pfdata->branch;
9: PetscBool netview = PETSC_FALSE;
11: PetscFunctionBegin;
12: PetscCall(PetscOptionsHasName(NULL, NULL, "-powernet_view", &netview));
13: for (i = 0; i < nbranches; i++) {
14: fbus = branch[i].internal_i;
15: tbus = branch[i].internal_j;
16: edgelist[2 * i] = fbus;
17: edgelist[2 * i + 1] = tbus;
18: if (netview) PetscCall(PetscPrintf(PETSC_COMM_SELF, "branch %" PetscInt_FMT ", bus[%" PetscInt_FMT "] -> bus[%" PetscInt_FMT "]\n", i, fbus, tbus));
19: }
20: if (netview) {
21: for (i = 0; i < pfdata->nbus; i++) {
22: if (pfdata->bus[i].ngen) {
23: PetscCall(PetscPrintf(PETSC_COMM_SELF, " bus %" PetscInt_FMT ": gen\n", i));
24: } else if (pfdata->bus[i].nload) {
25: PetscCall(PetscPrintf(PETSC_COMM_SELF, " bus %" PetscInt_FMT ": load\n", i));
26: }
27: }
28: }
29: PetscFunctionReturn(PETSC_SUCCESS);
30: }
32: PetscErrorCode FormJacobian_Power_private(DM networkdm, Vec localX, Mat J, PetscInt nv, PetscInt ne, const PetscInt *vtx, const PetscInt *edges, void *appctx)
33: {
34: const PetscScalar *xarr;
35: PetscInt i, v, row[2], col[8], e, vfrom, vto;
36: PetscInt offsetfrom, offsetto, goffsetfrom, goffsetto, numComps;
37: PetscScalar values[8];
38: PetscInt j, key, offset, goffset;
39: PetscScalar Vm;
40: UserCtx_Power *user_power = (UserCtx_Power *)appctx;
41: PetscScalar Sbase = user_power->Sbase;
42: VERTEX_Power bus;
43: PetscBool ghostvtex;
44: void *component;
46: PetscFunctionBegin;
47: PetscCall(VecGetArrayRead(localX, &xarr));
49: for (v = 0; v < nv; v++) {
50: PetscCall(DMNetworkIsGhostVertex(networkdm, vtx[v], &ghostvtex));
52: PetscCall(DMNetworkGetNumComponents(networkdm, vtx[v], &numComps));
53: for (j = 0; j < numComps; j++) {
54: PetscCall(DMNetworkGetLocalVecOffset(networkdm, vtx[v], ALL_COMPONENTS, &offset));
55: PetscCall(DMNetworkGetGlobalVecOffset(networkdm, vtx[v], ALL_COMPONENTS, &goffset));
56: PetscCall(DMNetworkGetComponent(networkdm, vtx[v], j, &key, &component, NULL));
58: if (key == user_power->compkey_bus) {
59: PetscInt nconnedges;
60: const PetscInt *connedges;
62: bus = (VERTEX_Power)component;
63: if (!ghostvtex) {
64: /* Handle reference bus constrained dofs */
65: if (bus->ide == REF_BUS || bus->ide == ISOLATED_BUS) {
66: row[0] = goffset;
67: row[1] = goffset + 1;
68: col[0] = goffset;
69: col[1] = goffset + 1;
70: col[2] = goffset;
71: col[3] = goffset + 1;
72: values[0] = 1.0;
73: values[1] = 0.0;
74: values[2] = 0.0;
75: values[3] = 1.0;
76: PetscCall(MatSetValues(J, 2, row, 2, col, values, ADD_VALUES));
77: break;
78: }
80: Vm = xarr[offset + 1];
82: /* Shunt injections */
83: row[0] = goffset;
84: row[1] = goffset + 1;
85: col[0] = goffset;
86: col[1] = goffset + 1;
87: values[0] = values[1] = values[2] = values[3] = 0.0;
88: if (bus->ide != PV_BUS) {
89: values[1] = 2.0 * Vm * bus->gl / Sbase;
90: values[3] = -2.0 * Vm * bus->bl / Sbase;
91: }
92: PetscCall(MatSetValues(J, 2, row, 2, col, values, ADD_VALUES));
93: }
95: PetscCall(DMNetworkGetSupportingEdges(networkdm, vtx[v], &nconnedges, &connedges));
97: for (i = 0; i < nconnedges; i++) {
98: EDGE_Power branch;
99: VERTEX_Power busf, bust;
100: PetscInt keyf, keyt;
101: PetscScalar Gff, Bff, Gft, Bft, Gtf, Btf, Gtt, Btt;
102: const PetscInt *cone;
103: PetscScalar Vmf, Vmt, thetaf, thetat, thetaft, thetatf;
105: e = connedges[i];
106: PetscCall(DMNetworkGetComponent(networkdm, e, 0, &key, (void **)&branch, NULL));
107: if (!branch->status) continue;
109: Gff = branch->yff[0];
110: Bff = branch->yff[1];
111: Gft = branch->yft[0];
112: Bft = branch->yft[1];
113: Gtf = branch->ytf[0];
114: Btf = branch->ytf[1];
115: Gtt = branch->ytt[0];
116: Btt = branch->ytt[1];
118: PetscCall(DMNetworkGetConnectedVertices(networkdm, edges[e], &cone));
119: vfrom = cone[0];
120: vto = cone[1];
122: PetscCall(DMNetworkGetLocalVecOffset(networkdm, vfrom, ALL_COMPONENTS, &offsetfrom));
123: PetscCall(DMNetworkGetLocalVecOffset(networkdm, vto, ALL_COMPONENTS, &offsetto));
124: PetscCall(DMNetworkGetGlobalVecOffset(networkdm, vfrom, ALL_COMPONENTS, &goffsetfrom));
125: PetscCall(DMNetworkGetGlobalVecOffset(networkdm, vto, ALL_COMPONENTS, &goffsetto));
127: if (goffsetto < 0) goffsetto = -goffsetto - 1;
129: thetaf = xarr[offsetfrom];
130: Vmf = xarr[offsetfrom + 1];
131: thetat = xarr[offsetto];
132: Vmt = xarr[offsetto + 1];
133: thetaft = thetaf - thetat;
134: thetatf = thetat - thetaf;
136: PetscCall(DMNetworkGetComponent(networkdm, vfrom, 0, &keyf, (void **)&busf, NULL));
137: PetscCall(DMNetworkGetComponent(networkdm, vto, 0, &keyt, (void **)&bust, NULL));
139: if (vfrom == vtx[v]) {
140: if (busf->ide != REF_BUS) {
141: /* farr[offsetfrom] += Gff*Vmf*Vmf + Vmf*Vmt*(Gft*PetscCosScalar(thetaft) + Bft*PetscSinScalar(thetaft)); */
142: row[0] = goffsetfrom;
143: col[0] = goffsetfrom;
144: col[1] = goffsetfrom + 1;
145: col[2] = goffsetto;
146: col[3] = goffsetto + 1;
147: values[0] = Vmf * Vmt * (Gft * -PetscSinScalar(thetaft) + Bft * PetscCosScalar(thetaft)); /* df_dthetaf */
148: values[1] = 2.0 * Gff * Vmf + Vmt * (Gft * PetscCosScalar(thetaft) + Bft * PetscSinScalar(thetaft)); /* df_dVmf */
149: values[2] = Vmf * Vmt * (Gft * PetscSinScalar(thetaft) + Bft * -PetscCosScalar(thetaft)); /* df_dthetat */
150: values[3] = Vmf * (Gft * PetscCosScalar(thetaft) + Bft * PetscSinScalar(thetaft)); /* df_dVmt */
152: PetscCall(MatSetValues(J, 1, row, 4, col, values, ADD_VALUES));
153: }
154: if (busf->ide != PV_BUS && busf->ide != REF_BUS) {
155: row[0] = goffsetfrom + 1;
156: col[0] = goffsetfrom;
157: col[1] = goffsetfrom + 1;
158: col[2] = goffsetto;
159: col[3] = goffsetto + 1;
160: /* farr[offsetfrom+1] += -Bff*Vmf*Vmf + Vmf*Vmt*(-Bft*PetscCosScalar(thetaft) + Gft*PetscSinScalar(thetaft)); */
161: values[0] = Vmf * Vmt * (Bft * PetscSinScalar(thetaft) + Gft * PetscCosScalar(thetaft));
162: values[1] = -2.0 * Bff * Vmf + Vmt * (-Bft * PetscCosScalar(thetaft) + Gft * PetscSinScalar(thetaft));
163: values[2] = Vmf * Vmt * (-Bft * PetscSinScalar(thetaft) + Gft * -PetscCosScalar(thetaft));
164: values[3] = Vmf * (-Bft * PetscCosScalar(thetaft) + Gft * PetscSinScalar(thetaft));
166: PetscCall(MatSetValues(J, 1, row, 4, col, values, ADD_VALUES));
167: }
168: } else {
169: if (bust->ide != REF_BUS) {
170: row[0] = goffsetto;
171: col[0] = goffsetto;
172: col[1] = goffsetto + 1;
173: col[2] = goffsetfrom;
174: col[3] = goffsetfrom + 1;
175: /* farr[offsetto] += Gtt*Vmt*Vmt + Vmt*Vmf*(Gtf*PetscCosScalar(thetatf) + Btf*PetscSinScalar(thetatf)); */
176: values[0] = Vmt * Vmf * (Gtf * -PetscSinScalar(thetatf) + Btf * PetscCosScalar(thetaft)); /* df_dthetat */
177: values[1] = 2.0 * Gtt * Vmt + Vmf * (Gtf * PetscCosScalar(thetatf) + Btf * PetscSinScalar(thetatf)); /* df_dVmt */
178: values[2] = Vmt * Vmf * (Gtf * PetscSinScalar(thetatf) + Btf * -PetscCosScalar(thetatf)); /* df_dthetaf */
179: values[3] = Vmt * (Gtf * PetscCosScalar(thetatf) + Btf * PetscSinScalar(thetatf)); /* df_dVmf */
181: PetscCall(MatSetValues(J, 1, row, 4, col, values, ADD_VALUES));
182: }
183: if (bust->ide != PV_BUS && bust->ide != REF_BUS) {
184: row[0] = goffsetto + 1;
185: col[0] = goffsetto;
186: col[1] = goffsetto + 1;
187: col[2] = goffsetfrom;
188: col[3] = goffsetfrom + 1;
189: /* farr[offsetto+1] += -Btt*Vmt*Vmt + Vmt*Vmf*(-Btf*PetscCosScalar(thetatf) + Gtf*PetscSinScalar(thetatf)); */
190: values[0] = Vmt * Vmf * (Btf * PetscSinScalar(thetatf) + Gtf * PetscCosScalar(thetatf));
191: values[1] = -2.0 * Btt * Vmt + Vmf * (-Btf * PetscCosScalar(thetatf) + Gtf * PetscSinScalar(thetatf));
192: values[2] = Vmt * Vmf * (-Btf * PetscSinScalar(thetatf) + Gtf * -PetscCosScalar(thetatf));
193: values[3] = Vmt * (-Btf * PetscCosScalar(thetatf) + Gtf * PetscSinScalar(thetatf));
195: PetscCall(MatSetValues(J, 1, row, 4, col, values, ADD_VALUES));
196: }
197: }
198: }
199: if (!ghostvtex && bus->ide == PV_BUS) {
200: row[0] = goffset + 1;
201: col[0] = goffset + 1;
202: values[0] = 1.0;
203: if (user_power->jac_error) values[0] = 50.0;
204: PetscCall(MatSetValues(J, 1, row, 1, col, values, ADD_VALUES));
205: }
206: }
207: }
208: }
210: PetscCall(VecRestoreArrayRead(localX, &xarr));
211: PetscFunctionReturn(PETSC_SUCCESS);
212: }
214: PetscErrorCode FormJacobian_Power(SNES snes, Vec X, Mat J, Mat Jpre, void *appctx)
215: {
216: DM networkdm;
217: Vec localX;
218: PetscInt nv, ne;
219: const PetscInt *vtx, *edges;
221: PetscFunctionBegin;
222: PetscCall(MatZeroEntries(J));
224: PetscCall(SNESGetDM(snes, &networkdm));
225: PetscCall(DMGetLocalVector(networkdm, &localX));
227: PetscCall(DMGlobalToLocalBegin(networkdm, X, INSERT_VALUES, localX));
228: PetscCall(DMGlobalToLocalEnd(networkdm, X, INSERT_VALUES, localX));
230: PetscCall(DMNetworkGetSubnetwork(networkdm, 0, &nv, &ne, &vtx, &edges));
231: PetscCall(FormJacobian_Power_private(networkdm, localX, J, nv, ne, vtx, edges, appctx));
233: PetscCall(DMRestoreLocalVector(networkdm, &localX));
235: PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY));
236: PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY));
237: PetscFunctionReturn(PETSC_SUCCESS);
238: }
240: PetscErrorCode FormFunction_Power(DM networkdm, Vec localX, Vec localF, PetscInt nv, PetscInt ne, const PetscInt *vtx, const PetscInt *edges, void *appctx)
241: {
242: UserCtx_Power *User = (UserCtx_Power *)appctx;
243: PetscInt e, v, vfrom, vto;
244: const PetscScalar *xarr;
245: PetscScalar *farr;
246: PetscInt offsetfrom, offsetto, offset, i, j, key, numComps;
247: PetscScalar Vm;
248: PetscScalar Sbase = User->Sbase;
249: VERTEX_Power bus = NULL;
250: GEN gen;
251: LOAD load;
252: PetscBool ghostvtex;
253: void *component;
255: PetscFunctionBegin;
256: PetscCall(VecGetArrayRead(localX, &xarr));
257: PetscCall(VecGetArray(localF, &farr));
259: for (v = 0; v < nv; v++) {
260: PetscCall(DMNetworkIsGhostVertex(networkdm, vtx[v], &ghostvtex));
261: PetscCall(DMNetworkGetNumComponents(networkdm, vtx[v], &numComps));
262: PetscCall(DMNetworkGetLocalVecOffset(networkdm, vtx[v], ALL_COMPONENTS, &offset));
264: for (j = 0; j < numComps; j++) {
265: PetscCall(DMNetworkGetComponent(networkdm, vtx[v], j, &key, &component, NULL));
266: if (key == User->compkey_bus) {
267: PetscInt nconnedges;
268: const PetscInt *connedges;
270: bus = (VERTEX_Power)component;
271: /* Handle reference bus constrained dofs */
272: if (bus->ide == REF_BUS || bus->ide == ISOLATED_BUS) {
273: farr[offset] = xarr[offset] - bus->va * PETSC_PI / 180.0;
274: farr[offset + 1] = xarr[offset + 1] - bus->vm;
275: break;
276: }
278: if (!ghostvtex) {
279: Vm = xarr[offset + 1];
281: /* Shunt injections */
282: farr[offset] += Vm * Vm * bus->gl / Sbase;
283: if (bus->ide != PV_BUS) farr[offset + 1] += -Vm * Vm * bus->bl / Sbase;
284: }
286: PetscCall(DMNetworkGetSupportingEdges(networkdm, vtx[v], &nconnedges, &connedges));
287: for (i = 0; i < nconnedges; i++) {
288: EDGE_Power branch;
289: PetscInt keye;
290: PetscScalar Gff, Bff, Gft, Bft, Gtf, Btf, Gtt, Btt;
291: const PetscInt *cone;
292: PetscScalar Vmf, Vmt, thetaf, thetat, thetaft, thetatf;
294: e = connedges[i];
295: PetscCall(DMNetworkGetComponent(networkdm, e, 0, &keye, (void **)&branch, NULL));
296: if (!branch->status) continue;
297: Gff = branch->yff[0];
298: Bff = branch->yff[1];
299: Gft = branch->yft[0];
300: Bft = branch->yft[1];
301: Gtf = branch->ytf[0];
302: Btf = branch->ytf[1];
303: Gtt = branch->ytt[0];
304: Btt = branch->ytt[1];
306: PetscCall(DMNetworkGetConnectedVertices(networkdm, e, &cone));
307: vfrom = cone[0];
308: vto = cone[1];
310: PetscCall(DMNetworkGetLocalVecOffset(networkdm, vfrom, ALL_COMPONENTS, &offsetfrom));
311: PetscCall(DMNetworkGetLocalVecOffset(networkdm, vto, ALL_COMPONENTS, &offsetto));
313: thetaf = xarr[offsetfrom];
314: Vmf = xarr[offsetfrom + 1];
315: thetat = xarr[offsetto];
316: Vmt = xarr[offsetto + 1];
317: thetaft = thetaf - thetat;
318: thetatf = thetat - thetaf;
320: if (vfrom == vtx[v]) {
321: farr[offsetfrom] += Gff * Vmf * Vmf + Vmf * Vmt * (Gft * PetscCosScalar(thetaft) + Bft * PetscSinScalar(thetaft));
322: farr[offsetfrom + 1] += -Bff * Vmf * Vmf + Vmf * Vmt * (-Bft * PetscCosScalar(thetaft) + Gft * PetscSinScalar(thetaft));
323: } else {
324: farr[offsetto] += Gtt * Vmt * Vmt + Vmt * Vmf * (Gtf * PetscCosScalar(thetatf) + Btf * PetscSinScalar(thetatf));
325: farr[offsetto + 1] += -Btt * Vmt * Vmt + Vmt * Vmf * (-Btf * PetscCosScalar(thetatf) + Gtf * PetscSinScalar(thetatf));
326: }
327: }
328: } else if (key == User->compkey_gen) {
329: if (!ghostvtex) {
330: gen = (GEN)component;
331: if (!gen->status) continue;
332: farr[offset] += -gen->pg / Sbase;
333: farr[offset + 1] += -gen->qg / Sbase;
334: }
335: } else if (key == User->compkey_load) {
336: if (!ghostvtex) {
337: load = (LOAD)component;
338: farr[offset] += load->pl / Sbase;
339: farr[offset + 1] += load->ql / Sbase;
340: }
341: }
342: }
343: if (bus && bus->ide == PV_BUS) farr[offset + 1] = xarr[offset + 1] - bus->vm;
344: }
345: PetscCall(VecRestoreArrayRead(localX, &xarr));
346: PetscCall(VecRestoreArray(localF, &farr));
347: PetscFunctionReturn(PETSC_SUCCESS);
348: }
350: PetscErrorCode SetInitialGuess_Power(DM networkdm, Vec localX, PetscInt nv, PetscInt ne, const PetscInt *vtx, const PetscInt *edges, void *appctx)
351: {
352: VERTEX_Power bus;
353: PetscInt i;
354: GEN gen;
355: PetscBool ghostvtex, sharedv;
356: PetscScalar *xarr;
357: PetscInt key, numComps, j, offset;
358: void *component;
359: PetscMPIInt rank;
360: MPI_Comm comm;
361: UserCtx_Power *User = (UserCtx_Power *)appctx;
363: PetscFunctionBegin;
364: PetscCall(PetscObjectGetComm((PetscObject)networkdm, &comm));
365: PetscCallMPI(MPI_Comm_rank(comm, &rank));
366: PetscCall(VecGetArray(localX, &xarr));
367: for (i = 0; i < nv; i++) {
368: PetscCall(DMNetworkIsGhostVertex(networkdm, vtx[i], &ghostvtex));
369: PetscCall(DMNetworkIsSharedVertex(networkdm, vtx[i], &sharedv));
370: if (ghostvtex || sharedv) continue;
372: PetscCall(DMNetworkGetLocalVecOffset(networkdm, vtx[i], ALL_COMPONENTS, &offset));
373: PetscCall(DMNetworkGetNumComponents(networkdm, vtx[i], &numComps));
374: for (j = 0; j < numComps; j++) {
375: PetscCall(DMNetworkGetComponent(networkdm, vtx[i], j, &key, &component, NULL));
376: if (key == User->compkey_bus) {
377: bus = (VERTEX_Power)component;
378: xarr[offset] = bus->va * PETSC_PI / 180.0;
379: xarr[offset + 1] = bus->vm;
380: } else if (key == User->compkey_gen) {
381: gen = (GEN)component;
382: if (!gen->status) continue;
383: xarr[offset + 1] = gen->vs;
384: break;
385: }
386: }
387: }
388: PetscCall(VecRestoreArray(localX, &xarr));
389: PetscFunctionReturn(PETSC_SUCCESS);
390: }