Actual source code: ex1.c
petsc-3.7.5 2017-01-01
2: static char help[] = "Basic equation for generator stability analysis.\n";
\begin{eqnarray}
\frac{2 H}{\omega_s}\frac{d \omega}{dt} & = & P_m - \frac{EV}{X} \sin(\theta) \\
\frac{d \theta}{dt} = \omega - \omega_s
\end{eqnarray}
13: /*
14: Include "petscts.h" so that we can use TS solvers. Note that this
15: file automatically includes:
16: petscsys.h - base PETSc routines petscvec.h - vectors
17: petscmat.h - matrices
18: petscis.h - index sets petscksp.h - Krylov subspace methods
19: petscviewer.h - viewers petscpc.h - preconditioners
20: petscksp.h - linear solvers
21: */
22: #include <petscts.h>
24: typedef struct {
25: PetscScalar H,omega_s,E,V,X;
26: PetscRandom rand;
27: } AppCtx;
31: /*
32: Defines the ODE passed to the ODE solver
33: */
34: static PetscErrorCode IFunction(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,AppCtx *ctx)
35: {
36: PetscErrorCode ierr;
37: PetscScalar *f,r;
38: const PetscScalar *u,*udot;
39: static PetscScalar R = .4;
42: PetscRandomGetValue(ctx->rand,&r);
43: if (r > .9) R = .5;
44: if (r < .1) R = .4;
45: R = .4;
46: /* The next three lines allow us to access the entries of the vectors directly */
47: VecGetArrayRead(U,&u);
48: VecGetArrayRead(Udot,&udot);
49: VecGetArray(F,&f);
50: f[0] = 2.0*ctx->H*udot[0]/ctx->omega_s + ctx->E*ctx->V*PetscSinScalar(u[1])/ctx->X - R;
51: f[1] = udot[1] - u[0] + ctx->omega_s;
53: VecRestoreArrayRead(U,&u);
54: VecRestoreArrayRead(Udot,&udot);
55: VecRestoreArray(F,&f);
56: return(0);
57: }
61: /*
62: Defines the Jacobian of the ODE passed to the ODE solver. See TSSetIJacobian() for the meaning of a and the Jacobian.
63: */
64: static PetscErrorCode IJacobian(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal a,Mat A,Mat B,AppCtx *ctx)
65: {
66: PetscErrorCode ierr;
67: PetscInt rowcol[] = {0,1};
68: PetscScalar J[2][2];
69: const PetscScalar *u,*udot;
72: VecGetArrayRead(U,&u);
73: VecGetArrayRead(Udot,&udot);
74: J[0][0] = 2.0*ctx->H*a/ctx->omega_s; J[0][1] = -ctx->E*ctx->V*PetscCosScalar(u[1])/ctx->X;
75: J[1][0] = -1.0; J[1][1] = a;
76: MatSetValues(B,2,rowcol,2,rowcol,&J[0][0],INSERT_VALUES);
77: VecRestoreArrayRead(U,&u);
78: VecRestoreArrayRead(Udot,&udot);
80: MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
81: MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
82: if (A != B) {
83: MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
84: MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
85: }
86: return(0);
87: }
91: int main(int argc,char **argv)
92: {
93: TS ts; /* ODE integrator */
94: Vec U; /* solution will be stored here */
95: Mat A; /* Jacobian matrix */
97: PetscMPIInt size;
98: PetscInt n = 2;
99: AppCtx ctx;
100: PetscScalar *u;
102: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
103: Initialize program
104: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
105: PetscInitialize(&argc,&argv,(char*)0,help);
106: MPI_Comm_size(PETSC_COMM_WORLD,&size);
107: if (size > 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Only for sequential runs");
109: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
110: Create necessary matrix and vectors
111: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
112: MatCreate(PETSC_COMM_WORLD,&A);
113: MatSetSizes(A,n,n,PETSC_DETERMINE,PETSC_DETERMINE);
114: MatSetFromOptions(A);
115: MatSetUp(A);
117: MatCreateVecs(A,&U,NULL);
119: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
120: Set runtime options
121: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
122: PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Reaction options","");
123: {
124: ctx.omega_s = 1.0;
125: PetscOptionsScalar("-omega_s","","",ctx.omega_s,&ctx.omega_s,NULL);
126: ctx.H = 1.0;
127: PetscOptionsScalar("-H","","",ctx.H,&ctx.H,NULL);
128: ctx.E = 1.0;
129: PetscOptionsScalar("-E","","",ctx.E,&ctx.E,NULL);
130: ctx.V = 1.0;
131: PetscOptionsScalar("-V","","",ctx.V,&ctx.V,NULL);
132: ctx.X = 1.0;
133: PetscOptionsScalar("-X","","",ctx.X,&ctx.X,NULL);
135: VecGetArray(U,&u);
136: u[0] = 1;
137: u[1] = .7;
138: VecRestoreArray(U,&u);
139: PetscOptionsGetVec(NULL,NULL,"-initial",U,NULL);
140: }
141: PetscOptionsEnd();
143: PetscRandomCreate(PETSC_COMM_WORLD,&ctx.rand);
144: PetscRandomSetFromOptions(ctx.rand);
146: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
147: Create timestepping solver context
148: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
149: TSCreate(PETSC_COMM_WORLD,&ts);
150: TSSetProblemType(ts,TS_NONLINEAR);
151: TSSetType(ts,TSROSW);
152: TSSetIFunction(ts,NULL,(TSIFunction) IFunction,&ctx);
153: TSSetIJacobian(ts,A,A,(TSIJacobian)IJacobian,&ctx);
155: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
156: Set initial conditions
157: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
158: TSSetSolution(ts,U);
160: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
161: Set solver options
162: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
163: TSSetDuration(ts,100000,2000.0);
164: TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);
165: TSSetInitialTimeStep(ts,0.0,.001);
166: TSSetFromOptions(ts);
168: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
169: Solve nonlinear system
170: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
171: TSSolve(ts,U);
173: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
174: Free work space. All PETSc objects should be destroyed when they are no longer needed.
175: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
176: MatDestroy(&A);
177: VecDestroy(&U);
178: TSDestroy(&ts);
179: PetscRandomDestroy(&ctx.rand);
181: PetscFinalize();
182: return(0);
183: }