Actual source code: ex9busdmnetwork.c
petsc-3.13.6 2020-09-29
2: static char help[] = "This example uses the same problem set up of ex9busdmnetwork.c. \n\
3: It demonstrates setting and accessing of variables for individual components, instead of \n\
4: the network vertices (as used in ex9busdmnetwork.c). This is especially useful where vertices \n\
5: /edges have multiple-components associated with them and one or more components has physics \n\
6: associated with it. \n\
7: Input parameters include:\n\
8: -nc : number of copies of the base case\n\n" ;
10: /* T
11: Concepts: DMNetwork
12: Concepts: PETSc TS solver
14: This example was modified from ex9busdmnetwork.c.
15: */
17: #include <petscts.h>
18: #include <petscdmnetwork.h>
20: #define FREQ 60
21: #define W_S (2*PETSC_PI*FREQ)
22: #define NGEN 3 /* No. of generators in the 9 bus system */
23: #define NLOAD 3 /* No. of loads in the 9 bus system */
24: #define NBUS 9 /* No. of buses in the 9 bus system */
25: #define NBRANCH 9 /* No. of branches in the 9 bus system */
27: typedef struct {
28: PetscInt id; /* Bus Number or extended bus name*/
29: PetscScalar mbase; /* MVA base of the machine */
30: PetscScalar PG; /* Generator active power output */
31: PetscScalar QG; /* Generator reactive power output */
33: /* Generator constants */
34: PetscScalar H; /* Inertia constant */
35: PetscScalar Rs; /* Stator Resistance */
36: PetscScalar Xd; /* d-axis reactance */
37: PetscScalar Xdp; /* d-axis transient reactance */
38: PetscScalar Xq; /* q-axis reactance Xq(1) set to 0.4360, value given in text 0.0969 */
39: PetscScalar Xqp; /* q-axis transient reactance */
40: PetscScalar Td0p; /* d-axis open circuit time constant */
41: PetscScalar Tq0p; /* q-axis open circuit time constant */
42: PetscScalar M; /* M = 2*H/W_S */
43: PetscScalar D; /* D = 0.1*M */
44: PetscScalar TM; /* Mechanical Torque */
45: } Gen;
47: typedef struct {
48: /* Exciter system constants */
49: PetscScalar KA ; /* Voltage regulator gain constant */
50: PetscScalar TA; /* Voltage regulator time constant */
51: PetscScalar KE; /* Exciter gain constant */
52: PetscScalar TE; /* Exciter time constant */
53: PetscScalar KF; /* Feedback stabilizer gain constant */
54: PetscScalar TF; /* Feedback stabilizer time constant */
55: PetscScalar k1,k2; /* calculating the saturation function SE = k1*exp(k2*Efd) */
56: PetscScalar Vref; /* Voltage regulator voltage setpoint */
57: } Exc;
59: typedef struct {
60: PetscInt id; /* node id */
61: PetscInt nofgen; /* Number of generators at the bus*/
62: PetscInt nofload; /* Number of load at the bus*/
63: PetscScalar yff[2]; /* yff[0]= imaginary part of admittance, yff[1]=real part of admittance*/
64: PetscScalar vr; /* Real component of bus voltage */
65: PetscScalar vi; /* Imaginary component of bus voltage */
66: } Bus;
68: /* Load constants
69: We use a composite load model that describes the load and reactive powers at each time instant as follows
70: P(t) = \sum\limits_{i=0}^ld_nsegsp \ld_alphap_i*P_D0(\frac{V_m(t)}{V_m0})^\ld_betap_i
71: Q(t) = \sum\limits_{i=0}^ld_nsegsq \ld_alphaq_i*Q_D0(\frac{V_m(t)}{V_m0})^\ld_betaq_i
72: where
73: id - index of the load
74: ld_nsegsp,ld_nsegsq - Number of individual load models for real and reactive power loads
75: ld_alphap,ld_alphap - Percentage contribution (weights) or loads
76: P_D0 - Real power load
77: Q_D0 - Reactive power load
78: Vm(t) - Voltage magnitude at time t
79: Vm0 - Voltage magnitude at t = 0
80: ld_betap, ld_betaq - exponents describing the load model for real and reactive part
82: Note: All loads have the same characteristic currently.
83: */
84: typedef struct {
85: PetscInt id; /* bus id */
86: PetscInt ld_nsegsp,ld_nsegsq;
87: PetscScalar PD0, QD0;
88: PetscScalar ld_alphap[3]; /* ld_alphap=[1,0,0], an array, not a value, so use *ld_alphap; */
89: PetscScalar ld_betap[3],ld_alphaq[3],ld_betaq[3];
90: } Load;
92: typedef struct {
93: PetscInt id; /* node id */
94: PetscScalar yft[2]; /* yft[0]= imaginary part of admittance, yft[1]=real part of admittance*/
95: } Branch;
97: typedef struct {
98: PetscReal tfaulton,tfaultoff; /* Fault on and off times */
99: PetscReal t;
100: PetscReal t0,tmax; /* initial time and final time */
101: PetscInt faultbus; /* Fault bus */
102: PetscScalar Rfault; /* Fault resistance (pu) */
103: PetscScalar *ybusfault;
104: PetscBool alg_flg;
105: } Userctx;
107: /* Used to read data into the DMNetwork components */
108: PetscErrorCode read_data(PetscInt nc, Gen **pgen,Exc **pexc, Load **pload,Bus **pbus, Branch **pbranch, PetscInt **pedgelist)
109: {
110: PetscErrorCode ierr;
111: PetscInt i,j,row[1],col[2];
112: PetscInt *edgelist;
113: PetscInt nofgen[9] = {1,1,1,0,0,0,0,0,0}; /* Buses at which generators are incident */
114: PetscInt nofload[9] = {0,0,0,0,1,1,0,1,0}; /* Buses at which loads are incident */
115: const PetscScalar *varr;
116: PetscScalar M[3],D[3];
117: Bus *bus;
118: Branch *branch;
119: Gen *gen;
120: Exc *exc;
121: Load *load;
122: Mat Ybus;
123: Vec V0;
125: /*10 parameters*/
126: /* Generator real and reactive powers (found via loadflow) */
127: static const PetscScalar PG[3] = {0.716786142395021,1.630000000000000,0.850000000000000};
128: static const PetscScalar QG[3] = {0.270702180178785,0.066120127797275,-0.108402221791588};
130: /* Generator constants */
131: static const PetscScalar H[3] = {23.64,6.4,3.01}; /* Inertia constant */
132: static const PetscScalar Rs[3] = {0.0,0.0,0.0}; /* Stator Resistance */
133: static const PetscScalar Xd[3] = {0.146,0.8958,1.3125}; /* d-axis reactance */
134: static const PetscScalar Xdp[3] = {0.0608,0.1198,0.1813}; /* d-axis transient reactance */
135: static const PetscScalar Xq[3] = {0.4360,0.8645,1.2578}; /* q-axis reactance Xq(1) set to 0.4360, value given in text 0.0969 */
136: static const PetscScalar Xqp[3] = {0.0969,0.1969,0.25}; /* q-axis transient reactance */
137: static const PetscScalar Td0p[3] = {8.96,6.0,5.89}; /* d-axis open circuit time constant */
138: static const PetscScalar Tq0p[3] = {0.31,0.535,0.6}; /* q-axis open circuit time constant */
140: /* Exciter system constants (8 parameters)*/
141: static const PetscScalar KA[3] = {20.0,20.0,20.0}; /* Voltage regulartor gain constant */
142: static const PetscScalar TA[3] = {0.2,0.2,0.2}; /* Voltage regulator time constant */
143: static const PetscScalar KE[3] = {1.0,1.0,1.0}; /* Exciter gain constant */
144: static const PetscScalar TE[3] = {0.314,0.314,0.314}; /* Exciter time constant */
145: static const PetscScalar KF[3] = {0.063,0.063,0.063}; /* Feedback stabilizer gain constant */
146: static const PetscScalar TF[3] = {0.35,0.35,0.35}; /* Feedback stabilizer time constant */
147: static const PetscScalar k1[3] = {0.0039,0.0039,0.0039};
148: static const PetscScalar k2[3] = {1.555,1.555,1.555}; /* k1 and k2 for calculating the saturation function SE = k1*exp(k2*Efd) */
150: /* Load constants */
151: static const PetscScalar PD0[3] = {1.25,0.9,1.0};
152: static const PetscScalar QD0[3] = {0.5,0.3,0.35};
153: static const PetscScalar ld_alphaq[3] = {1,0,0};
154: static const PetscScalar ld_betaq[3] = {2,1,0};
155: static const PetscScalar ld_betap[3] = {2,1,0};
156: static const PetscScalar ld_alphap[3] = {1,0,0};
157: PetscInt ld_nsegsp[3] = {3,3,3};
158: PetscInt ld_nsegsq[3] = {3,3,3};
159: PetscViewer Xview,Ybusview;
160: PetscInt neqs_net,m,n;
163: /* Read V0 and Ybus from files */
164: PetscViewerBinaryOpen (PETSC_COMM_SELF ,"X.bin" ,FILE_MODE_READ ,&Xview);
165: PetscViewerBinaryOpen (PETSC_COMM_SELF ,"Ybus.bin" ,FILE_MODE_READ ,&Ybusview);
166: VecCreate (PETSC_COMM_SELF ,&V0);
167: VecLoad (V0,Xview);
169: MatCreate (PETSC_COMM_SELF ,&Ybus);
170: MatSetType (Ybus,MATBAIJ );
171: MatLoad (Ybus,Ybusview);
173: /* Destroy unnecessary stuff */
174: PetscViewerDestroy (&Xview);
175: PetscViewerDestroy (&Ybusview);
177: MatGetLocalSize (Ybus,&m,&n);
178: neqs_net = 2*NBUS; /* # eqs. for network subsystem */
179: if (m != neqs_net || n != neqs_net) SETERRQ (PETSC_COMM_SELF ,0,"matrix Ybus is in wrong sizes" );
181: M[0] = 2*H[0]/W_S;
182: M[1] = 2*H[1]/W_S;
183: M[2] = 2*H[2]/W_S;
184: D[0] = 0.1*M[0];
185: D[1] = 0.1*M[1];
186: D[2] = 0.1*M[2];
188: /* Alocate memory for bus, generators, exciter, loads and branches */
189: PetscCalloc5 (NBUS*nc,&bus,NGEN*nc,&gen,NLOAD*nc,&load,NBRANCH*nc+(nc-1),&branch,NGEN*nc,&exc);
191: VecGetArrayRead (V0,&varr);
193: /* read bus data */
194: for (i = 0; i < nc; i++) {
195: for (j = 0; j < NBUS; j++) {
196: bus[i*9+j].id = i*9+j;
197: bus[i*9+j].nofgen = nofgen[j];
198: bus[i*9+j].nofload = nofload[j];
199: bus[i*9+j].vr = varr[2*j];
200: bus[i*9+j].vi = varr[2*j+1];
201: row[0] = 2*j;
202: col[0] = 2*j;
203: col[1] = 2*j+1;
204: /* real and imaginary part of admittance from Ybus into yff */
205: MatGetValues (Ybus,1,row,2,col,bus[i*9+j].yff);
206: }
207: }
209: /* read generator data */
210: for (i = 0; i<nc; i++){
211: for (j = 0; j < NGEN; j++) {
212: gen[i*3+j].id = i*3+j;
213: gen[i*3+j].PG = PG[j];
214: gen[i*3+j].QG = QG[j];
215: gen[i*3+j].H = H[j];
216: gen[i*3+j].Rs = Rs[j];
217: gen[i*3+j].Xd = Xd[j];
218: gen[i*3+j].Xdp = Xdp[j];
219: gen[i*3+j].Xq = Xq[j];
220: gen[i*3+j].Xqp = Xqp[j];
221: gen[i*3+j].Td0p = Td0p[j];
222: gen[i*3+j].Tq0p = Tq0p[j];
223: gen[i*3+j].M = M[j];
224: gen[i*3+j].D = D[j];
225: }
226: }
228: for (i = 0; i < nc; i++) {
229: for (j = 0; j < NGEN; j++) {
230: /* exciter system */
231: exc[i*3+j].KA = KA[j];
232: exc[i*3+j].TA = TA[j];
233: exc[i*3+j].KE = KE[j];
234: exc[i*3+j].TE = TE[j];
235: exc[i*3+j].KF = KF[j];
236: exc[i*3+j].TF = TF[j];
237: exc[i*3+j].k1 = k1[j];
238: exc[i*3+j].k2 = k2[j];
239: }
240: }
242: /* read load data */
243: for (i = 0; i<nc; i++){
244: for (j = 0; j < NLOAD; j++) {
245: load[i*3+j].id = i*3+j;
246: load[i*3+j].PD0 = PD0[j];
247: load[i*3+j].QD0 = QD0[j];
248: load[i*3+j].ld_nsegsp = ld_nsegsp[j];
250: load[i*3+j].ld_alphap[0] = ld_alphap[0];
251: load[i*3+j].ld_alphap[1] = ld_alphap[1];
252: load[i*3+j].ld_alphap[2] = ld_alphap[2];
254: load[i*3+j].ld_alphaq[0] = ld_alphaq[0];
255: load[i*3+j].ld_alphaq[1] = ld_alphaq[1];
256: load[i*3+j].ld_alphaq[2] = ld_alphaq[2];
258: load[i*3+j].ld_betap[0] = ld_betap[0];
259: load[i*3+j].ld_betap[1] = ld_betap[1];
260: load[i*3+j].ld_betap[2] = ld_betap[2];
261: load[i*3+j].ld_nsegsq = ld_nsegsq[j];
263: load[i*3+j].ld_betaq[0] = ld_betaq[0];
264: load[i*3+j].ld_betaq[1] = ld_betaq[1];
265: load[i*3+j].ld_betaq[2] = ld_betaq[2];
266: }
267: }
268: PetscCalloc1 (2*NBRANCH*nc+2*(nc-1),&edgelist);
270: /* read edgelist */
271: for (i = 0; i<nc; i++){
272: for (j = 0; j < NBRANCH; j++) {
273: switch (j) {
274: case 0:
275: edgelist[i*18+2*j] = 0+9*i;
276: edgelist[i*18+2*j+1] = 3+9*i;
277: break ;
278: case 1:
279: edgelist[i*18+2*j] = 1+9*i;
280: edgelist[i*18+2*j+1] = 6+9*i;
281: break ;
282: case 2:
283: edgelist[i*18+2*j] = 2+9*i;
284: edgelist[i*18+2*j+1] = 8+9*i;
285: break ;
286: case 3:
287: edgelist[i*18+2*j] = 3+9*i;
288: edgelist[i*18+2*j+1] = 4+9*i;
289: break ;
290: case 4:
291: edgelist[i*18+2*j] = 3+9*i;
292: edgelist[i*18+2*j+1] = 5+9*i;
293: break ;
294: case 5:
295: edgelist[i*18+2*j] = 4+9*i;
296: edgelist[i*18+2*j+1] = 6+9*i;
297: break ;
298: case 6:
299: edgelist[i*18+2*j] = 5+9*i;
300: edgelist[i*18+2*j+1] = 8+9*i;
301: break ;
302: case 7:
303: edgelist[i*18+2*j] = 6+9*i;
304: edgelist[i*18+2*j+1] = 7+9*i;
305: break ;
306: case 8:
307: edgelist[i*18+2*j] = 7+9*i;
308: edgelist[i*18+2*j+1] = 8+9*i;
309: break ;
310: default:
311: break ;
312: }
313: }
314: }
316: /* for connecting last bus of previous network(9*i-1) to first bus of next network(9*i), the branch admittance=-0.0301407+j17.3611 */
317: for (i = 1; i<nc; i++){
318: edgelist[18*nc+2*(i-1)] = 8+(i-1)*9;
319: edgelist[18*nc+2*(i-1)+1] = 9*i;
321: /* adding admittances to the off-diagonal elements */
322: branch[9*nc+(i-1)].id = 9*nc+(i-1);
323: branch[9*nc+(i-1)].yft[0] = 17.3611;
324: branch[9*nc+(i-1)].yft[1] = -0.0301407;
326: /* subtracting admittances from the diagonal elements */
327: bus[9*i-1].yff[0] -= 17.3611;
328: bus[9*i-1].yff[1] -= -0.0301407;
330: bus[9*i].yff[0] -= 17.3611;
331: bus[9*i].yff[1] -= -0.0301407;
332: }
334: /* read branch data */
335: for (i = 0; i<nc; i++){
336: for (j = 0; j < NBRANCH; j++) {
337: branch[i*9+j].id = i*9+j;
339: row[0] = edgelist[2*j]*2;
340: col[0] = edgelist[2*j+1]*2;
341: col[1] = edgelist[2*j+1]*2+1;
342: MatGetValues (Ybus,1,row,2,col,branch[i*9+j].yft);/*imaginary part of admittance*/
343: }
344: }
346: *pgen = gen;
347: *pexc = exc;
348: *pload = load;
349: *pbus = bus;
350: *pbranch = branch;
351: *pedgelist = edgelist;
353: VecRestoreArrayRead (V0,&varr);
355: /* Destroy unnecessary stuff */
356: MatDestroy (&Ybus);
357: VecDestroy (&V0);
358: return (0);
359: }
361: PetscErrorCode SetInitialGuess(DM networkdm, Vec X)
362: {
364: Bus *bus;
365: Gen *gen;
366: Exc *exc;
367: PetscInt v,vStart,vEnd,offset;
368: PetscInt key,numComps,j;
369: PetscBool ghostvtex;
370: Vec localX;
371: PetscScalar *xarr;
372: PetscScalar Vr=0,Vi=0,Vm=0,Vm2; /* Terminal voltage variables */
373: PetscScalar IGr, IGi; /* Generator real and imaginary current */
374: PetscScalar Eqp,Edp,delta; /* Generator variables */
375: PetscScalar Efd=0,RF,VR; /* Exciter variables */
376: PetscScalar Vd,Vq; /* Generator dq axis voltages */
377: PetscScalar Id,Iq; /* Generator dq axis currents */
378: PetscScalar theta; /* Generator phase angle */
379: PetscScalar SE;
380: void* component;
383: DMNetworkGetVertexRange (networkdm,&vStart,&vEnd);
384: DMGetLocalVector (networkdm,&localX);
386: VecSet (X,0.0);
387: DMGlobalToLocalBegin (networkdm,X,INSERT_VALUES ,localX);
388: DMGlobalToLocalEnd (networkdm,X,INSERT_VALUES ,localX);
390: VecGetArray (localX,&xarr);
392: for (v = vStart; v < vEnd; v++) {
393: DMNetworkIsGhostVertex (networkdm,v,&ghostvtex);
394: if (ghostvtex) continue ;
396: DMNetworkGetNumComponents (networkdm,v,&numComps);
397: for (j=0; j < numComps; j++) {
398: DMNetworkGetComponent (networkdm,v,j,&key,&component);
399: if (key == 1) {
400: bus = (Bus*)(component);
402: DMNetworkGetComponentVariableOffset (networkdm,v,j,&offset);
403: xarr[offset] = bus->vr;
404: xarr[offset+1] = bus->vi;
406: Vr = bus->vr;
407: Vi = bus->vi;
408: } else if (key == 2) {
409: gen = (Gen*)(component);
410: DMNetworkGetComponentVariableOffset (networkdm,v,j,&offset);
411: Vm = PetscSqrtScalar(Vr*Vr + Vi*Vi);
412: Vm2 = Vm*Vm;
413: /* Real part of gen current */
414: IGr = (Vr*gen->PG + Vi*gen->QG)/Vm2;
415: /* Imaginary part of gen current */
416: IGi = (Vi*gen->PG - Vr*gen->QG)/Vm2;
418: /* Machine angle */
419: delta = atan2(Vi+gen->Xq*IGr,Vr-gen->Xq*IGi);
420: theta = PETSC_PI/2.0 - delta;
422: /* d-axis stator current */
423: Id = IGr*PetscCosScalar(theta) - IGi*PetscSinScalar(theta);
425: /* q-axis stator current */
426: Iq = IGr*PetscSinScalar(theta) + IGi*PetscCosScalar(theta);
428: Vd = Vr*PetscCosScalar(theta) - Vi*PetscSinScalar(theta);
429: Vq = Vr*PetscSinScalar(theta) + Vi*PetscCosScalar(theta);
431: /* d-axis transient EMF */
432: Edp = Vd + gen->Rs*Id - gen->Xqp*Iq;
434: /* q-axis transient EMF */
435: Eqp = Vq + gen->Rs*Iq + gen->Xdp*Id;
437: gen->TM = gen->PG;
439: xarr[offset] = Eqp;
440: xarr[offset+1] = Edp;
441: xarr[offset+2] = delta;
442: xarr[offset+3] = W_S;
443: xarr[offset+4] = Id;
444: xarr[offset+5] = Iq;
446: Efd = Eqp + (gen->Xd - gen->Xdp)*Id;
448: } else if (key == 3) {
449: exc = (Exc*)(component);
450: DMNetworkGetComponentVariableOffset (networkdm,v,j,&offset);
451:
452: SE = exc->k1*PetscExpScalar(exc->k2*Efd);
453: VR = exc->KE*Efd + SE;
454: RF = exc->KF*Efd/exc->TF;
456: xarr[offset] = Efd;
457: xarr[offset+1] = RF;
458: xarr[offset+2] = VR;
460: exc->Vref = Vm + (VR/exc->KA);
461: }
462: }
463: }
464: VecRestoreArray (localX,&xarr);
465: DMLocalToGlobalBegin (networkdm,localX,ADD_VALUES ,X);
466: DMLocalToGlobalEnd (networkdm,localX,ADD_VALUES ,X);
467: DMRestoreLocalVector (networkdm,&localX);
468: return (0);
469: }
471: /* Converts from machine frame (dq) to network (phase a real,imag) reference frame */
472: PetscErrorCode dq2ri(PetscScalar Fd,PetscScalar Fq,PetscScalar delta,PetscScalar *Fr,PetscScalar *Fi)
473: {
475: *Fr = Fd*PetscSinScalar(delta) + Fq*PetscCosScalar(delta);
476: *Fi = -Fd*PetscCosScalar(delta) + Fq*PetscSinScalar(delta);
477: return (0);
478: }
480: /* Converts from network frame ([phase a real,imag) to machine (dq) reference frame */
481: PetscErrorCode ri2dq(PetscScalar Fr,PetscScalar Fi,PetscScalar delta,PetscScalar *Fd,PetscScalar *Fq)
482: {
484: *Fd = Fr*PetscSinScalar(delta) - Fi*PetscCosScalar(delta);
485: *Fq = Fr*PetscCosScalar(delta) + Fi*PetscSinScalar(delta);
486: return (0);
487: }
489: /* Computes F(t,U,U_t) where F() = 0 is the DAE to be solved. */
490: PetscErrorCode FormIFunction(TS ts,PetscReal t,Vec X,Vec Xdot,Vec F,Userctx *user)
491: {
492: PetscErrorCode ierr;
493: DM networkdm;
494: Vec localX,localXdot,localF;
495: PetscInt vfrom,vto,offsetfrom,offsetto;
496: PetscInt v,vStart,vEnd,e;
497: PetscScalar *farr;
498: PetscScalar Vd,Vq,SE;
499: const PetscScalar *xarr,*xdotarr;
500: void* component;
501: PetscScalar Vr=0, Vi=0;
504: VecSet (F,0.0);
506: TSGetDM (ts,&networkdm);
507: DMGetLocalVector (networkdm,&localF);
508: DMGetLocalVector (networkdm,&localX);
509: DMGetLocalVector (networkdm,&localXdot);
510: VecSet (localF,0.0);
512: /* update ghost values of localX and localXdot */
513: DMGlobalToLocalBegin (networkdm,X,INSERT_VALUES ,localX);
514: DMGlobalToLocalEnd (networkdm,X,INSERT_VALUES ,localX);
516: DMGlobalToLocalBegin (networkdm,Xdot,INSERT_VALUES ,localXdot);
517: DMGlobalToLocalEnd (networkdm,Xdot,INSERT_VALUES ,localXdot);
519: VecGetArrayRead (localX,&xarr);
520: VecGetArrayRead (localXdot,&xdotarr);
521: VecGetArray (localF,&farr);
523: DMNetworkGetVertexRange (networkdm,&vStart,&vEnd);
525: for (v=vStart; v < vEnd; v++) {
526: PetscInt i,j,offsetbus,offsetgen,offsetexc,key;
527: Bus *bus;
528: Gen *gen;
529: Exc *exc;
530: Load *load;
531: PetscBool ghostvtex;
532: PetscInt numComps;
533: PetscScalar Yffr,Yffi; /* Real and imaginary fault admittances */
534: PetscScalar Vm,Vm2,Vm0;
535: PetscScalar Vr0=0,Vi0=0;
536: PetscScalar PD,QD;
538: DMNetworkIsGhostVertex (networkdm,v,&ghostvtex);
539: DMNetworkGetNumComponents (networkdm,v,&numComps);
541: for (j = 0; j < numComps; j++) {
542: DMNetworkGetComponent (networkdm,v,j,&key,&component);
543: if (key == 1) {
544: PetscInt nconnedges;
545: const PetscInt *connedges;
547: bus = (Bus*)(component);
548: DMNetworkGetComponentVariableOffset (networkdm,v,j,&offsetbus);
549: if (!ghostvtex) {
550: Vr = xarr[offsetbus];
551: Vi = xarr[offsetbus+1];
553: Yffr = bus->yff[1];
554: Yffi = bus->yff[0];
556: if (user->alg_flg){
557: Yffr += user->ybusfault[bus->id*2+1];
558: Yffi += user->ybusfault[bus->id*2];
559: }
560: Vr0 = bus->vr;
561: Vi0 = bus->vi;
563: /* Network current balance residual IG + Y*V + IL = 0. Only YV is added here.
564: The generator current injection, IG, and load current injection, ID are added later
565: */
566: farr[offsetbus] += Yffi*Vr + Yffr*Vi; /* imaginary current due to diagonal elements */
567: farr[offsetbus+1] += Yffr*Vr - Yffi*Vi; /* real current due to diagonal elements */
568: }
570: DMNetworkGetSupportingEdges (networkdm,v,&nconnedges,&connedges);
572: for (i=0; i < nconnedges; i++) {
573: Branch *branch;
574: PetscInt keye;
575: PetscScalar Yfti, Yftr, Vfr, Vfi, Vtr, Vti;
576: const PetscInt *cone;
578: e = connedges[i];
579: DMNetworkGetComponent (networkdm,e,0,&keye,(void**)&branch);
581: Yfti = branch->yft[0];
582: Yftr = branch->yft[1];
584: DMNetworkGetConnectedVertices (networkdm,e,&cone);
586: vfrom = cone[0];
587: vto = cone[1];
589: DMNetworkGetComponentVariableOffset (networkdm,vfrom,0,&offsetfrom);
590: DMNetworkGetComponentVariableOffset (networkdm,vto,0,&offsetto);
592: /* From bus and to bus real and imaginary voltages */
593: Vfr = xarr[offsetfrom];
594: Vfi = xarr[offsetfrom+1];
595: Vtr = xarr[offsetto];
596: Vti = xarr[offsetto+1];
598: if (vfrom == v) {
599: farr[offsetfrom] += Yftr*Vti + Yfti*Vtr;
600: farr[offsetfrom+1] += Yftr*Vtr - Yfti*Vti;
601: } else {
602: farr[offsetto] += Yftr*Vfi + Yfti*Vfr;
603: farr[offsetto+1] += Yftr*Vfr - Yfti*Vfi;
604: }
605: }
606: } else if (key == 2){
607: if (!ghostvtex) {
608: PetscScalar Eqp,Edp,delta,w; /* Generator variables */
609: PetscScalar Efd; /* Exciter field voltage */
610: PetscScalar Id,Iq; /* Generator dq axis currents */
611: PetscScalar IGr,IGi,Zdq_inv[4],det;
612: PetscScalar Xd,Xdp,Td0p,Xq,Xqp,Tq0p,TM,D,M,Rs; /* Generator parameters */
614: gen = (Gen*)(component);
615: DMNetworkGetComponentVariableOffset (networkdm,v,j,&offsetgen);
617: /* Generator state variables */
618: Eqp = xarr[offsetgen];
619: Edp = xarr[offsetgen+1];
620: delta = xarr[offsetgen+2];
621: w = xarr[offsetgen+3];
622: Id = xarr[offsetgen+4];
623: Iq = xarr[offsetgen+5];
625: /* Generator parameters */
626: Xd = gen->Xd;
627: Xdp = gen->Xdp;
628: Td0p = gen->Td0p;
629: Xq = gen->Xq;
630: Xqp = gen->Xqp;
631: Tq0p = gen->Tq0p;
632: TM = gen->TM;
633: D = gen->D;
634: M = gen->M;
635: Rs = gen->Rs;
637: DMNetworkGetComponentVariableOffset (networkdm,v,2,&offsetexc);
638: Efd = xarr[offsetexc];
640: /* Generator differential equations */
641: farr[offsetgen] = (Eqp + (Xd - Xdp)*Id - Efd)/Td0p + xdotarr[offsetgen];
642: farr[offsetgen+1] = (Edp - (Xq - Xqp)*Iq)/Tq0p + xdotarr[offsetgen+1];
643: farr[offsetgen+2] = -w + W_S + xdotarr[offsetgen+2];
644: farr[offsetgen+3] = (-TM + Edp*Id + Eqp*Iq + (Xqp - Xdp)*Id*Iq + D*(w - W_S))/M + xdotarr[offsetgen+3];
646: ri2dq(Vr,Vi,delta,&Vd,&Vq);
648: /* Algebraic equations for stator currents */
649: det = Rs*Rs + Xdp*Xqp;
651: Zdq_inv[0] = Rs/det;
652: Zdq_inv[1] = Xqp/det;
653: Zdq_inv[2] = -Xdp/det;
654: Zdq_inv[3] = Rs/det;
656: farr[offsetgen+4] = Zdq_inv[0]*(-Edp + Vd) + Zdq_inv[1]*(-Eqp + Vq) + Id;
657: farr[offsetgen+5] = Zdq_inv[2]*(-Edp + Vd) + Zdq_inv[3]*(-Eqp + Vq) + Iq;
659: dq2ri(Id,Iq,delta,&IGr,&IGi);
661: /* Add generator current injection to network */
662: farr[offsetbus] -= IGi;
663: farr[offsetbus+1] -= IGr;
665: }
666: } else if (key == 3) {
667: if (!ghostvtex) {
668: PetscScalar k1,k2,KE,TE,TF,KA,KF,Vref,TA; /* Generator parameters */
669: PetscScalar Efd,RF,VR; /* Exciter variables */
670:
671: exc = (Exc*)(component);
672: DMNetworkGetComponentVariableOffset (networkdm,v,j,&offsetexc);
674: Efd = xarr[offsetexc];
675: RF = xarr[offsetexc+1];
676: VR = xarr[offsetexc+2];
678: k1 = exc->k1;
679: k2 = exc->k2;
680: KE = exc->KE;
681: TE = exc->TE;
682: TF = exc->TF;
683: KA = exc->KA;
684: KF = exc->KF;
685: Vref = exc->Vref;
686: TA = exc->TA;
688: Vm = PetscSqrtScalar(Vd*Vd + Vq*Vq);
689: SE = k1*PetscExpScalar(k2*Efd);
691: /* Exciter differential equations */
692: farr[offsetexc] = (KE*Efd + SE - VR)/TE + xdotarr[offsetexc];
693: farr[offsetexc+1] = (RF - KF*Efd/TF)/TF + xdotarr[offsetexc+1];
694: farr[offsetexc+2] = (VR - KA*RF + KA*KF*Efd/TF - KA*(Vref - Vm))/TA + xdotarr[offsetexc+2];
695:
696: }
697: } else if (key ==4){
698: if (!ghostvtex) {
699: PetscInt k;
700: PetscInt ld_nsegsp;
701: PetscInt ld_nsegsq;
702: PetscScalar *ld_alphap;
703: PetscScalar *ld_betap,*ld_alphaq,*ld_betaq,PD0, QD0, IDr,IDi;
705: load = (Load*)(component);
707: /* Load Parameters */
708: ld_nsegsp = load->ld_nsegsp;
709: ld_alphap = load->ld_alphap;
710: ld_betap = load->ld_betap;
711: ld_nsegsq = load->ld_nsegsq;
712: ld_alphaq = load->ld_alphaq;
713: ld_betaq = load->ld_betaq;
714: PD0 = load->PD0;
715: QD0 = load->QD0;
717: Vr = xarr[offsetbus]; /* Real part of generator terminal voltage */
718: Vi = xarr[offsetbus+1]; /* Imaginary part of the generator terminal voltage */
719: Vm = PetscSqrtScalar(Vr*Vr + Vi*Vi);
720: Vm2 = Vm*Vm;
721: Vm0 = PetscSqrtScalar(Vr0*Vr0 + Vi0*Vi0);
722: PD = QD = 0.0;
723: for (k=0; k < ld_nsegsp; k++) PD += ld_alphap[k]*PD0*PetscPowScalar((Vm/Vm0),ld_betap[k]);
724: for (k=0; k < ld_nsegsq; k++) QD += ld_alphaq[k]*QD0*PetscPowScalar((Vm/Vm0),ld_betaq[k]);
726: /* Load currents */
727: IDr = (PD*Vr + QD*Vi)/Vm2;
728: IDi = (-QD*Vr + PD*Vi)/Vm2;
730: /* Load current contribution to the network */
731: farr[offsetbus] += IDi;
732: farr[offsetbus+1] += IDr;
733: }
734: }
735: }
736: }
738: VecRestoreArrayRead (localX,&xarr);
739: VecRestoreArrayRead (localXdot,&xdotarr);
740: VecRestoreArray (localF,&farr);
741: DMRestoreLocalVector (networkdm,&localX);
742: DMRestoreLocalVector (networkdm,&localXdot);
744: DMLocalToGlobalBegin (networkdm,localF,ADD_VALUES ,F);
745: DMLocalToGlobalEnd (networkdm,localF,ADD_VALUES ,F);
746: DMRestoreLocalVector (networkdm,&localF);
747: return (0);
748: }
750: /* This function is used for solving the algebraic system only during fault on and
751: off times. It computes the entire F and then zeros out the part corresponding to
752: differential equations
753: F = [0;g(y)];
754: */
755: PetscErrorCode AlgFunction (SNES snes, Vec X, Vec F, void *ctx)
756: {
758: DM networkdm;
759: Vec localX,localF;
760: PetscInt vfrom,vto,offsetfrom,offsetto;
761: PetscInt v,vStart,vEnd,e;
762: PetscScalar *farr;
763: Userctx *user=(Userctx*)ctx;
764: const PetscScalar *xarr;
765: void* component;
766: PetscScalar Vr=0,Vi=0;
769: VecSet (F,0.0);
770: SNESGetDM (snes,&networkdm);
771: DMGetLocalVector (networkdm,&localF);
772: DMGetLocalVector (networkdm,&localX);
773: VecSet (localF,0.0);
775: /* update ghost values of locaX and locaXdot */
776: DMGlobalToLocalBegin (networkdm,X,INSERT_VALUES ,localX);
777: DMGlobalToLocalEnd (networkdm,X,INSERT_VALUES ,localX);
779: VecGetArrayRead (localX,&xarr);
780: VecGetArray (localF,&farr);
782: DMNetworkGetVertexRange (networkdm,&vStart,&vEnd);
784: for (v=vStart; v < vEnd; v++) {
785: PetscInt i,j,offsetbus,offsetgen,key,numComps;
786: PetscScalar Yffr, Yffi, Vm, Vm2, Vm0, Vr0=0, Vi0=0, PD, QD;
787: Bus *bus;
788: Gen *gen;
789: Load *load;
790: PetscBool ghostvtex;
792: DMNetworkIsGhostVertex (networkdm,v,&ghostvtex);
793: DMNetworkGetNumComponents (networkdm,v,&numComps);
795: for (j = 0; j < numComps; j++) {
796: DMNetworkGetComponent (networkdm,v,j,&key,&component);
797: if (key == 1) {
798: PetscInt nconnedges;
799: const PetscInt *connedges;
801: bus = (Bus*)(component);
802: DMNetworkGetComponentVariableOffset (networkdm,v,j,&offsetbus);
803: if (!ghostvtex) {
804: Vr = xarr[offsetbus];
805: Vi = xarr[offsetbus+1];
807: Yffr = bus->yff[1];
808: Yffi = bus->yff[0];
809: if (user->alg_flg){
810: Yffr += user->ybusfault[bus->id*2+1];
811: Yffi += user->ybusfault[bus->id*2];
812: }
813: Vr0 = bus->vr;
814: Vi0 = bus->vi;
816: farr[offsetbus] += Yffi*Vr + Yffr*Vi;
817: farr[offsetbus+1] += Yffr*Vr - Yffi*Vi;
818: }
819: DMNetworkGetSupportingEdges (networkdm,v,&nconnedges,&connedges);
821: for (i=0; i < nconnedges; i++) {
822: Branch *branch;
823: PetscInt keye;
824: PetscScalar Yfti, Yftr, Vfr, Vfi, Vtr, Vti;
825: const PetscInt *cone;
827: e = connedges[i];
828: DMNetworkGetComponent (networkdm,e,0,&keye,(void**)&branch);
830: Yfti = branch->yft[0];
831: Yftr = branch->yft[1];
833: DMNetworkGetConnectedVertices (networkdm,e,&cone);
834: vfrom = cone[0];
835: vto = cone[1];
837: DMNetworkGetComponentVariableOffset (networkdm,vfrom,0,&offsetfrom);
838: DMNetworkGetComponentVariableOffset (networkdm,vto,0,&offsetto);
line841">841: Vfr = xarr[offse
line842">842: Vfi = xarr[offsetf
line843">843: Vtr = xarr[off
line844">844: Vti = xarr[offse
line846">846: if (vfrom
line847">847: farr[offsetfrom] += Yftr*Vti + Yf
line848">848: farr[offsetfrom+1] += Yftr*Vtr - Yf
line849">849: } else
line850">850: farr[offsetto] += Yftr*Vfi + Yf
line851">851: farr[offsetto+1] += Yftr*Vfr - Yf
line852">852:
line853">853:
line854">854: } else if (key
line855">855: if (!ghost
/* Generator variables */
/* Generator dq axis currents */
line858">858: PetscScalar Vd,Vq,IGr,IGi,Zdq_inv[
/* Generator parameters */
line861">861: gen = (Gen*)(comp
line862">862: DMNetworkGetComponentVariableOffset (networkdm,v,j,&offs
/* Generator state variables */
line865">865: Eqp = xarr[offs
line866">866: Edp = xarr[offset
line867">867: delta = xarr[offset
/* w = xarr[idx+3]; not being used */
line869">869: Id = xarr[offset
line870">870: Iq = xarr[offset
/* Generator parameters */
line873">873: Xdp = gen-&
line874">874: Xqp = gen-&
line875">875: Rs = gen-
/* Set generator differential equation residual functions to zero */
line878">878: farr[offsetgen]
line879">879: farr[offsetgen+
line880">880: farr[offsetgen+
line881">881: farr[offsetgen+
line883">883: ri2dq(Vr,Vi,delta,&Vd,&a
/* Algebraic equations for stator currents */
line886">886: det = Rs*Rs + X
line888">888: Zdq_inv[0] =
line889">889: Zdq_inv[1] = X
line890">890: Zdq_inv[2] = -X
line891">891: Zdq_inv[3] =
line893">893: farr[offsetgen+4] = Zdq_inv[0]*(-Edp + Vd) + Zdq_inv[1]*(-Eqp + Vq
line894">894: farr[offsetgen+5] = Zdq_inv[2]*(-Edp + Vd) + Zdq_inv[3]*(-Eqp + Vq
/* Add generator current injection to network */
line897">897: dq2ri(Id,Iq,delta,&IGr,&am
line899">899: farr[offsetbus]
line900">900: farr[offsetbus+1]
/* Vm = PetscSqrtScalar(Vd*Vd + Vq*Vq);*/ /* a compiler warning: "Value stored to 'Vm' is never read" - comment out by Hong Zhang */
line904">904:
line905">905: } else if (key
line906">906: if (!ghost
line907">907: PetscInt off
line908">908: DMNetworkGetComponentVariableOffset (networkdm,v,j,&offs
/* Set exciter differential equation residual functions equal to zero*/
line910">910: farr[offsetex
line911">911: farr[offsetexc+
line912">912: farr[offsetexc+
line913">913:
line914">914: } else if (key
line915">915: if (!ghost
line916">916: PetscInt k,ld_nsegsp,ld_
line917">917: PetscScalar *ld_alphap,*ld_betap,*ld_alphaq,*ld_betaq,PD0,QD0,I
line919">919: load = (Load*)(comp
/* Load Parameters */
line922">922: ld_nsegsp = load->ld_
line923">923: ld_alphap = load->ld_
line924">924: ld_betap = load->ld
line925">925: ld_nsegsq = load->ld_
line926">926: ld_alphaq = load->ld_
line927">927: ld_betaq = load->ld
line929">929: PD0 = load-&
line930">930: QD0 = load-&
line932">932: Vm = PetscSqrtScalar(Vr*Vr +
line933">933: Vm2 =
line934">934: Vm0 = PetscSqrtScalar(Vr0*Vr0 + Vi
line935">935: PD = QD
line936">936: for (k=0; k < ld_nsegsp; k++) PD += ld_alphap[k]*PD0*PetscPowScalar((Vm/Vm0),ld_bet
line937">937: for (k=0; k < ld_nsegsq; k++) QD += ld_alphaq[k]*QD0*PetscPowScalar((Vm/Vm0),ld_bet
/* Load currents */
line940">940: IDr = (PD*Vr + QD*V
line941">941: IDi = (-QD*Vr + PD*V
line943">943: farr[offsetbus]
line944">944: farr[offsetbus+1]
line945">945:
line946">946:
line947">947:
line948">948:
line950">950: VecRestoreArrayRead (localX,&
line951">951: VecRestoreArray (localF,&
line952">952: DMRestoreLocalVector (networkdm,&l
line954">954: DMLocalToGlobalBegin (networkdm,localF,ADD_VALUES<
line955">955: DMLocalToGlobalEnd (networkdm,localF,ADD_VALUES<
line956">956: DMRestoreLocalVector (networkdm,&l
line957">957: return
line958">958
line960">960: int main(int argc,char ** argv)
line961">961
line963">963: PetscInt i,j,*edgelist= NULL,eStart,eEnd,vStar
line964">964: PetscInt genj,excj,loadj,component
/* No. of copies (default = 1) */
line966">966: PetscMPIInt siz
line967">967: Vec X
line968">968: TS
line969">969: SNES snes_al
line970">970: Bus
line971">971: Branch *
line972">972: Gen
line973">973: Exc
line974">974: Load
line975">975: DM net
line976">976: PetscLogStage
line977">977: Userctx
line978">978: KSP
line979">979: PC
line980">980: PetscInt numEdges=0,numVert
line982">982: PetscInitialize (&argc,&argv,"ex9busnetworkops" ,help);if (ierr) return
line983">983: PetscOptionsGetInt (NULL,NULL,"-nc" ,&nc
line984">984: MPI_Comm_size (PETSC_COMM_WORLD ,&
line985">985: MPI_Comm_rank (PETSC_COMM_WORLD ,&
/* Read initial voltage vector and Ybus */
line988">988: if (!
line989">989: read_data(nc,&gen,&exc,&load,&bus,&branch,&edg
line990">990:
line992">992: DMNetworkCreate (PETSC_COMM_WORLD ,&netw
line993">993: DMNetworkRegisterComponent (networkdm,"branchstruct" ,sizeof (Branch),&componentk
line994">994: DMNetworkRegisterComponent (networkdm,"busstruct" ,sizeof (Bus),&componentk
line995">995: DMNetworkRegisterComponent (networkdm,"genstruct" ,sizeof (Gen),&componentk
line996">996: DMNetworkRegisterComponent (networkdm,"excstruct" ,sizeof (Exc),&componentk
line997">997: DMNetworkRegisterComponent (networkdm,"loadstruct" ,sizeof (Load),&componentk
line999">999: PetscLogStageRegister ("Create network" ,&s
line1000">1000: PetscLogStagePush (s
/* Set local number of nodes and edges */
line1003">1003: if (
line1004">1004: numVertices = NBUS*nc; numEdges = NBRANCH*nc+
line1005">1005:
line1006">1006: DMNetworkSetSizes (networkdm,1,&numVertices,&numEdges,0
/* Add edge connectivity */
line1009">1009: DMNetworkSetEdgeList (networkdm,&edgelist
/* Set up the network layout */
line1012">1012: DMNetworkLayoutSetUp (netw
line1014">1014: if (!
line1015">1015: PetscFree (edg
line1016">1016:
/* Add network components: physical parameters of nodes and branches */
line1019">1019: if (!
line1020">1020: DMNetworkGetEdgeRange (networkdm,&eStart,&
line1021">1021: genj=0; loadj=0;
line1022">1022: for (i = eStart; i < eEnd;
line1023">1023: DMNetworkAddComponent (networkdm,i,componentkey[0],&branch[i-eS
line1024">1024:
line1026">1026: DMNetworkGetVertexRange (networkdm,&vStart,&
line1028">1028: for (i = vStart; i < vEnd;
line1029">1029: DMNetworkAddComponent (networkdm,i,componentkey[1],&bus[i-vS
/* Add number of variables */
line1031">1031: DMNetworkSetComponentNumVariables (networkdm,
line1032">1032: if (bus[i-vStart].no
line1033">1033: for (j = 0; j < bus[i-vStart].nofgen;
/* Add generator */
line1035">1035: DMNetworkAddComponent (networkdm,i,componentkey[2],&gen[ge
line1036">1036: DMNetworkSetComponentNumVariables (networkdm,
/* Add exciter */
line1038">1038: DMNetworkAddComponent (networkdm,i,componentkey[3],&exc[ex
line1039">1039: DMNetworkSetComponentNumVariables (networkdm,
line1040">1040:
line1041">1041:
line1042">1042: if (bus[i-vStart].nof
line1043">1043: for (j=0; j < bus[i-vStart].nofload;
line1044">1044: DMNetworkAddComponent (networkdm,i,componentkey[4],&load[loa
line1045">1045:
line1046">1046:
line1047">1047:
line1048">1048:
line1050">1050: DMSetUp (netw
line1052">1052: if (!
line1053">1053: PetscFree5 (bus,gen,load,branc
line1054">1054:
/* for parallel options: Network partitioning and distribution of data */
line1057">1057: if (size &g
line1058">1058: DMNetworkDistribute (&networ
line1059">1059:
line1060">1060: PetscLogStagePop
line1062">1062: DMCreateGlobalVector (networkdm,&
line1064">1064: SetInitialGuess(networ
/* Options for fault simulation */
line1067">1067: PetscOptionsBegin (PETSC_COMM_WORLD ,NULL,"Transient stability fault options" ,""
line1068">1068: user.tfaulton
line1069">1069: user.tfaultoff
line1070">1070: user.Rfault =
line1071">1071: user.faultbu
line1072">1072: PetscOptionsReal ("-tfaulton" ,"" ,"" ,user.tfaulton,&user.tfaulton
line1073">1073: PetscOptionsReal ("-tfaultoff" ,"" ,"" ,user.tfaultoff,&user.tfaultoff
line1074">1074: PetscOptionsInt ("-faultbus" ,"" ,"" ,user.faultbus,&user.faultbus
line1075">1075: user.t0
line1076">1076: user.tmax
line1077">1077: PetscOptionsReal ("-t0" ,"" ,"" ,user.t0,&user.t0
line1078">1078: PetscOptionsReal ("-tmax" ,"" ,"" ,user.tmax,&user.tmax
line1080">1080: PetscMalloc1 (18*nc,&user.ybus
line1081">1081: for (i = 0; i < 18*nc;
line1082">1082: user.ybusfault[
line1083">1083:
line1084">1084: user.ybusfault[user.faultbus*2+1] = 1/user.
line1085">1085: PetscOptionsEnd
/* Setup TS solver */
/*--------------------------------------------------------*/
line1089">1089: TSCreate (PETSC_COMM_WORLD ,&a
line1090">1090: TSSetDM (ts,(DM )netw
line1091">1091: TSSetType (ts,TSC
line1093">1093: TSGetSNES (ts,&
line1094">1094: SNESGetKSP (snes,&am
line1095">1095: KSPGetPC (ksp,&a
line1096">1096: PCSetType (pc,PCBJACOB
line1098">1098: TSSetIFunction (ts,NULL,(TSIFunction) FormIFunction,&
line1099">1099: TSSetMaxTime (ts,user.tfa
line1100">1100: TSSetExactFinalTime (ts,TS_EXACTFINALTIME_STEPOVE
line1101">1101: TSSetTimeStep (ts
line1102">1102: TSSetFromOptions
/*user.alg_flg = PETSC_TRUE is the period when fault exists. We add fault admittance to Ybus matrix.
eg, fault bus is 8. Y88(new)=Y88(old)+Yfault. */
line1106">1106: user.alg_flg = PETSC_FAL
/* Prefault period */
line1109">1109: if (!
line1110">1110: PetscPrintf (PETSC_COMM_SELF ,"... (1) Prefault period ... \n"
line1111">1111:
line1113">1113: TSSetSolution
line1114">1114: TSSetUp
line1115">1115: TSSolve
/* Create the nonlinear solver for solving the algebraic system */
line1118">1118: VecDuplicate (X,&
line1120">1120: SNESCreate (PETSC_COMM_WORLD ,&sne
line1121">1121: SNESSetDM (snes_alg,(DM )netw
line1122">1122: SNESSetFunction (snes_alg,F_alg,AlgFunction,&
line1123">1123: SNESSetOptionsPrefix (snes_alg,"alg_"
line1124">1124: SNESSetFromOptions (sne
/* Apply disturbance - resistive fault at user.faultbus */
/* This is done by adding shunt conductance to the diagonal location
in the Ybus matrix */
line1129">1129: user.alg_flg = PETSC_TR
/* Solve the algebraic equations */
line1132">1132: if (!
line1133">1133: PetscPrintf (PETSC_COMM_SELF ,"\n... (2) Apply disturbance, solve algebraic equations ... \n"
line1134">1134:
line1135">1135: SNESSolve (snes_alg,N
/* Disturbance period */
line1138">1138: TSSetTime (ts,user.tfa
line1139">1139: TSSetMaxTime (ts,user.tfau
line1140">1140: TSSetExactFinalTime (ts,TS_EXACTFINALTIME_STEPOVE
line1141">1141: TSSetIFunction (ts,NULL,(TSIFunction) FormIFunction,&
line1143">1143: user.alg_flg = PETSC_TR
line1144">1144: if (!
line1145">1145: PetscPrintf (PETSC_COMM_SELF ,"\n... (3) Disturbance period ... \n"
line1146">1146:
line1147">1147: TSSolve
/* Remove the fault */
line1150">1150: SNESSetFunction (snes_alg,F_alg,AlgFunction,&
line1152">1152: user.alg_flg = PETSC_FAL
/* Solve the algebraic equations */
line1154">1154: if (!
line1155">1155: PetscPrintf (PETSC_COMM_SELF ,"\n... (4) Remove fault, solve algebraic equations ... \n"
line1156">1156:
line1157">1157: SNESSolve (snes_alg,N
line1158">1158: SNESDestroy (&sne
/* Post-disturbance period */
line1161">1161: TSSetTime (ts,user.tfau
line1162">1162: TSSetMaxTime (ts,user
line1163">1163: TSSetExactFinalTime (ts,TS_EXACTFINALTIME_STEPOVE
line1164">1164: TSSetIFunction (ts,NULL,(TSIFunction) FormIFunction,&
line1166">1166: user.alg_flg = PETSC_FAL
line1167">1167: if (!
line1168">1168: PetscPrintf (PETSC_COMM_SELF ,"\n... (5) Post-disturbance period ... \n"
line1169">1169:
line1170">1170: TSSolve
line1172">1172: PetscFree (user.ybus
line1173">1173: VecDestroy (&
line1174">1174: VecDestroy (&
line1175">1175: DMDestroy (&netw
line1176">1176: TSDestroy (&a
line1177">1177: PetscFinalize
line1178">1178: return
line1179">1179:
/*TEST
build:
requires: double !complex !define(PETSC_USE_64BIT_INDICES)
test:
args: -ts_monitor -snes_converged_reason -alg_snes_converged_reason
localrunfiles: X.bin Ybus.bin ex9busnetworkops
test:
suffix: 2
nsize: 2
args: -ts_monitor -snes_converged_reason -alg_snes_converged_reason
localrunfiles: X.bin Ybus.bin ex9busnetworkops
TEST*/