1 /* Program usage: mpiexec -n 2 ./ex1 [-help] [all TAO options] */ 2 3 /* ---------------------------------------------------------------------- 4 min f(x) = (x0 - 2)^2 + (x1 - 2)^2 - 2*(x0 + x1) 5 s.t. x0^2 + x1 - 2 = 0 6 0 <= x0^2 - x1 <= 1 7 -1 <= x0, x1 <= 2 8 --> 9 g(x) = 0 10 h(x) >= 0 11 -1 <= x0, x1 <= 2 12 where 13 g(x) = x0^2 + x1 - 2 14 h(x) = [x0^2 - x1 15 1 -(x0^2 - x1)] 16 ---------------------------------------------------------------------- */ 17 18 #include <petsctao.h> 19 20 static char help[]= "Solves constrained optimiztion problem using pdipm.\n\ 21 Input parameters include:\n\ 22 -tao_type pdipm : sets Tao solver\n\ 23 -no_eq : removes the equaility constraints from the problem\n\ 24 -snes_fd : snes with finite difference Jacobian (needed for pdipm)\n\ 25 -snes_compare_explicit : compare user Jacobian with finite difference Jacobian \n\ 26 -tao_cmonitor : convergence monitor with constraint norm \n\ 27 -tao_view_solution : view exact solution at each itteration\n\ 28 Note: external package MUMPS is required to run pdipm. This is designed for a maximum of 2 processors, the code will error if size > 2.\n"; 29 30 /* 31 User-defined application context - contains data needed by the application 32 */ 33 typedef struct { 34 PetscInt n; /* Global length of x */ 35 PetscInt ne; /* Global number of equality constraints */ 36 PetscInt ni; /* Global number of inequality constraints */ 37 PetscBool noeqflag; 38 Vec x,xl,xu; 39 Vec ce,ci,bl,bu,Xseq; 40 Mat Ae,Ai,H; 41 VecScatter scat; 42 } AppCtx; 43 44 /* -------- User-defined Routines --------- */ 45 PetscErrorCode InitializeProblem(AppCtx *); 46 PetscErrorCode DestroyProblem(AppCtx *); 47 PetscErrorCode FormFunctionGradient(Tao,Vec,PetscReal *,Vec,void *); 48 PetscErrorCode FormHessian(Tao,Vec,Mat,Mat, void*); 49 PetscErrorCode FormInequalityConstraints(Tao,Vec,Vec,void*); 50 PetscErrorCode FormEqualityConstraints(Tao,Vec,Vec,void*); 51 PetscErrorCode FormInequalityJacobian(Tao,Vec,Mat,Mat, void*); 52 PetscErrorCode FormEqualityJacobian(Tao,Vec,Mat,Mat, void*); 53 54 PetscErrorCode main(int argc,char **argv) 55 { 56 PetscErrorCode ierr; /* used to check for functions returning nonzeros */ 57 Tao tao; 58 KSP ksp; 59 PC pc; 60 AppCtx user; /* application context */ 61 Vec x; 62 PetscMPIInt rank; 63 TaoType type; 64 PetscBool pdipm; 65 66 ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; 67 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRMPI(ierr); 68 if (rank>1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_WRONG_MPI_SIZE,"More than 2 processors detected. Example written to use max of 2 processors.\n"); 69 70 ierr = PetscPrintf(PETSC_COMM_WORLD,"---- Constrained Problem -----\n");CHKERRQ(ierr); 71 ierr = InitializeProblem(&user);CHKERRQ(ierr); /* sets up problem, function below */ 72 ierr = TaoCreate(PETSC_COMM_WORLD,&tao);CHKERRQ(ierr); 73 ierr = TaoSetType(tao,TAOPDIPM);CHKERRQ(ierr); 74 ierr = TaoSetInitialVector(tao,user.x);CHKERRQ(ierr); /* gets solution vector from problem */ 75 ierr = TaoSetVariableBounds(tao,user.xl,user.xu);CHKERRQ(ierr); /* sets lower upper bounds from given solution */ 76 ierr = TaoSetObjectiveAndGradientRoutine(tao,FormFunctionGradient,(void*)&user);CHKERRQ(ierr); 77 78 if (!user.noeqflag){ 79 ierr = TaoSetEqualityConstraintsRoutine(tao,user.ce,FormEqualityConstraints,(void*)&user);CHKERRQ(ierr); 80 } 81 ierr = TaoSetInequalityConstraintsRoutine(tao,user.ci,FormInequalityConstraints,(void*)&user);CHKERRQ(ierr); 82 if (!user.noeqflag){ 83 ierr = TaoSetJacobianEqualityRoutine(tao,user.Ae,user.Ae,FormEqualityJacobian,(void*)&user);CHKERRQ(ierr); /* equality jacobian */ 84 } 85 ierr = TaoSetJacobianInequalityRoutine(tao,user.Ai,user.Ai,FormInequalityJacobian,(void*)&user);CHKERRQ(ierr); /* inequality jacobian */ 86 ierr = TaoSetTolerances(tao,1.e-6,1.e-6,1.e-6);CHKERRQ(ierr); 87 ierr = TaoSetConstraintTolerances(tao,1.e-6,1.e-6);CHKERRQ(ierr); 88 89 ierr = TaoGetKSP(tao,&ksp);CHKERRQ(ierr); 90 ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 91 ierr = PCSetType(pc,PCCHOLESKY);CHKERRQ(ierr); 92 /* 93 This algorithm produces matrices with zeros along the diagonal therefore we use 94 MUMPS which provides solver for indefinite matrices 95 */ 96 ierr = PCFactorSetMatSolverType(pc,MATSOLVERMUMPS);CHKERRQ(ierr); /* requires mumps to solve pdipm */ 97 ierr = KSPSetType(ksp,KSPPREONLY);CHKERRQ(ierr); 98 ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); 99 100 ierr = TaoSetFromOptions(tao);CHKERRQ(ierr); 101 ierr = TaoGetType(tao,&type);CHKERRQ(ierr); 102 ierr = PetscObjectTypeCompare((PetscObject)tao,TAOPDIPM,&pdipm);CHKERRQ(ierr); 103 if (pdipm) { 104 ierr = TaoSetHessianRoutine(tao,user.H,user.H,FormHessian,(void*)&user);CHKERRQ(ierr); 105 } 106 107 ierr = TaoSolve(tao);CHKERRQ(ierr); 108 ierr = TaoGetSolutionVector(tao,&x);CHKERRQ(ierr); 109 ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 110 111 /* Free objects */ 112 ierr = DestroyProblem(&user);CHKERRQ(ierr); 113 ierr = TaoDestroy(&tao);CHKERRQ(ierr); 114 ierr = PetscFinalize(); 115 return ierr; 116 } 117 118 PetscErrorCode InitializeProblem(AppCtx *user) 119 { 120 PetscErrorCode ierr; 121 PetscMPIInt size; 122 PetscMPIInt rank; 123 PetscInt nloc,neloc,niloc; 124 125 PetscFunctionBegin; 126 ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRMPI(ierr); 127 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRMPI(ierr); 128 user->noeqflag = PETSC_FALSE; 129 ierr = PetscOptionsGetBool(NULL,NULL,"-no_eq",&user->noeqflag,NULL);CHKERRQ(ierr); 130 131 if (!user->noeqflag) { 132 ierr = PetscPrintf(PETSC_COMM_WORLD,"Solution should be f(1,1)=-2\n");CHKERRQ(ierr); 133 } 134 135 /* create vector x and set initial values */ 136 user->n = 2; /* global length */ 137 nloc = (rank==0)?user->n:0; 138 ierr = VecCreate(PETSC_COMM_WORLD,&user->x);CHKERRQ(ierr); 139 ierr = VecSetSizes(user->x,nloc,user->n);CHKERRQ(ierr); 140 ierr = VecSetFromOptions(user->x);CHKERRQ(ierr); 141 ierr = VecSet(user->x,0);CHKERRQ(ierr); 142 143 /* create and set lower and upper bound vectors */ 144 ierr = VecDuplicate(user->x,&user->xl);CHKERRQ(ierr); 145 ierr = VecDuplicate(user->x,&user->xu);CHKERRQ(ierr); 146 ierr = VecSet(user->xl,-1.0);CHKERRQ(ierr); 147 ierr = VecSet(user->xu,2.0);CHKERRQ(ierr); 148 149 /* create scater to zero */ 150 ierr = VecScatterCreateToZero(user->x,&user->scat,&user->Xseq);CHKERRQ(ierr); 151 152 user->ne = 1; 153 user->ni = 2; 154 neloc = (rank==0)?user->ne:0; 155 niloc = (rank==0)?user->ni:0; 156 157 if (!user->noeqflag){ 158 ierr = VecCreate(PETSC_COMM_WORLD,&user->ce);CHKERRQ(ierr); /* a 1x1 vec for equality constraints */ 159 ierr = VecSetSizes(user->ce,neloc,user->ne);CHKERRQ(ierr); 160 ierr = VecSetFromOptions(user->ce);CHKERRQ(ierr); 161 ierr = VecSetUp(user->ce);CHKERRQ(ierr); 162 } 163 164 ierr = VecCreate(PETSC_COMM_WORLD,&user->ci);CHKERRQ(ierr); /* a 2x1 vec for inequality constraints */ 165 ierr = VecSetSizes(user->ci,niloc,user->ni);CHKERRQ(ierr); 166 ierr = VecSetFromOptions(user->ci);CHKERRQ(ierr); 167 ierr = VecSetUp(user->ci);CHKERRQ(ierr); 168 169 /* nexn & nixn matricies for equaly and inequalty constriants */ 170 if (!user->noeqflag){ 171 ierr = MatCreate(PETSC_COMM_WORLD,&user->Ae);CHKERRQ(ierr); 172 ierr = MatSetSizes(user->Ae,neloc,nloc,user->ne,user->n);CHKERRQ(ierr); 173 ierr = MatSetFromOptions(user->Ae);CHKERRQ(ierr); 174 ierr = MatSetUp(user->Ae);CHKERRQ(ierr); 175 } 176 177 ierr = MatCreate(PETSC_COMM_WORLD,&user->Ai);CHKERRQ(ierr); 178 ierr = MatSetSizes(user->Ai,niloc,nloc,user->ni,user->n);CHKERRQ(ierr); 179 ierr = MatSetFromOptions(user->Ai);CHKERRQ(ierr); 180 ierr = MatSetUp(user->Ai);CHKERRQ(ierr); 181 182 ierr = MatCreate(PETSC_COMM_WORLD,&user->H);CHKERRQ(ierr); 183 ierr = MatSetSizes(user->H,nloc,nloc,user->n,user->n);CHKERRQ(ierr); 184 ierr = MatSetFromOptions(user->H);CHKERRQ(ierr); 185 ierr = MatSetUp(user->H);CHKERRQ(ierr); 186 PetscFunctionReturn(0); 187 } 188 189 PetscErrorCode DestroyProblem(AppCtx *user) 190 { 191 PetscErrorCode ierr; 192 193 PetscFunctionBegin; 194 if (!user->noeqflag){ 195 ierr = MatDestroy(&user->Ae);CHKERRQ(ierr); 196 } 197 ierr = MatDestroy(&user->Ai);CHKERRQ(ierr); 198 ierr = MatDestroy(&user->H);CHKERRQ(ierr); 199 200 ierr = VecDestroy(&user->x);CHKERRQ(ierr); 201 if (!user->noeqflag){ 202 ierr = VecDestroy(&user->ce);CHKERRQ(ierr); 203 } 204 ierr = VecDestroy(&user->ci);CHKERRQ(ierr); 205 ierr = VecDestroy(&user->xl);CHKERRQ(ierr); 206 ierr = VecDestroy(&user->xu);CHKERRQ(ierr); 207 ierr = VecDestroy(&user->Xseq);CHKERRQ(ierr); 208 ierr = VecScatterDestroy(&user->scat);CHKERRQ(ierr); 209 PetscFunctionReturn(0); 210 } 211 212 /* Evaluate 213 f(x) = (x0 - 2)^2 + (x1 - 2)^2 - 2*(x0 + x1) 214 G = grad f = [2*(x0 - 2) - 2; 215 2*(x1 - 2) - 2] 216 */ 217 PetscErrorCode FormFunctionGradient(Tao tao, Vec X, PetscReal *f, Vec G, void *ctx) 218 { 219 PetscScalar g; 220 const PetscScalar *x; 221 MPI_Comm comm; 222 PetscMPIInt rank; 223 PetscErrorCode ierr; 224 PetscReal fin; 225 AppCtx *user=(AppCtx*)ctx; 226 Vec Xseq=user->Xseq; 227 VecScatter scat=user->scat; 228 229 PetscFunctionBegin; 230 ierr = PetscObjectGetComm((PetscObject)tao,&comm);CHKERRQ(ierr); 231 ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 232 233 ierr = VecScatterBegin(scat,X,Xseq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 234 ierr = VecScatterEnd(scat,X,Xseq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 235 236 fin = 0.0; 237 if (!rank) { 238 ierr = VecGetArrayRead(Xseq,&x);CHKERRQ(ierr); 239 fin = (x[0]-2.0)*(x[0]-2.0) + (x[1]-2.0)*(x[1]-2.0) - 2.0*(x[0]+x[1]); 240 g = 2.0*(x[0]-2.0) - 2.0; 241 ierr = VecSetValue(G,0,g,INSERT_VALUES);CHKERRQ(ierr); 242 g = 2.0*(x[1]-2.0) - 2.0; 243 ierr = VecSetValue(G,1,g,INSERT_VALUES);CHKERRQ(ierr); 244 ierr = VecRestoreArrayRead(Xseq,&x);CHKERRQ(ierr); 245 } 246 ierr = MPI_Allreduce(&fin,f,1,MPIU_REAL,MPIU_SUM,comm);CHKERRMPI(ierr); 247 ierr = VecAssemblyBegin(G);CHKERRQ(ierr); 248 ierr = VecAssemblyEnd(G);CHKERRQ(ierr); 249 PetscFunctionReturn(0); 250 } 251 252 /* Evaluate 253 H = fxx + grad (grad g^T*DI) - grad (grad h^T*DE)] 254 = [ 2*(1+de[0]-di[0]+di[1]), 0; 255 0, 2] 256 */ 257 PetscErrorCode FormHessian(Tao tao, Vec x,Mat H, Mat Hpre, void *ctx) 258 { 259 AppCtx *user=(AppCtx*)ctx; 260 Vec DE,DI; 261 const PetscScalar *de,*di; 262 PetscInt zero=0,one=1; 263 PetscScalar two=2.0; 264 PetscScalar val=0.0; 265 Vec Deseq,Diseq=user->Xseq; 266 VecScatter Descat,Discat=user->scat; 267 PetscMPIInt rank; 268 MPI_Comm comm; 269 PetscErrorCode ierr; 270 271 PetscFunctionBegin; 272 ierr = TaoGetDualVariables(tao,&DE,&DI);CHKERRQ(ierr); 273 274 ierr = PetscObjectGetComm((PetscObject)tao,&comm);CHKERRQ(ierr); 275 ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 276 277 if (!user->noeqflag){ 278 ierr = VecScatterCreateToZero(DE,&Descat,&Deseq);CHKERRQ(ierr); 279 ierr = VecScatterBegin(Descat,DE,Deseq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 280 ierr = VecScatterEnd(Descat,DE,Deseq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 281 } 282 ierr = VecScatterBegin(Discat,DI,Diseq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 283 ierr = VecScatterEnd(Discat,DI,Diseq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 284 285 if (!rank){ 286 if (!user->noeqflag){ 287 ierr = VecGetArrayRead(Deseq,&de);CHKERRQ(ierr); /* places equality constraint dual into array */ 288 } 289 ierr = VecGetArrayRead(Diseq,&di);CHKERRQ(ierr); /* places inequality constraint dual into array */ 290 291 if (!user->noeqflag){ 292 val = 2.0 * (1 + de[0] - di[0] + di[1]); 293 ierr = VecRestoreArrayRead(Deseq,&de);CHKERRQ(ierr); 294 ierr = VecRestoreArrayRead(Diseq,&di);CHKERRQ(ierr); 295 } else { 296 val = 2.0 * (1 - di[0] + di[1]); 297 } 298 ierr = VecRestoreArrayRead(Diseq,&di);CHKERRQ(ierr); 299 ierr = MatSetValues(H,1,&zero,1,&zero,&val,INSERT_VALUES);CHKERRQ(ierr); 300 ierr = MatSetValues(H,1,&one,1,&one,&two,INSERT_VALUES);CHKERRQ(ierr); 301 } 302 ierr = MatAssemblyBegin(H,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 303 ierr = MatAssemblyEnd(H,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 304 if (!user->noeqflag){ 305 ierr = VecScatterDestroy(&Descat);CHKERRQ(ierr); 306 ierr = VecDestroy(&Deseq);CHKERRQ(ierr); 307 } 308 PetscFunctionReturn(0); 309 } 310 311 /* Evaluate 312 h = [ x0^2 - x1; 313 1 -(x0^2 - x1)] 314 */ 315 PetscErrorCode FormInequalityConstraints(Tao tao,Vec X,Vec CI,void *ctx) 316 { 317 const PetscScalar *x; 318 PetscScalar ci; 319 PetscErrorCode ierr; 320 MPI_Comm comm; 321 PetscMPIInt rank; 322 AppCtx *user=(AppCtx*)ctx; 323 Vec Xseq=user->Xseq; 324 VecScatter scat=user->scat; 325 326 PetscFunctionBegin; 327 ierr = PetscObjectGetComm((PetscObject)tao,&comm);CHKERRQ(ierr); 328 ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 329 330 ierr = VecScatterBegin(scat,X,Xseq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 331 ierr = VecScatterEnd(scat,X,Xseq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 332 333 if (!rank) { 334 ierr = VecGetArrayRead(Xseq,&x);CHKERRQ(ierr); 335 ci = x[0]*x[0] - x[1]; 336 ierr = VecSetValue(CI,0,ci,INSERT_VALUES);CHKERRQ(ierr); 337 ci = -x[0]*x[0] + x[1] + 1.0; 338 ierr = VecSetValue(CI,1,ci,INSERT_VALUES);CHKERRQ(ierr); 339 ierr = VecRestoreArrayRead(Xseq,&x);CHKERRQ(ierr); 340 } 341 ierr = VecAssemblyBegin(CI);CHKERRQ(ierr); 342 ierr = VecAssemblyEnd(CI);CHKERRQ(ierr); 343 PetscFunctionReturn(0); 344 } 345 346 /* Evaluate 347 g = [ x0^2 + x1 - 2] 348 */ 349 PetscErrorCode FormEqualityConstraints(Tao tao,Vec X,Vec CE,void *ctx) 350 { 351 const PetscScalar *x; 352 PetscScalar ce; 353 PetscErrorCode ierr; 354 MPI_Comm comm; 355 PetscMPIInt rank; 356 AppCtx *user=(AppCtx*)ctx; 357 Vec Xseq=user->Xseq; 358 VecScatter scat=user->scat; 359 360 PetscFunctionBegin; 361 ierr = PetscObjectGetComm((PetscObject)tao,&comm);CHKERRQ(ierr); 362 ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 363 364 ierr = VecScatterBegin(scat,X,Xseq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 365 ierr = VecScatterEnd(scat,X,Xseq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 366 367 if (!rank) { 368 ierr = VecGetArrayRead(Xseq,&x);CHKERRQ(ierr); 369 ce = x[0]*x[0] + x[1] - 2.0; 370 ierr = VecSetValue(CE,0,ce,INSERT_VALUES);CHKERRQ(ierr); 371 ierr = VecRestoreArrayRead(Xseq,&x);CHKERRQ(ierr); 372 } 373 ierr = VecAssemblyBegin(CE);CHKERRQ(ierr); 374 ierr = VecAssemblyEnd(CE);CHKERRQ(ierr); 375 PetscFunctionReturn(0); 376 } 377 378 /* 379 grad h = [ 2*x0, -1; 380 -2*x0, 1] 381 */ 382 PetscErrorCode FormInequalityJacobian(Tao tao, Vec X, Mat JI, Mat JIpre, void *ctx) 383 { 384 AppCtx *user=(AppCtx*)ctx; 385 PetscInt cols[2],min,max,i; 386 PetscScalar vals[2]; 387 const PetscScalar *x; 388 PetscErrorCode ierr; 389 Vec Xseq=user->Xseq; 390 VecScatter scat=user->scat; 391 MPI_Comm comm; 392 PetscMPIInt rank; 393 394 PetscFunctionBegin; 395 ierr = PetscObjectGetComm((PetscObject)tao,&comm);CHKERRQ(ierr); 396 ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 397 ierr = VecScatterBegin(scat,X,Xseq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 398 ierr = VecScatterEnd(scat,X,Xseq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 399 400 ierr = VecGetArrayRead(Xseq,&x);CHKERRQ(ierr); 401 ierr = MatGetOwnershipRange(JI,&min,&max);CHKERRQ(ierr); 402 403 cols[0] = 0; cols[1] = 1; 404 for (i=min;i<max;i++) { 405 if (i==0){ 406 vals[0] = 2*x[0]; vals[1] = -1.0; 407 ierr = MatSetValues(JI,1,&i,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 408 } 409 if (i==1) { 410 vals[0] = -2*x[0]; vals[1] = 1.0; 411 ierr = MatSetValues(JI,1,&i,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 412 } 413 } 414 ierr = VecRestoreArrayRead(Xseq,&x);CHKERRQ(ierr); 415 416 ierr = MatAssemblyBegin(JI,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 417 ierr = MatAssemblyEnd(JI,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 418 PetscFunctionReturn(0); 419 } 420 421 /* 422 grad g = [2*x0 423 1.0 ] 424 */ 425 PetscErrorCode FormEqualityJacobian(Tao tao,Vec X,Mat JE,Mat JEpre,void *ctx) 426 { 427 PetscInt rows[2]; 428 PetscScalar vals[2]; 429 const PetscScalar *x; 430 PetscMPIInt rank; 431 MPI_Comm comm; 432 PetscErrorCode ierr; 433 434 PetscFunctionBegin; 435 ierr = PetscObjectGetComm((PetscObject)tao,&comm);CHKERRQ(ierr); 436 ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 437 438 if (!rank) { 439 ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr); 440 rows[0] = 0; rows[1] = 1; 441 vals[0] = 2*x[0]; vals[1] = 1.0; 442 ierr = MatSetValues(JE,1,rows,2,rows,vals,INSERT_VALUES);CHKERRQ(ierr); 443 ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr); 444 } 445 ierr = MatAssemblyBegin(JE,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 446 ierr = MatAssemblyEnd(JE,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 447 PetscFunctionReturn(0); 448 } 449 450 451 /*TEST 452 453 build: 454 requires: !complex !define(PETSC_USE_CXX) mumps 455 456 test: 457 args: -tao_converged_reason -tao_pdipm_kkt_shift_pd 458 459 test: 460 suffix: 2 461 nsize: 2 462 args: -tao_converged_reason -tao_pdipm_kkt_shift_pd 463 464 test: 465 suffix: 3 466 args: -tao_converged_reason -no_eq 467 468 test: 469 suffix: 4 470 nsize: 2 471 args: -tao_converged_reason -no_eq 472 473 test: 474 suffix: 5 475 args: -tao_cmonitor -tao_type almm 476 477 test: 478 suffix: 6 479 args: -tao_cmonitor -tao_type almm -tao_almm_type phr 480 481 test: 482 suffix: 7 483 nsize: 2 484 args: -tao_cmonitor -tao_type almm 485 486 test: 487 suffix: 8 488 nsize: 2 489 requires: cuda 490 args: -tao_cmonitor -tao_type almm -vec_type cuda -mat_type aijcusparse 491 492 test: 493 suffix: 9 494 nsize: 2 495 args: -tao_cmonitor -tao_type almm -no_eq 496 497 test: 498 suffix: 10 499 nsize: 2 500 args: -tao_cmonitor -tao_type almm -tao_almm_type phr -no_eq 501 502 TEST*/ 503