1d8606c27SBarry Smith! Time-dependent advection-reaction PDE in 1d. Demonstrates IMEX methods 2d8606c27SBarry Smith! 3d8606c27SBarry Smith! u_t + a1*u_x = -k1*u + k2*v + s1 4d8606c27SBarry Smith! v_t + a2*v_x = k1*u - k2*v + s2 5ccfd86f1SBarry Smith! 0 < x < 1 6d8606c27SBarry Smith! a1 = 1, k1 = 10^6, s1 = 0, 7d8606c27SBarry Smith! a2 = 0, k2 = 2*k1, s2 = 1 8d8606c27SBarry Smith! 9d8606c27SBarry Smith! Initial conditions: 10d8606c27SBarry Smith! u(x,0) = 1 + s2*x 11d8606c27SBarry Smith! v(x,0) = k0/k1*u(x,0) + s1/k1 12d8606c27SBarry Smith! 13d8606c27SBarry Smith! Upstream boundary conditions: 14d8606c27SBarry Smith! u(0,t) = 1-sin(12*t)^4 15d8606c27SBarry Smith! 16d8606c27SBarry Smith 17d8606c27SBarry Smith#include <petsc/finclude/petscts.h> 18d8606c27SBarry Smith#include <petsc/finclude/petscdmda.h> 19c5e229c2SMartin Diehlprogram main 20d8606c27SBarry Smith use petscts 21d8606c27SBarry Smith implicit none 22d8606c27SBarry Smith 23d8606c27SBarry Smith! 24d8606c27SBarry Smith! Create an application context to contain data needed by the 25d8606c27SBarry Smith! application-provided call-back routines, FormJacobian() and 26d8606c27SBarry Smith! FormFunction(). We use a double precision array with six 27d8606c27SBarry Smith! entries, two for each problem parameter a, k, s. 28d8606c27SBarry Smith! 29d8606c27SBarry Smith PetscReal user(6) 30d8606c27SBarry Smith integer user_a, user_k, user_s 31d8606c27SBarry Smith parameter(user_a=0, user_k=2, user_s=4) 32d8606c27SBarry Smith 33d8606c27SBarry Smith TS ts 34d8606c27SBarry Smith SNES snes 35d8606c27SBarry Smith SNESLineSearch linesearch 36d8606c27SBarry Smith Vec X 37d8606c27SBarry Smith Mat J 38d8606c27SBarry Smith PetscInt mx 39d8606c27SBarry Smith PetscErrorCode ierr 40d8606c27SBarry Smith DM da 41d8606c27SBarry Smith PetscReal ftime, dt 42d8606c27SBarry Smith PetscReal one, pone 43d8606c27SBarry Smith PetscInt im11, i2 44d8606c27SBarry Smith PetscBool flg 45d8606c27SBarry Smith 46d8606c27SBarry Smith im11 = 11 47d8606c27SBarry Smith i2 = 2 48d8606c27SBarry Smith one = 1.0 49d8606c27SBarry Smith pone = one/10 50d8606c27SBarry Smith 51d8606c27SBarry Smith PetscCallA(PetscInitialize(ierr)) 52d8606c27SBarry Smith 53d8606c27SBarry Smith! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 54d8606c27SBarry Smith! Create distributed array (DMDA) to manage parallel grid and vectors 55d8606c27SBarry Smith! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 56d8606c27SBarry Smith PetscCallA(DMDACreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, im11, i2, i2, PETSC_NULL_INTEGER, da, ierr)) 57d8606c27SBarry Smith PetscCallA(DMSetFromOptions(da, ierr)) 58d8606c27SBarry Smith PetscCallA(DMSetUp(da, ierr)) 59d8606c27SBarry Smith 60d8606c27SBarry Smith! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 61ccfd86f1SBarry Smith! Extract global vectors from DMDA 62d8606c27SBarry Smith! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 63d8606c27SBarry Smith PetscCallA(DMCreateGlobalVector(da, X, ierr)) 64d8606c27SBarry Smith 65d8606c27SBarry Smith! Initialize user application context 66d8606c27SBarry Smith! Use zero-based indexing for command line parameters to match ex22.c 67d8606c27SBarry Smith user(user_a + 1) = 1.0 68d8606c27SBarry Smith PetscCallA(PetscOptionsGetReal(PETSC_NULL_OPTIONS, PETSC_NULL_CHARACTER, '-a0', user(user_a + 1), flg, ierr)) 69d8606c27SBarry Smith user(user_a + 2) = 0.0 70d8606c27SBarry Smith PetscCallA(PetscOptionsGetReal(PETSC_NULL_OPTIONS, PETSC_NULL_CHARACTER, '-a1', user(user_a + 2), flg, ierr)) 71d8606c27SBarry Smith user(user_k + 1) = 1000000.0 72d8606c27SBarry Smith PetscCallA(PetscOptionsGetReal(PETSC_NULL_OPTIONS, PETSC_NULL_CHARACTER, '-k0', user(user_k + 1), flg, ierr)) 73d8606c27SBarry Smith user(user_k + 2) = 2*user(user_k + 1) 74d8606c27SBarry Smith PetscCallA(PetscOptionsGetReal(PETSC_NULL_OPTIONS, PETSC_NULL_CHARACTER, '-k1', user(user_k + 2), flg, ierr)) 75d8606c27SBarry Smith user(user_s + 1) = 0.0 76d8606c27SBarry Smith PetscCallA(PetscOptionsGetReal(PETSC_NULL_OPTIONS, PETSC_NULL_CHARACTER, '-s0', user(user_s + 1), flg, ierr)) 77d8606c27SBarry Smith user(user_s + 2) = 1.0 78d8606c27SBarry Smith PetscCallA(PetscOptionsGetReal(PETSC_NULL_OPTIONS, PETSC_NULL_CHARACTER, '-s1', user(user_s + 2), flg, ierr)) 79d8606c27SBarry Smith 80d8606c27SBarry Smith! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 81d8606c27SBarry Smith! Create timestepping solver context 82d8606c27SBarry Smith! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 83d8606c27SBarry Smith PetscCallA(TSCreate(PETSC_COMM_WORLD, ts, ierr)) 84d8606c27SBarry Smith PetscCallA(TSSetDM(ts, da, ierr)) 85d8606c27SBarry Smith PetscCallA(TSSetType(ts, TSARKIMEX, ierr)) 86d8606c27SBarry Smith PetscCallA(TSSetRHSFunction(ts, PETSC_NULL_VEC, FormRHSFunction, user, ierr)) 87d8606c27SBarry Smith PetscCallA(TSSetIFunction(ts, PETSC_NULL_VEC, FormIFunction, user, ierr)) 88d8606c27SBarry Smith PetscCallA(DMSetMatType(da, MATAIJ, ierr)) 89d8606c27SBarry Smith PetscCallA(DMCreateMatrix(da, J, ierr)) 90d8606c27SBarry Smith PetscCallA(TSSetIJacobian(ts, J, J, FormIJacobian, user, ierr)) 91d8606c27SBarry Smith 92d8606c27SBarry Smith PetscCallA(TSGetSNES(ts, snes, ierr)) 93d8606c27SBarry Smith PetscCallA(SNESGetLineSearch(snes, linesearch, ierr)) 94d8606c27SBarry Smith PetscCallA(SNESLineSearchSetType(linesearch, SNESLINESEARCHBASIC, ierr)) 95d8606c27SBarry Smith 96d8606c27SBarry Smith ftime = 1.0 97d8606c27SBarry Smith PetscCallA(TSSetMaxTime(ts, ftime, ierr)) 98d8606c27SBarry Smith PetscCallA(TSSetExactFinalTime(ts, TS_EXACTFINALTIME_STEPOVER, ierr)) 99d8606c27SBarry Smith 100d8606c27SBarry Smith! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 101d8606c27SBarry Smith! Set initial conditions 102d8606c27SBarry Smith! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 103d8606c27SBarry Smith PetscCallA(FormInitialSolution(ts, X, user, ierr)) 104d8606c27SBarry Smith PetscCallA(TSSetSolution(ts, X, ierr)) 105d8606c27SBarry Smith PetscCallA(VecGetSize(X, mx, ierr)) 106d8606c27SBarry Smith! Advective CFL, I don't know why it needs so much safety factor. 107ccfd86f1SBarry Smith dt = pone*max(user(user_a + 1), user(user_a + 2))/mx 108d8606c27SBarry Smith PetscCallA(TSSetTimeStep(ts, dt, ierr)) 109d8606c27SBarry Smith 110d8606c27SBarry Smith! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 111d8606c27SBarry Smith! Set runtime options 112d8606c27SBarry Smith! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 113d8606c27SBarry Smith PetscCallA(TSSetFromOptions(ts, ierr)) 114d8606c27SBarry Smith 115d8606c27SBarry Smith! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 116d8606c27SBarry Smith! Solve nonlinear system 117d8606c27SBarry Smith! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 118d8606c27SBarry Smith PetscCallA(TSSolve(ts, X, ierr)) 119d8606c27SBarry Smith 120d8606c27SBarry Smith! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 121d8606c27SBarry Smith! Free work space. 122d8606c27SBarry Smith! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 123d8606c27SBarry Smith PetscCallA(MatDestroy(J, ierr)) 124d8606c27SBarry Smith PetscCallA(VecDestroy(X, ierr)) 125d8606c27SBarry Smith PetscCallA(TSDestroy(ts, ierr)) 126d8606c27SBarry Smith PetscCallA(DMDestroy(da, ierr)) 127d8606c27SBarry Smith PetscCallA(PetscFinalize(ierr)) 128fe66ebccSMartin Diehlcontains 129d8606c27SBarry Smith 130d8606c27SBarry Smith! Small helper to extract the layout, result uses 1-based indexing. 131d8606c27SBarry Smith subroutine GetLayout(da, mx, xs, xe, gxs, gxe, ierr) 132ce78bad3SBarry Smith use petscdm 133d8606c27SBarry Smith implicit none 134d8606c27SBarry Smith 135d8606c27SBarry Smith DM da 136d8606c27SBarry Smith PetscInt mx, xs, xe, gxs, gxe 137d8606c27SBarry Smith PetscErrorCode ierr 138d8606c27SBarry Smith PetscInt xm, gxm 1395d83a8b1SBarry Smith PetscCall(DMDAGetInfo(da, PETSC_NULL_INTEGER, mx, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, PETSC_NULL_ENUM, PETSC_NULL_ENUM, PETSC_NULL_ENUM, PETSC_NULL_ENUM, ierr)) 140d8606c27SBarry Smith PetscCall(DMDAGetCorners(da, xs, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, xm, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, ierr)) 141d8606c27SBarry Smith PetscCall(DMDAGetGhostCorners(da, gxs, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, gxm, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, ierr)) 142d8606c27SBarry Smith xs = xs + 1 143d8606c27SBarry Smith gxs = gxs + 1 144d8606c27SBarry Smith xe = xs + xm - 1 145d8606c27SBarry Smith gxe = gxs + gxm - 1 146d8606c27SBarry Smith end subroutine 147d8606c27SBarry Smith 148d8606c27SBarry Smith subroutine FormIFunctionLocal(mx, xs, xe, gxs, gxe, x, xdot, f, a, k, s, ierr) 149d8606c27SBarry Smith implicit none 150d8606c27SBarry Smith PetscInt mx, xs, xe, gxs, gxe 151d8606c27SBarry Smith PetscScalar x(2, xs:xe) 152d8606c27SBarry Smith PetscScalar xdot(2, xs:xe) 153d8606c27SBarry Smith PetscScalar f(2, xs:xe) 154d8606c27SBarry Smith PetscReal a(2), k(2), s(2) 155d8606c27SBarry Smith PetscErrorCode ierr 156d8606c27SBarry Smith PetscInt i 157*ceeae6b5SMartin Diehl do i = xs, xe 158d8606c27SBarry Smith f(1, i) = xdot(1, i) + k(1)*x(1, i) - k(2)*x(2, i) - s(1) 159d8606c27SBarry Smith f(2, i) = xdot(2, i) - k(1)*x(1, i) + k(2)*x(2, i) - s(2) 160*ceeae6b5SMartin Diehl end do 161d8606c27SBarry Smith end subroutine 162d8606c27SBarry Smith 163d8606c27SBarry Smith subroutine FormIFunction(ts, t, X, Xdot, F, user, ierr) 164d8606c27SBarry Smith use petscts 165d8606c27SBarry Smith implicit none 166d8606c27SBarry Smith 167d8606c27SBarry Smith TS ts 168d8606c27SBarry Smith PetscReal t 169d8606c27SBarry Smith Vec X, Xdot, F 170d8606c27SBarry Smith PetscReal user(6) 171d8606c27SBarry Smith PetscErrorCode ierr 172d8606c27SBarry Smith integer user_a, user_k, user_s 173d8606c27SBarry Smith parameter(user_a=1, user_k=3, user_s=5) 174d8606c27SBarry Smith 175d8606c27SBarry Smith DM da 176d8606c27SBarry Smith PetscInt mx, xs, xe, gxs, gxe 17742ce371bSBarry Smith PetscScalar, pointer :: xx(:), xxdot(:), ff(:) 178d8606c27SBarry Smith 179d8606c27SBarry Smith PetscCall(TSGetDM(ts, da, ierr)) 180d8606c27SBarry Smith PetscCall(GetLayout(da, mx, xs, xe, gxs, gxe, ierr)) 181d8606c27SBarry Smith 182d8606c27SBarry Smith! Get access to vector data 183ce78bad3SBarry Smith PetscCall(VecGetArrayRead(X, xx, ierr)) 184ce78bad3SBarry Smith PetscCall(VecGetArrayRead(Xdot, xxdot, ierr)) 185ce78bad3SBarry Smith PetscCall(VecGetArray(F, ff, ierr)) 186d8606c27SBarry Smith 18742ce371bSBarry Smith PetscCall(FormIFunctionLocal(mx, xs, xe, gxs, gxe, xx, xxdot, ff, user(user_a), user(user_k), user(user_s), ierr)) 188d8606c27SBarry Smith 189ce78bad3SBarry Smith PetscCall(VecRestoreArrayRead(X, xx, ierr)) 190ce78bad3SBarry Smith PetscCall(VecRestoreArrayRead(Xdot, xxdot, ierr)) 191ce78bad3SBarry Smith PetscCall(VecRestoreArray(F, ff, ierr)) 192d8606c27SBarry Smith end subroutine 193d8606c27SBarry Smith 194d8606c27SBarry Smith subroutine FormRHSFunctionLocal(mx, xs, xe, gxs, gxe, t, x, f, a, k, s, ierr) 195d8606c27SBarry Smith implicit none 196d8606c27SBarry Smith PetscInt mx, xs, xe, gxs, gxe 197d8606c27SBarry Smith PetscReal t 198d8606c27SBarry Smith PetscScalar x(2, gxs:gxe), f(2, xs:xe) 199d8606c27SBarry Smith PetscReal a(2), k(2), s(2) 200d8606c27SBarry Smith PetscErrorCode ierr 201d8606c27SBarry Smith PetscInt i, j 202d8606c27SBarry Smith PetscReal hx, u0t(2) 203d8606c27SBarry Smith PetscReal one, two, three, four, six, twelve 204d8606c27SBarry Smith PetscReal half, third, twothird, sixth 205d8606c27SBarry Smith PetscReal twelfth 206d8606c27SBarry Smith 207d8606c27SBarry Smith one = 1.0 208d8606c27SBarry Smith two = 2.0 209d8606c27SBarry Smith three = 3.0 210d8606c27SBarry Smith four = 4.0 211d8606c27SBarry Smith six = 6.0 212d8606c27SBarry Smith twelve = 12.0 213d8606c27SBarry Smith hx = one/mx 214d8606c27SBarry Smith! The Fortran standard only allows positive base for power functions; Nag compiler fails on this 215d8606c27SBarry Smith u0t(1) = one - abs(sin(twelve*t))**four 216d8606c27SBarry Smith u0t(2) = 0.0 217d8606c27SBarry Smith half = one/two 218d8606c27SBarry Smith third = one/three 219d8606c27SBarry Smith twothird = two/three 220d8606c27SBarry Smith sixth = one/six 221d8606c27SBarry Smith twelfth = one/twelve 222*ceeae6b5SMartin Diehl do i = xs, xe 223*ceeae6b5SMartin Diehl do j = 1, 2 2244820e4eaSBarry Smith if (i == 1) then 225d8606c27SBarry Smith f(j, i) = a(j)/hx*(third*u0t(j) + half*x(j, i) - x(j, i + 1) & 226d8606c27SBarry Smith& + sixth*x(j, i + 2)) 2274820e4eaSBarry Smith else if (i == 2) then 228d8606c27SBarry Smith f(j, i) = a(j)/hx*(-twelfth*u0t(j) + twothird*x(j, i - 1) & 229d8606c27SBarry Smith& - twothird*x(j, i + 1) + twelfth*x(j, i + 2)) 2304820e4eaSBarry Smith else if (i == mx - 1) then 231d8606c27SBarry Smith f(j, i) = a(j)/hx*(-sixth*x(j, i - 2) + x(j, i - 1) & 232d8606c27SBarry Smith& - half*x(j, i) - third*x(j, i + 1)) 2334820e4eaSBarry Smith else if (i == mx) then 234d8606c27SBarry Smith f(j, i) = a(j)/hx*(-x(j, i) + x(j, i - 1)) 235d8606c27SBarry Smith else 236d8606c27SBarry Smith f(j, i) = a(j)/hx*(-twelfth*x(j, i - 2) & 237d8606c27SBarry Smith& + twothird*x(j, i - 1) & 238d8606c27SBarry Smith& - twothird*x(j, i + 1) + twelfth*x(j, i + 2)) 239d8606c27SBarry Smith end if 240*ceeae6b5SMartin Diehl end do 241*ceeae6b5SMartin Diehl end do 242d8606c27SBarry Smith end subroutine 243d8606c27SBarry Smith 244d8606c27SBarry Smith subroutine FormRHSFunction(ts, t, X, F, user, ierr) 245d8606c27SBarry Smith use petscts 246d8606c27SBarry Smith implicit none 247d8606c27SBarry Smith 248d8606c27SBarry Smith TS ts 249d8606c27SBarry Smith PetscReal t 250d8606c27SBarry Smith Vec X, F 251d8606c27SBarry Smith PetscReal user(6) 252d8606c27SBarry Smith PetscErrorCode ierr 253d8606c27SBarry Smith integer user_a, user_k, user_s 254d8606c27SBarry Smith parameter(user_a=1, user_k=3, user_s=5) 255d8606c27SBarry Smith DM da 256d8606c27SBarry Smith Vec Xloc 257d8606c27SBarry Smith PetscInt mx, xs, xe, gxs, gxe 25842ce371bSBarry Smith PetscScalar, pointer :: xx(:), ff(:) 259d8606c27SBarry Smith 260d8606c27SBarry Smith PetscCall(TSGetDM(ts, da, ierr)) 261d8606c27SBarry Smith PetscCall(GetLayout(da, mx, xs, xe, gxs, gxe, ierr)) 262d8606c27SBarry Smith 263d8606c27SBarry Smith! Scatter ghost points to local vector,using the 2-step process 264d8606c27SBarry Smith! DMGlobalToLocalBegin(),DMGlobalToLocalEnd(). 265d8606c27SBarry Smith! By placing code between these two statements, computations can be 266d8606c27SBarry Smith! done while messages are in transition. 267d8606c27SBarry Smith PetscCall(DMGetLocalVector(da, Xloc, ierr)) 268d8606c27SBarry Smith PetscCall(DMGlobalToLocalBegin(da, X, INSERT_VALUES, Xloc, ierr)) 269d8606c27SBarry Smith PetscCall(DMGlobalToLocalEnd(da, X, INSERT_VALUES, Xloc, ierr)) 270d8606c27SBarry Smith 271d8606c27SBarry Smith! Get access to vector data 272ce78bad3SBarry Smith PetscCall(VecGetArrayRead(Xloc, xx, ierr)) 273ce78bad3SBarry Smith PetscCall(VecGetArray(F, ff, ierr)) 274d8606c27SBarry Smith 27542ce371bSBarry Smith PetscCall(FormRHSFunctionLocal(mx, xs, xe, gxs, gxe, t, xx, ff, user(user_a), user(user_k), user(user_s), ierr)) 276d8606c27SBarry Smith 277ce78bad3SBarry Smith PetscCall(VecRestoreArrayRead(Xloc, xx, ierr)) 278ce78bad3SBarry Smith PetscCall(VecRestoreArray(F, ff, ierr)) 279d8606c27SBarry Smith PetscCall(DMRestoreLocalVector(da, Xloc, ierr)) 280d8606c27SBarry Smith end subroutine 281d8606c27SBarry Smith 282d8606c27SBarry Smith! --------------------------------------------------------------------- 283d8606c27SBarry Smith! 284d8606c27SBarry Smith! IJacobian - Compute IJacobian = dF/dU + shift*dF/dUdot 285d8606c27SBarry Smith! 286d8606c27SBarry Smith subroutine FormIJacobian(ts, t, X, Xdot, shift, J, Jpre, user, ierr) 287d8606c27SBarry Smith use petscts 288d8606c27SBarry Smith implicit none 289d8606c27SBarry Smith 290d8606c27SBarry Smith TS ts 291d8606c27SBarry Smith PetscReal t, shift 292d8606c27SBarry Smith Vec X, Xdot 293d8606c27SBarry Smith Mat J, Jpre 294d8606c27SBarry Smith PetscReal user(6) 295d8606c27SBarry Smith PetscErrorCode ierr 296d8606c27SBarry Smith integer user_a, user_k, user_s 297d8606c27SBarry Smith parameter(user_a=0, user_k=2, user_s=4) 298d8606c27SBarry Smith 299d8606c27SBarry Smith DM da 300d8606c27SBarry Smith PetscInt mx, xs, xe, gxs, gxe 301d8606c27SBarry Smith PetscInt i, i1, row, col 302ccfd86f1SBarry Smith PetscReal k1, k2 303d8606c27SBarry Smith PetscScalar val(4) 304d8606c27SBarry Smith 305d8606c27SBarry Smith PetscCall(TSGetDM(ts, da, ierr)) 306d8606c27SBarry Smith PetscCall(GetLayout(da, mx, xs, xe, gxs, gxe, ierr)) 307d8606c27SBarry Smith 308d8606c27SBarry Smith i1 = 1 309d8606c27SBarry Smith k1 = user(user_k + 1) 310d8606c27SBarry Smith k2 = user(user_k + 2) 311*ceeae6b5SMartin Diehl do i = xs, xe 312d8606c27SBarry Smith row = i - gxs 313d8606c27SBarry Smith col = i - gxs 314d8606c27SBarry Smith val(1) = shift + k1 315d8606c27SBarry Smith val(2) = -k2 316d8606c27SBarry Smith val(3) = -k1 317d8606c27SBarry Smith val(4) = shift + k2 3185d83a8b1SBarry Smith PetscCall(MatSetValuesBlockedLocal(Jpre, i1, [row], i1, [col], val, INSERT_VALUES, ierr)) 319*ceeae6b5SMartin Diehl end do 320d8606c27SBarry Smith PetscCall(MatAssemblyBegin(Jpre, MAT_FINAL_ASSEMBLY, ierr)) 321d8606c27SBarry Smith PetscCall(MatAssemblyEnd(Jpre, MAT_FINAL_ASSEMBLY, ierr)) 322d8606c27SBarry Smith if (J /= Jpre) then 323d8606c27SBarry Smith PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY, ierr)) 324d8606c27SBarry Smith PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY, ierr)) 325d8606c27SBarry Smith end if 326d8606c27SBarry Smith end subroutine 327d8606c27SBarry Smith 328d8606c27SBarry Smith subroutine FormInitialSolutionLocal(mx, xs, xe, gxs, gxe, x, a, k, s, ierr) 329d8606c27SBarry Smith implicit none 330d8606c27SBarry Smith PetscInt mx, xs, xe, gxs, gxe 331d8606c27SBarry Smith PetscScalar x(2, xs:xe) 332d8606c27SBarry Smith PetscReal a(2), k(2), s(2) 333d8606c27SBarry Smith PetscErrorCode ierr 334d8606c27SBarry Smith 335d8606c27SBarry Smith PetscInt i 336d8606c27SBarry Smith PetscReal one, hx, r, ik 337d8606c27SBarry Smith one = 1.0 338d8606c27SBarry Smith hx = one/mx 339*ceeae6b5SMartin Diehl do i = xs, xe 340d8606c27SBarry Smith r = i*hx 3414820e4eaSBarry Smith if (k(2) /= 0.0) then 342d8606c27SBarry Smith ik = one/k(2) 343d8606c27SBarry Smith else 344d8606c27SBarry Smith ik = one 345d8606c27SBarry Smith end if 346d8606c27SBarry Smith x(1, i) = one + s(2)*r 347d8606c27SBarry Smith x(2, i) = k(1)*ik*x(1, i) + s(2)*ik 348*ceeae6b5SMartin Diehl end do 349d8606c27SBarry Smith end subroutine 350d8606c27SBarry Smith 351d8606c27SBarry Smith subroutine FormInitialSolution(ts, X, user, ierr) 352d8606c27SBarry Smith use petscts 353d8606c27SBarry Smith implicit none 354d8606c27SBarry Smith 355d8606c27SBarry Smith TS ts 356d8606c27SBarry Smith Vec X 357d8606c27SBarry Smith PetscReal user(6) 358d8606c27SBarry Smith PetscErrorCode ierr 359d8606c27SBarry Smith integer user_a, user_k, user_s 360d8606c27SBarry Smith parameter(user_a=1, user_k=3, user_s=5) 361d8606c27SBarry Smith 362d8606c27SBarry Smith DM da 363d8606c27SBarry Smith PetscInt mx, xs, xe, gxs, gxe 36442ce371bSBarry Smith PetscScalar, pointer :: xx(:) 365d8606c27SBarry Smith 366d8606c27SBarry Smith PetscCall(TSGetDM(ts, da, ierr)) 367d8606c27SBarry Smith PetscCall(GetLayout(da, mx, xs, xe, gxs, gxe, ierr)) 368d8606c27SBarry Smith 369d8606c27SBarry Smith! Get access to vector data 370ce78bad3SBarry Smith PetscCall(VecGetArray(X, xx, ierr)) 371d8606c27SBarry Smith 37242ce371bSBarry Smith PetscCall(FormInitialSolutionLocal(mx, xs, xe, gxs, gxe, xx, user(user_a), user(user_k), user(user_s), ierr)) 373d8606c27SBarry Smith 374ce78bad3SBarry Smith PetscCall(VecRestoreArray(X, xx, ierr)) 375d8606c27SBarry Smith end subroutine 376fe66ebccSMartin Diehlend program 377d8606c27SBarry Smith!/*TEST 378d8606c27SBarry Smith! 379d8606c27SBarry Smith! test: 380d8606c27SBarry Smith! args: -da_grid_x 200 -ts_arkimex_type 4 381d8606c27SBarry Smith! requires: !single 3823886731fSPierre Jolivet! output_file: output/empty.out 383d8606c27SBarry Smith! 384d8606c27SBarry Smith!TEST*/ 385