1 /* Program usage: mpiexec -n 1 minsurf1 [-help] [all TAO options] */ 2 3 /* Include "petsctao.h" so we can use TAO solvers. */ 4 #include <petsctao.h> 5 6 static char help[] = 7 "This example demonstrates use of the TAO package to \n\ 8 solve an unconstrained minimization problem. This example is based on a \n\ 9 problem from the MINPACK-2 test suite. Given a rectangular 2-D domain and \n\ 10 boundary values along the edges of the domain, the objective is to find the\n\ 11 surface with the minimal area that satisfies the boundary conditions.\n\ 12 The command line options are:\n\ 13 -mx <xg>, where <xg> = number of grid points in the 1st coordinate direction\n\ 14 -my <yg>, where <yg> = number of grid points in the 2nd coordinate direction\n\ 15 -start <st>, where <st> =0 for zero vector, and an average of the boundary conditions otherwise \n\n"; 16 17 /*T 18 Concepts: TAO^Solving an unconstrained minimization problem 19 Routines: TaoCreate(); TaoSetType(); 20 Routines: TaoSetInitialVector(); 21 Routines: TaoSetObjectiveAndGradientRoutine(); 22 Routines: TaoSetHessianRoutine(); TaoSetFromOptions(); 23 Routines: TaoGetKSP(); TaoSolve(); 24 Routines: TaoDestroy(); 25 Processors: 1 26 T*/ 27 28 /* 29 User-defined application context - contains data needed by the 30 application-provided call-back routines, FormFunctionGradient() 31 and FormHessian(). 32 */ 33 typedef struct { 34 PetscInt mx, my; /* discretization in x, y directions */ 35 PetscReal *bottom, *top, *left, *right; /* boundary values */ 36 Mat H; 37 } AppCtx; 38 39 /* -------- User-defined Routines --------- */ 40 41 static PetscErrorCode MSA_BoundaryConditions(AppCtx*); 42 static PetscErrorCode MSA_InitialPoint(AppCtx*,Vec); 43 static PetscErrorCode QuadraticH(AppCtx*,Vec,Mat); 44 PetscErrorCode FormFunctionGradient(Tao,Vec,PetscReal*,Vec,void*); 45 PetscErrorCode FormHessian(Tao,Vec,Mat,Mat,void*); 46 47 int main(int argc, char **argv) 48 { 49 PetscErrorCode ierr; /* used to check for functions returning nonzeros */ 50 PetscInt N; /* Size of vector */ 51 PetscMPIInt size; /* Number of processors */ 52 Vec x; /* solution, gradient vectors */ 53 KSP ksp; /* PETSc Krylov subspace method */ 54 PetscBool flg; /* A return value when checking for user options */ 55 Tao tao; /* Tao solver context */ 56 AppCtx user; /* user-defined work context */ 57 58 /* Initialize TAO,PETSc */ 59 ierr = PetscInitialize(&argc, &argv,(char *)0,help);if (ierr) return ierr; 60 61 ierr = MPI_Comm_size(MPI_COMM_WORLD,&size);CHKERRMPI(ierr); 62 if (size >1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_WRONG_MPI_SIZE,"Incorrect number of processors"); 63 64 /* Specify default dimension of the problem */ 65 user.mx = 4; user.my = 4; 66 67 /* Check for any command line arguments that override defaults */ 68 ierr = PetscOptionsGetInt(NULL,NULL,"-mx",&user.mx,&flg);CHKERRQ(ierr); 69 ierr = PetscOptionsGetInt(NULL,NULL,"-my",&user.my,&flg);CHKERRQ(ierr); 70 71 ierr = PetscPrintf(PETSC_COMM_SELF,"\n---- Minimum Surface Area Problem -----\n");CHKERRQ(ierr); 72 ierr = PetscPrintf(PETSC_COMM_SELF,"mx: %D my: %D \n\n",user.mx,user.my);CHKERRQ(ierr); 73 74 /* Calculate any derived values from parameters */ 75 N = user.mx*user.my; 76 77 /* Create TAO solver and set desired solution method */ 78 ierr = TaoCreate(PETSC_COMM_SELF,&tao);CHKERRQ(ierr); 79 ierr = TaoSetType(tao,TAOLMVM);CHKERRQ(ierr); 80 81 /* Initialize minsurf application data structure for use in the function evaluations */ 82 ierr = MSA_BoundaryConditions(&user);CHKERRQ(ierr); /* Application specific routine */ 83 84 /* 85 Create a vector to hold the variables. Compute an initial solution. 86 Set this vector, which will be used by TAO. 87 */ 88 ierr = VecCreateSeq(PETSC_COMM_SELF,N,&x);CHKERRQ(ierr); 89 ierr = MSA_InitialPoint(&user,x);CHKERRQ(ierr); /* Application specific routine */ 90 ierr = TaoSetInitialVector(tao,x);CHKERRQ(ierr); /* A TAO routine */ 91 92 /* Provide TAO routines for function, gradient, and Hessian evaluation */ 93 ierr = TaoSetObjectiveAndGradientRoutine(tao,FormFunctionGradient,(void *)&user);CHKERRQ(ierr); 94 95 /* Create a matrix data structure to store the Hessian. This structure will be used by TAO */ 96 ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,N,N,7,NULL,&(user.H));CHKERRQ(ierr); 97 ierr = MatSetOption(user.H,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 98 ierr = TaoSetHessianRoutine(tao,user.H,user.H,FormHessian,(void *)&user);CHKERRQ(ierr); 99 100 /* Check for any TAO command line options */ 101 ierr = TaoSetFromOptions(tao);CHKERRQ(ierr); 102 103 /* Limit the number of iterations in the KSP linear solver */ 104 ierr = TaoGetKSP(tao,&ksp);CHKERRQ(ierr); 105 if (ksp) { 106 ierr = KSPSetTolerances(ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,user.mx*user.my);CHKERRQ(ierr); 107 } 108 109 /* SOLVE THE APPLICATION */ 110 ierr = TaoSolve(tao);CHKERRQ(ierr); 111 112 ierr = TaoDestroy(&tao);CHKERRQ(ierr); 113 ierr = VecDestroy(&x);CHKERRQ(ierr); 114 ierr = MatDestroy(&user.H);CHKERRQ(ierr); 115 ierr = PetscFree(user.bottom);CHKERRQ(ierr); 116 ierr = PetscFree(user.top);CHKERRQ(ierr); 117 ierr = PetscFree(user.left);CHKERRQ(ierr); 118 ierr = PetscFree(user.right);CHKERRQ(ierr); 119 120 ierr = PetscFinalize(); 121 return ierr; 122 } 123 124 /* -------------------------------------------------------------------- */ 125 126 /* FormFunctionGradient - Evaluates function and corresponding gradient. 127 128 Input Parameters: 129 . tao - the Tao context 130 . X - input vector 131 . userCtx - optional user-defined context, as set by TaoSetFunctionGradient() 132 133 Output Parameters: 134 . fcn - the newly evaluated function 135 . G - vector containing the newly evaluated gradient 136 */ 137 PetscErrorCode FormFunctionGradient(Tao tao,Vec X,PetscReal *fcn,Vec G,void *userCtx) 138 { 139 AppCtx *user = (AppCtx *) userCtx; 140 PetscErrorCode ierr; 141 PetscInt i,j,row; 142 PetscInt mx=user->mx, my=user->my; 143 PetscReal rhx=mx+1, rhy=my+1; 144 PetscReal hx=1.0/(mx+1),hy=1.0/(my+1), hydhx=hy/hx, hxdhy=hx/hy, area=0.5*hx*hy, ft=0; 145 PetscReal f1,f2,f3,f4,f5,f6,d1,d2,d3,d4,d5,d6,d7,d8,xc,xl,xr,xt,xb,xlt,xrb; 146 PetscReal df1dxc,df2dxc,df3dxc,df4dxc,df5dxc,df6dxc; 147 PetscReal zero=0.0; 148 PetscScalar *g; 149 const PetscScalar *x; 150 151 PetscFunctionBeginUser; 152 ierr = VecSet(G, zero);CHKERRQ(ierr); 153 154 ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr); 155 ierr = VecGetArray(G,&g);CHKERRQ(ierr); 156 157 /* Compute function over the locally owned part of the mesh */ 158 for (j=0; j<my; j++) { 159 for (i=0; i< mx; i++) { 160 row=(j)*mx + (i); 161 xc = x[row]; 162 xlt=xrb=xl=xr=xb=xt=xc; 163 if (i==0) { /* left side */ 164 xl = user->left[j+1]; 165 xlt = user->left[j+2]; 166 } else { 167 xl = x[row-1]; 168 } 169 170 if (j==0) { /* bottom side */ 171 xb = user->bottom[i+1]; 172 xrb = user->bottom[i+2]; 173 } else { 174 xb = x[row-mx]; 175 } 176 177 if (i+1 == mx) { /* right side */ 178 xr = user->right[j+1]; 179 xrb = user->right[j]; 180 } else { 181 xr = x[row+1]; 182 } 183 184 if (j+1==0+my) { /* top side */ 185 xt = user->top[i+1]; 186 xlt = user->top[i]; 187 }else { 188 xt = x[row+mx]; 189 } 190 191 if (i>0 && j+1<my) { 192 xlt = x[row-1+mx]; 193 } 194 if (j>0 && i+1<mx) { 195 xrb = x[row+1-mx]; 196 } 197 198 d1 = (xc-xl); 199 d2 = (xc-xr); 200 d3 = (xc-xt); 201 d4 = (xc-xb); 202 d5 = (xr-xrb); 203 d6 = (xrb-xb); 204 d7 = (xlt-xl); 205 d8 = (xt-xlt); 206 207 df1dxc = d1*hydhx; 208 df2dxc = (d1*hydhx + d4*hxdhy); 209 df3dxc = d3*hxdhy; 210 df4dxc = (d2*hydhx + d3*hxdhy); 211 df5dxc = d2*hydhx; 212 df6dxc = d4*hxdhy; 213 214 d1 *= rhx; 215 d2 *= rhx; 216 d3 *= rhy; 217 d4 *= rhy; 218 d5 *= rhy; 219 d6 *= rhx; 220 d7 *= rhy; 221 d8 *= rhx; 222 223 f1 = PetscSqrtScalar(1.0 + d1*d1 + d7*d7); 224 f2 = PetscSqrtScalar(1.0 + d1*d1 + d4*d4); 225 f3 = PetscSqrtScalar(1.0 + d3*d3 + d8*d8); 226 f4 = PetscSqrtScalar(1.0 + d3*d3 + d2*d2); 227 f5 = PetscSqrtScalar(1.0 + d2*d2 + d5*d5); 228 f6 = PetscSqrtScalar(1.0 + d4*d4 + d6*d6); 229 230 ft = ft + (f2 + f4); 231 232 df1dxc /= f1; 233 df2dxc /= f2; 234 df3dxc /= f3; 235 df4dxc /= f4; 236 df5dxc /= f5; 237 df6dxc /= f6; 238 239 g[row] = (df1dxc+df2dxc+df3dxc+df4dxc+df5dxc+df6dxc)/2.0; 240 } 241 } 242 243 for (j=0; j<my; j++) { /* left side */ 244 d3 = (user->left[j+1] - user->left[j+2])*rhy; 245 d2 = (user->left[j+1] - x[j*mx])*rhx; 246 ft = ft+PetscSqrtScalar(1.0 + d3*d3 + d2*d2); 247 } 248 249 for (i=0; i<mx; i++) { /* bottom */ 250 d2 = (user->bottom[i+1]-user->bottom[i+2])*rhx; 251 d3 = (user->bottom[i+1]-x[i])*rhy; 252 ft = ft+PetscSqrtScalar(1.0 + d3*d3 + d2*d2); 253 } 254 255 for (j=0; j< my; j++) { /* right side */ 256 d1 = (x[(j+1)*mx-1]-user->right[j+1])*rhx; 257 d4 = (user->right[j]-user->right[j+1])*rhy; 258 ft = ft+PetscSqrtScalar(1.0 + d1*d1 + d4*d4); 259 } 260 261 for (i=0; i<mx; i++) { /* top side */ 262 d1 = (x[(my-1)*mx + i] - user->top[i+1])*rhy; 263 d4 = (user->top[i+1] - user->top[i])*rhx; 264 ft = ft+PetscSqrtScalar(1.0 + d1*d1 + d4*d4); 265 } 266 267 /* Bottom left corner */ 268 d1 = (user->left[0]-user->left[1])*rhy; 269 d2 = (user->bottom[0]-user->bottom[1])*rhx; 270 ft += PetscSqrtScalar(1.0 + d1*d1 + d2*d2); 271 272 /* Top right corner */ 273 d1 = (user->right[my+1] - user->right[my])*rhy; 274 d2 = (user->top[mx+1] - user->top[mx])*rhx; 275 ft += PetscSqrtScalar(1.0 + d1*d1 + d2*d2); 276 277 (*fcn)=ft*area; 278 279 /* Restore vectors */ 280 ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr); 281 ierr = VecRestoreArray(G,&g);CHKERRQ(ierr); 282 ierr = PetscLogFlops(67.0*mx*my);CHKERRQ(ierr); 283 PetscFunctionReturn(0); 284 } 285 286 /* ------------------------------------------------------------------- */ 287 /* 288 FormHessian - Evaluates the Hessian matrix. 289 290 Input Parameters: 291 . tao - the Tao context 292 . x - input vector 293 . ptr - optional user-defined context, as set by TaoSetHessian() 294 295 Output Parameters: 296 . H - Hessian matrix 297 . Hpre - optionally different preconditioning matrix 298 . flg - flag indicating matrix structure 299 300 */ 301 PetscErrorCode FormHessian(Tao tao,Vec X,Mat H, Mat Hpre, void *ptr) 302 { 303 PetscErrorCode ierr; 304 AppCtx *user = (AppCtx *) ptr; 305 306 PetscFunctionBeginUser; 307 /* Evaluate the Hessian entries*/ 308 ierr = QuadraticH(user,X,H);CHKERRQ(ierr); 309 PetscFunctionReturn(0); 310 } 311 312 /* ------------------------------------------------------------------- */ 313 /* 314 QuadraticH - Evaluates the Hessian matrix. 315 316 Input Parameters: 317 . user - user-defined context, as set by TaoSetHessian() 318 . X - input vector 319 320 Output Parameter: 321 . H - Hessian matrix 322 */ 323 PetscErrorCode QuadraticH(AppCtx *user, Vec X, Mat Hessian) 324 { 325 PetscErrorCode ierr; 326 PetscInt i,j,k,row; 327 PetscInt mx=user->mx, my=user->my; 328 PetscInt col[7]; 329 PetscReal hx=1.0/(mx+1), hy=1.0/(my+1), hydhx=hy/hx, hxdhy=hx/hy; 330 PetscReal rhx=mx+1, rhy=my+1; 331 PetscReal f1,f2,f3,f4,f5,f6,d1,d2,d3,d4,d5,d6,d7,d8,xc,xl,xr,xt,xb,xlt,xrb; 332 PetscReal hl,hr,ht,hb,hc,htl,hbr; 333 const PetscScalar *x; 334 PetscReal v[7]; 335 336 PetscFunctionBeginUser; 337 /* Get pointers to vector data */ 338 ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr); 339 340 /* Initialize matrix entries to zero */ 341 ierr = MatZeroEntries(Hessian);CHKERRQ(ierr); 342 343 /* Set various matrix options */ 344 ierr = MatSetOption(Hessian,MAT_IGNORE_OFF_PROC_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 345 346 /* Compute Hessian over the locally owned part of the mesh */ 347 for (i=0; i< mx; i++) { 348 for (j=0; j<my; j++) { 349 350 row=(j)*mx + (i); 351 352 xc = x[row]; 353 xlt=xrb=xl=xr=xb=xt=xc; 354 355 /* Left side */ 356 if (i==0) { 357 xl= user->left[j+1]; 358 xlt = user->left[j+2]; 359 } else { 360 xl = x[row-1]; 361 } 362 363 if (j==0) { 364 xb=user->bottom[i+1]; 365 xrb = user->bottom[i+2]; 366 } else { 367 xb = x[row-mx]; 368 } 369 370 if (i+1 == mx) { 371 xr=user->right[j+1]; 372 xrb = user->right[j]; 373 } else { 374 xr = x[row+1]; 375 } 376 377 if (j+1==my) { 378 xt=user->top[i+1]; 379 xlt = user->top[i]; 380 }else { 381 xt = x[row+mx]; 382 } 383 384 if (i>0 && j+1<my) { 385 xlt = x[row-1+mx]; 386 } 387 if (j>0 && i+1<mx) { 388 xrb = x[row+1-mx]; 389 } 390 391 d1 = (xc-xl)*rhx; 392 d2 = (xc-xr)*rhx; 393 d3 = (xc-xt)*rhy; 394 d4 = (xc-xb)*rhy; 395 d5 = (xrb-xr)*rhy; 396 d6 = (xrb-xb)*rhx; 397 d7 = (xlt-xl)*rhy; 398 d8 = (xlt-xt)*rhx; 399 400 f1 = PetscSqrtScalar(1.0 + d1*d1 + d7*d7); 401 f2 = PetscSqrtScalar(1.0 + d1*d1 + d4*d4); 402 f3 = PetscSqrtScalar(1.0 + d3*d3 + d8*d8); 403 f4 = PetscSqrtScalar(1.0 + d3*d3 + d2*d2); 404 f5 = PetscSqrtScalar(1.0 + d2*d2 + d5*d5); 405 f6 = PetscSqrtScalar(1.0 + d4*d4 + d6*d6); 406 407 hl = (-hydhx*(1.0+d7*d7)+d1*d7)/(f1*f1*f1)+(-hydhx*(1.0+d4*d4)+d1*d4)/(f2*f2*f2); 408 hr = (-hydhx*(1.0+d5*d5)+d2*d5)/(f5*f5*f5)+(-hydhx*(1.0+d3*d3)+d2*d3)/(f4*f4*f4); 409 ht = (-hxdhy*(1.0+d8*d8)+d3*d8)/(f3*f3*f3)+(-hxdhy*(1.0+d2*d2)+d2*d3)/(f4*f4*f4); 410 hb = (-hxdhy*(1.0+d6*d6)+d4*d6)/(f6*f6*f6)+(-hxdhy*(1.0+d1*d1)+d1*d4)/(f2*f2*f2); 411 412 hbr = -d2*d5/(f5*f5*f5) - d4*d6/(f6*f6*f6); 413 htl = -d1*d7/(f1*f1*f1) - d3*d8/(f3*f3*f3); 414 415 hc = hydhx*(1.0+d7*d7)/(f1*f1*f1) + hxdhy*(1.0+d8*d8)/(f3*f3*f3) + hydhx*(1.0+d5*d5)/(f5*f5*f5) + hxdhy*(1.0+d6*d6)/(f6*f6*f6) + 416 (hxdhy*(1.0+d1*d1)+hydhx*(1.0+d4*d4)-2*d1*d4)/(f2*f2*f2) + (hxdhy*(1.0+d2*d2)+hydhx*(1.0+d3*d3)-2*d2*d3)/(f4*f4*f4); 417 418 hl*=0.5; hr*=0.5; ht*=0.5; hb*=0.5; hbr*=0.5; htl*=0.5; hc*=0.5; 419 420 k=0; 421 if (j>0) { 422 v[k]=hb; col[k]=row - mx; k++; 423 } 424 425 if (j>0 && i < mx -1) { 426 v[k]=hbr; col[k]=row - mx+1; k++; 427 } 428 429 if (i>0) { 430 v[k]= hl; col[k]=row - 1; k++; 431 } 432 433 v[k]= hc; col[k]=row; k++; 434 435 if (i < mx-1) { 436 v[k]= hr; col[k]=row+1; k++; 437 } 438 439 if (i>0 && j < my-1) { 440 v[k]= htl; col[k] = row+mx-1; k++; 441 } 442 443 if (j < my-1) { 444 v[k]= ht; col[k] = row+mx; k++; 445 } 446 447 /* 448 Set matrix values using local numbering, which was defined 449 earlier, in the main routine. 450 */ 451 ierr = MatSetValues(Hessian,1,&row,k,col,v,INSERT_VALUES);CHKERRQ(ierr); 452 } 453 } 454 455 /* Restore vectors */ 456 ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr); 457 458 /* Assemble the matrix */ 459 ierr = MatAssemblyBegin(Hessian,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 460 ierr = MatAssemblyEnd(Hessian,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 461 462 ierr = PetscLogFlops(199.0*mx*my);CHKERRQ(ierr); 463 PetscFunctionReturn(0); 464 } 465 466 /* ------------------------------------------------------------------- */ 467 /* 468 MSA_BoundaryConditions - Calculates the boundary conditions for 469 the region. 470 471 Input Parameter: 472 . user - user-defined application context 473 474 Output Parameter: 475 . user - user-defined application context 476 */ 477 static PetscErrorCode MSA_BoundaryConditions(AppCtx * user) 478 { 479 PetscErrorCode ierr; 480 PetscInt i,j,k,limit=0; 481 PetscInt maxits=5; 482 PetscInt mx=user->mx,my=user->my; 483 PetscInt bsize=0, lsize=0, tsize=0, rsize=0; 484 PetscReal one=1.0, two=2.0, three=3.0, tol=1e-10; 485 PetscReal fnorm,det,hx,hy,xt=0,yt=0; 486 PetscReal u1,u2,nf1,nf2,njac11,njac12,njac21,njac22; 487 PetscReal b=-0.5, t=0.5, l=-0.5, r=0.5; 488 PetscReal *boundary; 489 490 PetscFunctionBeginUser; 491 bsize=mx+2; lsize=my+2; rsize=my+2; tsize=mx+2; 492 493 ierr = PetscMalloc1(bsize,&user->bottom);CHKERRQ(ierr); 494 ierr = PetscMalloc1(tsize,&user->top);CHKERRQ(ierr); 495 ierr = PetscMalloc1(lsize,&user->left);CHKERRQ(ierr); 496 ierr = PetscMalloc1(rsize,&user->right);CHKERRQ(ierr); 497 498 hx= (r-l)/(mx+1); hy=(t-b)/(my+1); 499 500 for (j=0; j<4; j++) { 501 if (j==0) { 502 yt=b; 503 xt=l; 504 limit=bsize; 505 boundary=user->bottom; 506 } else if (j==1) { 507 yt=t; 508 xt=l; 509 limit=tsize; 510 boundary=user->top; 511 } else if (j==2) { 512 yt=b; 513 xt=l; 514 limit=lsize; 515 boundary=user->left; 516 } else { /* if (j==3) */ 517 yt=b; 518 xt=r; 519 limit=rsize; 520 boundary=user->right; 521 } 522 523 for (i=0; i<limit; i++) { 524 u1=xt; 525 u2=-yt; 526 for (k=0; k<maxits; k++) { 527 nf1=u1 + u1*u2*u2 - u1*u1*u1/three-xt; 528 nf2=-u2 - u1*u1*u2 + u2*u2*u2/three-yt; 529 fnorm=PetscSqrtScalar(nf1*nf1+nf2*nf2); 530 if (fnorm <= tol) break; 531 njac11=one+u2*u2-u1*u1; 532 njac12=two*u1*u2; 533 njac21=-two*u1*u2; 534 njac22=-one - u1*u1 + u2*u2; 535 det = njac11*njac22-njac21*njac12; 536 u1 = u1-(njac22*nf1-njac12*nf2)/det; 537 u2 = u2-(njac11*nf2-njac21*nf1)/det; 538 } 539 540 boundary[i]=u1*u1-u2*u2; 541 if (j==0 || j==1) { 542 xt=xt+hx; 543 } else { /* if (j==2 || j==3) */ 544 yt=yt+hy; 545 } 546 } 547 } 548 PetscFunctionReturn(0); 549 } 550 551 /* ------------------------------------------------------------------- */ 552 /* 553 MSA_InitialPoint - Calculates the initial guess in one of three ways. 554 555 Input Parameters: 556 . user - user-defined application context 557 . X - vector for initial guess 558 559 Output Parameters: 560 . X - newly computed initial guess 561 */ 562 static PetscErrorCode MSA_InitialPoint(AppCtx * user, Vec X) 563 { 564 PetscInt start=-1,i,j; 565 PetscErrorCode ierr; 566 PetscReal zero=0.0; 567 PetscBool flg; 568 569 PetscFunctionBeginUser; 570 ierr = VecSet(X, zero);CHKERRQ(ierr); 571 ierr = PetscOptionsGetInt(NULL,NULL,"-start",&start,&flg);CHKERRQ(ierr); 572 573 if (flg && start==0) { /* The zero vector is reasonable */ 574 ierr = VecSet(X, zero);CHKERRQ(ierr); 575 } else { /* Take an average of the boundary conditions */ 576 PetscInt row; 577 PetscInt mx=user->mx,my=user->my; 578 PetscReal *x; 579 580 /* Get pointers to vector data */ 581 ierr = VecGetArray(X,&x);CHKERRQ(ierr); 582 /* Perform local computations */ 583 for (j=0; j<my; j++) { 584 for (i=0; i< mx; i++) { 585 row=(j)*mx + (i); 586 x[row] = (((j+1)*user->bottom[i+1]+(my-j+1)*user->top[i+1])/(my+2)+ ((i+1)*user->left[j+1]+(mx-i+1)*user->right[j+1])/(mx+2))/2.0; 587 } 588 } 589 /* Restore vectors */ 590 ierr = VecRestoreArray(X,&x);CHKERRQ(ierr); 591 } 592 PetscFunctionReturn(0); 593 } 594 595 /*TEST 596 597 build: 598 requires: !complex 599 600 test: 601 args: -tao_smonitor -tao_type nls -mx 10 -my 8 -tao_gatol 1.e-4 602 requires: !single 603 604 test: 605 suffix: 2 606 args: -tao_smonitor -tao_type bmrm -mx 10 -my 8 -tao_gatol 1.e-3 607 requires: !single 608 609 test: 610 suffix: 3 611 args: -tao_smonitor -tao_type lmvm -mx 10 -my 8 -tao_gatol 1.e-3 612 requires: !single 613 614 test: 615 suffix: 4 616 args: -tao_smonitor -tao_type bntr -mx 10 -my 8 -tao_gatol 1.e-4 617 requires: !single 618 619 test: 620 suffix: 5 621 args: -tao_smonitor -tao_type bntl -mx 10 -my 8 -tao_gatol 1.e-4 622 requires: !single 623 624 test: 625 suffix: 6 626 args: -tao_smonitor -tao_type bnls -mx 10 -my 8 -tao_gatol 1.e-4 627 requires: !single 628 629 test: 630 suffix: 7 631 args: -tao_smonitor -tao_type bntr -mx 10 -my 8 -tao_bnk_max_cg_its 3 -tao_gatol 1.e-4 632 requires: !single 633 634 test: 635 suffix: 8 636 args: -tao_smonitor -tao_type bntl -mx 10 -my 8 -tao_bnk_max_cg_its 3 -tao_gatol 1.e-4 637 requires: !single 638 639 test: 640 suffix: 9 641 args: -tao_smonitor -tao_type bnls -mx 10 -my 8 -tao_bnk_max_cg_its 3 -tao_gatol 1.e-4 642 requires: !single 643 644 TEST*/ 645