xref: /petsc/src/ts/tutorials/ex42.c (revision 5f80ce2ab25dff0f4601e710601cbbcecf323266)
1c4762a1bSJed Brown static char help[] = "Meinhard't activator-inhibitor model to test TS domain error feature.\n";
2c4762a1bSJed Brown 
3c4762a1bSJed Brown /*
4c4762a1bSJed Brown    The activator-inhibitor on a line is described by the PDE:
5c4762a1bSJed Brown 
6c4762a1bSJed Brown    da/dt = \alpha a^2 / (1 + \beta h) + \rho_a - \mu_a a + D_a d^2 a/ dx^2
7c4762a1bSJed Brown    dh/dt = \alpha a^2 + \rho_h - \mu_h h + D_h d^2 h/ dx^2
8c4762a1bSJed Brown 
9c4762a1bSJed Brown    The PDE part will be solve by finite-difference on the line of cells.
10c4762a1bSJed Brown  */
11c4762a1bSJed Brown 
12c4762a1bSJed Brown #include <petscts.h>
13c4762a1bSJed Brown 
14c4762a1bSJed Brown typedef struct {
15c4762a1bSJed Brown   PetscInt  nb_cells;
16c4762a1bSJed Brown   PetscReal alpha;
17c4762a1bSJed Brown   PetscReal beta;
18c4762a1bSJed Brown   PetscReal rho_a;
19c4762a1bSJed Brown   PetscReal rho_h;
20c4762a1bSJed Brown   PetscReal mu_a;
21c4762a1bSJed Brown   PetscReal mu_h;
22c4762a1bSJed Brown   PetscReal D_a;
23c4762a1bSJed Brown   PetscReal D_h;
24c4762a1bSJed Brown } AppCtx;
25c4762a1bSJed Brown 
26c4762a1bSJed Brown PetscErrorCode RHSFunction(TS ts, PetscReal t, Vec X, Vec DXDT, void* ptr)
27c4762a1bSJed Brown {
28c4762a1bSJed Brown   AppCtx*           user = (AppCtx*)ptr;
29c4762a1bSJed Brown   PetscInt          nb_cells, i;
30c4762a1bSJed Brown   PetscReal         alpha, beta;
31c4762a1bSJed Brown   PetscReal         rho_a, mu_a, D_a;
32c4762a1bSJed Brown   PetscReal         rho_h, mu_h, D_h;
33c4762a1bSJed Brown   PetscReal         a, h, da, dh, d2a, d2h;
34c4762a1bSJed Brown   PetscScalar       *dxdt;
35c4762a1bSJed Brown   const PetscScalar *x;
36c4762a1bSJed Brown 
37c4762a1bSJed Brown   PetscFunctionBegin;
38c4762a1bSJed Brown   nb_cells = user->nb_cells;
39c4762a1bSJed Brown   alpha    = user->alpha;
40c4762a1bSJed Brown   beta     = user->beta;
41c4762a1bSJed Brown   rho_a    = user->rho_a;
42c4762a1bSJed Brown   mu_a     = user->mu_a;
43c4762a1bSJed Brown   D_a      = user->D_a;
44c4762a1bSJed Brown   rho_h    = user->rho_h;
45c4762a1bSJed Brown   mu_h     = user->mu_h;
46c4762a1bSJed Brown   D_h      = user->D_h;
47c4762a1bSJed Brown 
48*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecGetArrayRead(X, &x));
49*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecGetArray(DXDT, &dxdt));
50c4762a1bSJed Brown 
51c4762a1bSJed Brown   for (i = 0 ; i < nb_cells ; i++) {
52c4762a1bSJed Brown     a = x[2*i];
53c4762a1bSJed Brown     h = x[2*i+1];
54c4762a1bSJed Brown     // Reaction:
55c4762a1bSJed Brown     da = alpha * a*a / (1. + beta * h) + rho_a - mu_a * a;
56c4762a1bSJed Brown     dh = alpha * a*a + rho_h - mu_h*h;
57c4762a1bSJed Brown     // Diffusion:
58c4762a1bSJed Brown     d2a = d2h = 0.;
59c4762a1bSJed Brown     if (i > 0) {
60c4762a1bSJed Brown       d2a += (x[2*(i-1)] - a);
61c4762a1bSJed Brown       d2h += (x[2*(i-1)+1] - h);
62c4762a1bSJed Brown     }
63c4762a1bSJed Brown     if (i < nb_cells-1) {
64c4762a1bSJed Brown       d2a += (x[2*(i+1)] - a);
65c4762a1bSJed Brown       d2h += (x[2*(i+1)+1] - h);
66c4762a1bSJed Brown     }
67c4762a1bSJed Brown     dxdt[2*i] = da + D_a*d2a;
68c4762a1bSJed Brown     dxdt[2*i+1] = dh + D_h*d2h;
69c4762a1bSJed Brown   }
70*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecRestoreArray(DXDT, &dxdt));
71*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecRestoreArrayRead(X, &x));
72c4762a1bSJed Brown   PetscFunctionReturn(0);
73c4762a1bSJed Brown }
74c4762a1bSJed Brown 
75c4762a1bSJed Brown PetscErrorCode RHSJacobian(TS ts, PetscReal t, Vec X, Mat J, Mat B, void *ptr)
76c4762a1bSJed Brown {
77c4762a1bSJed Brown   AppCtx            *user = (AppCtx*)ptr;
78c4762a1bSJed Brown   PetscInt          nb_cells, i, idx;
79c4762a1bSJed Brown   PetscReal         alpha, beta;
80c4762a1bSJed Brown   PetscReal         mu_a, D_a;
81c4762a1bSJed Brown   PetscReal         mu_h, D_h;
82c4762a1bSJed Brown   PetscReal         a, h;
83c4762a1bSJed Brown   const PetscScalar *x;
84c4762a1bSJed Brown   PetscScalar       va[4], vh[4];
85c4762a1bSJed Brown   PetscInt          ca[4], ch[4], rowa, rowh;
86c4762a1bSJed Brown 
87c4762a1bSJed Brown   PetscFunctionBegin;
88c4762a1bSJed Brown   nb_cells = user->nb_cells;
89c4762a1bSJed Brown   alpha    = user->alpha;
90c4762a1bSJed Brown   beta     = user->beta;
91c4762a1bSJed Brown   mu_a     = user->mu_a;
92c4762a1bSJed Brown   D_a      = user->D_a;
93c4762a1bSJed Brown   mu_h     = user->mu_h;
94c4762a1bSJed Brown   D_h      = user->D_h;
95c4762a1bSJed Brown 
96*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecGetArrayRead(X, &x));
97c4762a1bSJed Brown   for (i = 0; i < nb_cells ; ++i) {
98c4762a1bSJed Brown     rowa = 2*i;
99c4762a1bSJed Brown     rowh = 2*i+1;
100c4762a1bSJed Brown     a = x[2*i];
101c4762a1bSJed Brown     h = x[2*i+1];
102c4762a1bSJed Brown     ca[0] = ch[1] = 2*i;
103c4762a1bSJed Brown     va[0] = 2*alpha*a / (1.+beta*h) - mu_a;
104c4762a1bSJed Brown     vh[1] = 2*alpha*a;
105c4762a1bSJed Brown     ca[1] = ch[0] = 2*i+1;
106c4762a1bSJed Brown     va[1] = -beta*alpha*a*a / ((1.+beta*h)*(1.+beta*h));
107c4762a1bSJed Brown     vh[0] = -mu_h;
108c4762a1bSJed Brown     idx = 2;
109c4762a1bSJed Brown     if (i > 0) {
110c4762a1bSJed Brown       ca[idx] = 2*(i-1);
111c4762a1bSJed Brown       ch[idx] = 2*(i-1)+1;
112c4762a1bSJed Brown       va[idx] = D_a;
113c4762a1bSJed Brown       vh[idx] = D_h;
114c4762a1bSJed Brown       va[0] -= D_a;
115c4762a1bSJed Brown       vh[0] -= D_h;
116c4762a1bSJed Brown       idx++;
117c4762a1bSJed Brown     }
118c4762a1bSJed Brown     if (i < nb_cells-1) {
119c4762a1bSJed Brown       ca[idx] = 2*(i+1);
120c4762a1bSJed Brown       ch[idx] = 2*(i+1)+1;
121c4762a1bSJed Brown       va[idx] = D_a;
122c4762a1bSJed Brown       vh[idx] = D_h;
123c4762a1bSJed Brown       va[0] -= D_a;
124c4762a1bSJed Brown       vh[0] -= D_h;
125c4762a1bSJed Brown       idx++;
126c4762a1bSJed Brown     }
127*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatSetValues(B, 1, &rowa, idx, ca, va, INSERT_VALUES));
128*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatSetValues(B, 1, &rowh, idx, ch, vh, INSERT_VALUES));
129c4762a1bSJed Brown   }
130*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecRestoreArrayRead(X, &x));
131*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY));
132*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY));
133c4762a1bSJed Brown   if (J != B) {
134*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY));
135*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY));
136c4762a1bSJed Brown   }
137c4762a1bSJed Brown   PetscFunctionReturn(0);
138c4762a1bSJed Brown }
139c4762a1bSJed Brown 
140c4762a1bSJed Brown PetscErrorCode DomainErrorFunction(TS ts, PetscReal t, Vec Y, PetscBool *accept)
141c4762a1bSJed Brown {
142c4762a1bSJed Brown   AppCtx            *user;
143c4762a1bSJed Brown   PetscReal         dt;
144c4762a1bSJed Brown   const PetscScalar *x;
145c4762a1bSJed Brown   PetscInt          nb_cells, i;
146c4762a1bSJed Brown 
147362febeeSStefano Zampini   PetscFunctionBegin;
148*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSGetApplicationContext(ts, &user));
149c4762a1bSJed Brown   nb_cells = user->nb_cells;
150*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecGetArrayRead(Y, &x));
151c4762a1bSJed Brown   for (i = 0 ; i < 2*nb_cells ; ++i) {
152c4762a1bSJed Brown     if (PetscRealPart(x[i]) < 0) {
153*5f80ce2aSJacob Faibussowitsch       CHKERRQ(TSGetTimeStep(ts, &dt));
154*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, " ** Domain Error at time %g\n", (double)t));
155c4762a1bSJed Brown       *accept = PETSC_FALSE;
156c4762a1bSJed Brown       break;
157c4762a1bSJed Brown     }
158c4762a1bSJed Brown   }
159*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecRestoreArrayRead(Y, &x));
160c4762a1bSJed Brown   PetscFunctionReturn(0);
161c4762a1bSJed Brown }
162c4762a1bSJed Brown 
163c4762a1bSJed Brown PetscErrorCode FormInitialState(Vec X, AppCtx* user)
164c4762a1bSJed Brown {
165c4762a1bSJed Brown   PetscRandom    R;
166c4762a1bSJed Brown 
167c4762a1bSJed Brown   PetscFunctionBegin;
168*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscRandomCreate(PETSC_COMM_WORLD, &R));
169*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscRandomSetFromOptions(R));
170*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscRandomSetInterval(R, 0., 10.));
171c4762a1bSJed Brown 
172c4762a1bSJed Brown   /*
173c4762a1bSJed Brown    * Initialize the state vector
174c4762a1bSJed Brown    */
175*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecSetRandom(X, R));
176*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscRandomDestroy(&R));
177c4762a1bSJed Brown   PetscFunctionReturn(0);
178c4762a1bSJed Brown }
179c4762a1bSJed Brown 
180c4762a1bSJed Brown PetscErrorCode PrintSolution(Vec X, AppCtx *user)
181c4762a1bSJed Brown {
182c4762a1bSJed Brown   const PetscScalar *x;
183c4762a1bSJed Brown   PetscInt          i;
184c4762a1bSJed Brown   PetscInt          nb_cells = user->nb_cells;
185c4762a1bSJed Brown 
186c4762a1bSJed Brown   PetscFunctionBegin;
187*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecGetArrayRead(X, &x));
188*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "Activator,Inhibitor\n"));
189c4762a1bSJed Brown   for (i = 0 ; i < nb_cells ; i++) {
190*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "%5.6e,%5.6e\n", (double)x[2*i], (double)x[2*i+1]));
191c4762a1bSJed Brown   }
192*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecRestoreArrayRead(X, &x));
193c4762a1bSJed Brown   PetscFunctionReturn(0);
194c4762a1bSJed Brown }
195c4762a1bSJed Brown 
196c4762a1bSJed Brown int main(int argc, char **argv)
197c4762a1bSJed Brown {
198c4762a1bSJed Brown   TS             ts;       /* time-stepping context */
199c4762a1bSJed Brown   Vec            x;       /* State vector */
200c4762a1bSJed Brown   Mat            J; /* Jacobian matrix */
201c4762a1bSJed Brown   AppCtx         user; /* user-defined context */
202c4762a1bSJed Brown   PetscErrorCode ierr;
203c4762a1bSJed Brown   PetscReal      ftime;
204c4762a1bSJed Brown   PetscInt       its;
205c4762a1bSJed Brown   PetscMPIInt    size;
206c4762a1bSJed Brown 
207c4762a1bSJed Brown   ierr = PetscInitialize(&argc, &argv, NULL, help);if (ierr) return ierr;
208*5f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
2093c633725SBarry Smith   PetscCheck(size == 1,PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "This is a uniprocessor example only");
210c4762a1bSJed Brown 
211c4762a1bSJed Brown   /*
212c4762a1bSJed Brown    * Allow user to set the grid dimensions and the equations parameters
213c4762a1bSJed Brown    */
214c4762a1bSJed Brown 
215c4762a1bSJed Brown   user.nb_cells = 50;
216c4762a1bSJed Brown   user.alpha = 10.;
217c4762a1bSJed Brown   user.beta = 1.;
218c4762a1bSJed Brown   user.rho_a = 1.;
219c4762a1bSJed Brown   user.rho_h = 2.;
220c4762a1bSJed Brown   user.mu_a = 2.;
221c4762a1bSJed Brown   user.mu_h = 3.;
222c4762a1bSJed Brown   user.D_a = 0.;
223c4762a1bSJed Brown   user.D_h = 30.;
224c4762a1bSJed Brown 
225c4762a1bSJed Brown   ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "", "Problem settings", "PROBLEM");CHKERRQ(ierr);
226*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-nb_cells", "Number of cells", "ex42.c",user.nb_cells, &user.nb_cells,NULL));
227*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-alpha", "Autocatalysis factor", "ex42.c",user.alpha, &user.alpha,NULL));
228*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-beta", "Inhibition factor", "ex42.c",user.beta, &user.beta,NULL));
229*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-rho_a", "Default production of the activator", "ex42.c",user.rho_a, &user.rho_a,NULL));
230*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-mu_a", "Degradation rate of the activator", "ex42.c",user.mu_a, &user.mu_a,NULL));
231*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-D_a", "Diffusion rate of the activator", "ex42.c",user.D_a, &user.D_a,NULL));
232*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-rho_h", "Default production of the inhibitor", "ex42.c",user.rho_h, &user.rho_h,NULL));
233*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-mu_h", "Degradation rate of the inhibitor", "ex42.c",user.mu_h, &user.mu_h,NULL));
234*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-D_h", "Diffusion rate of the inhibitor", "ex42.c",user.D_h, &user.D_h,NULL));
235c4762a1bSJed Brown   ierr = PetscOptionsEnd();CHKERRQ(ierr);
236c4762a1bSJed Brown 
237*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "nb_cells: %D\n", user.nb_cells));
238*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "alpha: %5.5g\n", (double)user.alpha));
239*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "beta:  %5.5g\n", (double)user.beta));
240*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "rho_a: %5.5g\n", (double)user.rho_a));
241*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "mu_a:  %5.5g\n", (double)user.mu_a));
242*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "D_a:   %5.5g\n", (double)user.D_a));
243*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "rho_h: %5.5g\n", (double)user.rho_h));
244*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "mu_h:  %5.5g\n", (double)user.mu_h));
245*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "D_h:   %5.5g\n", (double)user.D_h));
246c4762a1bSJed Brown 
247c4762a1bSJed Brown   /*
248c4762a1bSJed Brown    * Create vector to hold the solution
249c4762a1bSJed Brown    */
250*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecCreateSeq(PETSC_COMM_WORLD, 2*user.nb_cells, &x));
251c4762a1bSJed Brown 
252c4762a1bSJed Brown   /*
253c4762a1bSJed Brown    * Create time-stepper context
254c4762a1bSJed Brown    */
255*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSCreate(PETSC_COMM_WORLD, &ts));
256*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetProblemType(ts, TS_NONLINEAR));
257c4762a1bSJed Brown 
258c4762a1bSJed Brown   /*
259c4762a1bSJed Brown    * Tell the time-stepper context where to compute the solution
260c4762a1bSJed Brown    */
261*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetSolution(ts, x));
262c4762a1bSJed Brown 
263c4762a1bSJed Brown   /*
264c4762a1bSJed Brown    * Allocate the jacobian matrix
265c4762a1bSJed Brown    */
266*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatCreateSeqAIJ(PETSC_COMM_WORLD, 2*user.nb_cells, 2*user.nb_cells, 4, 0, &J));
267c4762a1bSJed Brown 
268c4762a1bSJed Brown   /*
269c4762a1bSJed Brown    * Provide the call-back for the non-linear function we are evaluating.
270c4762a1bSJed Brown    */
271*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetRHSFunction(ts, NULL, RHSFunction, &user));
272c4762a1bSJed Brown 
273c4762a1bSJed Brown   /*
274c4762a1bSJed Brown    * Set the Jacobian matrix and the function user to compute Jacobians
275c4762a1bSJed Brown    */
276*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetRHSJacobian(ts, J, J, RHSJacobian, &user));
277c4762a1bSJed Brown 
278c4762a1bSJed Brown   /*
279c4762a1bSJed Brown    * Set the function checking the domain
280c4762a1bSJed Brown    */
281*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetFunctionDomainError(ts, &DomainErrorFunction));
282c4762a1bSJed Brown 
283c4762a1bSJed Brown   /*
284c4762a1bSJed Brown    * Initialize the problem with random values
285c4762a1bSJed Brown    */
286*5f80ce2aSJacob Faibussowitsch   CHKERRQ(FormInitialState(x, &user));
287c4762a1bSJed Brown 
288c4762a1bSJed Brown   /*
289c4762a1bSJed Brown    * Read the solver type from options
290c4762a1bSJed Brown    */
291*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetType(ts, TSPSEUDO));
292c4762a1bSJed Brown 
293c4762a1bSJed Brown   /*
294c4762a1bSJed Brown    * Set a large number of timesteps and final duration time to insure
295c4762a1bSJed Brown    * convergenge to steady state
296c4762a1bSJed Brown    */
297*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetMaxSteps(ts, 2147483647));
298*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetMaxTime(ts, 1.e12));
299*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER));
300c4762a1bSJed Brown 
301c4762a1bSJed Brown   /*
302c4762a1bSJed Brown    * Set a larger number of potential errors
303c4762a1bSJed Brown    */
304*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetMaxStepRejections(ts, 50));
305c4762a1bSJed Brown 
306c4762a1bSJed Brown   /*
307c4762a1bSJed Brown    * Also start with a very small dt
308c4762a1bSJed Brown    */
309*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetTimeStep(ts, 0.05));
310c4762a1bSJed Brown 
311c4762a1bSJed Brown   /*
312c4762a1bSJed Brown    * Set a larger time step increment
313c4762a1bSJed Brown    */
314*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSPseudoSetTimeStepIncrement(ts, 1.5));
315c4762a1bSJed Brown 
316c4762a1bSJed Brown   /*
317c4762a1bSJed Brown    * Let the user personalise TS
318c4762a1bSJed Brown    */
319*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetFromOptions(ts));
320c4762a1bSJed Brown 
321c4762a1bSJed Brown   /*
322c4762a1bSJed Brown    * Set the context for the time stepper
323c4762a1bSJed Brown    */
324*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetApplicationContext(ts, &user));
325c4762a1bSJed Brown 
326c4762a1bSJed Brown   /*
327c4762a1bSJed Brown    * Setup the time stepper, ready for evaluation
328c4762a1bSJed Brown    */
329*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetUp(ts));
330c4762a1bSJed Brown 
331c4762a1bSJed Brown   /*
332c4762a1bSJed Brown    * Perform the solve.
333c4762a1bSJed Brown    */
334*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSolve(ts, x));
335*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSGetSolveTime(ts, &ftime));
336*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSGetStepNumber(ts,&its));
337*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "Number of time steps = %D, final time: %4.2e\nResult:\n\n", its, (double)ftime));
338*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PrintSolution(x, &user));
339c4762a1bSJed Brown 
340c4762a1bSJed Brown   /*
341c4762a1bSJed Brown    * Free the data structures
342c4762a1bSJed Brown    */
343*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&x));
344*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&J));
345*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TSDestroy(&ts));
346c4762a1bSJed Brown   ierr = PetscFinalize();
347c4762a1bSJed Brown   return ierr;
348c4762a1bSJed Brown }
349c4762a1bSJed Brown 
350c4762a1bSJed Brown /*TEST
351c4762a1bSJed Brown     build:
352f56ea12dSJed Brown       requires: !single !complex
353c4762a1bSJed Brown 
354c4762a1bSJed Brown     test:
355c4762a1bSJed Brown       args: -ts_max_steps 8
356c4762a1bSJed Brown       output_file: output/ex42.out
357c4762a1bSJed Brown 
358c4762a1bSJed Brown TEST*/
359