1d8606c27SBarry Smith! Program usage: mpiexec -n <proc> eptorsion2f [all TAO options] 2d8606c27SBarry Smith! 3d8606c27SBarry Smith! Description: This example demonstrates use of the TAO package to solve 4d8606c27SBarry Smith! unconstrained minimization problems in parallel. This example is based 5d8606c27SBarry Smith! on the Elastic-Plastic Torsion (dept) problem from the MINPACK-2 test suite. 6d8606c27SBarry Smith! The command line options are: 7d8606c27SBarry Smith! -mx <xg>, where <xg> = number of grid points in the 1st coordinate direction 8d8606c27SBarry Smith! -my <yg>, where <yg> = number of grid points in the 2nd coordinate direction 9d8606c27SBarry Smith! -par <param>, where <param> = angle of twist per unit length 10d8606c27SBarry Smith! 11d8606c27SBarry Smith! 12d8606c27SBarry Smith! ---------------------------------------------------------------------- 13d8606c27SBarry Smith! 14d8606c27SBarry Smith! Elastic-plastic torsion problem. 15d8606c27SBarry Smith! 16d8606c27SBarry Smith! The elastic plastic torsion problem arises from the deconverged 17d8606c27SBarry Smith! of the stress field on an infinitely long cylindrical bar, which is 18d8606c27SBarry Smith! equivalent to the solution of the following problem: 19d8606c27SBarry Smith! min{ .5 * integral(||gradient(v(x))||^2 dx) - C * integral(v(x) dx)} 20d8606c27SBarry Smith! where C is the torsion angle per unit length. 21d8606c27SBarry Smith! 22d8606c27SBarry Smith! The C version of this code is eptorsion2.c 23d8606c27SBarry Smith! 24d8606c27SBarry Smith! ---------------------------------------------------------------------- 25ce78bad3SBarry Smith#include "petsc/finclude/petscdmda.h" 26d8606c27SBarry Smith#include "petsc/finclude/petsctao.h" 27*c5e229c2SMartin Diehlmodule eptorsion2fmodule 28d8606c27SBarry Smith use petscdmda 29d8606c27SBarry Smith use petsctao 30d8606c27SBarry Smith implicit none 31d8606c27SBarry Smith 32392a88c0SBlaise Bourdin type(tVec) localX 33392a88c0SBlaise Bourdin type(tDM) dm 34d8606c27SBarry Smith PetscReal param 35d8606c27SBarry Smith PetscInt mx, my 36d8606c27SBarry Smithend module 37d8606c27SBarry Smith 3877d968b7SBarry Smithuse eptorsion2fmodule 39d8606c27SBarry Smithimplicit none 40d8606c27SBarry Smith! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 41d8606c27SBarry Smith! Variable declarations 42d8606c27SBarry Smith! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 43d8606c27SBarry Smith! 44d8606c27SBarry Smith! See additional variable declarations in the file eptorsion2f.h 45d8606c27SBarry Smith! 46d8606c27SBarry SmithPetscErrorCode ierr ! used to check for functions returning nonzeros 47392a88c0SBlaise Bourdintype(tVec) x ! solution vector 48392a88c0SBlaise Bourdintype(tMat) H ! hessian matrix 49d8606c27SBarry SmithPetscInt Nx, Ny ! number of processes in x- and y- directions 50ce78bad3SBarry Smithtype(tTao) ta ! Tao solver context 51d8606c27SBarry SmithPetscBool flg 52d8606c27SBarry SmithPetscInt i1 53d8606c27SBarry SmithPetscInt dummy 54d8606c27SBarry Smith 55d8606c27SBarry Smith! Note: Any user-defined Fortran routines (such as FormGradient) 56d8606c27SBarry Smith! MUST be declared as external. 57d8606c27SBarry Smith 58d8606c27SBarry Smithexternal FormInitialGuess, FormFunctionGradient, ComputeHessian 59d8606c27SBarry Smithexternal Monitor, ConvergenceTest 60d8606c27SBarry Smith 61d8606c27SBarry Smithi1 = 1 62d8606c27SBarry Smith 63d8606c27SBarry Smith! Initialize TAO, PETSc contexts 64d8606c27SBarry SmithPetscCallA(PetscInitialize(ierr)) 65d8606c27SBarry Smith 66d8606c27SBarry Smith! Specify default parameters 67d8606c27SBarry Smithparam = 5.0 68d8606c27SBarry Smithmx = 10 69d8606c27SBarry Smithmy = 10 70d8606c27SBarry SmithNx = PETSC_DECIDE 71d8606c27SBarry SmithNy = PETSC_DECIDE 72d8606c27SBarry Smith 73d8606c27SBarry Smith! Check for any command line arguments that might override defaults 74d8606c27SBarry SmithPetscCallA(PetscOptionsGetInt(PETSC_NULL_OPTIONS, PETSC_NULL_CHARACTER, '-mx', mx, flg, ierr)) 75d8606c27SBarry SmithPetscCallA(PetscOptionsGetInt(PETSC_NULL_OPTIONS, PETSC_NULL_CHARACTER, '-my', my, flg, ierr)) 76d8606c27SBarry SmithPetscCallA(PetscOptionsGetReal(PETSC_NULL_OPTIONS, PETSC_NULL_CHARACTER, '-par', param, flg, ierr)) 77d8606c27SBarry Smith 78d8606c27SBarry Smith! Set up distributed array and vectors 795d83a8b1SBarry SmithPetscCallA(DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DMDA_STENCIL_BOX, mx, my, Nx, Ny, i1, i1, PETSC_NULL_INTEGER_ARRAY, PETSC_NULL_INTEGER_ARRAY, dm, ierr)) 80d8606c27SBarry SmithPetscCallA(DMSetFromOptions(dm, ierr)) 81d8606c27SBarry SmithPetscCallA(DMSetUp(dm, ierr)) 82d8606c27SBarry Smith 83d8606c27SBarry Smith! Create vectors 84d8606c27SBarry SmithPetscCallA(DMCreateGlobalVector(dm, x, ierr)) 85d8606c27SBarry SmithPetscCallA(DMCreateLocalVector(dm, localX, ierr)) 86d8606c27SBarry Smith 87d8606c27SBarry Smith! Create Hessian 88d8606c27SBarry SmithPetscCallA(DMCreateMatrix(dm, H, ierr)) 89d8606c27SBarry SmithPetscCallA(MatSetOption(H, MAT_SYMMETRIC, PETSC_TRUE, ierr)) 90d8606c27SBarry Smith 91d8606c27SBarry Smith! The TAO code begins here 92d8606c27SBarry Smith 93d8606c27SBarry Smith! Create TAO solver 94ce78bad3SBarry SmithPetscCallA(TaoCreate(PETSC_COMM_WORLD, ta, ierr)) 95ce78bad3SBarry SmithPetscCallA(TaoSetType(ta, TAOCG, ierr)) 96d8606c27SBarry Smith 97d8606c27SBarry Smith! Set routines for function and gradient evaluation 98d8606c27SBarry Smith 99ce78bad3SBarry SmithPetscCallA(TaoSetObjectiveAndGradient(ta, PETSC_NULL_VEC, FormFunctionGradient, 0, ierr)) 100ce78bad3SBarry SmithPetscCallA(TaoSetHessian(ta, H, H, ComputeHessian, 0, ierr)) 101d8606c27SBarry Smith 102d8606c27SBarry Smith! Set initial guess 103d8606c27SBarry SmithPetscCallA(FormInitialGuess(x, ierr)) 104ce78bad3SBarry SmithPetscCallA(TaoSetSolution(ta, x, ierr)) 105d8606c27SBarry Smith 106d8606c27SBarry SmithPetscCallA(PetscOptionsHasName(PETSC_NULL_OPTIONS, PETSC_NULL_CHARACTER, '-testmonitor', flg, ierr)) 107d8606c27SBarry Smithif (flg) then 108ce78bad3SBarry Smith PetscCallA(TaoMonitorSet(ta, Monitor, dummy, PETSC_NULL_FUNCTION, ierr)) 109d8606c27SBarry Smithend if 110d8606c27SBarry Smith 111d8606c27SBarry SmithPetscCallA(PetscOptionsHasName(PETSC_NULL_OPTIONS, PETSC_NULL_CHARACTER, '-testconvergence', flg, ierr)) 112d8606c27SBarry Smithif (flg) then 113ce78bad3SBarry Smith PetscCallA(TaoSetConvergenceTest(ta, ConvergenceTest, dummy, ierr)) 114d8606c27SBarry Smithend if 115d8606c27SBarry Smith 116d8606c27SBarry Smith! Check for any TAO command line options 117ce78bad3SBarry SmithPetscCallA(TaoSetFromOptions(ta, ierr)) 118d8606c27SBarry Smith 119d8606c27SBarry Smith! SOLVE THE APPLICATION 120ce78bad3SBarry SmithPetscCallA(TaoSolve(ta, ierr)) 121d8606c27SBarry Smith 122d8606c27SBarry Smith! Free TAO data structures 123ce78bad3SBarry SmithPetscCallA(TaoDestroy(ta, ierr)) 124d8606c27SBarry Smith 125d8606c27SBarry Smith! Free PETSc data structures 126d8606c27SBarry SmithPetscCallA(VecDestroy(x, ierr)) 127d8606c27SBarry SmithPetscCallA(VecDestroy(localX, ierr)) 128d8606c27SBarry SmithPetscCallA(MatDestroy(H, ierr)) 129d8606c27SBarry SmithPetscCallA(DMDestroy(dm, ierr)) 130d8606c27SBarry Smith 131d8606c27SBarry Smith! Finalize TAO and PETSc 132d8606c27SBarry SmithPetscCallA(PetscFinalize(ierr)) 133d8606c27SBarry Smithend 134d8606c27SBarry Smith 135d8606c27SBarry Smith! --------------------------------------------------------------------- 136d8606c27SBarry Smith! 137d8606c27SBarry Smith! FormInitialGuess - Computes an initial approximation to the solution. 138d8606c27SBarry Smith! 139d8606c27SBarry Smith! Input Parameters: 140d8606c27SBarry Smith! X - vector 141d8606c27SBarry Smith! 142d8606c27SBarry Smith! Output Parameters: 143d8606c27SBarry Smith! X - vector 144d8606c27SBarry Smith! ierr - error code 145d8606c27SBarry Smith! 146d8606c27SBarry Smithsubroutine FormInitialGuess(X, ierr) 14777d968b7SBarry Smith use eptorsion2fmodule 148d8606c27SBarry Smith implicit none 149d8606c27SBarry Smith 150d8606c27SBarry Smith! Input/output variables: 151d8606c27SBarry Smith Vec X 152d8606c27SBarry Smith PetscErrorCode ierr 153d8606c27SBarry Smith 154d8606c27SBarry Smith! Local variables: 155d8606c27SBarry Smith PetscInt i, j, k, xe, ye 156d8606c27SBarry Smith PetscReal temp, val, hx, hy 157d8606c27SBarry Smith PetscInt xs, ys, xm, ym 158d8606c27SBarry Smith PetscInt gxm, gym, gxs, gys 159d8606c27SBarry Smith PetscInt i1 160d8606c27SBarry Smith 161d8606c27SBarry Smith i1 = 1 162d8606c27SBarry Smith hx = 1.0/real(mx + 1) 163d8606c27SBarry Smith hy = 1.0/real(my + 1) 164d8606c27SBarry Smith 165d8606c27SBarry Smith! Get corner information 166d8606c27SBarry Smith PetscCall(DMDAGetCorners(dm, xs, ys, PETSC_NULL_INTEGER, xm, ym, PETSC_NULL_INTEGER, ierr)) 167d8606c27SBarry Smith PetscCall(DMDAGetGhostCorners(dm, gxs, gys, PETSC_NULL_INTEGER, gxm, gym, PETSC_NULL_INTEGER, ierr)) 168d8606c27SBarry Smith 169d8606c27SBarry Smith! Compute initial guess over locally owned part of mesh 170d8606c27SBarry Smith xe = xs + xm 171d8606c27SBarry Smith ye = ys + ym 172d8606c27SBarry Smith do j = ys, ye - 1 173d8606c27SBarry Smith temp = min(j + 1, my - j)*hy 174d8606c27SBarry Smith do i = xs, xe - 1 175d8606c27SBarry Smith k = (j - gys)*gxm + i - gxs 176d8606c27SBarry Smith val = min((min(i + 1, mx - i))*hx, temp) 1775d83a8b1SBarry Smith PetscCall(VecSetValuesLocal(X, i1, [k], [val], ADD_VALUES, ierr)) 178d8606c27SBarry Smith end do 179d8606c27SBarry Smith end do 180d8606c27SBarry Smith PetscCall(VecAssemblyBegin(X, ierr)) 181d8606c27SBarry Smith PetscCall(VecAssemblyEnd(X, ierr)) 182d8606c27SBarry Smithend 183d8606c27SBarry Smith 184d8606c27SBarry Smith! --------------------------------------------------------------------- 185d8606c27SBarry Smith! 186d8606c27SBarry Smith! FormFunctionGradient - Evaluates gradient G(X). 187d8606c27SBarry Smith! 188d8606c27SBarry Smith! Input Parameters: 189d8606c27SBarry Smith! tao - the Tao context 190d8606c27SBarry Smith! X - input vector 191d8606c27SBarry Smith! dummy - optional user-defined context (not used here) 192d8606c27SBarry Smith! 193d8606c27SBarry Smith! Output Parameters: 194d8606c27SBarry Smith! f - the function value at X 195d8606c27SBarry Smith! G - vector containing the newly evaluated gradient 196d8606c27SBarry Smith! ierr - error code 197d8606c27SBarry Smith! 198d8606c27SBarry Smith! Notes: 199d8606c27SBarry Smith! This routine serves as a wrapper for the lower-level routine 200d8606c27SBarry Smith! "ApplicationGradient", where the actual computations are 201d8606c27SBarry Smith! done using the standard Fortran style of treating the local 202d8606c27SBarry Smith! input vector data as an array over the local mesh. 203d8606c27SBarry Smith! 204ce78bad3SBarry Smithsubroutine FormFunctionGradient(ta, X, f, G, dummy, ierr) 20577d968b7SBarry Smith use eptorsion2fmodule 206d8606c27SBarry Smith implicit none 207d8606c27SBarry Smith 208d8606c27SBarry Smith! Input/output variables: 209ce78bad3SBarry Smith type(tTao) ta 210392a88c0SBlaise Bourdin type(tVec) X, G 211d8606c27SBarry Smith PetscReal f 212d8606c27SBarry Smith PetscErrorCode ierr 213d8606c27SBarry Smith PetscInt dummy 214d8606c27SBarry Smith 215d8606c27SBarry Smith! Declarations for use with local array: 216d8606c27SBarry Smith 21742ce371bSBarry Smith PetscReal, pointer :: lx_v(:) 218d8606c27SBarry Smith 219d8606c27SBarry Smith! Local variables: 220d8606c27SBarry Smith PetscReal zero, p5, area, cdiv3 221d8606c27SBarry Smith PetscReal val, flin, fquad, floc 222d8606c27SBarry Smith PetscReal v, vb, vl, vr, vt, dvdx 223d8606c27SBarry Smith PetscReal dvdy, hx, hy 224d8606c27SBarry Smith PetscInt xe, ye, xsm, ysm 225d8606c27SBarry Smith PetscInt xep, yep, i, j, k, ind 226d8606c27SBarry Smith PetscInt xs, ys, xm, ym 227d8606c27SBarry Smith PetscInt gxs, gys, gxm, gym 228d8606c27SBarry Smith PetscInt i1 229d8606c27SBarry Smith 230d8606c27SBarry Smith i1 = 1 231d8606c27SBarry Smith ierr = 0 232d8606c27SBarry Smith cdiv3 = param/3.0 233d8606c27SBarry Smith zero = 0.0 234d8606c27SBarry Smith p5 = 0.5 235d8606c27SBarry Smith hx = 1.0/real(mx + 1) 236d8606c27SBarry Smith hy = 1.0/real(my + 1) 237d8606c27SBarry Smith fquad = zero 238d8606c27SBarry Smith flin = zero 239d8606c27SBarry Smith 240d8606c27SBarry Smith! Initialize gradient to zero 241d8606c27SBarry Smith PetscCall(VecSet(G, zero, ierr)) 242d8606c27SBarry Smith 243d8606c27SBarry Smith! Scatter ghost points to local vector 244d8606c27SBarry Smith PetscCall(DMGlobalToLocalBegin(dm, X, INSERT_VALUES, localX, ierr)) 245d8606c27SBarry Smith PetscCall(DMGlobalToLocalEnd(dm, X, INSERT_VALUES, localX, ierr)) 246d8606c27SBarry Smith 247d8606c27SBarry Smith! Get corner information 248d8606c27SBarry Smith PetscCall(DMDAGetCorners(dm, xs, ys, PETSC_NULL_INTEGER, xm, ym, PETSC_NULL_INTEGER, ierr)) 249d8606c27SBarry Smith PetscCall(DMDAGetGhostCorners(dm, gxs, gys, PETSC_NULL_INTEGER, gxm, gym, PETSC_NULL_INTEGER, ierr)) 250d8606c27SBarry Smith 251d8606c27SBarry Smith! Get pointer to vector data. 252ce78bad3SBarry Smith PetscCall(VecGetArrayRead(localX, lx_v, ierr)) 253d8606c27SBarry Smith 254d8606c27SBarry Smith! Set local loop dimensions 255d8606c27SBarry Smith xe = xs + xm 256d8606c27SBarry Smith ye = ys + ym 2574820e4eaSBarry Smith if (xs == 0) then 258d8606c27SBarry Smith xsm = xs - 1 259d8606c27SBarry Smith else 260d8606c27SBarry Smith xsm = xs 261d8606c27SBarry Smith end if 2624820e4eaSBarry Smith if (ys == 0) then 263d8606c27SBarry Smith ysm = ys - 1 264d8606c27SBarry Smith else 265d8606c27SBarry Smith ysm = ys 266d8606c27SBarry Smith end if 2674820e4eaSBarry Smith if (xe == mx) then 268d8606c27SBarry Smith xep = xe + 1 269d8606c27SBarry Smith else 270d8606c27SBarry Smith xep = xe 271d8606c27SBarry Smith end if 2724820e4eaSBarry Smith if (ye == my) then 273d8606c27SBarry Smith yep = ye + 1 274d8606c27SBarry Smith else 275d8606c27SBarry Smith yep = ye 276d8606c27SBarry Smith end if 277d8606c27SBarry Smith 278d8606c27SBarry Smith! Compute local gradient contributions over the lower triangular elements 279d8606c27SBarry Smith 280d8606c27SBarry Smith do j = ysm, ye - 1 281d8606c27SBarry Smith do i = xsm, xe - 1 282d8606c27SBarry Smith k = (j - gys)*gxm + i - gxs 283d8606c27SBarry Smith v = zero 284d8606c27SBarry Smith vr = zero 285d8606c27SBarry Smith vt = zero 2864820e4eaSBarry Smith if (i >= 0 .and. j >= 0) v = lx_v(k + 1) 2874820e4eaSBarry Smith if (i < mx - 1 .and. j > -1) vr = lx_v(k + 2) 2884820e4eaSBarry Smith if (i > -1 .and. j < my - 1) vt = lx_v(k + 1 + gxm) 289d8606c27SBarry Smith dvdx = (vr - v)/hx 290d8606c27SBarry Smith dvdy = (vt - v)/hy 2914820e4eaSBarry Smith if (i /= -1 .and. j /= -1) then 292d8606c27SBarry Smith ind = k 293d8606c27SBarry Smith val = -dvdx/hx - dvdy/hy - cdiv3 2945d83a8b1SBarry Smith PetscCall(VecSetValuesLocal(G, i1, [k], [val], ADD_VALUES, ierr)) 295d8606c27SBarry Smith end if 2964820e4eaSBarry Smith if (i /= mx - 1 .and. j /= -1) then 297d8606c27SBarry Smith ind = k + 1 298d8606c27SBarry Smith val = dvdx/hx - cdiv3 2995d83a8b1SBarry Smith PetscCall(VecSetValuesLocal(G, i1, [ind], [val], ADD_VALUES, ierr)) 300d8606c27SBarry Smith end if 3014820e4eaSBarry Smith if (i /= -1 .and. j /= my - 1) then 302d8606c27SBarry Smith ind = k + gxm 303d8606c27SBarry Smith val = dvdy/hy - cdiv3 3045d83a8b1SBarry Smith PetscCall(VecSetValuesLocal(G, i1, [ind], [val], ADD_VALUES, ierr)) 305d8606c27SBarry Smith end if 306d8606c27SBarry Smith fquad = fquad + dvdx*dvdx + dvdy*dvdy 307d8606c27SBarry Smith flin = flin - cdiv3*(v + vr + vt) 308d8606c27SBarry Smith end do 309d8606c27SBarry Smith end do 310d8606c27SBarry Smith 311d8606c27SBarry Smith! Compute local gradient contributions over the upper triangular elements 312d8606c27SBarry Smith 313d8606c27SBarry Smith do j = ys, yep - 1 314d8606c27SBarry Smith do i = xs, xep - 1 315d8606c27SBarry Smith k = (j - gys)*gxm + i - gxs 316d8606c27SBarry Smith vb = zero 317d8606c27SBarry Smith vl = zero 318d8606c27SBarry Smith v = zero 3194820e4eaSBarry Smith if (i < mx .and. j > 0) vb = lx_v(k + 1 - gxm) 3204820e4eaSBarry Smith if (i > 0 .and. j < my) vl = lx_v(k) 3214820e4eaSBarry Smith if (i < mx .and. j < my) v = lx_v(1 + k) 322d8606c27SBarry Smith dvdx = (v - vl)/hx 323d8606c27SBarry Smith dvdy = (v - vb)/hy 3244820e4eaSBarry Smith if (i /= mx .and. j /= 0) then 325d8606c27SBarry Smith ind = k - gxm 326d8606c27SBarry Smith val = -dvdy/hy - cdiv3 3275d83a8b1SBarry Smith PetscCall(VecSetValuesLocal(G, i1, [ind], [val], ADD_VALUES, ierr)) 328d8606c27SBarry Smith end if 3294820e4eaSBarry Smith if (i /= 0 .and. j /= my) then 330d8606c27SBarry Smith ind = k - 1 331d8606c27SBarry Smith val = -dvdx/hx - cdiv3 3325d83a8b1SBarry Smith PetscCall(VecSetValuesLocal(G, i1, [ind], [val], ADD_VALUES, ierr)) 333d8606c27SBarry Smith end if 3344820e4eaSBarry Smith if (i /= mx .and. j /= my) then 335d8606c27SBarry Smith ind = k 336d8606c27SBarry Smith val = dvdx/hx + dvdy/hy - cdiv3 3375d83a8b1SBarry Smith PetscCall(VecSetValuesLocal(G, i1, [ind], [val], ADD_VALUES, ierr)) 338d8606c27SBarry Smith end if 339d8606c27SBarry Smith fquad = fquad + dvdx*dvdx + dvdy*dvdy 340d8606c27SBarry Smith flin = flin - cdiv3*(vb + vl + v) 341d8606c27SBarry Smith end do 342d8606c27SBarry Smith end do 343d8606c27SBarry Smith 344d8606c27SBarry Smith! Restore vector 345ce78bad3SBarry Smith PetscCall(VecRestoreArrayRead(localX, lx_v, ierr)) 346d8606c27SBarry Smith 347d8606c27SBarry Smith! Assemble gradient vector 348d8606c27SBarry Smith PetscCall(VecAssemblyBegin(G, ierr)) 349d8606c27SBarry Smith PetscCall(VecAssemblyEnd(G, ierr)) 350d8606c27SBarry Smith 351d8606c27SBarry Smith! Scale the gradient 352d8606c27SBarry Smith area = p5*hx*hy 353d8606c27SBarry Smith floc = area*(p5*fquad + flin) 354d8606c27SBarry Smith PetscCall(VecScale(G, area, ierr)) 355d8606c27SBarry Smith 356d8606c27SBarry Smith! Sum function contributions from all processes 357d8606c27SBarry Smith PetscCallMPI(MPI_Allreduce(floc, f, 1, MPIU_SCALAR, MPIU_SUM, PETSC_COMM_WORLD, ierr)) 358d8606c27SBarry Smith PetscCall(PetscLogFlops(20.0d0*(ye - ysm)*(xe - xsm) + 16.0d0*(xep - xs)*(yep - ys), ierr)) 359d8606c27SBarry Smithend 360d8606c27SBarry Smith 361ce78bad3SBarry Smithsubroutine ComputeHessian(ta, X, H, Hpre, dummy, ierr) 36277d968b7SBarry Smith use eptorsion2fmodule 363d8606c27SBarry Smith implicit none 364d8606c27SBarry Smith 365ce78bad3SBarry Smith type(tTao) ta 366392a88c0SBlaise Bourdin type(tVec) X 367392a88c0SBlaise Bourdin type(tMat) H, Hpre 368d8606c27SBarry Smith PetscErrorCode ierr 369d8606c27SBarry Smith PetscInt dummy 370d8606c27SBarry Smith 371d8606c27SBarry Smith PetscInt i, j, k 372d8606c27SBarry Smith PetscInt col(0:4), row 373d8606c27SBarry Smith PetscInt xs, xm, gxs, gxm 374d8606c27SBarry Smith PetscInt ys, ym, gys, gym 375d8606c27SBarry Smith PetscReal v(0:4) 376d8606c27SBarry Smith PetscInt i1 377d8606c27SBarry Smith 378d8606c27SBarry Smith i1 = 1 379d8606c27SBarry Smith 380d8606c27SBarry Smith! Get local grid boundaries 381d8606c27SBarry Smith PetscCall(DMDAGetCorners(dm, xs, ys, PETSC_NULL_INTEGER, xm, ym, PETSC_NULL_INTEGER, ierr)) 382d8606c27SBarry Smith PetscCall(DMDAGetGhostCorners(dm, gxs, gys, PETSC_NULL_INTEGER, gxm, gym, PETSC_NULL_INTEGER, ierr)) 383d8606c27SBarry Smith 384d8606c27SBarry Smith do j = ys, ys + ym - 1 385d8606c27SBarry Smith do i = xs, xs + xm - 1 386d8606c27SBarry Smith row = (j - gys)*gxm + (i - gxs) 387d8606c27SBarry Smith 388d8606c27SBarry Smith k = 0 3894820e4eaSBarry Smith if (j > gys) then 390d8606c27SBarry Smith v(k) = -1.0 391d8606c27SBarry Smith col(k) = row - gxm 392d8606c27SBarry Smith k = k + 1 393d8606c27SBarry Smith end if 394d8606c27SBarry Smith 3954820e4eaSBarry Smith if (i > gxs) then 396d8606c27SBarry Smith v(k) = -1.0 397d8606c27SBarry Smith col(k) = row - 1 398d8606c27SBarry Smith k = k + 1 399d8606c27SBarry Smith end if 400d8606c27SBarry Smith 401d8606c27SBarry Smith v(k) = 4.0 402d8606c27SBarry Smith col(k) = row 403d8606c27SBarry Smith k = k + 1 404d8606c27SBarry Smith 4054820e4eaSBarry Smith if (i + 1 < gxs + gxm) then 406d8606c27SBarry Smith v(k) = -1.0 407d8606c27SBarry Smith col(k) = row + 1 408d8606c27SBarry Smith k = k + 1 409d8606c27SBarry Smith end if 410d8606c27SBarry Smith 4114820e4eaSBarry Smith if (j + 1 < gys + gym) then 412d8606c27SBarry Smith v(k) = -1.0 413d8606c27SBarry Smith col(k) = row + gxm 414d8606c27SBarry Smith k = k + 1 415d8606c27SBarry Smith end if 416d8606c27SBarry Smith 4175d83a8b1SBarry Smith PetscCall(MatSetValuesLocal(H, i1, [row], k, col, v, INSERT_VALUES, ierr)) 418d8606c27SBarry Smith end do 419d8606c27SBarry Smith end do 420d8606c27SBarry Smith 421d8606c27SBarry Smith! Assemble matrix 422d8606c27SBarry Smith PetscCall(MatAssemblyBegin(H, MAT_FINAL_ASSEMBLY, ierr)) 423d8606c27SBarry Smith PetscCall(MatAssemblyEnd(H, MAT_FINAL_ASSEMBLY, ierr)) 424d8606c27SBarry Smith 425d8606c27SBarry Smith! Tell the matrix we will never add a new nonzero location to the 426d8606c27SBarry Smith! matrix. If we do it will generate an error. 427d8606c27SBarry Smith 428d8606c27SBarry Smith PetscCall(MatSetOption(H, MAT_NEW_NONZERO_LOCATION_ERR, PETSC_TRUE, ierr)) 429d8606c27SBarry Smith PetscCall(MatSetOption(H, MAT_SYMMETRIC, PETSC_TRUE, ierr)) 430d8606c27SBarry Smith 431d8606c27SBarry Smith PetscCall(PetscLogFlops(9.0d0*xm*ym + 49.0d0*xm, ierr)) 432d8606c27SBarry Smith 433d8606c27SBarry Smith ierr = 0 434d8606c27SBarry Smithend 435d8606c27SBarry Smith 436ce78bad3SBarry Smithsubroutine Monitor(ta, dummy, ierr) 43777d968b7SBarry Smith use eptorsion2fmodule 438d8606c27SBarry Smith implicit none 439d8606c27SBarry Smith 440ce78bad3SBarry Smith type(tTao) ta 441d8606c27SBarry Smith PetscInt dummy 442d8606c27SBarry Smith PetscErrorCode ierr 443d8606c27SBarry Smith 444d8606c27SBarry Smith PetscInt its 445d8606c27SBarry Smith PetscReal f, gnorm, cnorm, xdiff 446d8606c27SBarry Smith TaoConvergedReason reason 447d8606c27SBarry Smith 448ce78bad3SBarry Smith PetscCall(TaoGetSolutionStatus(ta, its, f, gnorm, cnorm, xdiff, reason, ierr)) 4494820e4eaSBarry Smith if (mod(its, 5) /= 0) then 450d8606c27SBarry Smith PetscCall(PetscPrintf(PETSC_COMM_WORLD, 'iteration multiple of 5\n', ierr)) 451d8606c27SBarry Smith end if 452d8606c27SBarry Smith 453d8606c27SBarry Smith ierr = 0 454d8606c27SBarry Smith 455d8606c27SBarry Smithend 456d8606c27SBarry Smith 457ce78bad3SBarry Smithsubroutine ConvergenceTest(ta, dummy, ierr) 45877d968b7SBarry Smith use eptorsion2fmodule 459d8606c27SBarry Smith implicit none 460d8606c27SBarry Smith 461ce78bad3SBarry Smith type(tTao) ta 462d8606c27SBarry Smith PetscInt dummy 463d8606c27SBarry Smith PetscErrorCode ierr 464d8606c27SBarry Smith 465d8606c27SBarry Smith PetscInt its 466d8606c27SBarry Smith PetscReal f, gnorm, cnorm, xdiff 467d8606c27SBarry Smith TaoConvergedReason reason 468d8606c27SBarry Smith 469ce78bad3SBarry Smith PetscCall(TaoGetSolutionStatus(ta, its, f, gnorm, cnorm, xdiff, reason, ierr)) 4704820e4eaSBarry Smith if (its == 7) then 471ce78bad3SBarry Smith PetscCall(TaoSetConvergedReason(ta, TAO_DIVERGED_MAXITS, ierr)) 472d8606c27SBarry Smith end if 473d8606c27SBarry Smith 474d8606c27SBarry Smith ierr = 0 475d8606c27SBarry Smith 476d8606c27SBarry Smithend 477d8606c27SBarry Smith 478d8606c27SBarry Smith!/*TEST 479d8606c27SBarry Smith! 480d8606c27SBarry Smith! build: 481d8606c27SBarry Smith! requires: !complex 482d8606c27SBarry Smith! 483d8606c27SBarry Smith! test: 48410978b7dSBarry Smith! args: -tao_monitor_short -tao_type nls -tao_gttol 1.e-2 485d8606c27SBarry Smith! 486d8606c27SBarry Smith! test: 487d8606c27SBarry Smith! suffix: 2 488d8606c27SBarry Smith! nsize: 2 48910978b7dSBarry Smith! args: -tao_monitor_short -tao_type lmvm -tao_gttol 1.e-2 490d8606c27SBarry Smith! 491d8606c27SBarry Smith! test: 492d8606c27SBarry Smith! suffix: 3 493d8606c27SBarry Smith! args: -testmonitor -tao_type lmvm -tao_gttol 1.e-2 494d8606c27SBarry Smith!TEST*/ 495