1*c4762a1bSJed Brown /* 2*c4762a1bSJed Brown Include "petsctao.h" so we can use TAO solvers 3*c4762a1bSJed Brown Include "petscdmda.h" so that we can use distributed arrays (DMs) for managing 4*c4762a1bSJed Brown Include "petscksp.h" so we can set KSP type 5*c4762a1bSJed Brown the parallel mesh. 6*c4762a1bSJed Brown */ 7*c4762a1bSJed Brown 8*c4762a1bSJed Brown #include <petsctao.h> 9*c4762a1bSJed Brown #include <petscdmda.h> 10*c4762a1bSJed Brown 11*c4762a1bSJed Brown static char help[]= 12*c4762a1bSJed Brown "This example demonstrates use of the TAO package to \n\ 13*c4762a1bSJed Brown solve a bound constrained minimization problem. This example is based on \n\ 14*c4762a1bSJed Brown the problem DPJB from the MINPACK-2 test suite. This pressure journal \n\ 15*c4762a1bSJed Brown bearing problem is an example of elliptic variational problem defined over \n\ 16*c4762a1bSJed Brown a two dimensional rectangle. By discretizing the domain into triangular \n\ 17*c4762a1bSJed Brown elements, the pressure surrounding the journal bearing is defined as the \n\ 18*c4762a1bSJed Brown minimum of a quadratic function whose variables are bounded below by zero.\n\ 19*c4762a1bSJed Brown The command line options are:\n\ 20*c4762a1bSJed Brown -mx <xg>, where <xg> = number of grid points in the 1st coordinate direction\n\ 21*c4762a1bSJed Brown -my <yg>, where <yg> = number of grid points in the 2nd coordinate direction\n\ 22*c4762a1bSJed Brown \n"; 23*c4762a1bSJed Brown 24*c4762a1bSJed Brown /*T 25*c4762a1bSJed Brown Concepts: TAO^Solving a bound constrained minimization problem 26*c4762a1bSJed Brown Routines: TaoCreate(); 27*c4762a1bSJed Brown Routines: TaoSetType(); TaoSetObjectiveAndGradientRoutine(); 28*c4762a1bSJed Brown Routines: TaoSetHessianRoutine(); 29*c4762a1bSJed Brown Routines: TaoSetVariableBounds(); 30*c4762a1bSJed Brown Routines: TaoSetMonitor(); TaoSetConvergenceTest(); 31*c4762a1bSJed Brown Routines: TaoSetInitialVector(); 32*c4762a1bSJed Brown Routines: TaoSetFromOptions(); 33*c4762a1bSJed Brown Routines: TaoSolve(); 34*c4762a1bSJed Brown Routines: TaoDestroy(); 35*c4762a1bSJed Brown Processors: n 36*c4762a1bSJed Brown T*/ 37*c4762a1bSJed Brown 38*c4762a1bSJed Brown 39*c4762a1bSJed Brown 40*c4762a1bSJed Brown /* 41*c4762a1bSJed Brown User-defined application context - contains data needed by the 42*c4762a1bSJed Brown application-provided call-back routines, FormFunctionGradient(), 43*c4762a1bSJed Brown FormHessian(). 44*c4762a1bSJed Brown */ 45*c4762a1bSJed Brown typedef struct { 46*c4762a1bSJed Brown /* problem parameters */ 47*c4762a1bSJed Brown PetscReal ecc; /* test problem parameter */ 48*c4762a1bSJed Brown PetscReal b; /* A dimension of journal bearing */ 49*c4762a1bSJed Brown PetscInt nx,ny; /* discretization in x, y directions */ 50*c4762a1bSJed Brown 51*c4762a1bSJed Brown /* Working space */ 52*c4762a1bSJed Brown DM dm; /* distributed array data structure */ 53*c4762a1bSJed Brown Mat A; /* Quadratic Objective term */ 54*c4762a1bSJed Brown Vec B; /* Linear Objective term */ 55*c4762a1bSJed Brown } AppCtx; 56*c4762a1bSJed Brown 57*c4762a1bSJed Brown /* User-defined routines */ 58*c4762a1bSJed Brown static PetscReal p(PetscReal xi, PetscReal ecc); 59*c4762a1bSJed Brown static PetscErrorCode FormFunctionGradient(Tao, Vec, PetscReal *,Vec,void *); 60*c4762a1bSJed Brown static PetscErrorCode FormHessian(Tao,Vec,Mat, Mat, void *); 61*c4762a1bSJed Brown static PetscErrorCode ComputeB(AppCtx*); 62*c4762a1bSJed Brown static PetscErrorCode Monitor(Tao, void*); 63*c4762a1bSJed Brown static PetscErrorCode ConvergenceTest(Tao, void*); 64*c4762a1bSJed Brown 65*c4762a1bSJed Brown int main( int argc, char **argv ) 66*c4762a1bSJed Brown { 67*c4762a1bSJed Brown PetscErrorCode ierr; /* used to check for functions returning nonzeros */ 68*c4762a1bSJed Brown PetscInt Nx, Ny; /* number of processors in x- and y- directions */ 69*c4762a1bSJed Brown PetscInt m; /* number of local elements in vectors */ 70*c4762a1bSJed Brown Vec x; /* variables vector */ 71*c4762a1bSJed Brown Vec xl,xu; /* bounds vectors */ 72*c4762a1bSJed Brown PetscReal d1000 = 1000; 73*c4762a1bSJed Brown PetscBool flg,testgetdiag; /* A return variable when checking for user options */ 74*c4762a1bSJed Brown Tao tao; /* Tao solver context */ 75*c4762a1bSJed Brown KSP ksp; 76*c4762a1bSJed Brown AppCtx user; /* user-defined work context */ 77*c4762a1bSJed Brown PetscReal zero = 0.0; /* lower bound on all variables */ 78*c4762a1bSJed Brown 79*c4762a1bSJed Brown /* Initialize PETSC and TAO */ 80*c4762a1bSJed Brown ierr = PetscInitialize( &argc, &argv,(char *)0,help );if (ierr) return ierr; 81*c4762a1bSJed Brown 82*c4762a1bSJed Brown /* Set the default values for the problem parameters */ 83*c4762a1bSJed Brown user.nx = 50; user.ny = 50; user.ecc = 0.1; user.b = 10.0; 84*c4762a1bSJed Brown testgetdiag = PETSC_FALSE; 85*c4762a1bSJed Brown 86*c4762a1bSJed Brown /* Check for any command line arguments that override defaults */ 87*c4762a1bSJed Brown ierr = PetscOptionsGetInt(NULL,NULL,"-mx",&user.nx,&flg);CHKERRQ(ierr); 88*c4762a1bSJed Brown ierr = PetscOptionsGetInt(NULL,NULL,"-my",&user.ny,&flg);CHKERRQ(ierr); 89*c4762a1bSJed Brown ierr = PetscOptionsGetReal(NULL,NULL,"-ecc",&user.ecc,&flg);CHKERRQ(ierr); 90*c4762a1bSJed Brown ierr = PetscOptionsGetReal(NULL,NULL,"-b",&user.b,&flg);CHKERRQ(ierr); 91*c4762a1bSJed Brown ierr = PetscOptionsGetBool(NULL,NULL,"-test_getdiagonal",&testgetdiag,NULL);CHKERRQ(ierr); 92*c4762a1bSJed Brown 93*c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_WORLD,"\n---- Journal Bearing Problem SHB-----\n");CHKERRQ(ierr); 94*c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_WORLD,"mx: %D, my: %D, ecc: %g \n\n",user.nx,user.ny,(double)user.ecc);CHKERRQ(ierr); 95*c4762a1bSJed Brown 96*c4762a1bSJed Brown /* Let Petsc determine the grid division */ 97*c4762a1bSJed Brown Nx = PETSC_DECIDE; Ny = PETSC_DECIDE; 98*c4762a1bSJed Brown 99*c4762a1bSJed Brown /* 100*c4762a1bSJed Brown A two dimensional distributed array will help define this problem, 101*c4762a1bSJed Brown which derives from an elliptic PDE on two dimensional domain. From 102*c4762a1bSJed Brown the distributed array, Create the vectors. 103*c4762a1bSJed Brown */ 104*c4762a1bSJed Brown ierr = DMDACreate2d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,user.nx,user.ny,Nx,Ny,1,1,NULL,NULL,&user.dm);CHKERRQ(ierr); 105*c4762a1bSJed Brown ierr = DMSetFromOptions(user.dm);CHKERRQ(ierr); 106*c4762a1bSJed Brown ierr = DMSetUp(user.dm);CHKERRQ(ierr); 107*c4762a1bSJed Brown 108*c4762a1bSJed Brown /* 109*c4762a1bSJed Brown Extract global and local vectors from DM; the vector user.B is 110*c4762a1bSJed Brown used solely as work space for the evaluation of the function, 111*c4762a1bSJed Brown gradient, and Hessian. Duplicate for remaining vectors that are 112*c4762a1bSJed Brown the same types. 113*c4762a1bSJed Brown */ 114*c4762a1bSJed Brown ierr = DMCreateGlobalVector(user.dm,&x);CHKERRQ(ierr); /* Solution */ 115*c4762a1bSJed Brown ierr = VecDuplicate(x,&user.B);CHKERRQ(ierr); /* Linear objective */ 116*c4762a1bSJed Brown 117*c4762a1bSJed Brown 118*c4762a1bSJed Brown /* Create matrix user.A to store quadratic, Create a local ordering scheme. */ 119*c4762a1bSJed Brown ierr = VecGetLocalSize(x,&m);CHKERRQ(ierr); 120*c4762a1bSJed Brown ierr = DMCreateMatrix(user.dm,&user.A);CHKERRQ(ierr); 121*c4762a1bSJed Brown 122*c4762a1bSJed Brown if (testgetdiag) { 123*c4762a1bSJed Brown ierr = MatSetOperation(user.A,MATOP_GET_DIAGONAL,NULL);CHKERRQ(ierr); 124*c4762a1bSJed Brown } 125*c4762a1bSJed Brown 126*c4762a1bSJed Brown /* User defined function -- compute linear term of quadratic */ 127*c4762a1bSJed Brown ierr = ComputeB(&user);CHKERRQ(ierr); 128*c4762a1bSJed Brown 129*c4762a1bSJed Brown /* The TAO code begins here */ 130*c4762a1bSJed Brown 131*c4762a1bSJed Brown /* 132*c4762a1bSJed Brown Create the optimization solver 133*c4762a1bSJed Brown Suitable methods: TAOGPCG, TAOBQPIP, TAOTRON, TAOBLMVM 134*c4762a1bSJed Brown */ 135*c4762a1bSJed Brown ierr = TaoCreate(PETSC_COMM_WORLD,&tao);CHKERRQ(ierr); 136*c4762a1bSJed Brown ierr = TaoSetType(tao,TAOBLMVM);CHKERRQ(ierr); 137*c4762a1bSJed Brown 138*c4762a1bSJed Brown 139*c4762a1bSJed Brown /* Set the initial vector */ 140*c4762a1bSJed Brown ierr = VecSet(x, zero);CHKERRQ(ierr); 141*c4762a1bSJed Brown ierr = TaoSetInitialVector(tao,x);CHKERRQ(ierr); 142*c4762a1bSJed Brown 143*c4762a1bSJed Brown /* Set the user function, gradient, hessian evaluation routines and data structures */ 144*c4762a1bSJed Brown ierr = TaoSetObjectiveAndGradientRoutine(tao,FormFunctionGradient,(void*) &user);CHKERRQ(ierr); 145*c4762a1bSJed Brown 146*c4762a1bSJed Brown ierr = TaoSetHessianRoutine(tao,user.A,user.A,FormHessian,(void*)&user);CHKERRQ(ierr); 147*c4762a1bSJed Brown 148*c4762a1bSJed Brown /* Set a routine that defines the bounds */ 149*c4762a1bSJed Brown ierr = VecDuplicate(x,&xl);CHKERRQ(ierr); 150*c4762a1bSJed Brown ierr = VecDuplicate(x,&xu);CHKERRQ(ierr); 151*c4762a1bSJed Brown ierr = VecSet(xl, zero);CHKERRQ(ierr); 152*c4762a1bSJed Brown ierr = VecSet(xu, d1000);CHKERRQ(ierr); 153*c4762a1bSJed Brown ierr = TaoSetVariableBounds(tao,xl,xu);CHKERRQ(ierr); 154*c4762a1bSJed Brown 155*c4762a1bSJed Brown ierr = TaoGetKSP(tao,&ksp);CHKERRQ(ierr); 156*c4762a1bSJed Brown if (ksp) { 157*c4762a1bSJed Brown ierr = KSPSetType(ksp,KSPCG);CHKERRQ(ierr); 158*c4762a1bSJed Brown } 159*c4762a1bSJed Brown 160*c4762a1bSJed Brown ierr = PetscOptionsHasName(NULL,NULL,"-testmonitor",&flg);CHKERRQ(ierr); 161*c4762a1bSJed Brown if (flg) { 162*c4762a1bSJed Brown ierr = TaoSetMonitor(tao,Monitor,&user,NULL);CHKERRQ(ierr); 163*c4762a1bSJed Brown } 164*c4762a1bSJed Brown ierr = PetscOptionsHasName(NULL,NULL,"-testconvergence",&flg);CHKERRQ(ierr); 165*c4762a1bSJed Brown if (flg) { 166*c4762a1bSJed Brown ierr = TaoSetConvergenceTest(tao,ConvergenceTest,&user);CHKERRQ(ierr); 167*c4762a1bSJed Brown } 168*c4762a1bSJed Brown 169*c4762a1bSJed Brown /* Check for any tao command line options */ 170*c4762a1bSJed Brown ierr = TaoSetFromOptions(tao);CHKERRQ(ierr); 171*c4762a1bSJed Brown 172*c4762a1bSJed Brown /* Solve the bound constrained problem */ 173*c4762a1bSJed Brown ierr = TaoSolve(tao);CHKERRQ(ierr); 174*c4762a1bSJed Brown 175*c4762a1bSJed Brown /* Free PETSc data structures */ 176*c4762a1bSJed Brown ierr = VecDestroy(&x);CHKERRQ(ierr); 177*c4762a1bSJed Brown ierr = VecDestroy(&xl);CHKERRQ(ierr); 178*c4762a1bSJed Brown ierr = VecDestroy(&xu);CHKERRQ(ierr); 179*c4762a1bSJed Brown ierr = MatDestroy(&user.A);CHKERRQ(ierr); 180*c4762a1bSJed Brown ierr = VecDestroy(&user.B);CHKERRQ(ierr); 181*c4762a1bSJed Brown 182*c4762a1bSJed Brown /* Free TAO data structures */ 183*c4762a1bSJed Brown ierr = TaoDestroy(&tao);CHKERRQ(ierr); 184*c4762a1bSJed Brown ierr = DMDestroy(&user.dm);CHKERRQ(ierr); 185*c4762a1bSJed Brown ierr = PetscFinalize(); 186*c4762a1bSJed Brown return ierr; 187*c4762a1bSJed Brown } 188*c4762a1bSJed Brown 189*c4762a1bSJed Brown 190*c4762a1bSJed Brown static PetscReal p(PetscReal xi, PetscReal ecc) 191*c4762a1bSJed Brown { 192*c4762a1bSJed Brown PetscReal t=1.0+ecc*PetscCosScalar(xi); 193*c4762a1bSJed Brown return (t*t*t); 194*c4762a1bSJed Brown } 195*c4762a1bSJed Brown 196*c4762a1bSJed Brown PetscErrorCode ComputeB(AppCtx* user) 197*c4762a1bSJed Brown { 198*c4762a1bSJed Brown PetscErrorCode ierr; 199*c4762a1bSJed Brown PetscInt i,j,k; 200*c4762a1bSJed Brown PetscInt nx,ny,xs,xm,gxs,gxm,ys,ym,gys,gym; 201*c4762a1bSJed Brown PetscReal two=2.0, pi=4.0*atan(1.0); 202*c4762a1bSJed Brown PetscReal hx,hy,ehxhy; 203*c4762a1bSJed Brown PetscReal temp,*b; 204*c4762a1bSJed Brown PetscReal ecc=user->ecc; 205*c4762a1bSJed Brown 206*c4762a1bSJed Brown nx=user->nx; 207*c4762a1bSJed Brown ny=user->ny; 208*c4762a1bSJed Brown hx=two*pi/(nx+1.0); 209*c4762a1bSJed Brown hy=two*user->b/(ny+1.0); 210*c4762a1bSJed Brown ehxhy = ecc*hx*hy; 211*c4762a1bSJed Brown 212*c4762a1bSJed Brown 213*c4762a1bSJed Brown /* 214*c4762a1bSJed Brown Get local grid boundaries 215*c4762a1bSJed Brown */ 216*c4762a1bSJed Brown ierr = DMDAGetCorners(user->dm,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr); 217*c4762a1bSJed Brown ierr = DMDAGetGhostCorners(user->dm,&gxs,&gys,NULL,&gxm,&gym,NULL);CHKERRQ(ierr); 218*c4762a1bSJed Brown 219*c4762a1bSJed Brown /* Compute the linear term in the objective function */ 220*c4762a1bSJed Brown ierr = VecGetArray(user->B,&b);CHKERRQ(ierr); 221*c4762a1bSJed Brown for (i=xs; i<xs+xm; i++){ 222*c4762a1bSJed Brown temp=PetscSinScalar((i+1)*hx); 223*c4762a1bSJed Brown for (j=ys; j<ys+ym; j++){ 224*c4762a1bSJed Brown k=xm*(j-ys)+(i-xs); 225*c4762a1bSJed Brown b[k]= - ehxhy*temp; 226*c4762a1bSJed Brown } 227*c4762a1bSJed Brown } 228*c4762a1bSJed Brown ierr = VecRestoreArray(user->B,&b);CHKERRQ(ierr); 229*c4762a1bSJed Brown ierr = PetscLogFlops(5*xm*ym+3*xm);CHKERRQ(ierr); 230*c4762a1bSJed Brown 231*c4762a1bSJed Brown return 0; 232*c4762a1bSJed Brown } 233*c4762a1bSJed Brown 234*c4762a1bSJed Brown PetscErrorCode FormFunctionGradient(Tao tao, Vec X, PetscReal *fcn,Vec G,void *ptr) 235*c4762a1bSJed Brown { 236*c4762a1bSJed Brown AppCtx* user=(AppCtx*)ptr; 237*c4762a1bSJed Brown PetscErrorCode ierr; 238*c4762a1bSJed Brown PetscInt i,j,k,kk; 239*c4762a1bSJed Brown PetscInt col[5],row,nx,ny,xs,xm,gxs,gxm,ys,ym,gys,gym; 240*c4762a1bSJed Brown PetscReal one=1.0, two=2.0, six=6.0,pi=4.0*atan(1.0); 241*c4762a1bSJed Brown PetscReal hx,hy,hxhy,hxhx,hyhy; 242*c4762a1bSJed Brown PetscReal xi,v[5]; 243*c4762a1bSJed Brown PetscReal ecc=user->ecc, trule1,trule2,trule3,trule4,trule5,trule6; 244*c4762a1bSJed Brown PetscReal vmiddle, vup, vdown, vleft, vright; 245*c4762a1bSJed Brown PetscReal tt,f1,f2; 246*c4762a1bSJed Brown PetscReal *x,*g,zero=0.0; 247*c4762a1bSJed Brown Vec localX; 248*c4762a1bSJed Brown 249*c4762a1bSJed Brown nx=user->nx; 250*c4762a1bSJed Brown ny=user->ny; 251*c4762a1bSJed Brown hx=two*pi/(nx+1.0); 252*c4762a1bSJed Brown hy=two*user->b/(ny+1.0); 253*c4762a1bSJed Brown hxhy=hx*hy; 254*c4762a1bSJed Brown hxhx=one/(hx*hx); 255*c4762a1bSJed Brown hyhy=one/(hy*hy); 256*c4762a1bSJed Brown 257*c4762a1bSJed Brown ierr = DMGetLocalVector(user->dm,&localX);CHKERRQ(ierr); 258*c4762a1bSJed Brown 259*c4762a1bSJed Brown ierr = DMGlobalToLocalBegin(user->dm,X,INSERT_VALUES,localX);CHKERRQ(ierr); 260*c4762a1bSJed Brown ierr = DMGlobalToLocalEnd(user->dm,X,INSERT_VALUES,localX);CHKERRQ(ierr); 261*c4762a1bSJed Brown 262*c4762a1bSJed Brown ierr = VecSet(G, zero);CHKERRQ(ierr); 263*c4762a1bSJed Brown /* 264*c4762a1bSJed Brown Get local grid boundaries 265*c4762a1bSJed Brown */ 266*c4762a1bSJed Brown ierr = DMDAGetCorners(user->dm,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr); 267*c4762a1bSJed Brown ierr = DMDAGetGhostCorners(user->dm,&gxs,&gys,NULL,&gxm,&gym,NULL);CHKERRQ(ierr); 268*c4762a1bSJed Brown 269*c4762a1bSJed Brown ierr = VecGetArray(localX,&x);CHKERRQ(ierr); 270*c4762a1bSJed Brown ierr = VecGetArray(G,&g);CHKERRQ(ierr); 271*c4762a1bSJed Brown 272*c4762a1bSJed Brown for (i=xs; i< xs+xm; i++){ 273*c4762a1bSJed Brown xi=(i+1)*hx; 274*c4762a1bSJed Brown trule1=hxhy*( p(xi,ecc) + p(xi+hx,ecc) + p(xi,ecc) ) / six; /* L(i,j) */ 275*c4762a1bSJed Brown trule2=hxhy*( p(xi,ecc) + p(xi-hx,ecc) + p(xi,ecc) ) / six; /* U(i,j) */ 276*c4762a1bSJed Brown trule3=hxhy*( p(xi,ecc) + p(xi+hx,ecc) + p(xi+hx,ecc) ) / six; /* U(i+1,j) */ 277*c4762a1bSJed Brown trule4=hxhy*( p(xi,ecc) + p(xi-hx,ecc) + p(xi-hx,ecc) ) / six; /* L(i-1,j) */ 278*c4762a1bSJed Brown trule5=trule1; /* L(i,j-1) */ 279*c4762a1bSJed Brown trule6=trule2; /* U(i,j+1) */ 280*c4762a1bSJed Brown 281*c4762a1bSJed Brown vdown=-(trule5+trule2)*hyhy; 282*c4762a1bSJed Brown vleft=-hxhx*(trule2+trule4); 283*c4762a1bSJed Brown vright= -hxhx*(trule1+trule3); 284*c4762a1bSJed Brown vup=-hyhy*(trule1+trule6); 285*c4762a1bSJed Brown vmiddle=(hxhx)*(trule1+trule2+trule3+trule4)+hyhy*(trule1+trule2+trule5+trule6); 286*c4762a1bSJed Brown 287*c4762a1bSJed Brown for (j=ys; j<ys+ym; j++){ 288*c4762a1bSJed Brown 289*c4762a1bSJed Brown row=(j-gys)*gxm + (i-gxs); 290*c4762a1bSJed Brown v[0]=0; v[1]=0; v[2]=0; v[3]=0; v[4]=0; 291*c4762a1bSJed Brown 292*c4762a1bSJed Brown k=0; 293*c4762a1bSJed Brown if (j>gys){ 294*c4762a1bSJed Brown v[k]=vdown; col[k]=row - gxm; k++; 295*c4762a1bSJed Brown } 296*c4762a1bSJed Brown 297*c4762a1bSJed Brown if (i>gxs){ 298*c4762a1bSJed Brown v[k]= vleft; col[k]=row - 1; k++; 299*c4762a1bSJed Brown } 300*c4762a1bSJed Brown 301*c4762a1bSJed Brown v[k]= vmiddle; col[k]=row; k++; 302*c4762a1bSJed Brown 303*c4762a1bSJed Brown if (i+1 < gxs+gxm){ 304*c4762a1bSJed Brown v[k]= vright; col[k]=row+1; k++; 305*c4762a1bSJed Brown } 306*c4762a1bSJed Brown 307*c4762a1bSJed Brown if (j+1 <gys+gym){ 308*c4762a1bSJed Brown v[k]= vup; col[k] = row+gxm; k++; 309*c4762a1bSJed Brown } 310*c4762a1bSJed Brown tt=0; 311*c4762a1bSJed Brown for (kk=0;kk<k;kk++){ 312*c4762a1bSJed Brown tt+=v[kk]*x[col[kk]]; 313*c4762a1bSJed Brown } 314*c4762a1bSJed Brown row=(j-ys)*xm + (i-xs); 315*c4762a1bSJed Brown g[row]=tt; 316*c4762a1bSJed Brown 317*c4762a1bSJed Brown } 318*c4762a1bSJed Brown 319*c4762a1bSJed Brown } 320*c4762a1bSJed Brown 321*c4762a1bSJed Brown ierr = VecRestoreArray(localX,&x);CHKERRQ(ierr); 322*c4762a1bSJed Brown ierr = VecRestoreArray(G,&g);CHKERRQ(ierr); 323*c4762a1bSJed Brown 324*c4762a1bSJed Brown ierr = DMRestoreLocalVector(user->dm,&localX);CHKERRQ(ierr); 325*c4762a1bSJed Brown 326*c4762a1bSJed Brown ierr = VecDot(X,G,&f1);CHKERRQ(ierr); 327*c4762a1bSJed Brown ierr = VecDot(user->B,X,&f2);CHKERRQ(ierr); 328*c4762a1bSJed Brown ierr = VecAXPY(G, one, user->B);CHKERRQ(ierr); 329*c4762a1bSJed Brown *fcn = f1/2.0 + f2; 330*c4762a1bSJed Brown 331*c4762a1bSJed Brown 332*c4762a1bSJed Brown ierr = PetscLogFlops((91 + 10*ym) * xm);CHKERRQ(ierr); 333*c4762a1bSJed Brown return 0; 334*c4762a1bSJed Brown 335*c4762a1bSJed Brown } 336*c4762a1bSJed Brown 337*c4762a1bSJed Brown 338*c4762a1bSJed Brown /* 339*c4762a1bSJed Brown FormHessian computes the quadratic term in the quadratic objective function 340*c4762a1bSJed Brown Notice that the objective function in this problem is quadratic (therefore a constant 341*c4762a1bSJed Brown hessian). If using a nonquadratic solver, then you might want to reconsider this function 342*c4762a1bSJed Brown */ 343*c4762a1bSJed Brown PetscErrorCode FormHessian(Tao tao,Vec X,Mat hes, Mat Hpre, void *ptr) 344*c4762a1bSJed Brown { 345*c4762a1bSJed Brown AppCtx* user=(AppCtx*)ptr; 346*c4762a1bSJed Brown PetscErrorCode ierr; 347*c4762a1bSJed Brown PetscInt i,j,k; 348*c4762a1bSJed Brown PetscInt col[5],row,nx,ny,xs,xm,gxs,gxm,ys,ym,gys,gym; 349*c4762a1bSJed Brown PetscReal one=1.0, two=2.0, six=6.0,pi=4.0*atan(1.0); 350*c4762a1bSJed Brown PetscReal hx,hy,hxhy,hxhx,hyhy; 351*c4762a1bSJed Brown PetscReal xi,v[5]; 352*c4762a1bSJed Brown PetscReal ecc=user->ecc, trule1,trule2,trule3,trule4,trule5,trule6; 353*c4762a1bSJed Brown PetscReal vmiddle, vup, vdown, vleft, vright; 354*c4762a1bSJed Brown PetscBool assembled; 355*c4762a1bSJed Brown 356*c4762a1bSJed Brown nx=user->nx; 357*c4762a1bSJed Brown ny=user->ny; 358*c4762a1bSJed Brown hx=two*pi/(nx+1.0); 359*c4762a1bSJed Brown hy=two*user->b/(ny+1.0); 360*c4762a1bSJed Brown hxhy=hx*hy; 361*c4762a1bSJed Brown hxhx=one/(hx*hx); 362*c4762a1bSJed Brown hyhy=one/(hy*hy); 363*c4762a1bSJed Brown 364*c4762a1bSJed Brown /* 365*c4762a1bSJed Brown Get local grid boundaries 366*c4762a1bSJed Brown */ 367*c4762a1bSJed Brown ierr = DMDAGetCorners(user->dm,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr); 368*c4762a1bSJed Brown ierr = DMDAGetGhostCorners(user->dm,&gxs,&gys,NULL,&gxm,&gym,NULL);CHKERRQ(ierr); 369*c4762a1bSJed Brown ierr = MatAssembled(hes,&assembled);CHKERRQ(ierr); 370*c4762a1bSJed Brown if (assembled){ierr = MatZeroEntries(hes);CHKERRQ(ierr);} 371*c4762a1bSJed Brown 372*c4762a1bSJed Brown for (i=xs; i< xs+xm; i++){ 373*c4762a1bSJed Brown xi=(i+1)*hx; 374*c4762a1bSJed Brown trule1=hxhy*( p(xi,ecc) + p(xi+hx,ecc) + p(xi,ecc) ) / six; /* L(i,j) */ 375*c4762a1bSJed Brown trule2=hxhy*( p(xi,ecc) + p(xi-hx,ecc) + p(xi,ecc) ) / six; /* U(i,j) */ 376*c4762a1bSJed Brown trule3=hxhy*( p(xi,ecc) + p(xi+hx,ecc) + p(xi+hx,ecc) ) / six; /* U(i+1,j) */ 377*c4762a1bSJed Brown trule4=hxhy*( p(xi,ecc) + p(xi-hx,ecc) + p(xi-hx,ecc) ) / six; /* L(i-1,j) */ 378*c4762a1bSJed Brown trule5=trule1; /* L(i,j-1) */ 379*c4762a1bSJed Brown trule6=trule2; /* U(i,j+1) */ 380*c4762a1bSJed Brown 381*c4762a1bSJed Brown vdown=-(trule5+trule2)*hyhy; 382*c4762a1bSJed Brown vleft=-hxhx*(trule2+trule4); 383*c4762a1bSJed Brown vright= -hxhx*(trule1+trule3); 384*c4762a1bSJed Brown vup=-hyhy*(trule1+trule6); 385*c4762a1bSJed Brown vmiddle=(hxhx)*(trule1+trule2+trule3+trule4)+hyhy*(trule1+trule2+trule5+trule6); 386*c4762a1bSJed Brown v[0]=0; v[1]=0; v[2]=0; v[3]=0; v[4]=0; 387*c4762a1bSJed Brown 388*c4762a1bSJed Brown for (j=ys; j<ys+ym; j++){ 389*c4762a1bSJed Brown row=(j-gys)*gxm + (i-gxs); 390*c4762a1bSJed Brown 391*c4762a1bSJed Brown k=0; 392*c4762a1bSJed Brown if (j>gys){ 393*c4762a1bSJed Brown v[k]=vdown; col[k]=row - gxm; k++; 394*c4762a1bSJed Brown } 395*c4762a1bSJed Brown 396*c4762a1bSJed Brown if (i>gxs){ 397*c4762a1bSJed Brown v[k]= vleft; col[k]=row - 1; k++; 398*c4762a1bSJed Brown } 399*c4762a1bSJed Brown 400*c4762a1bSJed Brown v[k]= vmiddle; col[k]=row; k++; 401*c4762a1bSJed Brown 402*c4762a1bSJed Brown if (i+1 < gxs+gxm){ 403*c4762a1bSJed Brown v[k]= vright; col[k]=row+1; k++; 404*c4762a1bSJed Brown } 405*c4762a1bSJed Brown 406*c4762a1bSJed Brown if (j+1 <gys+gym){ 407*c4762a1bSJed Brown v[k]= vup; col[k] = row+gxm; k++; 408*c4762a1bSJed Brown } 409*c4762a1bSJed Brown ierr = MatSetValuesLocal(hes,1,&row,k,col,v,INSERT_VALUES);CHKERRQ(ierr); 410*c4762a1bSJed Brown 411*c4762a1bSJed Brown } 412*c4762a1bSJed Brown 413*c4762a1bSJed Brown } 414*c4762a1bSJed Brown 415*c4762a1bSJed Brown /* 416*c4762a1bSJed Brown Assemble matrix, using the 2-step process: 417*c4762a1bSJed Brown MatAssemblyBegin(), MatAssemblyEnd(). 418*c4762a1bSJed Brown By placing code between these two statements, computations can be 419*c4762a1bSJed Brown done while messages are in transition. 420*c4762a1bSJed Brown */ 421*c4762a1bSJed Brown ierr = MatAssemblyBegin(hes,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 422*c4762a1bSJed Brown ierr = MatAssemblyEnd(hes,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 423*c4762a1bSJed Brown 424*c4762a1bSJed Brown /* 425*c4762a1bSJed Brown Tell the matrix we will never add a new nonzero location to the 426*c4762a1bSJed Brown matrix. If we do it will generate an error. 427*c4762a1bSJed Brown */ 428*c4762a1bSJed Brown ierr = MatSetOption(hes,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 429*c4762a1bSJed Brown ierr = MatSetOption(hes,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 430*c4762a1bSJed Brown 431*c4762a1bSJed Brown ierr = PetscLogFlops(9*xm*ym+49*xm);CHKERRQ(ierr); 432*c4762a1bSJed Brown ierr = MatNorm(hes,NORM_1,&hx);CHKERRQ(ierr); 433*c4762a1bSJed Brown return 0; 434*c4762a1bSJed Brown } 435*c4762a1bSJed Brown 436*c4762a1bSJed Brown PetscErrorCode Monitor(Tao tao, void *ctx) 437*c4762a1bSJed Brown { 438*c4762a1bSJed Brown PetscErrorCode ierr; 439*c4762a1bSJed Brown PetscInt its; 440*c4762a1bSJed Brown PetscReal f,gnorm,cnorm,xdiff; 441*c4762a1bSJed Brown TaoConvergedReason reason; 442*c4762a1bSJed Brown 443*c4762a1bSJed Brown PetscFunctionBegin; 444*c4762a1bSJed Brown ierr = TaoGetSolutionStatus(tao, &its, &f, &gnorm, &cnorm, &xdiff, &reason);CHKERRQ(ierr); 445*c4762a1bSJed Brown if (!(its%5)) { 446*c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_WORLD,"iteration=%D\tf=%g\n",its,(double)f);CHKERRQ(ierr); 447*c4762a1bSJed Brown } 448*c4762a1bSJed Brown PetscFunctionReturn(0); 449*c4762a1bSJed Brown } 450*c4762a1bSJed Brown 451*c4762a1bSJed Brown PetscErrorCode ConvergenceTest(Tao tao, void *ctx) 452*c4762a1bSJed Brown { 453*c4762a1bSJed Brown PetscErrorCode ierr; 454*c4762a1bSJed Brown PetscInt its; 455*c4762a1bSJed Brown PetscReal f,gnorm,cnorm,xdiff; 456*c4762a1bSJed Brown TaoConvergedReason reason; 457*c4762a1bSJed Brown 458*c4762a1bSJed Brown PetscFunctionBegin; 459*c4762a1bSJed Brown ierr = TaoGetSolutionStatus(tao, &its, &f, &gnorm, &cnorm, &xdiff, &reason);CHKERRQ(ierr); 460*c4762a1bSJed Brown if (its == 100) { 461*c4762a1bSJed Brown ierr = TaoSetConvergedReason(tao,TAO_DIVERGED_MAXITS);CHKERRQ(ierr); 462*c4762a1bSJed Brown } 463*c4762a1bSJed Brown PetscFunctionReturn(0); 464*c4762a1bSJed Brown 465*c4762a1bSJed Brown } 466*c4762a1bSJed Brown 467*c4762a1bSJed Brown 468*c4762a1bSJed Brown /*TEST 469*c4762a1bSJed Brown 470*c4762a1bSJed Brown build: 471*c4762a1bSJed Brown requires: !complex 472*c4762a1bSJed Brown 473*c4762a1bSJed Brown test: 474*c4762a1bSJed Brown args: -tao_smonitor -mx 8 -my 12 -tao_type tron -tao_gatol 1.e-5 475*c4762a1bSJed Brown requires: !single 476*c4762a1bSJed Brown 477*c4762a1bSJed Brown test: 478*c4762a1bSJed Brown suffix: 2 479*c4762a1bSJed Brown nsize: 2 480*c4762a1bSJed Brown args: -tao_smonitor -mx 50 -my 50 -ecc 0.99 -tao_type gpcg -tao_gatol 1.e-5 481*c4762a1bSJed Brown requires: !single 482*c4762a1bSJed Brown 483*c4762a1bSJed Brown test: 484*c4762a1bSJed Brown suffix: 3 485*c4762a1bSJed Brown nsize: 2 486*c4762a1bSJed Brown args: -tao_smonitor -mx 10 -my 16 -ecc 0.9 -tao_type bqpip -tao_gatol 1.e-4 487*c4762a1bSJed Brown requires: !single 488*c4762a1bSJed Brown 489*c4762a1bSJed Brown test: 490*c4762a1bSJed Brown suffix: 4 491*c4762a1bSJed Brown nsize: 2 492*c4762a1bSJed Brown args: -tao_smonitor -mx 10 -my 16 -ecc 0.9 -tao_type bqpip -tao_gatol 1.e-4 -test_getdiagonal 493*c4762a1bSJed Brown output_file: output/jbearing2_3.out 494*c4762a1bSJed Brown requires: !single 495*c4762a1bSJed Brown 496*c4762a1bSJed Brown test: 497*c4762a1bSJed Brown suffix: 5 498*c4762a1bSJed Brown args: -tao_smonitor -mx 8 -my 12 -tao_type bncg -tao_bncg_type gd -tao_gatol 1e-4 499*c4762a1bSJed Brown requires: !single 500*c4762a1bSJed Brown 501*c4762a1bSJed Brown test: 502*c4762a1bSJed Brown suffix: 6 503*c4762a1bSJed Brown args: -tao_smonitor -mx 8 -my 12 -tao_type bncg -tao_gatol 1e-4 504*c4762a1bSJed Brown requires: !single 505*c4762a1bSJed Brown 506*c4762a1bSJed Brown test: 507*c4762a1bSJed Brown suffix: 7 508*c4762a1bSJed Brown args: -tao_smonitor -mx 8 -my 12 -tao_type bnls -tao_gatol 1e-5 509*c4762a1bSJed Brown requires: !single 510*c4762a1bSJed Brown 511*c4762a1bSJed Brown test: 512*c4762a1bSJed Brown suffix: 8 513*c4762a1bSJed Brown args: -tao_smonitor -mx 8 -my 12 -tao_type bntr -tao_gatol 1e-5 514*c4762a1bSJed Brown requires: !single 515*c4762a1bSJed Brown 516*c4762a1bSJed Brown test: 517*c4762a1bSJed Brown suffix: 9 518*c4762a1bSJed Brown args: -tao_smonitor -mx 8 -my 12 -tao_type bntl -tao_gatol 1e-5 519*c4762a1bSJed Brown requires: !single 520*c4762a1bSJed Brown 521*c4762a1bSJed Brown test: 522*c4762a1bSJed Brown suffix: 10 523*c4762a1bSJed Brown args: -tao_smonitor -mx 8 -my 12 -tao_type bnls -tao_gatol 1e-5 -tao_bnk_max_cg_its 3 524*c4762a1bSJed Brown requires: !single 525*c4762a1bSJed Brown 526*c4762a1bSJed Brown test: 527*c4762a1bSJed Brown suffix: 11 528*c4762a1bSJed Brown args: -tao_smonitor -mx 8 -my 12 -tao_type bntr -tao_gatol 1e-5 -tao_bnk_max_cg_its 3 529*c4762a1bSJed Brown requires: !single 530*c4762a1bSJed Brown 531*c4762a1bSJed Brown test: 532*c4762a1bSJed Brown suffix: 12 533*c4762a1bSJed Brown args: -tao_smonitor -mx 8 -my 12 -tao_type bntl -tao_gatol 1e-5 -tao_bnk_max_cg_its 3 534*c4762a1bSJed Brown requires: !single 535*c4762a1bSJed Brown 536*c4762a1bSJed Brown test: 537*c4762a1bSJed Brown suffix: 13 538*c4762a1bSJed Brown args: -tao_smonitor -mx 8 -my 12 -tao_gatol 1e-4 -tao_type bqnls 539*c4762a1bSJed Brown requires: !single 540*c4762a1bSJed Brown 541*c4762a1bSJed Brown test: 542*c4762a1bSJed Brown suffix: 14 543*c4762a1bSJed Brown args: -tao_smonitor -mx 8 -my 12 -tao_gatol 1e-4 -tao_type blmvm 544*c4762a1bSJed Brown requires: !single 545*c4762a1bSJed Brown 546*c4762a1bSJed Brown test: 547*c4762a1bSJed Brown suffix: 15 548*c4762a1bSJed Brown args: -tao_smonitor -mx 8 -my 12 -tao_gatol 1e-4 -tao_type bqnkls -tao_bqnk_mat_type lmvmbfgs 549*c4762a1bSJed Brown requires: !single 550*c4762a1bSJed Brown 551*c4762a1bSJed Brown test: 552*c4762a1bSJed Brown suffix: 16 553*c4762a1bSJed Brown args: -tao_smonitor -mx 8 -my 12 -tao_gatol 1e-4 -tao_type bqnktr -tao_bqnk_mat_type lmvmsr1 554*c4762a1bSJed Brown requires: !single 555*c4762a1bSJed Brown 556*c4762a1bSJed Brown test: 557*c4762a1bSJed Brown suffix: 17 558*c4762a1bSJed Brown args: -tao_smonitor -mx 8 -my 12 -tao_gatol 1e-4 -tao_type bqnls -tao_bqnls_mat_lmvm_scale_type scalar 559*c4762a1bSJed Brown requires: !single 560*c4762a1bSJed Brown 561*c4762a1bSJed Brown test: 562*c4762a1bSJed Brown suffix: 18 563*c4762a1bSJed Brown args: -tao_smonitor -mx 8 -my 12 -tao_gatol 1e-4 -tao_type bqnls -tao_bqnls_mat_lmvm_scale_type none 564*c4762a1bSJed Brown requires: !single 565*c4762a1bSJed Brown 566*c4762a1bSJed Brown TEST*/ 567