1c4762a1bSJed Brown static char help[] = "Solves the time dependent Allen-Cahn equation with IMEX methods"; 2c4762a1bSJed Brown 3c4762a1bSJed Brown /* 4c4762a1bSJed Brown * allen_cahn.c 5c4762a1bSJed Brown * 6c4762a1bSJed Brown * Created on: Jun 8, 2012 7c4762a1bSJed Brown * Author: Hong Zhang 8c4762a1bSJed Brown */ 9c4762a1bSJed Brown 10c4762a1bSJed Brown #include <petscts.h> 11c4762a1bSJed Brown 12c4762a1bSJed Brown /* 13c4762a1bSJed Brown * application context 14c4762a1bSJed Brown */ 15c4762a1bSJed Brown typedef struct { 16c4762a1bSJed Brown PetscReal param; /* parameter */ 17c4762a1bSJed Brown PetscReal xleft, xright; /* range in x-direction */ 18c4762a1bSJed Brown PetscInt mx; /* Discretization in x-direction */ 19c4762a1bSJed Brown } AppCtx; 20c4762a1bSJed Brown 21c4762a1bSJed Brown static PetscErrorCode RHSFunction(TS, PetscReal, Vec, Vec, void *); 22c4762a1bSJed Brown static PetscErrorCode FormIFunction(TS, PetscReal, Vec, Vec, Vec, void *); 23c4762a1bSJed Brown static PetscErrorCode FormIJacobian(TS, PetscReal, Vec, Vec, PetscReal, Mat, Mat, void *ctx); 24c4762a1bSJed Brown static PetscErrorCode FormInitialSolution(TS, Vec, void *); 25c4762a1bSJed Brown 269371c9d4SSatish Balay int main(int argc, char **argv) { 27c4762a1bSJed Brown TS ts; 28c4762a1bSJed Brown Vec x; /* solution vector */ 29c4762a1bSJed Brown Mat A; /* Jacobian */ 30c4762a1bSJed Brown PetscInt steps, mx; 31c4762a1bSJed Brown PetscReal ftime; 32c4762a1bSJed Brown AppCtx user; /* user-defined work context */ 33c4762a1bSJed Brown 34327415f7SBarry Smith PetscFunctionBeginUser; 359566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 36c4762a1bSJed Brown 37c4762a1bSJed Brown /* Initialize user application context */ 38d0609cedSBarry Smith PetscOptionsBegin(PETSC_COMM_WORLD, NULL, "Allen-Cahn equation", ""); 39c4762a1bSJed Brown user.param = 9e-4; 40c4762a1bSJed Brown user.xleft = -1.; 41c4762a1bSJed Brown user.xright = 2.; 42c4762a1bSJed Brown user.mx = 400; 439566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-eps", "parameter", "", user.param, &user.param, NULL)); 44d0609cedSBarry Smith PetscOptionsEnd(); 45c4762a1bSJed Brown 46c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 47c4762a1bSJed Brown Set runtime options 48c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 49c4762a1bSJed Brown /* 509566063dSJacob Faibussowitsch * PetscCall(PetscOptionsGetBool(NULL,NULL,"-monitor",&monitor,NULL)); 51c4762a1bSJed Brown */ 52c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 53c4762a1bSJed Brown Create necessary matrix and vectors, solve same ODE on every process 54c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 559566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD, &A)); 569566063dSJacob Faibussowitsch PetscCall(MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, user.mx, user.mx)); 579566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(A)); 589566063dSJacob Faibussowitsch PetscCall(MatSetUp(A)); 599566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(A, &x, NULL)); 60c4762a1bSJed Brown 61c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 62c4762a1bSJed Brown Create time stepping solver context 63c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 649566063dSJacob Faibussowitsch PetscCall(TSCreate(PETSC_COMM_WORLD, &ts)); 659566063dSJacob Faibussowitsch PetscCall(TSSetType(ts, TSEIMEX)); 669566063dSJacob Faibussowitsch PetscCall(TSSetRHSFunction(ts, NULL, RHSFunction, &user)); 679566063dSJacob Faibussowitsch PetscCall(TSSetIFunction(ts, NULL, FormIFunction, &user)); 689566063dSJacob Faibussowitsch PetscCall(TSSetIJacobian(ts, A, A, FormIJacobian, &user)); 69c4762a1bSJed Brown ftime = 22; 709566063dSJacob Faibussowitsch PetscCall(TSSetMaxTime(ts, ftime)); 719566063dSJacob Faibussowitsch PetscCall(TSSetExactFinalTime(ts, TS_EXACTFINALTIME_STEPOVER)); 72c4762a1bSJed Brown 73c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 74c4762a1bSJed Brown Set initial conditions 75c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 769566063dSJacob Faibussowitsch PetscCall(FormInitialSolution(ts, x, &user)); 779566063dSJacob Faibussowitsch PetscCall(TSSetSolution(ts, x)); 789566063dSJacob Faibussowitsch PetscCall(VecGetSize(x, &mx)); 79c4762a1bSJed Brown 80c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 81c4762a1bSJed Brown Set runtime options 82c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 839566063dSJacob Faibussowitsch PetscCall(TSSetFromOptions(ts)); 84c4762a1bSJed Brown 85c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 86c4762a1bSJed Brown Solve nonlinear system 87c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 889566063dSJacob Faibussowitsch PetscCall(TSSolve(ts, x)); 899566063dSJacob Faibussowitsch PetscCall(TSGetTime(ts, &ftime)); 909566063dSJacob Faibussowitsch PetscCall(TSGetStepNumber(ts, &steps)); 9163a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "eps %g, steps %" PetscInt_FMT ", ftime %g\n", (double)user.param, steps, (double)ftime)); 929566063dSJacob Faibussowitsch /* PetscCall(VecView(x,PETSC_VIEWER_STDOUT_WORLD));*/ 93c4762a1bSJed Brown 94c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 95c4762a1bSJed Brown Free work space. 96c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 979566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 989566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 999566063dSJacob Faibussowitsch PetscCall(TSDestroy(&ts)); 1009566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 101b122ec5aSJacob Faibussowitsch return 0; 102c4762a1bSJed Brown } 103c4762a1bSJed Brown 1049371c9d4SSatish Balay static PetscErrorCode RHSFunction(TS ts, PetscReal t, Vec X, Vec F, void *ptr) { 105c4762a1bSJed Brown AppCtx *user = (AppCtx *)ptr; 106c4762a1bSJed Brown PetscScalar *f; 107c4762a1bSJed Brown const PetscScalar *x; 108c4762a1bSJed Brown PetscInt i, mx; 109c4762a1bSJed Brown PetscReal hx, eps; 110c4762a1bSJed Brown 111c4762a1bSJed Brown PetscFunctionBegin; 112c4762a1bSJed Brown mx = user->mx; 113c4762a1bSJed Brown eps = user->param; 114c4762a1bSJed Brown hx = (user->xright - user->xleft) / (mx - 1); 1159566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X, &x)); 1169566063dSJacob Faibussowitsch PetscCall(VecGetArray(F, &f)); 117c4762a1bSJed Brown f[0] = 2. * eps * (x[1] - x[0]) / (hx * hx); /*boundary*/ 118*ad540459SPierre Jolivet for (i = 1; i < mx - 1; i++) f[i] = eps * (x[i + 1] - 2. * x[i] + x[i - 1]) / (hx * hx); 119c4762a1bSJed Brown f[mx - 1] = 2. * eps * (x[mx - 2] - x[mx - 1]) / (hx * hx); /*boundary*/ 1209566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X, &x)); 1219566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(F, &f)); 122c4762a1bSJed Brown PetscFunctionReturn(0); 123c4762a1bSJed Brown } 124c4762a1bSJed Brown 1259371c9d4SSatish Balay static PetscErrorCode FormIFunction(TS ts, PetscReal t, Vec X, Vec Xdot, Vec F, void *ptr) { 126c4762a1bSJed Brown AppCtx *user = (AppCtx *)ptr; 127c4762a1bSJed Brown PetscScalar *f; 128c4762a1bSJed Brown const PetscScalar *x, *xdot; 129c4762a1bSJed Brown PetscInt i, mx; 130c4762a1bSJed Brown 131c4762a1bSJed Brown PetscFunctionBegin; 132c4762a1bSJed Brown mx = user->mx; 1339566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X, &x)); 1349566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(Xdot, &xdot)); 1359566063dSJacob Faibussowitsch PetscCall(VecGetArray(F, &f)); 136c4762a1bSJed Brown 137*ad540459SPierre Jolivet for (i = 0; i < mx; i++) f[i] = xdot[i] - x[i] * (1. - x[i] * x[i]); 138c4762a1bSJed Brown 1399566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X, &x)); 1409566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(Xdot, &xdot)); 1419566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(F, &f)); 142c4762a1bSJed Brown PetscFunctionReturn(0); 143c4762a1bSJed Brown } 144c4762a1bSJed Brown 1459371c9d4SSatish Balay static PetscErrorCode FormIJacobian(TS ts, PetscReal t, Vec U, Vec Udot, PetscReal a, Mat J, Mat Jpre, void *ctx) { 146c4762a1bSJed Brown AppCtx *user = (AppCtx *)ctx; 147c4762a1bSJed Brown PetscScalar v; 148c4762a1bSJed Brown const PetscScalar *x; 149c4762a1bSJed Brown PetscInt i, col; 150c4762a1bSJed Brown 151c4762a1bSJed Brown PetscFunctionBegin; 1529566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(U, &x)); 153c4762a1bSJed Brown for (i = 0; i < user->mx; i++) { 154c4762a1bSJed Brown v = a - 1. + 3. * x[i] * x[i]; 155c4762a1bSJed Brown col = i; 1569566063dSJacob Faibussowitsch PetscCall(MatSetValues(J, 1, &i, 1, &col, &v, INSERT_VALUES)); 157c4762a1bSJed Brown } 1589566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(U, &x)); 159c4762a1bSJed Brown 1609566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY)); 1619566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY)); 162c4762a1bSJed Brown if (J != Jpre) { 1639566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(Jpre, MAT_FINAL_ASSEMBLY)); 1649566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(Jpre, MAT_FINAL_ASSEMBLY)); 165c4762a1bSJed Brown } 166c4762a1bSJed Brown /* MatView(J,PETSC_VIEWER_STDOUT_WORLD);*/ 167c4762a1bSJed Brown PetscFunctionReturn(0); 168c4762a1bSJed Brown } 169c4762a1bSJed Brown 1709371c9d4SSatish Balay static PetscErrorCode FormInitialSolution(TS ts, Vec U, void *ctx) { 171c4762a1bSJed Brown AppCtx *user = (AppCtx *)ctx; 172c4762a1bSJed Brown PetscInt i; 173c4762a1bSJed Brown PetscScalar *x; 174c4762a1bSJed Brown PetscReal hx, x_map; 175c4762a1bSJed Brown 176c4762a1bSJed Brown PetscFunctionBegin; 177c4762a1bSJed Brown hx = (user->xright - user->xleft) / (PetscReal)(user->mx - 1); 1789566063dSJacob Faibussowitsch PetscCall(VecGetArray(U, &x)); 179c4762a1bSJed Brown for (i = 0; i < user->mx; i++) { 180c4762a1bSJed Brown x_map = user->xleft + i * hx; 181c4762a1bSJed Brown if (x_map >= 0.7065) { 182c4762a1bSJed Brown x[i] = PetscTanhReal((x_map - 0.8) / (2. * PetscSqrtReal(user->param))); 183c4762a1bSJed Brown } else if (x_map >= 0.4865) { 184c4762a1bSJed Brown x[i] = PetscTanhReal((0.613 - x_map) / (2. * PetscSqrtReal(user->param))); 185c4762a1bSJed Brown } else if (x_map >= 0.28) { 186c4762a1bSJed Brown x[i] = PetscTanhReal((x_map - 0.36) / (2. * PetscSqrtReal(user->param))); 187c4762a1bSJed Brown } else if (x_map >= -0.7) { 188c4762a1bSJed Brown x[i] = PetscTanhReal((0.2 - x_map) / (2. * PetscSqrtReal(user->param))); 189c4762a1bSJed Brown } else if (x_map >= -1) { 190c4762a1bSJed Brown x[i] = PetscTanhReal((x_map + 0.9) / (2. * PetscSqrtReal(user->param))); 191c4762a1bSJed Brown } 192c4762a1bSJed Brown } 1939566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(U, &x)); 194c4762a1bSJed Brown PetscFunctionReturn(0); 195c4762a1bSJed Brown } 196c4762a1bSJed Brown 197c4762a1bSJed Brown /*TEST 198c4762a1bSJed Brown 199c4762a1bSJed Brown test: 200c4762a1bSJed Brown args: -ts_rtol 1e-04 -ts_dt 0.025 -pc_type lu -ksp_error_if_not_converged TRUE -ts_type eimex -ts_adapt_type none -ts_eimex_order_adapt -ts_eimex_max_rows 7 -ts_monitor_draw_solution 201c4762a1bSJed Brown requires: x 202c4762a1bSJed Brown timeoutfactor: 3 203c4762a1bSJed Brown 204c4762a1bSJed Brown TEST*/ 205