1c4762a1bSJed Brown! Time-dependent advection-reaction PDE in 1d. Demonstrates IMEX methods 2c4762a1bSJed Brown! 3c4762a1bSJed Brown! u_t + a1*u_x = -k1*u + k2*v + s1 4c4762a1bSJed Brown! v_t + a2*v_x = k1*u - k2*v + s2 5ccfd86f1SBarry Smith! 0 < x < 1 6c4762a1bSJed Brown! a1 = 1, k1 = 10^6, s1 = 0, 7c4762a1bSJed Brown! a2 = 0, k2 = 2*k1, s2 = 1 8c4762a1bSJed Brown! 9c4762a1bSJed Brown! Initial conditions: 10c4762a1bSJed Brown! u(x,0) = 1 + s2*x 11c4762a1bSJed Brown! v(x,0) = k0/k1*u(x,0) + s1/k1 12c4762a1bSJed Brown! 13c4762a1bSJed Brown! Upstream boundary conditions: 14c4762a1bSJed Brown! u(0,t) = 1-sin(12*t)^4 15c4762a1bSJed Brown! 16c4762a1bSJed Brown 1777d968b7SBarry Smith module ex22f_mfmodule 18c4762a1bSJed Brown#include <petsc/finclude/petscts.h> 19c4762a1bSJed Brown use petscts 20c4762a1bSJed Brown PetscScalar::PETSC_SHIFT 21c4762a1bSJed Brown TS::tscontext 22c4762a1bSJed Brown Mat::Jmat 23c4762a1bSJed Brown PetscReal::MFuser(6) 2477d968b7SBarry Smith end module ex22f_mfmodule 25c4762a1bSJed Brown 26c4762a1bSJed Brownprogram main 2777d968b7SBarry Smith use ex22f_mfmodule 28ce78bad3SBarry Smith use petscdm 29c4762a1bSJed Brown implicit none 30c4762a1bSJed Brown 31c4762a1bSJed Brown ! 32c4762a1bSJed Brown ! Create an application context to contain data needed by the 33c4762a1bSJed Brown ! application-provided call-back routines, FormJacobian() and 34c4762a1bSJed Brown ! FormFunction(). We use a double precision array with six 35c4762a1bSJed Brown ! entries, two for each problem parameter a, k, s. 36c4762a1bSJed Brown ! 37c4762a1bSJed Brown PetscReal user(6) 38c4762a1bSJed Brown integer user_a,user_k,user_s 39c4762a1bSJed Brown parameter (user_a = 0,user_k = 2,user_s = 4) 40c4762a1bSJed Brown 41c4762a1bSJed Brown TS ts 42c4762a1bSJed Brown Vec X 43c4762a1bSJed Brown Mat J 44c4762a1bSJed Brown PetscInt mx 45c4762a1bSJed Brown PetscBool OptionSaveToDisk 46c4762a1bSJed Brown PetscErrorCode ierr 47c4762a1bSJed Brown DM da 48c4762a1bSJed Brown PetscReal ftime,dt 49c4762a1bSJed Brown PetscReal one,pone 50c4762a1bSJed Brown PetscInt im11,i2 51c4762a1bSJed Brown PetscBool flg 52c4762a1bSJed Brown 53c4762a1bSJed Brown PetscInt xs,xe,gxs,gxe,dof,gdof 54c4762a1bSJed Brown PetscScalar shell_shift 55c4762a1bSJed Brown Mat A 56c4762a1bSJed Brown 57c4762a1bSJed Brown im11 = 11 58c4762a1bSJed Brown i2 = 2 59c4762a1bSJed Brown one = 1.0 60c4762a1bSJed Brown pone = one / 10 61c4762a1bSJed Brown 62d8606c27SBarry Smith PetscCallA(PetscInitialize(ierr)) 63c4762a1bSJed Brown 64c4762a1bSJed Brown ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 65c4762a1bSJed Brown ! Create distributed array (DMDA) to manage parallel grid and vectors 66c4762a1bSJed Brown ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 675d83a8b1SBarry Smith PetscCallA(DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,im11,i2,i2,PETSC_NULL_INTEGER_ARRAY,da,ierr)) 68d8606c27SBarry Smith PetscCallA(DMSetFromOptions(da,ierr)) 69d8606c27SBarry Smith PetscCallA(DMSetUp(da,ierr)) 70c4762a1bSJed Brown 71c4762a1bSJed Brown ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 72ccfd86f1SBarry Smith ! Extract global vectors from DMDA 73c4762a1bSJed Brown ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 74d8606c27SBarry Smith PetscCallA(DMCreateGlobalVector(da,X,ierr)) 75c4762a1bSJed Brown 76c4762a1bSJed Brown ! Initialize user application context 77c4762a1bSJed Brown ! Use zero-based indexing for command line parameters to match ex22.c 78c4762a1bSJed Brown user(user_a+1) = 1.0 79d8606c27SBarry Smith PetscCallA(PetscOptionsGetReal(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-a0',user(user_a+1),flg,ierr)) 80c4762a1bSJed Brown user(user_a+2) = 0.0 81d8606c27SBarry Smith PetscCallA(PetscOptionsGetReal(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-a1',user(user_a+2),flg,ierr)) 82c4762a1bSJed Brown user(user_k+1) = 1000000.0 83d8606c27SBarry Smith PetscCallA(PetscOptionsGetReal(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-k0', user(user_k+1),flg,ierr)) 84c4762a1bSJed Brown user(user_k+2) = 2*user(user_k+1) 85d8606c27SBarry Smith PetscCallA(PetscOptionsGetReal(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-k1', user(user_k+2),flg,ierr)) 86c4762a1bSJed Brown user(user_s+1) = 0.0 87d8606c27SBarry Smith PetscCallA(PetscOptionsGetReal(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s0',user(user_s+1),flg,ierr)) 88c4762a1bSJed Brown user(user_s+2) = 1.0 89d8606c27SBarry Smith PetscCallA(PetscOptionsGetReal(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s1',user(user_s+2),flg,ierr)) 90c4762a1bSJed Brown 91c4762a1bSJed Brown OptionSaveToDisk=.FALSE. 92d8606c27SBarry Smith PetscCallA(PetscOptionsGetBool(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-sdisk',OptionSaveToDisk,flg,ierr)) 93c4762a1bSJed Brown ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 94c4762a1bSJed Brown ! Create timestepping solver context 95c4762a1bSJed Brown ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 96d8606c27SBarry Smith PetscCallA(TSCreate(PETSC_COMM_WORLD,ts,ierr)) 97c4762a1bSJed Brown tscontext=ts 98d8606c27SBarry Smith PetscCallA(TSSetDM(ts,da,ierr)) 99d8606c27SBarry Smith PetscCallA(TSSetType(ts,TSARKIMEX,ierr)) 100d8606c27SBarry Smith PetscCallA(TSSetRHSFunction(ts,PETSC_NULL_VEC,FormRHSFunction,user,ierr)) 101c4762a1bSJed Brown 102c4762a1bSJed Brown ! - - - - - - - - -- - - - - 103c4762a1bSJed Brown ! Matrix free setup 104d8606c27SBarry Smith PetscCallA(GetLayout(da,mx,xs,xe,gxs,gxe,ierr)) 105c4762a1bSJed Brown dof=i2*(xe-xs+1) 106c4762a1bSJed Brown gdof=i2*(gxe-gxs+1) 107d8606c27SBarry Smith PetscCallA(MatCreateShell(PETSC_COMM_WORLD,dof,dof,gdof,gdof,shell_shift,A,ierr)) 108c4762a1bSJed Brown 109d8606c27SBarry Smith PetscCallA(MatShellSetOperation(A,MATOP_MULT,MyMult,ierr)) 110c4762a1bSJed Brown ! - - - - - - - - - - - - 111c4762a1bSJed Brown 112d8606c27SBarry Smith PetscCallA(TSSetIFunction(ts,PETSC_NULL_VEC,FormIFunction,user,ierr)) 113d8606c27SBarry Smith PetscCallA(DMSetMatType(da,MATAIJ,ierr)) 114d8606c27SBarry Smith PetscCallA(DMCreateMatrix(da,J,ierr)) 115c4762a1bSJed Brown 116c4762a1bSJed Brown Jmat=J 117c4762a1bSJed Brown 118d8606c27SBarry Smith PetscCallA(TSSetIJacobian(ts,J,J,FormIJacobian,user,ierr)) 119d8606c27SBarry Smith PetscCallA(TSSetIJacobian(ts,A,A,FormIJacobianMF,user,ierr)) 120c4762a1bSJed Brown 121c4762a1bSJed Brown ftime = 1.0 122d8606c27SBarry Smith PetscCallA(TSSetMaxTime(ts,ftime,ierr)) 123d8606c27SBarry Smith PetscCallA(TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER,ierr)) 124c4762a1bSJed Brown 125c4762a1bSJed Brown ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 126c4762a1bSJed Brown ! Set initial conditions 127c4762a1bSJed Brown ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 128d8606c27SBarry Smith PetscCallA(FormInitialSolution(ts,X,user,ierr)) 129d8606c27SBarry Smith PetscCallA(TSSetSolution(ts,X,ierr)) 130d8606c27SBarry Smith PetscCallA(VecGetSize(X,mx,ierr)) 131c4762a1bSJed Brown ! Advective CFL, I don't know why it needs so much safety factor. 132ccfd86f1SBarry Smith dt = pone * max(user(user_a+1),user(user_a+2)) / mx 133d8606c27SBarry Smith PetscCallA(TSSetTimeStep(ts,dt,ierr)) 134c4762a1bSJed Brown 135c4762a1bSJed Brown ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 136c4762a1bSJed Brown ! Set runtime options 137c4762a1bSJed Brown ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 138d8606c27SBarry Smith PetscCallA(TSSetFromOptions(ts,ierr)) 139c4762a1bSJed Brown 140c4762a1bSJed Brown ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 141c4762a1bSJed Brown ! Solve nonlinear system 142c4762a1bSJed Brown ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 143d8606c27SBarry Smith PetscCallA(TSSolve(ts,X,ierr)) 144c4762a1bSJed Brown 145c4762a1bSJed Brown if (OptionSaveToDisk) then 146d8606c27SBarry Smith PetscCallA(GetLayout(da,mx,xs,xe,gxs,gxe,ierr)) 147c4762a1bSJed Brown dof=i2*(xe-xs+1) 148c4762a1bSJed Brown gdof=i2*(gxe-gxs+1) 149d8606c27SBarry Smith call SaveSolutionToDisk(da,X,gdof,xs,xe) 150c4762a1bSJed Brown end if 151c4762a1bSJed Brown 152c4762a1bSJed Brown ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 153c4762a1bSJed Brown ! Free work space. 154c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 155d8606c27SBarry Smith PetscCallA(MatDestroy(A,ierr)) 156d8606c27SBarry Smith PetscCallA(MatDestroy(J,ierr)) 157d8606c27SBarry Smith PetscCallA(VecDestroy(X,ierr)) 158d8606c27SBarry Smith PetscCallA(TSDestroy(ts,ierr)) 159d8606c27SBarry Smith PetscCallA(DMDestroy(da,ierr)) 160d8606c27SBarry Smith PetscCallA(PetscFinalize(ierr)) 161*fe66ebccSMartin Diehl contains 162c4762a1bSJed Brown 163c4762a1bSJed Brown! Small helper to extract the layout, result uses 1-based indexing. 164c4762a1bSJed Brown subroutine GetLayout(da,mx,xs,xe,gxs,gxe,ierr) 165ce78bad3SBarry Smith use petscdm 166c4762a1bSJed Brown implicit none 167c4762a1bSJed Brown 168c4762a1bSJed Brown DM da 169c4762a1bSJed Brown PetscInt mx,xs,xe,gxs,gxe 170c4762a1bSJed Brown PetscErrorCode ierr 171c4762a1bSJed Brown PetscInt xm,gxm 1725d83a8b1SBarry 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)) 173d8606c27SBarry Smith PetscCall(DMDAGetCorners(da,xs,PETSC_NULL_INTEGER,PETSC_NULL_INTEGER,xm,PETSC_NULL_INTEGER,PETSC_NULL_INTEGER,ierr)) 174d8606c27SBarry Smith PetscCall(DMDAGetGhostCorners(da,gxs,PETSC_NULL_INTEGER,PETSC_NULL_INTEGER,gxm,PETSC_NULL_INTEGER,PETSC_NULL_INTEGER,ierr)) 175c4762a1bSJed Brown xs = xs + 1 176c4762a1bSJed Brown gxs = gxs + 1 177c4762a1bSJed Brown xe = xs + xm - 1 178c4762a1bSJed Brown gxe = gxs + gxm - 1 179c4762a1bSJed Brownend subroutine GetLayout 180c4762a1bSJed Brown 181c4762a1bSJed Brownsubroutine FormIFunctionLocal(mx,xs,xe,gxs,gxe,x,xdot,f,a,k,s,ierr) 182c4762a1bSJed Brown implicit none 183c4762a1bSJed Brown PetscInt mx,xs,xe,gxs,gxe 184c4762a1bSJed Brown PetscScalar x(2,xs:xe) 185c4762a1bSJed Brown PetscScalar xdot(2,xs:xe) 186c4762a1bSJed Brown PetscScalar f(2,xs:xe) 187c4762a1bSJed Brown PetscReal a(2),k(2),s(2) 188c4762a1bSJed Brown PetscErrorCode ierr 189c4762a1bSJed Brown PetscInt i 190c4762a1bSJed Brown do i = xs,xe 191c4762a1bSJed Brown f(1,i) = xdot(1,i) + k(1)*x(1,i) - k(2)*x(2,i) - s(1) 192c4762a1bSJed Brown f(2,i) = xdot(2,i) - k(1)*x(1,i) + k(2)*x(2,i) - s(2) 193c4762a1bSJed Brown end do 194c4762a1bSJed Brownend subroutine FormIFunctionLocal 195c4762a1bSJed Brown 196c4762a1bSJed Brownsubroutine FormIFunction(ts,t,X,Xdot,F,user,ierr) 197ce78bad3SBarry Smith use petscdm 198c4762a1bSJed Brown use petscts 199c4762a1bSJed Brown implicit none 200c4762a1bSJed Brown 201c4762a1bSJed Brown TS ts 202c4762a1bSJed Brown PetscReal t 203c4762a1bSJed Brown Vec X,Xdot,F 204c4762a1bSJed Brown PetscReal user(6) 205c4762a1bSJed Brown PetscErrorCode ierr 206c4762a1bSJed Brown integer user_a,user_k,user_s 207c4762a1bSJed Brown parameter (user_a = 1,user_k = 3,user_s = 5) 208c4762a1bSJed Brown 209c4762a1bSJed Brown DM da 210c4762a1bSJed Brown PetscInt mx,xs,xe,gxs,gxe 21142ce371bSBarry Smith PetscScalar,pointer :: xx(:),xxdot(:),ff(:) 212c4762a1bSJed Brown 213d8606c27SBarry Smith PetscCall(TSGetDM(ts,da,ierr)) 214d8606c27SBarry Smith PetscCall(GetLayout(da,mx,xs,xe,gxs,gxe,ierr)) 215c4762a1bSJed Brown 216c4762a1bSJed Brown ! Get access to vector data 217ce78bad3SBarry Smith PetscCall(VecGetArrayRead(X,xx,ierr)) 218ce78bad3SBarry Smith PetscCall(VecGetArrayRead(Xdot,xxdot,ierr)) 219ce78bad3SBarry Smith PetscCall(VecGetArray(F,ff,ierr)) 220c4762a1bSJed Brown 22142ce371bSBarry Smith PetscCall(FormIFunctionLocal(mx,xs,xe,gxs,gxe,xx,xxdot,ff,user(user_a),user(user_k),user(user_s),ierr)) 222c4762a1bSJed Brown 223ce78bad3SBarry Smith PetscCall(VecRestoreArrayRead(X,xx,ierr)) 224ce78bad3SBarry Smith PetscCall(VecRestoreArrayRead(Xdot,xxdot,ierr)) 225ce78bad3SBarry Smith PetscCall(VecRestoreArray(F,ff,ierr)) 226c4762a1bSJed Brownend subroutine FormIFunction 227c4762a1bSJed Brown 228c4762a1bSJed Brownsubroutine FormRHSFunctionLocal(mx,xs,xe,gxs,gxe,t,x,f,a,k,s,ierr) 229c4762a1bSJed Brown implicit none 230c4762a1bSJed Brown PetscInt mx,xs,xe,gxs,gxe 231c4762a1bSJed Brown PetscReal t 232c4762a1bSJed Brown PetscScalar x(2,gxs:gxe),f(2,xs:xe) 233c4762a1bSJed Brown PetscReal a(2),k(2),s(2) 234c4762a1bSJed Brown PetscErrorCode ierr 235c4762a1bSJed Brown PetscInt i,j 236c4762a1bSJed Brown PetscReal hx,u0t(2) 237c4762a1bSJed Brown PetscReal one,two,three,four,six,twelve 238c4762a1bSJed Brown PetscReal half,third,twothird,sixth 239c4762a1bSJed Brown PetscReal twelfth 240c4762a1bSJed Brown 241c4762a1bSJed Brown one = 1.0 242c4762a1bSJed Brown two = 2.0 243c4762a1bSJed Brown three = 3.0 244c4762a1bSJed Brown four = 4.0 245c4762a1bSJed Brown six = 6.0 246c4762a1bSJed Brown twelve = 12.0 247c4762a1bSJed Brown hx = one / mx 248c4762a1bSJed Brown u0t(1) = one - sin(twelve*t)**four 249c4762a1bSJed Brown u0t(2) = 0.0 250c4762a1bSJed Brown half = one/two 251c4762a1bSJed Brown third = one / three 252c4762a1bSJed Brown twothird = two / three 253c4762a1bSJed Brown sixth = one / six 254c4762a1bSJed Brown twelfth = one / twelve 255c4762a1bSJed Brown do i = xs,xe 256c4762a1bSJed Brown do j = 1,2 257c4762a1bSJed Brown if (i .eq. 1) then 258c4762a1bSJed Brown f(j,i) = a(j)/hx*(third*u0t(j) + half*x(j,i) - x(j,i+1) + sixth*x(j,i+2)) 259c4762a1bSJed Brown else if (i .eq. 2) then 260c4762a1bSJed Brown f(j,i) = a(j)/hx*(-twelfth*u0t(j) + twothird*x(j,i-1) - twothird*x(j,i+1) + twelfth*x(j,i+2)) 261c4762a1bSJed Brown else if (i .eq. mx-1) then 262c4762a1bSJed Brown f(j,i) = a(j)/hx*(-sixth*x(j,i-2) + x(j,i-1) - half*x(j,i) -third*x(j,i+1)) 263c4762a1bSJed Brown else if (i .eq. mx) then 264c4762a1bSJed Brown f(j,i) = a(j)/hx*(-x(j,i) + x(j,i-1)) 265c4762a1bSJed Brown else 266c4762a1bSJed Brown f(j,i) = a(j)/hx*(-twelfth*x(j,i-2) + twothird*x(j,i-1) - twothird*x(j,i+1) + twelfth*x(j,i+2)) 267c4762a1bSJed Brown end if 268c4762a1bSJed Brown end do 269c4762a1bSJed Brown end do 270c4762a1bSJed Brown 271c4762a1bSJed Brown#ifdef EXPLICIT_INTEGRATOR22 272c4762a1bSJed Brown do i = xs,xe 273c4762a1bSJed Brown f(1,i) = f(1,i) -( k(1)*x(1,i) - k(2)*x(2,i) - s(1)) 274c4762a1bSJed Brown f(2,i) = f(2,i) -(- k(1)*x(1,i) + k(2)*x(2,i) - s(2)) 275c4762a1bSJed Brown end do 276c4762a1bSJed Brown#endif 277c4762a1bSJed Brown 278c4762a1bSJed Brownend subroutine FormRHSFunctionLocal 279c4762a1bSJed Brown 280c4762a1bSJed Brownsubroutine FormRHSFunction(ts,t,X,F,user,ierr) 281c4762a1bSJed Brown use petscts 282ce78bad3SBarry Smith use petscdm 283c4762a1bSJed Brown implicit none 284c4762a1bSJed Brown 285c4762a1bSJed Brown TS ts 286c4762a1bSJed Brown PetscReal t 287c4762a1bSJed Brown Vec X,F 288c4762a1bSJed Brown PetscReal user(6) 289c4762a1bSJed Brown PetscErrorCode ierr 290c4762a1bSJed Brown integer user_a,user_k,user_s 291c4762a1bSJed Brown parameter (user_a = 1,user_k = 3,user_s = 5) 292c4762a1bSJed Brown DM da 293c4762a1bSJed Brown Vec Xloc 294c4762a1bSJed Brown PetscInt mx,xs,xe,gxs,gxe 29542ce371bSBarry Smith PetscScalar,pointer :: xx(:), ff(:) 296c4762a1bSJed Brown 297d8606c27SBarry Smith PetscCall(TSGetDM(ts,da,ierr)) 298d8606c27SBarry Smith PetscCall(GetLayout(da,mx,xs,xe,gxs,gxe,ierr)) 299c4762a1bSJed Brown 300c4762a1bSJed Brown ! Scatter ghost points to local vector,using the 2-step process 301c4762a1bSJed Brown ! DMGlobalToLocalBegin(),DMGlobalToLocalEnd(). 302c4762a1bSJed Brown ! By placing code between these two statements, computations can be 303c4762a1bSJed Brown ! done while messages are in transition. 304d8606c27SBarry Smith PetscCall(DMGetLocalVector(da,Xloc,ierr)) 305d8606c27SBarry Smith PetscCall(DMGlobalToLocalBegin(da,X,INSERT_VALUES,Xloc,ierr)) 306d8606c27SBarry Smith PetscCall(DMGlobalToLocalEnd(da,X,INSERT_VALUES,Xloc,ierr)) 307c4762a1bSJed Brown 308c4762a1bSJed Brown ! Get access to vector data 309ce78bad3SBarry Smith PetscCall(VecGetArrayRead(Xloc,xx,ierr)) 310ce78bad3SBarry Smith PetscCall(VecGetArray(F,ff,ierr)) 311c4762a1bSJed Brown 31242ce371bSBarry Smith PetscCall(FormRHSFunctionLocal(mx,xs,xe,gxs,gxe,t,xx,ff,user(user_a),user(user_k),user(user_s),ierr)) 313c4762a1bSJed Brown 314ce78bad3SBarry Smith PetscCall(VecRestoreArrayRead(Xloc,xx,ierr)) 315ce78bad3SBarry Smith PetscCall(VecRestoreArray(F,ff,ierr)) 316d8606c27SBarry Smith PetscCall(DMRestoreLocalVector(da,Xloc,ierr)) 317c4762a1bSJed Brownend subroutine FormRHSFunction 318c4762a1bSJed Brown 319c4762a1bSJed Brown! --------------------------------------------------------------------- 320c4762a1bSJed Brown! 321c4762a1bSJed Brown! IJacobian - Compute IJacobian = dF/dU + shift*dF/dUdot 322c4762a1bSJed Brown! 323c4762a1bSJed Brownsubroutine FormIJacobian(ts,t,X,Xdot,shift,J,Jpre,user,ierr) 324c4762a1bSJed Brown use petscts 325ce78bad3SBarry Smith use petscdm 326c4762a1bSJed Brown implicit none 327c4762a1bSJed Brown 328c4762a1bSJed Brown TS ts 329c4762a1bSJed Brown PetscReal t,shift 330c4762a1bSJed Brown Vec X,Xdot 331c4762a1bSJed Brown Mat J,Jpre 332c4762a1bSJed Brown PetscReal user(6) 333c4762a1bSJed Brown PetscErrorCode ierr 334c4762a1bSJed Brown integer user_a,user_k,user_s 335c4762a1bSJed Brown parameter (user_a = 0,user_k = 2,user_s = 4) 336c4762a1bSJed Brown 337c4762a1bSJed Brown DM da 338c4762a1bSJed Brown PetscInt mx,xs,xe,gxs,gxe 339c4762a1bSJed Brown PetscInt i,i1,row,col 340ccfd86f1SBarry Smith PetscReal k1,k2 341c4762a1bSJed Brown PetscScalar val(4) 342c4762a1bSJed Brown 343d8606c27SBarry Smith PetscCall(TSGetDM(ts,da,ierr)) 344d8606c27SBarry Smith PetscCall(GetLayout(da,mx,xs,xe,gxs,gxe,ierr)) 345c4762a1bSJed Brown 346c4762a1bSJed Brown i1 = 1 347c4762a1bSJed Brown k1 = user(user_k+1) 348c4762a1bSJed Brown k2 = user(user_k+2) 349c4762a1bSJed Brown do i = xs,xe 350c4762a1bSJed Brown row = i-gxs 351c4762a1bSJed Brown col = i-gxs 352c4762a1bSJed Brown val(1) = shift + k1 353c4762a1bSJed Brown val(2) = -k2 354c4762a1bSJed Brown val(3) = -k1 355c4762a1bSJed Brown val(4) = shift + k2 3565d83a8b1SBarry Smith PetscCall(MatSetValuesBlockedLocal(Jpre,i1,[row],i1,[col],val,INSERT_VALUES,ierr)) 357c4762a1bSJed Brown end do 358d8606c27SBarry Smith PetscCall(MatAssemblyBegin(Jpre,MAT_FINAL_ASSEMBLY,ierr)) 359d8606c27SBarry Smith PetscCall(MatAssemblyEnd(Jpre,MAT_FINAL_ASSEMBLY,ierr)) 360c4762a1bSJed Brown if (J /= Jpre) then 361d8606c27SBarry Smith PetscCall(MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY,ierr)) 362d8606c27SBarry Smith PetscCall(MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY,ierr)) 363c4762a1bSJed Brown end if 364c4762a1bSJed Brownend subroutine FormIJacobian 365c4762a1bSJed Brown 366c4762a1bSJed Brownsubroutine FormInitialSolutionLocal(mx,xs,xe,gxs,gxe,x,a,k,s,ierr) 367c4762a1bSJed Brown implicit none 368c4762a1bSJed Brown PetscInt mx,xs,xe,gxs,gxe 369c4762a1bSJed Brown PetscScalar x(2,xs:xe) 370c4762a1bSJed Brown PetscReal a(2),k(2),s(2) 371c4762a1bSJed Brown PetscErrorCode ierr 372c4762a1bSJed Brown 373c4762a1bSJed Brown PetscInt i 374c4762a1bSJed Brown PetscReal one,hx,r,ik 375c4762a1bSJed Brown one = 1.0 376c4762a1bSJed Brown hx = one / mx 377c4762a1bSJed Brown do i=xs,xe 378c4762a1bSJed Brown r = i*hx 379c4762a1bSJed Brown if (k(2) .ne. 0.0) then 380c4762a1bSJed Brown ik = one/k(2) 381c4762a1bSJed Brown else 382c4762a1bSJed Brown ik = one 383c4762a1bSJed Brown end if 384c4762a1bSJed Brown x(1,i) = one + s(2)*r 385c4762a1bSJed Brown x(2,i) = k(1)*ik*x(1,i) + s(2)*ik 386c4762a1bSJed Brown end do 387c4762a1bSJed Brownend subroutine FormInitialSolutionLocal 388c4762a1bSJed Brown 389c4762a1bSJed Brownsubroutine FormInitialSolution(ts,X,user,ierr) 390c4762a1bSJed Brown use petscts 391ce78bad3SBarry Smith use petscdm 392c4762a1bSJed Brown implicit none 393c4762a1bSJed Brown 394c4762a1bSJed Brown TS ts 395c4762a1bSJed Brown Vec X 396c4762a1bSJed Brown PetscReal user(6) 397c4762a1bSJed Brown PetscErrorCode ierr 398c4762a1bSJed Brown integer user_a,user_k,user_s 399c4762a1bSJed Brown parameter (user_a = 1,user_k = 3,user_s = 5) 400c4762a1bSJed Brown 401c4762a1bSJed Brown DM da 402c4762a1bSJed Brown PetscInt mx,xs,xe,gxs,gxe 40342ce371bSBarry Smith PetscScalar,pointer :: xx(:) 404c4762a1bSJed Brown 405d8606c27SBarry Smith PetscCall(TSGetDM(ts,da,ierr)) 406d8606c27SBarry Smith PetscCall(GetLayout(da,mx,xs,xe,gxs,gxe,ierr)) 407c4762a1bSJed Brown 408c4762a1bSJed Brown ! Get access to vector data 409ce78bad3SBarry Smith PetscCall(VecGetArray(X,xx,ierr)) 410c4762a1bSJed Brown 41142ce371bSBarry Smith PetscCall(FormInitialSolutionLocal(mx,xs,xe,gxs,gxe,xx,user(user_a),user(user_k),user(user_s),ierr)) 412c4762a1bSJed Brown 413ce78bad3SBarry Smith PetscCall(VecRestoreArray(X,xx,ierr)) 414c4762a1bSJed Brownend subroutine FormInitialSolution 415c4762a1bSJed Brown 416c4762a1bSJed Brown! --------------------------------------------------------------------- 417c4762a1bSJed Brown! 418c4762a1bSJed Brown! IJacobian - Compute IJacobian = dF/dU + shift*dF/dUdot 419c4762a1bSJed Brown! 420c4762a1bSJed Brownsubroutine FormIJacobianMF(ts,t,X,Xdot,shift,J,Jpre,user,ierr) 42177d968b7SBarry Smith use ex22f_mfmodule 422c4762a1bSJed Brown implicit none 423c4762a1bSJed Brown TS ts 424c4762a1bSJed Brown PetscReal t,shift 425c4762a1bSJed Brown Vec X,Xdot 426c4762a1bSJed Brown Mat J,Jpre 427c4762a1bSJed Brown PetscReal user(6) 428c4762a1bSJed Brown PetscErrorCode ierr 429c4762a1bSJed Brown 430c4762a1bSJed Brown PETSC_SHIFT=shift 431c4762a1bSJed Brown MFuser=user 432c4762a1bSJed Brown 433c4762a1bSJed Brownend subroutine FormIJacobianMF 434c4762a1bSJed Brown 435c4762a1bSJed Brown! ------------------------------------------------------------------- 436c4762a1bSJed Brown! 437c4762a1bSJed Brown! MyMult - user provided matrix multiply 438c4762a1bSJed Brown! 439c4762a1bSJed Brown! Input Parameters: 440c4762a1bSJed Brown!. X - input vector 441c4762a1bSJed Brown! 442c4762a1bSJed Brown! Output Parameter: 443c4762a1bSJed Brown!. F - function vector 444c4762a1bSJed Brown! 445c4762a1bSJed Brownsubroutine MyMult(A,X,F,ierr) 44677d968b7SBarry Smith use ex22f_mfmodule 447c4762a1bSJed Brown implicit none 448c4762a1bSJed Brown 449c4762a1bSJed Brown Mat A 450c4762a1bSJed Brown Vec X,F 451c4762a1bSJed Brown 452c4762a1bSJed Brown PetscErrorCode ierr 453c4762a1bSJed Brown PetscScalar shift 454c4762a1bSJed Brown 455c4762a1bSJed Brown! Mat J,Jpre 456c4762a1bSJed Brown 457c4762a1bSJed Brown PetscReal user(6) 458c4762a1bSJed Brown 459c4762a1bSJed Brown integer user_a,user_k,user_s 460c4762a1bSJed Brown parameter (user_a = 0,user_k = 2,user_s = 4) 461c4762a1bSJed Brown 462c4762a1bSJed Brown DM da 463c4762a1bSJed Brown PetscInt mx,xs,xe,gxs,gxe 464c4762a1bSJed Brown PetscInt i,i1,row,col 465ccfd86f1SBarry Smith PetscReal k1,k2 466c4762a1bSJed Brown PetscScalar val(4) 467c4762a1bSJed Brown 468c4762a1bSJed Brown shift=PETSC_SHIFT 469c4762a1bSJed Brown user=MFuser 470c4762a1bSJed Brown 471d8606c27SBarry Smith PetscCall(TSGetDM(tscontext,da,ierr)) 472d8606c27SBarry Smith PetscCall(GetLayout(da,mx,xs,xe,gxs,gxe,ierr)) 473c4762a1bSJed Brown 474c4762a1bSJed Brown i1 = 1 475c4762a1bSJed Brown k1 = user(user_k+1) 476c4762a1bSJed Brown k2 = user(user_k+2) 477c4762a1bSJed Brown 478c4762a1bSJed Brown do i = xs,xe 479c4762a1bSJed Brown row = i-gxs 480c4762a1bSJed Brown col = i-gxs 481c4762a1bSJed Brown val(1) = shift + k1 482c4762a1bSJed Brown val(2) = -k2 483c4762a1bSJed Brown val(3) = -k1 484c4762a1bSJed Brown val(4) = shift + k2 4855d83a8b1SBarry Smith PetscCall(MatSetValuesBlockedLocal(Jmat,i1,[row],i1,[col],val,INSERT_VALUES,ierr)) 486c4762a1bSJed Brown end do 487c4762a1bSJed Brown 488d8606c27SBarry Smith! PetscCall(MatAssemblyBegin(Jpre,MAT_FINAL_ASSEMBLY,ierr)) 489d8606c27SBarry Smith! PetscCall(MatAssemblyEnd(Jpre,MAT_FINAL_ASSEMBLY,ierr)) 490c4762a1bSJed Brown! if (J /= Jpre) then 491d8606c27SBarry Smith PetscCall(MatAssemblyBegin(Jmat,MAT_FINAL_ASSEMBLY,ierr)) 492d8606c27SBarry Smith PetscCall(MatAssemblyEnd(Jmat,MAT_FINAL_ASSEMBLY,ierr)) 493c4762a1bSJed Brown! end if 494c4762a1bSJed Brown 495d8606c27SBarry Smith PetscCall(MatMult(Jmat,X,F,ierr)) 496c4762a1bSJed Brown 497c4762a1bSJed Brownend subroutine MyMult 498c4762a1bSJed Brown 499c4762a1bSJed Brown! 500c4762a1bSJed Brownsubroutine SaveSolutionToDisk(da,X,gdof,xs,xe) 501ce78bad3SBarry Smith use petscdm 502c4762a1bSJed Brown implicit none 503c4762a1bSJed Brown 504c4762a1bSJed Brown Vec X 505c4762a1bSJed Brown DM da 506c4762a1bSJed Brown PetscInt xs,xe,two 507c4762a1bSJed Brown PetscInt gdof,i 508c4762a1bSJed Brown PetscErrorCode ierr 509c4762a1bSJed Brown PetscScalar data2(2,xs:xe),data(gdof) 51042ce371bSBarry Smith PetscScalar,pointer :: xx(:) 511c4762a1bSJed Brown 512ce78bad3SBarry Smith PetscCall(VecGetArrayRead(X,xx,ierr)) 513c4762a1bSJed Brown 514c4762a1bSJed Brown two = 2 51542ce371bSBarry Smith data2=reshape(xx(gdof:gdof),(/two,xe-xs+1/)) 516c4762a1bSJed Brown data=reshape(data2,(/gdof/)) 517c4762a1bSJed Brown open(1020,file='solution_out_ex22f_mf.txt') 518c4762a1bSJed Brown do i=1,gdof 519c4762a1bSJed Brown write(1020,'(e24.16,1x)') data(i) 520c4762a1bSJed Brown end do 521c4762a1bSJed Brown close(1020) 522c4762a1bSJed Brown 523ce78bad3SBarry Smith PetscCall(VecRestoreArrayRead(X,xx,ierr)) 524c4762a1bSJed Brownend subroutine SaveSolutionToDisk 525*fe66ebccSMartin Diehlend program main 526c4762a1bSJed Brown 527c4762a1bSJed Brown!/*TEST 528c4762a1bSJed Brown! 529c4762a1bSJed Brown! test: 530c4762a1bSJed Brown! args: -da_grid_x 200 -ts_arkimex_type 4 531c4762a1bSJed Brown! requires: !single 532c4762a1bSJed Brown! output_file: output/ex22f_mf_1.out 533c4762a1bSJed Brown! 534c4762a1bSJed Brown!TEST*/ 535