xref: /petsc/src/ts/tutorials/ex22f.F90 (revision 4820e4ea99a084ae862a8c395f732bc7c0e1a6d0)
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 Smithprogram main
18d8606c27SBarry Smith#include <petsc/finclude/petscts.h>
19d8606c27SBarry Smith#include <petsc/finclude/petscdmda.h>
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
157d8606c27SBarry Smith    do 10 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)
160d8606c27SBarry Smith10    continue
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
222d8606c27SBarry Smith        do 20 i = xs, xe
223d8606c27SBarry Smith          do 10 j = 1, 2
224*4820e4eaSBarry 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))
227*4820e4eaSBarry 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))
230*4820e4eaSBarry 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))
233*4820e4eaSBarry 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
240d8606c27SBarry Smith10          continue
241d8606c27SBarry Smith20          continue
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)
311d8606c27SBarry Smith              do 10 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))
319d8606c27SBarry Smith10              continue
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
339d8606c27SBarry Smith                  do 10 i = xs, xe
340d8606c27SBarry Smith                    r = i*hx
341*4820e4eaSBarry 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
348d8606c27SBarry Smith10                  continue
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 Diehl                    end 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