1*c4762a1bSJed Brown static const char help[] = "Newton's method to solve a two-variable system, sequentially.\n" 2*c4762a1bSJed Brown "The same problem is solved twice - i) fully assembled system + ii) block system\n\n"; 3*c4762a1bSJed Brown 4*c4762a1bSJed Brown /*T 5*c4762a1bSJed Brown Concepts: SNES^basic uniprocessor example, block objects 6*c4762a1bSJed Brown Processors: 1 7*c4762a1bSJed Brown T*/ 8*c4762a1bSJed Brown 9*c4762a1bSJed Brown 10*c4762a1bSJed Brown 11*c4762a1bSJed Brown /* 12*c4762a1bSJed Brown Include "petscsnes.h" so that we can use SNES solvers. Note that this 13*c4762a1bSJed Brown file automatically includes: 14*c4762a1bSJed Brown petscsys.h - base PETSc routines petscvec.h - vectors 15*c4762a1bSJed Brown petscsys.h - system routines petscmat.h - matrices 16*c4762a1bSJed Brown petscis.h - index sets petscksp.h - Krylov subspace methods 17*c4762a1bSJed Brown petscviewer.h - viewers petscpc.h - preconditioners 18*c4762a1bSJed Brown petscksp.h - linear solvers 19*c4762a1bSJed Brown */ 20*c4762a1bSJed Brown #include <petscsnes.h> 21*c4762a1bSJed Brown 22*c4762a1bSJed Brown /* 23*c4762a1bSJed Brown This example is block version of the test found at 24*c4762a1bSJed Brown ${PETSC_DIR}/src/snes/tutorials/ex1.c 25*c4762a1bSJed Brown In this test we replace the Jacobian systems 26*c4762a1bSJed Brown [J]{x} = {F} 27*c4762a1bSJed Brown where 28*c4762a1bSJed Brown 29*c4762a1bSJed Brown [J] = (j_00, j_01), {x} = (x_0, x_1)^T, {F} = (f_0, f_1)^T 30*c4762a1bSJed Brown (j_10, j_11) 31*c4762a1bSJed Brown where [J] \in \mathbb^{2 \times 2}, {x},{F} \in \mathbb^{2 \times 1}, 32*c4762a1bSJed Brown 33*c4762a1bSJed Brown with a block system in which each block is of length 1. 34*c4762a1bSJed Brown i.e. The block system is thus 35*c4762a1bSJed Brown 36*c4762a1bSJed Brown [J] = ([j00], [j01]), {x} = ({x0}, {x1})^T, {F} = ({f0}, {f1})^T 37*c4762a1bSJed Brown ([j10], [j11]) 38*c4762a1bSJed Brown where 39*c4762a1bSJed Brown [j00], [j01], [j10], [j11] \in \mathbb^{1 \times 1} 40*c4762a1bSJed Brown {x0}, {x1}, {f0}, {f1} \in \mathbb^{1 \times 1} 41*c4762a1bSJed Brown 42*c4762a1bSJed Brown In practice we would not bother defing blocks of size one, and would instead assemble the 43*c4762a1bSJed Brown full system. This is just a simple test to illustrate how to manipulate the blocks and 44*c4762a1bSJed Brown to confirm the implementation is correct. 45*c4762a1bSJed Brown */ 46*c4762a1bSJed Brown 47*c4762a1bSJed Brown /* 48*c4762a1bSJed Brown User-defined routines 49*c4762a1bSJed Brown */ 50*c4762a1bSJed Brown static PetscErrorCode FormJacobian1(SNES,Vec,Mat,Mat,void*); 51*c4762a1bSJed Brown static PetscErrorCode FormFunction1(SNES,Vec,Vec,void*); 52*c4762a1bSJed Brown static PetscErrorCode FormJacobian2(SNES,Vec,Mat,Mat,void*); 53*c4762a1bSJed Brown static PetscErrorCode FormFunction2(SNES,Vec,Vec,void*); 54*c4762a1bSJed Brown static PetscErrorCode FormJacobian1_block(SNES,Vec,Mat,Mat,void*); 55*c4762a1bSJed Brown static PetscErrorCode FormFunction1_block(SNES,Vec,Vec,void*); 56*c4762a1bSJed Brown static PetscErrorCode FormJacobian2_block(SNES,Vec,Mat,Mat,void*); 57*c4762a1bSJed Brown static PetscErrorCode FormFunction2_block(SNES,Vec,Vec,void*); 58*c4762a1bSJed Brown 59*c4762a1bSJed Brown 60*c4762a1bSJed Brown static PetscErrorCode assembled_system(void) 61*c4762a1bSJed Brown { 62*c4762a1bSJed Brown SNES snes; /* nonlinear solver context */ 63*c4762a1bSJed Brown KSP ksp; /* linear solver context */ 64*c4762a1bSJed Brown PC pc; /* preconditioner context */ 65*c4762a1bSJed Brown Vec x,r; /* solution, residual vectors */ 66*c4762a1bSJed Brown Mat J; /* Jacobian matrix */ 67*c4762a1bSJed Brown PetscErrorCode ierr; 68*c4762a1bSJed Brown PetscInt its; 69*c4762a1bSJed Brown PetscScalar pfive = .5,*xx; 70*c4762a1bSJed Brown PetscBool flg; 71*c4762a1bSJed Brown 72*c4762a1bSJed Brown PetscFunctionBeginUser; 73*c4762a1bSJed Brown PetscPrintf(PETSC_COMM_WORLD, "\n\n========================= Assembled system =========================\n\n"); 74*c4762a1bSJed Brown 75*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 76*c4762a1bSJed Brown Create nonlinear solver context 77*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 78*c4762a1bSJed Brown 79*c4762a1bSJed Brown ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); 80*c4762a1bSJed Brown 81*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 82*c4762a1bSJed Brown Create matrix and vector data structures; set corresponding routines 83*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 84*c4762a1bSJed Brown 85*c4762a1bSJed Brown /* 86*c4762a1bSJed Brown Create vectors for solution and nonlinear function 87*c4762a1bSJed Brown */ 88*c4762a1bSJed Brown ierr = VecCreateSeq(PETSC_COMM_SELF,2,&x);CHKERRQ(ierr); 89*c4762a1bSJed Brown ierr = VecDuplicate(x,&r);CHKERRQ(ierr); 90*c4762a1bSJed Brown 91*c4762a1bSJed Brown /* 92*c4762a1bSJed Brown Create Jacobian matrix data structure 93*c4762a1bSJed Brown */ 94*c4762a1bSJed Brown ierr = MatCreate(PETSC_COMM_SELF,&J);CHKERRQ(ierr); 95*c4762a1bSJed Brown ierr = MatSetSizes(J,PETSC_DECIDE,PETSC_DECIDE,2,2);CHKERRQ(ierr); 96*c4762a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 97*c4762a1bSJed Brown ierr = MatSetUp(J);CHKERRQ(ierr); 98*c4762a1bSJed Brown 99*c4762a1bSJed Brown ierr = PetscOptionsHasName(NULL,NULL,"-hard",&flg);CHKERRQ(ierr); 100*c4762a1bSJed Brown if (!flg) { 101*c4762a1bSJed Brown /* 102*c4762a1bSJed Brown Set function evaluation routine and vector. 103*c4762a1bSJed Brown */ 104*c4762a1bSJed Brown ierr = SNESSetFunction(snes,r,FormFunction1,NULL);CHKERRQ(ierr); 105*c4762a1bSJed Brown 106*c4762a1bSJed Brown /* 107*c4762a1bSJed Brown Set Jacobian matrix data structure and Jacobian evaluation routine 108*c4762a1bSJed Brown */ 109*c4762a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,FormJacobian1,NULL);CHKERRQ(ierr); 110*c4762a1bSJed Brown } else { 111*c4762a1bSJed Brown ierr = SNESSetFunction(snes,r,FormFunction2,NULL);CHKERRQ(ierr); 112*c4762a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,FormJacobian2,NULL);CHKERRQ(ierr); 113*c4762a1bSJed Brown } 114*c4762a1bSJed Brown 115*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 116*c4762a1bSJed Brown Customize nonlinear solver; set runtime options 117*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 118*c4762a1bSJed Brown 119*c4762a1bSJed Brown /* 120*c4762a1bSJed Brown Set linear solver defaults for this problem. By extracting the 121*c4762a1bSJed Brown KSP, KSP, and PC contexts from the SNES context, we can then 122*c4762a1bSJed Brown directly call any KSP, KSP, and PC routines to set various options. 123*c4762a1bSJed Brown */ 124*c4762a1bSJed Brown ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 125*c4762a1bSJed Brown ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 126*c4762a1bSJed Brown ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 127*c4762a1bSJed Brown ierr = KSPSetTolerances(ksp,1.e-4,PETSC_DEFAULT,PETSC_DEFAULT,20);CHKERRQ(ierr); 128*c4762a1bSJed Brown 129*c4762a1bSJed Brown /* 130*c4762a1bSJed Brown Set SNES/KSP/KSP/PC runtime options, e.g., 131*c4762a1bSJed Brown -snes_view -snes_monitor -ksp_type <ksp> -pc_type <pc> 132*c4762a1bSJed Brown These options will override those specified above as long as 133*c4762a1bSJed Brown SNESSetFromOptions() is called _after_ any other customization 134*c4762a1bSJed Brown routines. 135*c4762a1bSJed Brown */ 136*c4762a1bSJed Brown ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); 137*c4762a1bSJed Brown 138*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 139*c4762a1bSJed Brown Evaluate initial guess; then solve nonlinear system 140*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 141*c4762a1bSJed Brown if (!flg) { 142*c4762a1bSJed Brown ierr = VecSet(x,pfive);CHKERRQ(ierr); 143*c4762a1bSJed Brown } else { 144*c4762a1bSJed Brown ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 145*c4762a1bSJed Brown xx[0] = 2.0; xx[1] = 3.0; 146*c4762a1bSJed Brown ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 147*c4762a1bSJed Brown } 148*c4762a1bSJed Brown /* 149*c4762a1bSJed Brown Note: The user should initialize the vector, x, with the initial guess 150*c4762a1bSJed Brown for the nonlinear solver prior to calling SNESSolve(). In particular, 151*c4762a1bSJed Brown to employ an initial guess of zero, the user should explicitly set 152*c4762a1bSJed Brown this vector to zero by calling VecSet(). 153*c4762a1bSJed Brown */ 154*c4762a1bSJed Brown 155*c4762a1bSJed Brown ierr = SNESSolve(snes,NULL,x);CHKERRQ(ierr); 156*c4762a1bSJed Brown ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); 157*c4762a1bSJed Brown if (flg) { 158*c4762a1bSJed Brown Vec f; 159*c4762a1bSJed Brown ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 160*c4762a1bSJed Brown ierr = SNESGetFunction(snes,&f,0,0);CHKERRQ(ierr); 161*c4762a1bSJed Brown ierr = VecView(r,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 162*c4762a1bSJed Brown } 163*c4762a1bSJed Brown 164*c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF,"number of SNES iterations = %D\n\n",its);CHKERRQ(ierr); 165*c4762a1bSJed Brown 166*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 167*c4762a1bSJed Brown Free work space. All PETSc objects should be destroyed when they 168*c4762a1bSJed Brown are no longer needed. 169*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 170*c4762a1bSJed Brown 171*c4762a1bSJed Brown ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); 172*c4762a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); 173*c4762a1bSJed Brown PetscFunctionReturn(0); 174*c4762a1bSJed Brown } 175*c4762a1bSJed Brown 176*c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 177*c4762a1bSJed Brown /* 178*c4762a1bSJed Brown FormFunction1 - Evaluates nonlinear function, F(x). 179*c4762a1bSJed Brown 180*c4762a1bSJed Brown Input Parameters: 181*c4762a1bSJed Brown . snes - the SNES context 182*c4762a1bSJed Brown . x - input vector 183*c4762a1bSJed Brown . dummy - optional user-defined context (not used here) 184*c4762a1bSJed Brown 185*c4762a1bSJed Brown Output Parameter: 186*c4762a1bSJed Brown . f - function vector 187*c4762a1bSJed Brown */ 188*c4762a1bSJed Brown static PetscErrorCode FormFunction1(SNES snes,Vec x,Vec f,void *dummy) 189*c4762a1bSJed Brown { 190*c4762a1bSJed Brown PetscErrorCode ierr; 191*c4762a1bSJed Brown const PetscScalar *xx; 192*c4762a1bSJed Brown PetscScalar *ff; 193*c4762a1bSJed Brown 194*c4762a1bSJed Brown PetscFunctionBeginUser; 195*c4762a1bSJed Brown /* 196*c4762a1bSJed Brown Get pointers to vector data. 197*c4762a1bSJed Brown - For default PETSc vectors, VecGetArray() returns a pointer to 198*c4762a1bSJed Brown the data array. Otherwise, the routine is implementation dependent. 199*c4762a1bSJed Brown - You MUST call VecRestoreArray() when you no longer need access to 200*c4762a1bSJed Brown the array. 201*c4762a1bSJed Brown */ 202*c4762a1bSJed Brown ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 203*c4762a1bSJed Brown ierr = VecGetArray(f,&ff);CHKERRQ(ierr); 204*c4762a1bSJed Brown 205*c4762a1bSJed Brown /* 206*c4762a1bSJed Brown Compute function 207*c4762a1bSJed Brown */ 208*c4762a1bSJed Brown ff[0] = xx[0]*xx[0] + xx[0]*xx[1] - 3.0; 209*c4762a1bSJed Brown ff[1] = xx[0]*xx[1] + xx[1]*xx[1] - 6.0; 210*c4762a1bSJed Brown 211*c4762a1bSJed Brown 212*c4762a1bSJed Brown /* 213*c4762a1bSJed Brown Restore vectors 214*c4762a1bSJed Brown */ 215*c4762a1bSJed Brown ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 216*c4762a1bSJed Brown ierr = VecRestoreArray(f,&ff);CHKERRQ(ierr); 217*c4762a1bSJed Brown PetscFunctionReturn(0); 218*c4762a1bSJed Brown } 219*c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 220*c4762a1bSJed Brown /* 221*c4762a1bSJed Brown FormJacobian1 - Evaluates Jacobian matrix. 222*c4762a1bSJed Brown 223*c4762a1bSJed Brown Input Parameters: 224*c4762a1bSJed Brown . snes - the SNES context 225*c4762a1bSJed Brown . x - input vector 226*c4762a1bSJed Brown . dummy - optional user-defined context (not used here) 227*c4762a1bSJed Brown 228*c4762a1bSJed Brown Output Parameters: 229*c4762a1bSJed Brown . jac - Jacobian matrix 230*c4762a1bSJed Brown . B - optionally different preconditioning matrix 231*c4762a1bSJed Brown . flag - flag indicating matrix structure 232*c4762a1bSJed Brown */ 233*c4762a1bSJed Brown static PetscErrorCode FormJacobian1(SNES snes,Vec x,Mat jac,Mat B,void *dummy) 234*c4762a1bSJed Brown { 235*c4762a1bSJed Brown const PetscScalar *xx; 236*c4762a1bSJed Brown PetscScalar A[4]; 237*c4762a1bSJed Brown PetscErrorCode ierr; 238*c4762a1bSJed Brown PetscInt idx[2] = {0,1}; 239*c4762a1bSJed Brown 240*c4762a1bSJed Brown PetscFunctionBeginUser; 241*c4762a1bSJed Brown /* 242*c4762a1bSJed Brown Get pointer to vector data 243*c4762a1bSJed Brown */ 244*c4762a1bSJed Brown ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 245*c4762a1bSJed Brown 246*c4762a1bSJed Brown /* 247*c4762a1bSJed Brown Compute Jacobian entries and insert into matrix. 248*c4762a1bSJed Brown - Since this is such a small problem, we set all entries for 249*c4762a1bSJed Brown the matrix at once. 250*c4762a1bSJed Brown */ 251*c4762a1bSJed Brown A[0] = 2.0*xx[0] + xx[1]; A[1] = xx[0]; 252*c4762a1bSJed Brown A[2] = xx[1]; A[3] = xx[0] + 2.0*xx[1]; 253*c4762a1bSJed Brown ierr = MatSetValues(jac,2,idx,2,idx,A,INSERT_VALUES);CHKERRQ(ierr); 254*c4762a1bSJed Brown 255*c4762a1bSJed Brown /* 256*c4762a1bSJed Brown Restore vector 257*c4762a1bSJed Brown */ 258*c4762a1bSJed Brown ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 259*c4762a1bSJed Brown 260*c4762a1bSJed Brown /* 261*c4762a1bSJed Brown Assemble matrix 262*c4762a1bSJed Brown */ 263*c4762a1bSJed Brown ierr = MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 264*c4762a1bSJed Brown ierr = MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 265*c4762a1bSJed Brown PetscFunctionReturn(0); 266*c4762a1bSJed Brown } 267*c4762a1bSJed Brown 268*c4762a1bSJed Brown 269*c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 270*c4762a1bSJed Brown static PetscErrorCode FormFunction2(SNES snes,Vec x,Vec f,void *dummy) 271*c4762a1bSJed Brown { 272*c4762a1bSJed Brown PetscErrorCode ierr; 273*c4762a1bSJed Brown const PetscScalar *xx; 274*c4762a1bSJed Brown PetscScalar *ff; 275*c4762a1bSJed Brown 276*c4762a1bSJed Brown PetscFunctionBeginUser; 277*c4762a1bSJed Brown /* 278*c4762a1bSJed Brown Get pointers to vector data. 279*c4762a1bSJed Brown - For default PETSc vectors, VecGetArray() returns a pointer to 280*c4762a1bSJed Brown the data array. Otherwise, the routine is implementation dependent. 281*c4762a1bSJed Brown - You MUST call VecRestoreArray() when you no longer need access to 282*c4762a1bSJed Brown the array. 283*c4762a1bSJed Brown */ 284*c4762a1bSJed Brown ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 285*c4762a1bSJed Brown ierr = VecGetArray(f,&ff);CHKERRQ(ierr); 286*c4762a1bSJed Brown 287*c4762a1bSJed Brown /* 288*c4762a1bSJed Brown Compute function 289*c4762a1bSJed Brown */ 290*c4762a1bSJed Brown ff[0] = PetscSinScalar(3.0*xx[0]) + xx[0]; 291*c4762a1bSJed Brown ff[1] = xx[1]; 292*c4762a1bSJed Brown 293*c4762a1bSJed Brown /* 294*c4762a1bSJed Brown Restore vectors 295*c4762a1bSJed Brown */ 296*c4762a1bSJed Brown ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 297*c4762a1bSJed Brown ierr = VecRestoreArray(f,&ff);CHKERRQ(ierr); 298*c4762a1bSJed Brown PetscFunctionReturn(0); 299*c4762a1bSJed Brown } 300*c4762a1bSJed Brown 301*c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 302*c4762a1bSJed Brown static PetscErrorCode FormJacobian2(SNES snes,Vec x,Mat jac,Mat B,void *dummy) 303*c4762a1bSJed Brown { 304*c4762a1bSJed Brown const PetscScalar *xx; 305*c4762a1bSJed Brown PetscScalar A[4]; 306*c4762a1bSJed Brown PetscErrorCode ierr; 307*c4762a1bSJed Brown PetscInt idx[2] = {0,1}; 308*c4762a1bSJed Brown 309*c4762a1bSJed Brown PetscFunctionBeginUser; 310*c4762a1bSJed Brown /* 311*c4762a1bSJed Brown Get pointer to vector data 312*c4762a1bSJed Brown */ 313*c4762a1bSJed Brown ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 314*c4762a1bSJed Brown 315*c4762a1bSJed Brown /* 316*c4762a1bSJed Brown Compute Jacobian entries and insert into matrix. 317*c4762a1bSJed Brown - Since this is such a small problem, we set all entries for 318*c4762a1bSJed Brown the matrix at once. 319*c4762a1bSJed Brown */ 320*c4762a1bSJed Brown A[0] = 3.0*PetscCosScalar(3.0*xx[0]) + 1.0; A[1] = 0.0; 321*c4762a1bSJed Brown A[2] = 0.0; A[3] = 1.0; 322*c4762a1bSJed Brown ierr = MatSetValues(jac,2,idx,2,idx,A,INSERT_VALUES);CHKERRQ(ierr); 323*c4762a1bSJed Brown 324*c4762a1bSJed Brown /* 325*c4762a1bSJed Brown Restore vector 326*c4762a1bSJed Brown */ 327*c4762a1bSJed Brown ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 328*c4762a1bSJed Brown 329*c4762a1bSJed Brown /* 330*c4762a1bSJed Brown Assemble matrix 331*c4762a1bSJed Brown */ 332*c4762a1bSJed Brown ierr = MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 333*c4762a1bSJed Brown ierr = MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 334*c4762a1bSJed Brown PetscFunctionReturn(0); 335*c4762a1bSJed Brown } 336*c4762a1bSJed Brown 337*c4762a1bSJed Brown static int block_system(void) 338*c4762a1bSJed Brown { 339*c4762a1bSJed Brown SNES snes; /* nonlinear solver context */ 340*c4762a1bSJed Brown KSP ksp; /* linear solver context */ 341*c4762a1bSJed Brown PC pc; /* preconditioner context */ 342*c4762a1bSJed Brown Vec x,r; /* solution, residual vectors */ 343*c4762a1bSJed Brown Mat J; /* Jacobian matrix */ 344*c4762a1bSJed Brown PetscErrorCode ierr; 345*c4762a1bSJed Brown PetscInt its; 346*c4762a1bSJed Brown PetscScalar pfive = .5; 347*c4762a1bSJed Brown PetscBool flg; 348*c4762a1bSJed Brown 349*c4762a1bSJed Brown Mat j11, j12, j21, j22; 350*c4762a1bSJed Brown Vec x1, x2, r1, r2; 351*c4762a1bSJed Brown Vec bv; 352*c4762a1bSJed Brown Vec bx[2]; 353*c4762a1bSJed Brown Mat bA[2][2]; 354*c4762a1bSJed Brown 355*c4762a1bSJed Brown PetscFunctionBeginUser; 356*c4762a1bSJed Brown PetscPrintf(PETSC_COMM_WORLD, "\n\n========================= Block system =========================\n\n"); 357*c4762a1bSJed Brown 358*c4762a1bSJed Brown ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); 359*c4762a1bSJed Brown 360*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 361*c4762a1bSJed Brown Create matrix and vector data structures; set corresponding routines 362*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 363*c4762a1bSJed Brown 364*c4762a1bSJed Brown /* 365*c4762a1bSJed Brown Create sub vectors for solution and nonlinear function 366*c4762a1bSJed Brown */ 367*c4762a1bSJed Brown ierr = VecCreateSeq(PETSC_COMM_SELF,1,&x1);CHKERRQ(ierr); 368*c4762a1bSJed Brown ierr = VecDuplicate(x1,&r1);CHKERRQ(ierr); 369*c4762a1bSJed Brown 370*c4762a1bSJed Brown ierr = VecCreateSeq(PETSC_COMM_SELF,1,&x2);CHKERRQ(ierr); 371*c4762a1bSJed Brown ierr = VecDuplicate(x2,&r2);CHKERRQ(ierr); 372*c4762a1bSJed Brown 373*c4762a1bSJed Brown /* 374*c4762a1bSJed Brown Create the block vectors 375*c4762a1bSJed Brown */ 376*c4762a1bSJed Brown bx[0] = x1; 377*c4762a1bSJed Brown bx[1] = x2; 378*c4762a1bSJed Brown ierr = VecCreateNest(PETSC_COMM_WORLD,2,NULL,bx,&x);CHKERRQ(ierr); 379*c4762a1bSJed Brown ierr = VecAssemblyBegin(x);CHKERRQ(ierr); 380*c4762a1bSJed Brown ierr = VecAssemblyEnd(x);CHKERRQ(ierr); 381*c4762a1bSJed Brown ierr = VecDestroy(&x1);CHKERRQ(ierr); 382*c4762a1bSJed Brown ierr = VecDestroy(&x2);CHKERRQ(ierr); 383*c4762a1bSJed Brown 384*c4762a1bSJed Brown bx[0] = r1; 385*c4762a1bSJed Brown bx[1] = r2; 386*c4762a1bSJed Brown ierr = VecCreateNest(PETSC_COMM_WORLD,2,NULL,bx,&r);CHKERRQ(ierr); 387*c4762a1bSJed Brown ierr = VecDestroy(&r1);CHKERRQ(ierr); 388*c4762a1bSJed Brown ierr = VecDestroy(&r2);CHKERRQ(ierr); 389*c4762a1bSJed Brown ierr = VecAssemblyBegin(r);CHKERRQ(ierr); 390*c4762a1bSJed Brown ierr = VecAssemblyEnd(r);CHKERRQ(ierr); 391*c4762a1bSJed Brown 392*c4762a1bSJed Brown /* 393*c4762a1bSJed Brown Create sub Jacobian matrix data structure 394*c4762a1bSJed Brown */ 395*c4762a1bSJed Brown ierr = MatCreate(PETSC_COMM_WORLD, &j11);CHKERRQ(ierr); 396*c4762a1bSJed Brown ierr = MatSetSizes(j11, 1, 1, 1, 1);CHKERRQ(ierr); 397*c4762a1bSJed Brown ierr = MatSetType(j11, MATSEQAIJ);CHKERRQ(ierr); 398*c4762a1bSJed Brown ierr = MatSetUp(j11);CHKERRQ(ierr); 399*c4762a1bSJed Brown 400*c4762a1bSJed Brown ierr = MatCreate(PETSC_COMM_WORLD, &j12);CHKERRQ(ierr); 401*c4762a1bSJed Brown ierr = MatSetSizes(j12, 1, 1, 1, 1);CHKERRQ(ierr); 402*c4762a1bSJed Brown ierr = MatSetType(j12, MATSEQAIJ);CHKERRQ(ierr); 403*c4762a1bSJed Brown ierr = MatSetUp(j12);CHKERRQ(ierr); 404*c4762a1bSJed Brown 405*c4762a1bSJed Brown ierr = MatCreate(PETSC_COMM_WORLD, &j21);CHKERRQ(ierr); 406*c4762a1bSJed Brown ierr = MatSetSizes(j21, 1, 1, 1, 1);CHKERRQ(ierr); 407*c4762a1bSJed Brown ierr = MatSetType(j21, MATSEQAIJ);CHKERRQ(ierr); 408*c4762a1bSJed Brown ierr = MatSetUp(j21);CHKERRQ(ierr); 409*c4762a1bSJed Brown 410*c4762a1bSJed Brown ierr = MatCreate(PETSC_COMM_WORLD, &j22);CHKERRQ(ierr); 411*c4762a1bSJed Brown ierr = MatSetSizes(j22, PETSC_DECIDE, PETSC_DECIDE, 1, 1);CHKERRQ(ierr); 412*c4762a1bSJed Brown ierr = MatSetType(j22, MATSEQAIJ);CHKERRQ(ierr); 413*c4762a1bSJed Brown ierr = MatSetUp(j22);CHKERRQ(ierr); 414*c4762a1bSJed Brown /* 415*c4762a1bSJed Brown Create block Jacobian matrix data structure 416*c4762a1bSJed Brown */ 417*c4762a1bSJed Brown bA[0][0] = j11; 418*c4762a1bSJed Brown bA[0][1] = j12; 419*c4762a1bSJed Brown bA[1][0] = j21; 420*c4762a1bSJed Brown bA[1][1] = j22; 421*c4762a1bSJed Brown 422*c4762a1bSJed Brown ierr = MatCreateNest(PETSC_COMM_WORLD,2,NULL,2,NULL,&bA[0][0],&J);CHKERRQ(ierr); 423*c4762a1bSJed Brown ierr = MatSetUp(J);CHKERRQ(ierr); 424*c4762a1bSJed Brown ierr = MatNestSetVecType(J,VECNEST);CHKERRQ(ierr); 425*c4762a1bSJed Brown ierr = MatDestroy(&j11);CHKERRQ(ierr); 426*c4762a1bSJed Brown ierr = MatDestroy(&j12);CHKERRQ(ierr); 427*c4762a1bSJed Brown ierr = MatDestroy(&j21);CHKERRQ(ierr); 428*c4762a1bSJed Brown ierr = MatDestroy(&j22);CHKERRQ(ierr); 429*c4762a1bSJed Brown 430*c4762a1bSJed Brown ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 431*c4762a1bSJed Brown ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 432*c4762a1bSJed Brown 433*c4762a1bSJed Brown ierr = PetscOptionsHasName(NULL,NULL,"-hard",&flg);CHKERRQ(ierr); 434*c4762a1bSJed Brown if (!flg) { 435*c4762a1bSJed Brown /* 436*c4762a1bSJed Brown Set function evaluation routine and vector. 437*c4762a1bSJed Brown */ 438*c4762a1bSJed Brown ierr = SNESSetFunction(snes,r,FormFunction1_block,NULL);CHKERRQ(ierr); 439*c4762a1bSJed Brown 440*c4762a1bSJed Brown /* 441*c4762a1bSJed Brown Set Jacobian matrix data structure and Jacobian evaluation routine 442*c4762a1bSJed Brown */ 443*c4762a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,FormJacobian1_block,NULL);CHKERRQ(ierr); 444*c4762a1bSJed Brown } else { 445*c4762a1bSJed Brown ierr = SNESSetFunction(snes,r,FormFunction2_block,NULL);CHKERRQ(ierr); 446*c4762a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,FormJacobian2_block,NULL);CHKERRQ(ierr); 447*c4762a1bSJed Brown } 448*c4762a1bSJed Brown 449*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 450*c4762a1bSJed Brown Customize nonlinear solver; set runtime options 451*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 452*c4762a1bSJed Brown 453*c4762a1bSJed Brown /* 454*c4762a1bSJed Brown Set linear solver defaults for this problem. By extracting the 455*c4762a1bSJed Brown KSP, KSP, and PC contexts from the SNES context, we can then 456*c4762a1bSJed Brown directly call any KSP, KSP, and PC routines to set various options. 457*c4762a1bSJed Brown */ 458*c4762a1bSJed Brown ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 459*c4762a1bSJed Brown ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 460*c4762a1bSJed Brown ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 461*c4762a1bSJed Brown ierr = KSPSetTolerances(ksp,1.e-4,PETSC_DEFAULT,PETSC_DEFAULT,20);CHKERRQ(ierr); 462*c4762a1bSJed Brown 463*c4762a1bSJed Brown /* 464*c4762a1bSJed Brown Set SNES/KSP/KSP/PC runtime options, e.g., 465*c4762a1bSJed Brown -snes_view -snes_monitor -ksp_type <ksp> -pc_type <pc> 466*c4762a1bSJed Brown These options will override those specified above as long as 467*c4762a1bSJed Brown SNESSetFromOptions() is called _after_ any other customization 468*c4762a1bSJed Brown routines. 469*c4762a1bSJed Brown */ 470*c4762a1bSJed Brown ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); 471*c4762a1bSJed Brown 472*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 473*c4762a1bSJed Brown Evaluate initial guess; then solve nonlinear system 474*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 475*c4762a1bSJed Brown if (!flg) { 476*c4762a1bSJed Brown ierr = VecSet(x,pfive);CHKERRQ(ierr); 477*c4762a1bSJed Brown } else { 478*c4762a1bSJed Brown Vec *vecs; 479*c4762a1bSJed Brown ierr = VecNestGetSubVecs(x, NULL, &vecs);CHKERRQ(ierr); 480*c4762a1bSJed Brown bv = vecs[0]; 481*c4762a1bSJed Brown /* ierr = VecBlockGetSubVec(x, 0, &bv);CHKERRQ(ierr); */ 482*c4762a1bSJed Brown ierr = VecSetValue(bv, 0, 2.0, INSERT_VALUES);CHKERRQ(ierr); /* xx[0] = 2.0; */ 483*c4762a1bSJed Brown ierr = VecAssemblyBegin(bv);CHKERRQ(ierr); 484*c4762a1bSJed Brown ierr = VecAssemblyEnd(bv);CHKERRQ(ierr); 485*c4762a1bSJed Brown 486*c4762a1bSJed Brown /* ierr = VecBlockGetSubVec(x, 1, &bv);CHKERRQ(ierr); */ 487*c4762a1bSJed Brown bv = vecs[1]; 488*c4762a1bSJed Brown ierr = VecSetValue(bv, 0, 3.0, INSERT_VALUES);CHKERRQ(ierr); /* xx[1] = 3.0; */ 489*c4762a1bSJed Brown ierr = VecAssemblyBegin(bv);CHKERRQ(ierr); 490*c4762a1bSJed Brown ierr = VecAssemblyEnd(bv);CHKERRQ(ierr); 491*c4762a1bSJed Brown } 492*c4762a1bSJed Brown /* 493*c4762a1bSJed Brown Note: The user should initialize the vector, x, with the initial guess 494*c4762a1bSJed Brown for the nonlinear solver prior to calling SNESSolve(). In particular, 495*c4762a1bSJed Brown to employ an initial guess of zero, the user should explicitly set 496*c4762a1bSJed Brown this vector to zero by calling VecSet(). 497*c4762a1bSJed Brown */ 498*c4762a1bSJed Brown ierr = SNESSolve(snes,NULL,x);CHKERRQ(ierr); 499*c4762a1bSJed Brown ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); 500*c4762a1bSJed Brown if (flg) { 501*c4762a1bSJed Brown Vec f; 502*c4762a1bSJed Brown ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 503*c4762a1bSJed Brown ierr = SNESGetFunction(snes,&f,0,0);CHKERRQ(ierr); 504*c4762a1bSJed Brown ierr = VecView(r,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 505*c4762a1bSJed Brown } 506*c4762a1bSJed Brown 507*c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF,"number of SNES iterations = %D\n\n",its);CHKERRQ(ierr); 508*c4762a1bSJed Brown 509*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 510*c4762a1bSJed Brown Free work space. All PETSc objects should be destroyed when they 511*c4762a1bSJed Brown are no longer needed. 512*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 513*c4762a1bSJed Brown ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); 514*c4762a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); 515*c4762a1bSJed Brown PetscFunctionReturn(0); 516*c4762a1bSJed Brown } 517*c4762a1bSJed Brown 518*c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 519*c4762a1bSJed Brown static PetscErrorCode FormFunction1_block(SNES snes,Vec x,Vec f,void *dummy) 520*c4762a1bSJed Brown { 521*c4762a1bSJed Brown Vec *xx, *ff, x1,x2, f1,f2; 522*c4762a1bSJed Brown PetscScalar ff_0, ff_1; 523*c4762a1bSJed Brown PetscScalar xx_0, xx_1; 524*c4762a1bSJed Brown PetscInt index,nb; 525*c4762a1bSJed Brown PetscErrorCode ierr; 526*c4762a1bSJed Brown 527*c4762a1bSJed Brown PetscFunctionBeginUser; 528*c4762a1bSJed Brown /* get blocks for function */ 529*c4762a1bSJed Brown ierr = VecNestGetSubVecs(f, &nb, &ff);CHKERRQ(ierr); 530*c4762a1bSJed Brown f1 = ff[0]; f2 = ff[1]; 531*c4762a1bSJed Brown 532*c4762a1bSJed Brown /* get blocks for solution */ 533*c4762a1bSJed Brown ierr = VecNestGetSubVecs(x, &nb, &xx);CHKERRQ(ierr); 534*c4762a1bSJed Brown x1 = xx[0]; x2 = xx[1]; 535*c4762a1bSJed Brown 536*c4762a1bSJed Brown /* get solution values */ 537*c4762a1bSJed Brown index = 0; 538*c4762a1bSJed Brown ierr = VecGetValues(x1,1, &index, &xx_0);CHKERRQ(ierr); 539*c4762a1bSJed Brown ierr = VecGetValues(x2,1, &index, &xx_1);CHKERRQ(ierr); 540*c4762a1bSJed Brown 541*c4762a1bSJed Brown /* Compute function */ 542*c4762a1bSJed Brown ff_0 = xx_0*xx_0 + xx_0*xx_1 - 3.0; 543*c4762a1bSJed Brown ff_1 = xx_0*xx_1 + xx_1*xx_1 - 6.0; 544*c4762a1bSJed Brown 545*c4762a1bSJed Brown /* set function values */ 546*c4762a1bSJed Brown ierr = VecSetValue(f1, index, ff_0, INSERT_VALUES);CHKERRQ(ierr); 547*c4762a1bSJed Brown 548*c4762a1bSJed Brown ierr = VecSetValue(f2, index, ff_1, INSERT_VALUES);CHKERRQ(ierr); 549*c4762a1bSJed Brown 550*c4762a1bSJed Brown ierr = VecAssemblyBegin(f);CHKERRQ(ierr); 551*c4762a1bSJed Brown ierr = VecAssemblyEnd(f);CHKERRQ(ierr); 552*c4762a1bSJed Brown PetscFunctionReturn(0); 553*c4762a1bSJed Brown } 554*c4762a1bSJed Brown 555*c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 556*c4762a1bSJed Brown static PetscErrorCode FormJacobian1_block(SNES snes,Vec x,Mat jac,Mat B,void *dummy) 557*c4762a1bSJed Brown { 558*c4762a1bSJed Brown Vec *xx, x1,x2; 559*c4762a1bSJed Brown PetscScalar xx_0, xx_1; 560*c4762a1bSJed Brown PetscInt index,nb; 561*c4762a1bSJed Brown PetscScalar A_00, A_01, A_10, A_11; 562*c4762a1bSJed Brown Mat j11, j12, j21, j22; 563*c4762a1bSJed Brown Mat **mats; 564*c4762a1bSJed Brown PetscErrorCode ierr; 565*c4762a1bSJed Brown 566*c4762a1bSJed Brown PetscFunctionBeginUser; 567*c4762a1bSJed Brown /* get blocks for solution */ 568*c4762a1bSJed Brown ierr = VecNestGetSubVecs(x, &nb, &xx);CHKERRQ(ierr); 569*c4762a1bSJed Brown x1 = xx[0]; x2 = xx[1]; 570*c4762a1bSJed Brown 571*c4762a1bSJed Brown /* get solution values */ 572*c4762a1bSJed Brown index = 0; 573*c4762a1bSJed Brown ierr = VecGetValues(x1,1, &index, &xx_0);CHKERRQ(ierr); 574*c4762a1bSJed Brown ierr = VecGetValues(x2,1, &index, &xx_1);CHKERRQ(ierr); 575*c4762a1bSJed Brown 576*c4762a1bSJed Brown /* get block matrices */ 577*c4762a1bSJed Brown ierr = MatNestGetSubMats(jac,NULL,NULL,&mats);CHKERRQ(ierr); 578*c4762a1bSJed Brown j11 = mats[0][0]; 579*c4762a1bSJed Brown j12 = mats[0][1]; 580*c4762a1bSJed Brown j21 = mats[1][0]; 581*c4762a1bSJed Brown j22 = mats[1][1]; 582*c4762a1bSJed Brown 583*c4762a1bSJed Brown /* compute jacobian entries */ 584*c4762a1bSJed Brown A_00 = 2.0*xx_0 + xx_1; 585*c4762a1bSJed Brown A_01 = xx_0; 586*c4762a1bSJed Brown A_10 = xx_1; 587*c4762a1bSJed Brown A_11 = xx_0 + 2.0*xx_1; 588*c4762a1bSJed Brown 589*c4762a1bSJed Brown /* set jacobian values */ 590*c4762a1bSJed Brown ierr = MatSetValue(j11, 0,0, A_00, INSERT_VALUES);CHKERRQ(ierr); 591*c4762a1bSJed Brown ierr = MatSetValue(j12, 0,0, A_01, INSERT_VALUES);CHKERRQ(ierr); 592*c4762a1bSJed Brown ierr = MatSetValue(j21, 0,0, A_10, INSERT_VALUES);CHKERRQ(ierr); 593*c4762a1bSJed Brown ierr = MatSetValue(j22, 0,0, A_11, INSERT_VALUES);CHKERRQ(ierr); 594*c4762a1bSJed Brown 595*c4762a1bSJed Brown /* Assemble sub matrix */ 596*c4762a1bSJed Brown ierr = MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 597*c4762a1bSJed Brown ierr = MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 598*c4762a1bSJed Brown PetscFunctionReturn(0); 599*c4762a1bSJed Brown } 600*c4762a1bSJed Brown 601*c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 602*c4762a1bSJed Brown static PetscErrorCode FormFunction2_block(SNES snes,Vec x,Vec f,void *dummy) 603*c4762a1bSJed Brown { 604*c4762a1bSJed Brown PetscErrorCode ierr; 605*c4762a1bSJed Brown PetscScalar *ff; 606*c4762a1bSJed Brown const PetscScalar *xx; 607*c4762a1bSJed Brown 608*c4762a1bSJed Brown PetscFunctionBeginUser; 609*c4762a1bSJed Brown /* 610*c4762a1bSJed Brown Get pointers to vector data. 611*c4762a1bSJed Brown - For default PETSc vectors, VecGetArray() returns a pointer to 612*c4762a1bSJed Brown the data array. Otherwise, the routine is implementation dependent. 613*c4762a1bSJed Brown - You MUST call VecRestoreArray() when you no longer need access to 614*c4762a1bSJed Brown the array. 615*c4762a1bSJed Brown */ 616*c4762a1bSJed Brown ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 617*c4762a1bSJed Brown ierr = VecGetArray(f,&ff);CHKERRQ(ierr); 618*c4762a1bSJed Brown 619*c4762a1bSJed Brown /* 620*c4762a1bSJed Brown Compute function 621*c4762a1bSJed Brown */ 622*c4762a1bSJed Brown ff[0] = PetscSinScalar(3.0*xx[0]) + xx[0]; 623*c4762a1bSJed Brown ff[1] = xx[1]; 624*c4762a1bSJed Brown 625*c4762a1bSJed Brown /* 626*c4762a1bSJed Brown Restore vectors 627*c4762a1bSJed Brown */ 628*c4762a1bSJed Brown ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 629*c4762a1bSJed Brown ierr = VecRestoreArray(f,&ff);CHKERRQ(ierr); 630*c4762a1bSJed Brown PetscFunctionReturn(0); 631*c4762a1bSJed Brown } 632*c4762a1bSJed Brown 633*c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 634*c4762a1bSJed Brown static PetscErrorCode FormJacobian2_block(SNES snes,Vec x,Mat jac,Mat B,void *dummy) 635*c4762a1bSJed Brown { 636*c4762a1bSJed Brown const PetscScalar *xx; 637*c4762a1bSJed Brown PetscScalar A[4]; 638*c4762a1bSJed Brown PetscErrorCode ierr; 639*c4762a1bSJed Brown PetscInt idx[2] = {0,1}; 640*c4762a1bSJed Brown 641*c4762a1bSJed Brown PetscFunctionBeginUser; 642*c4762a1bSJed Brown /* 643*c4762a1bSJed Brown Get pointer to vector data 644*c4762a1bSJed Brown */ 645*c4762a1bSJed Brown ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 646*c4762a1bSJed Brown 647*c4762a1bSJed Brown /* 648*c4762a1bSJed Brown Compute Jacobian entries and insert into matrix. 649*c4762a1bSJed Brown - Since this is such a small problem, we set all entries for 650*c4762a1bSJed Brown the matrix at once. 651*c4762a1bSJed Brown */ 652*c4762a1bSJed Brown A[0] = 3.0*PetscCosScalar(3.0*xx[0]) + 1.0; A[1] = 0.0; 653*c4762a1bSJed Brown A[2] = 0.0; A[3] = 1.0; 654*c4762a1bSJed Brown ierr = MatSetValues(jac,2,idx,2,idx,A,INSERT_VALUES);CHKERRQ(ierr); 655*c4762a1bSJed Brown 656*c4762a1bSJed Brown /* 657*c4762a1bSJed Brown Restore vector 658*c4762a1bSJed Brown */ 659*c4762a1bSJed Brown ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 660*c4762a1bSJed Brown 661*c4762a1bSJed Brown /* 662*c4762a1bSJed Brown Assemble matrix 663*c4762a1bSJed Brown */ 664*c4762a1bSJed Brown ierr = MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 665*c4762a1bSJed Brown ierr = MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 666*c4762a1bSJed Brown PetscFunctionReturn(0); 667*c4762a1bSJed Brown } 668*c4762a1bSJed Brown 669*c4762a1bSJed Brown int main(int argc,char **argv) 670*c4762a1bSJed Brown { 671*c4762a1bSJed Brown PetscMPIInt size; 672*c4762a1bSJed Brown PetscErrorCode ierr; 673*c4762a1bSJed Brown 674*c4762a1bSJed Brown ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; 675*c4762a1bSJed Brown 676*c4762a1bSJed Brown ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); 677*c4762a1bSJed Brown if (size != 1) SETERRQ(PETSC_COMM_WORLD, 1,"This is a uniprocessor example only!"); 678*c4762a1bSJed Brown 679*c4762a1bSJed Brown ierr = assembled_system();CHKERRQ(ierr); 680*c4762a1bSJed Brown 681*c4762a1bSJed Brown ierr = block_system();CHKERRQ(ierr); 682*c4762a1bSJed Brown 683*c4762a1bSJed Brown ierr = PetscFinalize(); 684*c4762a1bSJed Brown return ierr; 685*c4762a1bSJed Brown } 686*c4762a1bSJed Brown 687*c4762a1bSJed Brown 688*c4762a1bSJed Brown /*TEST 689*c4762a1bSJed Brown 690*c4762a1bSJed Brown test: 691*c4762a1bSJed Brown args: -snes_monitor_short 692*c4762a1bSJed Brown requires: !single 693*c4762a1bSJed Brown 694*c4762a1bSJed Brown TEST*/ 695