xref: /petsc/src/ts/tutorials/ex22f.F90 (revision fe66ebcc023cb303106674d426ee542bea707d38)
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      program 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))
128*fe66ebccSMartin Diehl      contains
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 Smith 10   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
224d8606c27SBarry Smith            if (i .eq. 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))
227d8606c27SBarry Smith            else if (i .eq. 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))
230d8606c27SBarry Smith            else if (i .eq. 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))
233d8606c27SBarry Smith            else if (i .eq. 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 Smith 10      continue
241d8606c27SBarry Smith 20   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 Smith 10   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
341d8606c27SBarry Smith         if (k(2) .ne. 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 Smith 10   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
376*fe66ebccSMartin 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
382d8606c27SBarry Smith!
383d8606c27SBarry Smith!TEST*/
384