int main(int argc,char **argv) { Mat A; /* operator matrix */ EPS eps; /* eigenproblem solver context */ EPSType type; PetscMPIInt nproc, myproc; PetscInt nev; PetscErrorCode ierr; SlepcInitialize(&argc, &argv, (char*)0, 0); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&nproc); CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&myproc); CHKERRQ(ierr); int L = 8; ierr = PetscOptionsGetInt(NULL,"-L", &L, NULL); CHKERRQ(ierr); PetscInt N_global = 1 << L; PetscInt N_local = N_global / nproc; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Compute the operator matrix that defines the eigensystem, Ax=kx - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ model m; m.comm = PETSC_COMM_WORLD; m.L = L; m.buffer = new double[N_local]; if (m.buffer == 0) { MPI_Abort(MPI_COMM_WORLD, 4); } for (int i=0; i<L; ++i) { m.lattice.push_back(std::make_pair(i, (i+1)%L)); } ierr = MatCreateShell(PETSC_COMM_WORLD, N_local, N_local, N_global, N_global, &m, &A); CHKERRQ(ierr); ierr = MatSetFromOptions(A); CHKERRQ(ierr); ierr = MatShellSetOperation(A,MATOP_MULT,(void(*)())MatMult_myMat); CHKERRQ(ierr); ierr = MatShellSetOperation(A,MATOP_MULT_TRANSPOSE,(void(*)())MatMult_myMat); CHKERRQ(ierr); ierr = MatShellSetOperation(A,MATOP_GET_DIAGONAL,(void(*)())MatGetDiagonal_myMat); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the eigensolver and set various options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Create eigensolver context */ ierr = EPSCreate(PETSC_COMM_WORLD,&eps); CHKERRQ(ierr); /* Set operators. In this case, it is a standard eigenvalue problem */ ierr = EPSSetOperators(eps,A,NULL); CHKERRQ(ierr); ierr = EPSSetProblemType(eps,EPS_HEP); CHKERRQ(ierr); ierr = EPSSetDimensions(eps, 5, 100, 100); CHKERRQ(ierr); ierr = EPSSetTolerances(eps, (PetscScalar) 1e-1, (PetscInt) 100); CHKERRQ(ierr); //Vec v0; //MatGetVecs(A, &v0, NULL); //VecSet(v0,1.0); //EPSSetInitialSpace(eps,1,&v0); /* Set solver parameters at runtime */ ierr = EPSSetFromOptions(eps); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the eigensystem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = EPSSolve(eps);CHKERRQ(ierr); /* Optional: Get some information from the solver and display it */ ierr = EPSGetType(eps,&type); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Solution method: %s\n\n",type); CHKERRQ(ierr); ierr = EPSGetDimensions(eps,&nev,NULL,NULL); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Number of requested eigenvalues: %D\n",nev); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Display solution and clean up - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = EPSPrintSolution(eps,NULL); CHKERRQ(ierr); ierr = EPSDestroy(&eps); CHKERRQ(ierr); ierr = MatDestroy(&A); CHKERRQ(ierr); ierr = SlepcFinalize(); return 0; }
int main(int argc,char **argv) { AppCtx user; /* user-defined work context */ PetscInt mx,my; PetscErrorCode ierr; MPI_Comm comm; DM da; Vec x; Mat J = NULL,Jmf = NULL; MatShellCtx matshellctx; PetscInt mlocal,nlocal; PC pc; KSP ksp; PetscBool errorinmatmult = PETSC_FALSE,errorinpcapply = PETSC_FALSE,errorinpcsetup = PETSC_FALSE; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return(1); PetscFunctionBeginUser; ierr = PetscOptionsGetBool(NULL,"-error_in_matmult",&errorinmatmult,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-error_in_pcapply",&errorinpcapply,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-error_in_pcsetup",&errorinpcsetup,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-error_in_domain",&user.errorindomain,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-error_in_domainmf",&user.errorindomainmf,NULL);CHKERRQ(ierr); comm = PETSC_COMM_WORLD; ierr = SNESCreate(comm,&user.snes);CHKERRQ(ierr); /* Create distributed array object to manage parallel grid and vectors for principal unknowns (x) and governing residuals (f) */ ierr = DMDACreate2d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,-4,-4,PETSC_DECIDE,PETSC_DECIDE,4,1,0,0,&da);CHKERRQ(ierr); ierr = SNESSetDM(user.snes,da);CHKERRQ(ierr); ierr = DMDAGetInfo(da,0,&mx,&my,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); /* Problem parameters (velocity of lid, prandtl, and grashof numbers) */ user.lidvelocity = 1.0/(mx*my); user.prandtl = 1.0; user.grashof = 1.0; ierr = PetscOptionsGetReal(NULL,"-lidvelocity",&user.lidvelocity,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-prandtl",&user.prandtl,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-grashof",&user.grashof,NULL);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,"-contours",&user.draw_contours);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"x_velocity");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"y_velocity");CHKERRQ(ierr); ierr = DMDASetFieldName(da,2,"Omega");CHKERRQ(ierr); ierr = DMDASetFieldName(da,3,"temperature");CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create user context, set problem data, create vector data structures. Also, compute the initial guess. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create nonlinear solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMSetApplicationContext(da,&user);CHKERRQ(ierr); ierr = DMDASNESSetFunctionLocal(da,INSERT_VALUES,(PetscErrorCode (*)(DMDALocalInfo*,void*,void*,void*))FormFunctionLocal,&user);CHKERRQ(ierr); if (errorinmatmult) { ierr = MatCreateSNESMF(user.snes,&Jmf);CHKERRQ(ierr); ierr = MatSetFromOptions(Jmf);CHKERRQ(ierr); ierr = MatGetLocalSize(Jmf,&mlocal,&nlocal);CHKERRQ(ierr); matshellctx.Jmf = Jmf; ierr = MatCreateShell(PetscObjectComm((PetscObject)Jmf),mlocal,nlocal,PETSC_DECIDE,PETSC_DECIDE,&matshellctx,&J);CHKERRQ(ierr); ierr = MatShellSetOperation(J,MATOP_MULT,(void (*)(void))MatMult_MyShell);CHKERRQ(ierr); ierr = MatShellSetOperation(J,MATOP_ASSEMBLY_END,(void (*)(void))MatAssemblyEnd_MyShell);CHKERRQ(ierr); ierr = SNESSetJacobian(user.snes,J,J,MatMFFDComputeJacobian,NULL);CHKERRQ(ierr); } ierr = SNESSetFromOptions(user.snes);CHKERRQ(ierr); ierr = PetscPrintf(comm,"lid velocity = %g, prandtl # = %g, grashof # = %g\n",(double)user.lidvelocity,(double)user.prandtl,(double)user.grashof);CHKERRQ(ierr); if (errorinpcapply) { ierr = SNESGetKSP(user.snes,&ksp);CHKERRQ(ierr); ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCSHELL);CHKERRQ(ierr); ierr = PCShellSetApply(pc,PCApply_MyShell);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = FormInitialGuess(&user,da,x);CHKERRQ(ierr); if (errorinpcsetup) { ierr = SNESSetUp(user.snes);CHKERRQ(ierr); ierr = SNESSetJacobian(user.snes,NULL,NULL,SNESComputeJacobian_MyShell,NULL);CHKERRQ(ierr); } ierr = SNESSolve(user.snes,NULL,x);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = MatDestroy(&Jmf);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = SNESDestroy(&user.snes);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int implicit_solver(HashTable* El_Table, HashTable* NodeTable, double delta_t, double LapCoef, TimeProps* timeprops_ptr) { Vec x, b, xlocal; /* approx solution, RHS */ Mat A; /* linear system matrix */ KSP ksp; /* KSP context */ PetscReal norm; //,val1,val2; /* norm of solution error */ PetscErrorCode ierr; PetscInt xsize, *num_elem_proc, *to, *from, its; PetscMPIInt rank, size; KSPConvergedReason reason; VecScatter vscat; IS globalis, tois; MPI_Comm_rank(PETSC_COMM_WORLD, &rank); MPI_Comm_size(PETSC_COMM_WORLD, &size); /* ------------------------------------------------------------------- Compute the matrix and right-hand-side vector that define the linear system, Ax = b. ------------------------------------------------------------------- */ ierr = PetscMalloc(size * sizeof(PetscInt), &num_elem_proc); CHKERRQ(ierr); num_elem_proc[rank] = num_nonzero_elem(El_Table); if (rank > 0) MPI_Send(&num_elem_proc[rank], 1, MPI_INT, 0, 22, PETSC_COMM_WORLD); if (rank == 0) for (int i = 1; i < size; i++) MPI_Recv(&num_elem_proc[i], 1, MPI_INT, i, 22, PETSC_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Barrier(PETSC_COMM_WORLD); MPI_Bcast(num_elem_proc, size, MPI_INT, 0, PETSC_COMM_WORLD); //printf("Number of elements are (hi i am second)...........%d\n", num_nonzero_elem(Laplacian->El_Table)); int total_elem = 0, start_elem = 0; //MPI_Allreduce(&num_elem, total_elem, 1, MPI_INT, MPI_SUM, PETSC_COMM_WORLD); ierr = PetscMalloc(num_elem_proc[rank] * sizeof(PetscInt), &to); CHKERRQ(ierr); ierr = PetscMalloc(num_elem_proc[rank] * sizeof(PetscInt), &from); CHKERRQ(ierr); for (int i = 0; i < size; i++) total_elem += num_elem_proc[i]; for (int i = 0; i < rank; i++) start_elem += num_elem_proc[i]; for (int i = 0; i < num_elem_proc[rank]; i++) { from[i] = i; to[i] = i + start_elem; } ierr = ISCreateGeneral(PETSC_COMM_WORLD, num_elem_proc[rank], from, PETSC_COPY_VALUES, &tois); CHKERRQ(ierr); ierr = ISCreateGeneral(PETSC_COMM_WORLD, num_elem_proc[rank], to, PETSC_COPY_VALUES, &globalis); CHKERRQ(ierr); /* Create parallel vectors */ ierr = VecCreate(PETSC_COMM_WORLD, &b); CHKERRQ(ierr); ierr = VecSetType(b, VECSTANDARD); CHKERRQ(ierr); ierr = VecSetSizes(b, num_elem_proc[rank], total_elem); CHKERRQ(ierr); ierr = VecSetFromOptions(b); CHKERRQ(ierr); ierr = VecGetSize(b, &xsize); //cout<<"size b is "<<xsize<<endl; ierr = VecCreateSeq(PETSC_COMM_SELF, num_elem_proc[rank], &xlocal); CHKERRQ(ierr); ierr = VecScatterCreate(xlocal, tois, b, globalis, &vscat); CHKERRQ(ierr); // we have to create a map between local and global vector myctx.El_Table = El_Table; myctx.Node_Table = NodeTable; myctx.Scatter = vscat; myctx.Total_elem = total_elem; myctx.Num_elem_proc = num_elem_proc; myctx.rank = rank; myctx.size = size; myctx.Timeptr = timeprops_ptr; myctx.LapCoef = LapCoef; myctx.delta_t = delta_t; /* right-hand-side vector. */ ierr = MakeRHS(&myctx, b); CHKERRQ(ierr); //ierr = VecView(b,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = VecDuplicate(b, &x); CHKERRQ(ierr); ierr = VecCopy(b, x); CHKERRQ(ierr); //ierr = VecView(x,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = VecGetSize(x, &xsize); //cout<<"size x is "<<xsize<<endl; /* Create and assemble parallel matrix */ ierr = MatCreateShell(PETSC_COMM_WORLD, num_elem_proc[rank], num_elem_proc[rank], total_elem, total_elem, &myctx, &A); CHKERRQ(ierr); ierr = MatShellSetOperation(A, MATOP_MULT, (void (*)(void))MatLaplacian2D_Mult);CHKERRQ (ierr); /* Create linear solver context */ ierr = KSPCreate(PETSC_COMM_WORLD, &ksp); CHKERRQ(ierr); /* Set operators. Here the matrix that defines the linear system also serves as the preconditioning matrix. */ ierr = KSPSetOperators(ksp, A, A/*,DIFFERENT_NONZERO_PATTERN*/); CHKERRQ(ierr); ierr = KSPSetType(ksp, KSPFGMRES); CHKERRQ(ierr); /* Set default preconditioner for this program to be block Jacobi. This choice can be overridden at runtime with the option -pc_type <type> */ // ierr = KSPSetTolerances(ksp,1.e-7,PETSC_DEFAULT,1.e9,3000);CHKERRQ(ierr); ierr = KSPSetTolerances(ksp, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, 50000); CHKERRQ(ierr); /* ------------------------------------------------------------------- Solve the linear system ------------------------------------------------------------------- */ ierr = KSPSetInitialGuessNonzero(ksp, PETSC_TRUE); CHKERRQ(ierr); /* Solve the linear system */ ierr = KSPSolve(ksp, b, x); CHKERRQ(ierr); /* ------------------------------------------------------------------- Check solution and clean up ------------------------------------------------------------------- */ /* Check the error */ //ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); if (rank == 0) { ierr = KSPGetIterationNumber(ksp, &its); CHKERRQ(ierr); ierr = KSPGetResidualNorm(ksp, &norm); CHKERRQ(ierr); ierr = PetscSynchronizedPrintf( MPI_COMM_SELF, "Norm of error %g iterations %D\n", (double) norm, its); CHKERRQ(ierr); //PetscSynchronizedFlush(PETSC_COMM_WORLD); ierr = KSPGetConvergedReason(ksp, &reason); ierr = PetscSynchronizedPrintf( MPI_COMM_SELF, "kind of divergence is: ...........%D \n", reason); //PetscSynchronizedFlush(PETSC_COMM_WORLD); } /* */ //ierr = VecGetArray(x,&xx);CHKERRQ(ierr); update_phi(El_Table, x, &myctx); //ierr = VecRestoreArray(x, &xx);CHKERRQ(ierr); /* Free work space. All PETSc objects should be destroyed when they are no longer needed. */ MPI_Barrier(PETSC_COMM_WORLD); ierr = KSPDestroy(&ksp); CHKERRQ(ierr); //ierr = PetscFree(phin);CHKERRQ(ierr); ierr = VecDestroy(&x); CHKERRQ(ierr); //ierr = PCDestroy(&pc);CHKERRQ(ierr); ierr = VecDestroy(&b); CHKERRQ(ierr); ierr = MatDestroy(&A); CHKERRQ(ierr); ierr = VecScatterDestroy(&vscat); CHKERRQ(ierr); ierr = ISDestroy(&globalis); CHKERRQ(ierr); ierr = ISDestroy(&tois); CHKERRQ(ierr); PetscFree(num_elem_proc); CHKERRQ(ierr); PetscFree(to); CHKERRQ(ierr); PetscFree(from); CHKERRQ(ierr); return 0; }
krylov_petsc_info_t krylov_petsc_solve ( p4est_t* p4est, problem_data_t* vecs, weakeqn_ptrs_t* fcns, p4est_ghost_t** ghost, element_data_t** ghost_data, dgmath_jit_dbase_t* dgmath_jit_dbase, krylov_petsc_params_t* krylov_params ) { krylov_petsc_info_t info; KSP ksp; Vec x,b; PC pc; /* double* u_temp; */ /* double* rhs_temp; */ KSPCreate(PETSC_COMM_WORLD,&ksp); VecCreate(PETSC_COMM_WORLD,&x);//CHKERRQ(ierr); VecSetSizes(x, vecs->local_nodes, PETSC_DECIDE);//CHKERRQ(ierr); VecSetFromOptions(x);//CHKERRQ(ierr); VecDuplicate(x,&b);//CHKERRQ(ierr); /* VecGetArray(x,&u_temp); */ /* VecGetArray(b,&rhs_temp); */ krylov_pc_ctx_t kct; kct.p4est = p4est; kct.vecs = vecs; kct.fcns = fcns; kct.ghost = ghost; kct.ghost_data = ghost_data; kct.dgmath_jit_dbase = dgmath_jit_dbase; kct.pc_data = krylov_params->pc_data; if (krylov_params->ksp_monitor) PetscOptionsSetValue(NULL,"-ksp_monitor",""); if (krylov_params->ksp_monitor) PetscOptionsSetValue(NULL,"-ksp_view",""); /* KSPMonitorSet(ksp, KSPMonitorDefault, NULL, NULL); */ /* PetscOptionsSetValue(NULL,"-ksp_converged_reason",""); */ PetscOptionsSetValue(NULL,"-ksp_atol","1e-20"); /* PetscOptionsSetValue(NULL,"-with-debugging","1"); */ PetscOptionsSetValue(NULL,"-ksp_rtol","1e-20"); PetscOptionsSetValue(NULL,"-ksp_max_it","1000000"); KSPGetPC(ksp,&pc); krylov_pc_t* kp = NULL; if (krylov_params != NULL && krylov_params->user_defined_pc) { PCSetType(pc,PCSHELL);//CHKERRQ(ierr); kp = krylov_params->pc_create(&kct); PCShellSetApply(pc, krylov_petsc_pc_apply);//CHKERRQ(ierr); PCShellSetSetUp(pc, krylov_petsc_pc_setup); PCShellSetContext(pc, kp);//CHKERRQ(ierr); } else { PCSetType(pc,PCNONE);//CHKERRQ(ierr); } KSPSetType(ksp, krylov_params->krylov_type); KSPSetFromOptions(ksp); /* Create matrix-free shell for Aij */ Mat A; MatCreateShell ( PETSC_COMM_WORLD, vecs->local_nodes, vecs->local_nodes, PETSC_DETERMINE, PETSC_DETERMINE, (void*)&kct, &A ); MatShellSetOperation(A,MATOP_MULT,(void(*)())krylov_petsc_apply_aij); /* Set Amat and Pmat, where Pmat is the matrix the Preconditioner needs */ KSPSetOperators(ksp,A,A); /* linalg_copy_1st_to_2nd(vecs->u, u_temp, vecs->local_nodes); */ /* linalg_copy_1st_to_2nd(vecs->rhs, rhs_temp, vecs->local_nodes); */ VecPlaceArray(b, vecs->rhs); VecPlaceArray(x, vecs->u); KSPSolve(ksp,b,x); if (krylov_params != NULL && krylov_params->user_defined_pc) { krylov_params->pc_destroy(kp); } KSPGetIterationNumber(ksp, &(info.iterations)); KSPGetResidualNorm(ksp, &(info.residual_norm)); /* linalg_copy_1st_to_2nd(u_temp, vecs->u, vecs->local_nodes); */ /* VecRestoreArray(x,&u_temp); */ /* VecRestoreArray(b,&rhs_temp); */ VecResetArray(b); VecResetArray(x); VecDestroy(&x); VecDestroy(&b); KSPDestroy(&ksp); return info; }
int main(int argc,char **args) { User user; Mat A,S; PetscScalar *data,diag = 1.3; PetscReal tol = PETSC_SMALL; PetscInt i,j,m = PETSC_DECIDE,n = PETSC_DECIDE,M = 17,N = 15,s1,s2; PetscInt test, ntest = 2; PetscMPIInt rank,size; PetscBool nc = PETSC_FALSE, cong; PetscBool ronl = PETSC_TRUE; PetscBool randomize = PETSC_FALSE; PetscBool keep = PETSC_FALSE; PetscBool testzerorows = PETSC_TRUE, testdiagscale = PETSC_TRUE, testgetdiag = PETSC_TRUE; PetscBool testshift = PETSC_TRUE, testscale = PETSC_TRUE, testdup = PETSC_TRUE, testreset = PETSC_TRUE; PetscErrorCode ierr; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-M",&M,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-N",&N,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-ml",&m,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-nl",&n,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-square_nc",&nc,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-rows_only",&ronl,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-randomize",&randomize,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-test_zerorows",&testzerorows,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-test_diagscale",&testdiagscale,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-test_getdiag",&testgetdiag,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-test_shift",&testshift,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-test_scale",&testscale,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-test_dup",&testdup,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-test_reset",&testreset,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-loop",&ntest,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-tol",&tol,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetScalar(NULL,NULL,"-diag",&diag,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-keep",&keep,NULL);CHKERRQ(ierr); /* This tests square matrices with different row/col layout */ if (nc && size > 1) { M = PetscMax(PetscMax(N,M),1); N = M; m = n = 0; if (rank == 0) { m = M-1; n = 1; } else if (rank == 1) { m = 1; n = N-1; } } ierr = MatCreateDense(PETSC_COMM_WORLD,m,n,M,N,NULL,&A);CHKERRQ(ierr); ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); ierr = MatHasCongruentLayouts(A,&cong);CHKERRQ(ierr); ierr = MatGetOwnershipRange(A,&s1,NULL);CHKERRQ(ierr); s2 = 1; while (s2 < M) s2 *= 10; ierr = MatDenseGetArray(A,&data);CHKERRQ(ierr); for (j = 0; j < N; j++) { for (i = 0; i < m; i++) { data[j*m + i] = s2*j + i + s1 + 1; } } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatConvert(A,MATAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); ierr = MatSetOption(A,MAT_KEEP_NONZERO_PATTERN,keep);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)A,"initial");CHKERRQ(ierr); ierr = MatViewFromOptions(A,NULL,"-view_mat");CHKERRQ(ierr); ierr = PetscNew(&user);CHKERRQ(ierr); ierr = MatCreateShell(PETSC_COMM_WORLD,m,n,M,N,user,&S);CHKERRQ(ierr); ierr = MatShellSetOperation(S,MATOP_MULT,(void (*)(void))MatMult_User);CHKERRQ(ierr); ierr = MatShellSetOperation(S,MATOP_MULT_TRANSPOSE,(void (*)(void))MatMultTranspose_User);CHKERRQ(ierr); if (cong) { ierr = MatShellSetOperation(S,MATOP_GET_DIAGONAL,(void (*)(void))MatGetDiagonal_User);CHKERRQ(ierr); } ierr = MatDuplicate(A,MAT_COPY_VALUES,&user->B);CHKERRQ(ierr); /* Square and rows only scaling */ ronl = cong ? ronl : PETSC_TRUE; for (test = 0; test < ntest; test++) { PetscReal err; if (testzerorows) { Mat ST,B,C,BT,BTT; IS zr; Vec x = NULL, b1 = NULL, b2 = NULL; PetscInt *idxs = NULL, nr = 0; if (rank == (test%size)) { nr = 1; ierr = PetscMalloc1(nr,&idxs);CHKERRQ(ierr); if (test%2) { idxs[0] = (2*M - 1 - test/2)%M; } else { idxs[0] = (test/2)%M; } idxs[0] = PetscMax(idxs[0],0); } ierr = ISCreateGeneral(PETSC_COMM_WORLD,nr,idxs,PETSC_OWN_POINTER,&zr);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)zr,"ZR");CHKERRQ(ierr); ierr = ISViewFromOptions(zr,NULL,"-view_is");CHKERRQ(ierr); ierr = MatCreateVecs(A,&x,&b1);CHKERRQ(ierr); if (randomize) { ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); ierr = VecSetRandom(b1,NULL);CHKERRQ(ierr); } else { ierr = VecSet(x,11.4);CHKERRQ(ierr); ierr = VecSet(b1,-14.2);CHKERRQ(ierr); } ierr = VecDuplicate(b1,&b2);CHKERRQ(ierr); ierr = VecCopy(b1,b2);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)b1,"A_B1");CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)b2,"A_B2");CHKERRQ(ierr); if (size > 1 && !cong) { /* MATMPIAIJ ZeroRows and ZeroRowsColumns are buggy in this case */ ierr = VecDestroy(&b1);CHKERRQ(ierr); } if (ronl) { ierr = MatZeroRowsIS(A,zr,diag,x,b1);CHKERRQ(ierr); ierr = MatZeroRowsIS(S,zr,diag,x,b2);CHKERRQ(ierr); } else { ierr = MatZeroRowsColumnsIS(A,zr,diag,x,b1);CHKERRQ(ierr); ierr = MatZeroRowsColumnsIS(S,zr,diag,x,b2);CHKERRQ(ierr); ierr = ISDestroy(&zr);CHKERRQ(ierr); /* Mix zerorows and zerorowscols */ nr = 0; idxs = NULL; if (!rank) { nr = 1; ierr = PetscMalloc1(nr,&idxs);CHKERRQ(ierr); if (test%2) { idxs[0] = (3*M - 2 - test/2)%M; } else { idxs[0] = (test/2+1)%M; } idxs[0] = PetscMax(idxs[0],0); } ierr = ISCreateGeneral(PETSC_COMM_WORLD,nr,idxs,PETSC_OWN_POINTER,&zr);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)zr,"ZR2");CHKERRQ(ierr); ierr = ISViewFromOptions(zr,NULL,"-view_is");CHKERRQ(ierr); ierr = MatZeroRowsIS(A,zr,diag*2.0+PETSC_SMALL,NULL,NULL);CHKERRQ(ierr); ierr = MatZeroRowsIS(S,zr,diag*2.0+PETSC_SMALL,NULL,NULL);CHKERRQ(ierr); } ierr = ISDestroy(&zr);CHKERRQ(ierr); if (b1) { Vec b; ierr = VecViewFromOptions(b1,NULL,"-view_b");CHKERRQ(ierr); ierr = VecViewFromOptions(b2,NULL,"-view_b");CHKERRQ(ierr); ierr = VecDuplicate(b1,&b);CHKERRQ(ierr); ierr = VecCopy(b1,b);CHKERRQ(ierr); ierr = VecAXPY(b,-1.0,b2);CHKERRQ(ierr); ierr = VecNorm(b,NORM_INFINITY,&err);CHKERRQ(ierr); if (err >= tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"[test %D] Error b %g\n",test,(double)err);CHKERRQ(ierr); } ierr = VecDestroy(&b);CHKERRQ(ierr); } ierr = VecDestroy(&b1);CHKERRQ(ierr); ierr = VecDestroy(&b2);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = MatConvert(S,MATDENSE,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); ierr = MatCreateTranspose(S,&ST);CHKERRQ(ierr); ierr = MatComputeOperator(ST,MATDENSE,&BT);CHKERRQ(ierr); ierr = MatTranspose(BT,MAT_INITIAL_MATRIX,&BTT);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)B,"S");CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)BTT,"STT");CHKERRQ(ierr); ierr = MatConvert(A,MATDENSE,MAT_INITIAL_MATRIX,&C);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)C,"A");CHKERRQ(ierr); ierr = MatViewFromOptions(C,NULL,"-view_mat");CHKERRQ(ierr); ierr = MatViewFromOptions(B,NULL,"-view_mat");CHKERRQ(ierr); ierr = MatViewFromOptions(BTT,NULL,"-view_mat");CHKERRQ(ierr); ierr = MatAXPY(C,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatNorm(C,NORM_FROBENIUS,&err);CHKERRQ(ierr); if (err >= tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"[test %D] Error mat mult %g\n",test,(double)err);CHKERRQ(ierr); } ierr = MatConvert(A,MATDENSE,MAT_REUSE_MATRIX,&C);CHKERRQ(ierr); ierr = MatAXPY(C,-1.0,BTT,SAME_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatNorm(C,NORM_FROBENIUS,&err);CHKERRQ(ierr); if (err >= tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"[test %D] Error mat mult transpose %g\n",test,(double)err);CHKERRQ(ierr); } ierr = MatDestroy(&ST);CHKERRQ(ierr); ierr = MatDestroy(&BTT);CHKERRQ(ierr); ierr = MatDestroy(&BT);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); } if (testdiagscale) { /* MatDiagonalScale() */ Vec vr,vl; ierr = MatCreateVecs(A,&vr,&vl);CHKERRQ(ierr); if (randomize) { ierr = VecSetRandom(vr,NULL);CHKERRQ(ierr); ierr = VecSetRandom(vl,NULL);CHKERRQ(ierr); } else { ierr = VecSet(vr,test%2 ? 0.15 : 1.0/0.15);CHKERRQ(ierr); ierr = VecSet(vl,test%2 ? -1.2 : 1.0/-1.2);CHKERRQ(ierr); } ierr = MatDiagonalScale(A,vl,vr);CHKERRQ(ierr); ierr = MatDiagonalScale(S,vl,vr);CHKERRQ(ierr); ierr = VecDestroy(&vr);CHKERRQ(ierr); ierr = VecDestroy(&vl);CHKERRQ(ierr); } if (testscale) { /* MatScale() */ ierr = MatScale(A,test%2 ? 1.4 : 1.0/1.4);CHKERRQ(ierr); ierr = MatScale(S,test%2 ? 1.4 : 1.0/1.4);CHKERRQ(ierr); } if (testshift && cong) { /* MatShift() : MATSHELL shift is broken when row/cols layout are not congruent and left/right scaling have been applied */ ierr = MatShift(A,test%2 ? -77.5 : 77.5);CHKERRQ(ierr); ierr = MatShift(S,test%2 ? -77.5 : 77.5);CHKERRQ(ierr); } if (testgetdiag && cong) { /* MatGetDiagonal() */ Vec dA,dS; ierr = MatCreateVecs(A,&dA,NULL);CHKERRQ(ierr); ierr = MatCreateVecs(S,&dS,NULL);CHKERRQ(ierr); ierr = MatGetDiagonal(A,dA);CHKERRQ(ierr); ierr = MatGetDiagonal(S,dS);CHKERRQ(ierr); ierr = VecAXPY(dA,-1.0,dS);CHKERRQ(ierr); ierr = VecNorm(dA,NORM_INFINITY,&err);CHKERRQ(ierr); if (err >= tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"[test %D] Error diag %g\n",test,(double)err);CHKERRQ(ierr); } ierr = VecDestroy(&dA);CHKERRQ(ierr); ierr = VecDestroy(&dS);CHKERRQ(ierr); } if (testdup && !test) { Mat A2, S2; ierr = MatDuplicate(A,MAT_COPY_VALUES,&A2);CHKERRQ(ierr); ierr = MatDuplicate(S,MAT_COPY_VALUES,&S2);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&S);CHKERRQ(ierr); A = A2; S = S2; } if (testreset && (ntest == 1 || test == ntest-2)) { /* reset MATSHELL */ ierr = MatAssemblyBegin(S,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(S,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* reset A */ ierr = MatCopy(user->B,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); } } ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&user->B);CHKERRQ(ierr); ierr = MatDestroy(&S);CHKERRQ(ierr); ierr = PetscFree(user);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
PetscErrorCode PEPSetUp_Linear(PEP pep) { PetscErrorCode ierr; PEP_LINEAR *ctx = (PEP_LINEAR*)pep->data; PetscInt i=0; EPSWhich which; PetscBool trackall,istrivial,flg; PetscScalar sigma; /* function tables */ PetscErrorCode (*fcreate[][2])(MPI_Comm,PEP_LINEAR*,Mat*) = { { MatCreateExplicit_Linear_N1A, MatCreateExplicit_Linear_N1B }, /* N1 */ { MatCreateExplicit_Linear_N2A, MatCreateExplicit_Linear_N2B }, /* N2 */ { MatCreateExplicit_Linear_S1A, MatCreateExplicit_Linear_S1B }, /* S1 */ { MatCreateExplicit_Linear_S2A, MatCreateExplicit_Linear_S2B }, /* S2 */ { MatCreateExplicit_Linear_H1A, MatCreateExplicit_Linear_H1B }, /* H1 */ { MatCreateExplicit_Linear_H2A, MatCreateExplicit_Linear_H2B } /* H2 */ }; PetscErrorCode (*fmult[][2])(Mat,Vec,Vec) = { { MatMult_Linear_N1A, MatMult_Linear_N1B }, { MatMult_Linear_N2A, MatMult_Linear_N2B }, { MatMult_Linear_S1A, MatMult_Linear_S1B }, { MatMult_Linear_S2A, MatMult_Linear_S2B }, { MatMult_Linear_H1A, MatMult_Linear_H1B }, { MatMult_Linear_H2A, MatMult_Linear_H2B } }; PetscErrorCode (*fgetdiagonal[][2])(Mat,Vec) = { { MatGetDiagonal_Linear_N1A, MatGetDiagonal_Linear_N1B }, { MatGetDiagonal_Linear_N2A, MatGetDiagonal_Linear_N2B }, { MatGetDiagonal_Linear_S1A, MatGetDiagonal_Linear_S1B }, { MatGetDiagonal_Linear_S2A, MatGetDiagonal_Linear_S2B }, { MatGetDiagonal_Linear_H1A, MatGetDiagonal_Linear_H1B }, { MatGetDiagonal_Linear_H2A, MatGetDiagonal_Linear_H2B } }; PetscFunctionBegin; if (!ctx->cform) ctx->cform = 1; if (!pep->which) pep->which = PEP_LARGEST_MAGNITUDE; if (pep->basis!=PEP_BASIS_MONOMIAL) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"Solver not implemented for non-monomial bases"); if (pep->nmat!=3) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"Solver only available for quadratic problems"); if (pep->scale==PEP_SCALE_DIAGONAL || pep->scale==PEP_SCALE_BOTH) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"Diagonal scaling not allowed in PEP linear solver"); ierr = STGetTransform(pep->st,&flg);CHKERRQ(ierr); if (flg) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"ST transformation flag not allowed for PEP linear solver"); /* compute scale factor if no set by user */ ierr = PEPComputeScaleFactor(pep);CHKERRQ(ierr); ierr = STGetOperators(pep->st,0,&ctx->K);CHKERRQ(ierr); ierr = STGetOperators(pep->st,1,&ctx->C);CHKERRQ(ierr); ierr = STGetOperators(pep->st,2,&ctx->M);CHKERRQ(ierr); ctx->sfactor = pep->sfactor; ierr = MatDestroy(&ctx->A);CHKERRQ(ierr); ierr = MatDestroy(&ctx->B);CHKERRQ(ierr); ierr = VecDestroy(&ctx->x1);CHKERRQ(ierr); ierr = VecDestroy(&ctx->x2);CHKERRQ(ierr); ierr = VecDestroy(&ctx->y1);CHKERRQ(ierr); ierr = VecDestroy(&ctx->y2);CHKERRQ(ierr); switch (pep->problem_type) { case PEP_GENERAL: i = 0; break; case PEP_HERMITIAN: i = 2; break; case PEP_GYROSCOPIC: i = 4; break; default: SETERRQ(PetscObjectComm((PetscObject)pep),1,"Wrong value of pep->problem_type"); } i += ctx->cform-1; if (ctx->explicitmatrix) { ctx->x1 = ctx->x2 = ctx->y1 = ctx->y2 = NULL; ierr = (*fcreate[i][0])(PetscObjectComm((PetscObject)pep),ctx,&ctx->A);CHKERRQ(ierr); ierr = (*fcreate[i][1])(PetscObjectComm((PetscObject)pep),ctx,&ctx->B);CHKERRQ(ierr); } else { ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)pep),1,pep->nloc,pep->n,NULL,&ctx->x1);CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)pep),1,pep->nloc,pep->n,NULL,&ctx->x2);CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)pep),1,pep->nloc,pep->n,NULL,&ctx->y1);CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)pep),1,pep->nloc,pep->n,NULL,&ctx->y2);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)pep,(PetscObject)ctx->x1);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)pep,(PetscObject)ctx->x2);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)pep,(PetscObject)ctx->y1);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)pep,(PetscObject)ctx->y2);CHKERRQ(ierr); ierr = MatCreateShell(PetscObjectComm((PetscObject)pep),2*pep->nloc,2*pep->nloc,2*pep->n,2*pep->n,ctx,&ctx->A);CHKERRQ(ierr); ierr = MatShellSetOperation(ctx->A,MATOP_MULT,(void(*)(void))fmult[i][0]);CHKERRQ(ierr); ierr = MatShellSetOperation(ctx->A,MATOP_GET_DIAGONAL,(void(*)(void))fgetdiagonal[i][0]);CHKERRQ(ierr); ierr = MatCreateShell(PetscObjectComm((PetscObject)pep),2*pep->nloc,2*pep->nloc,2*pep->n,2*pep->n,ctx,&ctx->B);CHKERRQ(ierr); ierr = MatShellSetOperation(ctx->B,MATOP_MULT,(void(*)(void))fmult[i][1]);CHKERRQ(ierr); ierr = MatShellSetOperation(ctx->B,MATOP_GET_DIAGONAL,(void(*)(void))fgetdiagonal[i][1]);CHKERRQ(ierr); } ierr = PetscLogObjectParent((PetscObject)pep,(PetscObject)ctx->A);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)pep,(PetscObject)ctx->B);CHKERRQ(ierr); if (!ctx->eps) { ierr = PEPLinearGetEPS(pep,&ctx->eps);CHKERRQ(ierr); } ierr = EPSSetOperators(ctx->eps,ctx->A,ctx->B);CHKERRQ(ierr); if (pep->problem_type==PEP_HERMITIAN) { ierr = EPSSetProblemType(ctx->eps,EPS_GHIEP);CHKERRQ(ierr); } else { ierr = EPSSetProblemType(ctx->eps,EPS_GNHEP);CHKERRQ(ierr); } switch (pep->which) { case PEP_LARGEST_MAGNITUDE: which = EPS_LARGEST_MAGNITUDE; break; case PEP_SMALLEST_MAGNITUDE: which = EPS_SMALLEST_MAGNITUDE; break; case PEP_LARGEST_REAL: which = EPS_LARGEST_REAL; break; case PEP_SMALLEST_REAL: which = EPS_SMALLEST_REAL; break; case PEP_LARGEST_IMAGINARY: which = EPS_LARGEST_IMAGINARY; break; case PEP_SMALLEST_IMAGINARY: which = EPS_SMALLEST_IMAGINARY; break; case PEP_TARGET_MAGNITUDE: which = EPS_TARGET_MAGNITUDE; break; case PEP_TARGET_REAL: which = EPS_TARGET_REAL; break; case PEP_TARGET_IMAGINARY: which = EPS_TARGET_IMAGINARY; break; default: SETERRQ(PetscObjectComm((PetscObject)pep),1,"Wrong value of which"); } ierr = EPSSetWhichEigenpairs(ctx->eps,which);CHKERRQ(ierr); ierr = EPSSetDimensions(ctx->eps,pep->nev,pep->ncv?pep->ncv:PETSC_DEFAULT,pep->mpd?pep->mpd:PETSC_DEFAULT);CHKERRQ(ierr); ierr = EPSSetTolerances(ctx->eps,pep->tol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL/10.0:pep->tol/10.0,pep->max_it?pep->max_it:PETSC_DEFAULT);CHKERRQ(ierr); ierr = RGIsTrivial(pep->rg,&istrivial);CHKERRQ(ierr); if (!istrivial) { ierr = EPSSetRG(ctx->eps,pep->rg);CHKERRQ(ierr); } /* Transfer the trackall option from pep to eps */ ierr = PEPGetTrackAll(pep,&trackall);CHKERRQ(ierr); ierr = EPSSetTrackAll(ctx->eps,trackall);CHKERRQ(ierr); /* temporary change of target */ if (pep->sfactor!=1.0) { ierr = EPSGetTarget(ctx->eps,&sigma);CHKERRQ(ierr); ierr = EPSSetTarget(ctx->eps,sigma/pep->sfactor);CHKERRQ(ierr); } ierr = EPSSetUp(ctx->eps);CHKERRQ(ierr); ierr = EPSGetDimensions(ctx->eps,NULL,&pep->ncv,&pep->mpd);CHKERRQ(ierr); ierr = EPSGetTolerances(ctx->eps,NULL,&pep->max_it);CHKERRQ(ierr); if (pep->nini>0) { ierr = PetscInfo(pep,"Ignoring initial vectors\n");CHKERRQ(ierr); } ierr = PEPAllocateSolution(pep,0);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@C MatCreateLMVM - Creates a limited memory matrix for lmvm algorithms. Collective on A Input Parameters: + comm - MPI Communicator . n - local size of vectors - N - global size of vectors Output Parameters: . A - New LMVM matrix Level: developer @*/ extern PetscErrorCode MatCreateLMVM(MPI_Comm comm, PetscInt n, PetscInt N, Mat *A) { MatLMVMCtx *ctx; PetscErrorCode ierr; PetscInt nhistory; PetscFunctionBegin; /* create data structure and populate with default values */ ierr = PetscNew(&ctx);CHKERRQ(ierr); ctx->lm=5; ctx->eps=0.0; ctx->limitType=MatLMVM_Limit_None; ctx->scaleType=MatLMVM_Scale_Broyden; ctx->rScaleType = MatLMVM_Rescale_Scalar; ctx->s_alpha = 1.0; ctx->r_alpha = 1.0; ctx->r_beta = 0.5; ctx->mu = 1.0; ctx->nu = 100.0; ctx->phi = 0.125; ctx->scalar_history = 1; ctx->rescale_history = 1; ctx->delta_min = 1e-7; ctx->delta_max = 100.0; /* Begin configuration */ ierr = PetscOptionsInt("-tao_lmm_vectors", "vectors to use for approximation", "", ctx->lm, &ctx->lm, 0);CHKERRQ(ierr); ierr = PetscOptionsReal("-tao_lmm_limit_mu", "mu limiting factor", "", ctx->mu, &ctx->mu, 0);CHKERRQ(ierr); ierr = PetscOptionsReal("-tao_lmm_limit_nu", "nu limiting factor", "", ctx->nu, &ctx->nu, 0);CHKERRQ(ierr); ierr = PetscOptionsReal("-tao_lmm_broyden_phi", "phi factor for Broyden scaling", "", ctx->phi, &ctx->phi, 0);CHKERRQ(ierr); ierr = PetscOptionsReal("-tao_lmm_scalar_alpha", "alpha factor for scalar scaling", "",ctx->s_alpha, &ctx->s_alpha, 0);CHKERRQ(ierr); ierr = PetscOptionsReal("-tao_lmm_rescale_alpha", "alpha factor for rescaling diagonal", "", ctx->r_alpha, &ctx->r_alpha, 0);CHKERRQ(ierr); ierr = PetscOptionsReal("-tao_lmm_rescale_beta", "beta factor for rescaling diagonal", "", ctx->r_beta, &ctx->r_beta, 0);CHKERRQ(ierr); ierr = PetscOptionsInt("-tao_lmm_scalar_history", "amount of history for scalar scaling", "", ctx->scalar_history, &ctx->scalar_history, 0);CHKERRQ(ierr); ierr = PetscOptionsInt("-tao_lmm_rescale_history", "amount of history for rescaling diagonal", "", ctx->rescale_history, &ctx->rescale_history, 0);CHKERRQ(ierr); ierr = PetscOptionsReal("-tao_lmm_eps", "rejection tolerance", "", ctx->eps, &ctx->eps, 0);CHKERRQ(ierr); ierr = PetscOptionsEList("-tao_lmm_scale_type", "scale type", "", Scale_Table, MatLMVM_Scale_Types, Scale_Table[ctx->scaleType], &ctx->scaleType, 0);CHKERRQ(ierr); ierr = PetscOptionsEList("-tao_lmm_rescale_type", "rescale type", "", Rescale_Table, MatLMVM_Rescale_Types, Rescale_Table[ctx->rScaleType], &ctx->rScaleType, 0);CHKERRQ(ierr); ierr = PetscOptionsEList("-tao_lmm_limit_type", "limit type", "", Limit_Table, MatLMVM_Limit_Types, Limit_Table[ctx->limitType], &ctx->limitType, 0);CHKERRQ(ierr); ierr = PetscOptionsReal("-tao_lmm_delta_min", "minimum delta value", "", ctx->delta_min, &ctx->delta_min, 0);CHKERRQ(ierr); ierr = PetscOptionsReal("-tao_lmm_delta_max", "maximum delta value", "", ctx->delta_max, &ctx->delta_max, 0);CHKERRQ(ierr); /* Complete configuration */ ctx->rescale_history = PetscMin(ctx->rescale_history, ctx->lm); ierr = PetscMalloc1(ctx->lm+1,&ctx->rho);CHKERRQ(ierr); ierr = PetscMalloc1(ctx->lm+1,&ctx->beta);CHKERRQ(ierr); nhistory = PetscMax(ctx->scalar_history,1); ierr = PetscMalloc1(nhistory,&ctx->yy_history);CHKERRQ(ierr); ierr = PetscMalloc1(nhistory,&ctx->ys_history);CHKERRQ(ierr); ierr = PetscMalloc1(nhistory,&ctx->ss_history);CHKERRQ(ierr); nhistory = PetscMax(ctx->rescale_history,1); ierr = PetscMalloc1(nhistory,&ctx->yy_rhistory);CHKERRQ(ierr); ierr = PetscMalloc1(nhistory,&ctx->ys_rhistory);CHKERRQ(ierr); ierr = PetscMalloc1(nhistory,&ctx->ss_rhistory);CHKERRQ(ierr); /* Finish initializations */ ctx->lmnow = 0; ctx->iter = 0; ctx->nupdates = 0; ctx->nrejects = 0; ctx->delta = 1.0; ctx->Gprev = 0; ctx->Xprev = 0; ctx->scale = 0; ctx->useScale = PETSC_FALSE; ctx->H0 = 0; ctx->useDefaultH0=PETSC_TRUE; ierr = MatCreateShell(comm, n, n, N, N, ctx, A);CHKERRQ(ierr); ierr = MatShellSetOperation(*A,MATOP_DESTROY,(void(*)(void))MatDestroy_LMVM);CHKERRQ(ierr); ierr = MatShellSetOperation(*A,MATOP_VIEW,(void(*)(void))MatView_LMVM);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int Argc,char **Args) { PetscInt x_mesh = 15,levels = 3,cycles = 1,use_jacobi = 0; PetscInt i,smooths = 1,*N,its; PetscErrorCode ierr; PCMGType am = PC_MG_MULTIPLICATIVE; Mat cmat,mat[20],fmat; KSP cksp,ksp[20],kspmg; PetscReal e[3]; /* l_2 error,max error, residual */ char *shellname; Vec x,solution,X[20],R[20],B[20]; PC pcmg,pc; PetscTruth flg; PetscInitialize(&Argc,&Args,(char *)0,help); ierr = PetscOptionsGetInt(PETSC_NULL,"-x",&x_mesh,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-l",&levels,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-c",&cycles,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-smooths",&smooths,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL,"-a",&flg);CHKERRQ(ierr); if (flg) {am = PC_MG_ADDITIVE;} ierr = PetscOptionsHasName(PETSC_NULL,"-f",&flg);CHKERRQ(ierr); if (flg) {am = PC_MG_FULL;} ierr = PetscOptionsHasName(PETSC_NULL,"-j",&flg);CHKERRQ(ierr); if (flg) {use_jacobi = 1;} ierr = PetscMalloc(levels*sizeof(PetscInt),&N);CHKERRQ(ierr); N[0] = x_mesh; for (i=1; i<levels; i++) { N[i] = N[i-1]/2; if (N[i] < 1) {SETERRQ(1,"Too many levels");} } ierr = Create1dLaplacian(N[levels-1],&cmat);CHKERRQ(ierr); ierr = KSPCreate(PETSC_COMM_WORLD,&kspmg);CHKERRQ(ierr); ierr = KSPGetPC(kspmg,&pcmg);CHKERRQ(ierr); ierr = KSPSetFromOptions(kspmg);CHKERRQ(ierr); ierr = PCSetType(pcmg,PCMG);CHKERRQ(ierr); ierr = PCMGSetLevels(pcmg,levels,PETSC_NULL);CHKERRQ(ierr); ierr = PCMGSetType(pcmg,am);CHKERRQ(ierr); ierr = PCMGGetCoarseSolve(pcmg,&cksp);CHKERRQ(ierr); ierr = KSPSetOperators(cksp,cmat,cmat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = KSPGetPC(cksp,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCLU);CHKERRQ(ierr); ierr = KSPSetType(cksp,KSPPREONLY);CHKERRQ(ierr); /* zero is finest level */ for (i=0; i<levels-1; i++) { ierr = PCMGSetResidual(pcmg,levels - 1 - i,residual,(Mat)0);CHKERRQ(ierr); ierr = MatCreateShell(PETSC_COMM_WORLD,N[i+1],N[i],N[i+1],N[i],(void*)0,&mat[i]);CHKERRQ(ierr); ierr = MatShellSetOperation(mat[i],MATOP_MULT,(void(*)(void))restrct);CHKERRQ(ierr); ierr = MatShellSetOperation(mat[i],MATOP_MULT_TRANSPOSE_ADD,(void(*)(void))interpolate);CHKERRQ(ierr); ierr = PCMGSetInterpolation(pcmg,levels - 1 - i,mat[i]);CHKERRQ(ierr); ierr = PCMGSetRestriction(pcmg,levels - 1 - i,mat[i]);CHKERRQ(ierr); ierr = PCMGSetCyclesOnLevel(pcmg,levels - 1 - i,cycles);CHKERRQ(ierr); /* set smoother */ ierr = PCMGGetSmoother(pcmg,levels - 1 - i,&ksp[i]);CHKERRQ(ierr); ierr = KSPGetPC(ksp[i],&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCSHELL);CHKERRQ(ierr); ierr = PCShellSetName(pc,"user_precond");CHKERRQ(ierr); ierr = PCShellGetName(pc,&shellname);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"level=%D, PCShell name is %s\n",i,shellname);CHKERRQ(ierr); /* this is a dummy! since KSP requires a matrix passed in */ ierr = KSPSetOperators(ksp[i],mat[i],mat[i],DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); /* We override the matrix passed in by forcing it to use Richardson with a user provided application. This is non-standard and this practice should be avoided. */ ierr = PCShellSetApplyRichardson(pc,gauss_seidel);CHKERRQ(ierr); if (use_jacobi) { ierr = PCShellSetApplyRichardson(pc,jacobi);CHKERRQ(ierr); } ierr = KSPSetType(ksp[i],KSPRICHARDSON);CHKERRQ(ierr); ierr = KSPSetInitialGuessNonzero(ksp[i],PETSC_TRUE);CHKERRQ(ierr); ierr = KSPSetTolerances(ksp[i],PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,smooths);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,N[i],&x);CHKERRQ(ierr); X[levels - 1 - i] = x; if (i > 0) { ierr = PCMGSetX(pcmg,levels - 1 - i,x);CHKERRQ(ierr); } ierr = VecCreateSeq(PETSC_COMM_SELF,N[i],&x);CHKERRQ(ierr); B[levels -1 - i] = x; if (i > 0) { ierr = PCMGSetRhs(pcmg,levels - 1 - i,x);CHKERRQ(ierr); } ierr = VecCreateSeq(PETSC_COMM_SELF,N[i],&x);CHKERRQ(ierr); R[levels - 1 - i] = x; ierr = PCMGSetR(pcmg,levels - 1 - i,x);CHKERRQ(ierr); } /* create coarse level vectors */ ierr = VecCreateSeq(PETSC_COMM_SELF,N[levels-1],&x);CHKERRQ(ierr); ierr = PCMGSetX(pcmg,0,x);CHKERRQ(ierr); X[0] = x; ierr = VecCreateSeq(PETSC_COMM_SELF,N[levels-1],&x);CHKERRQ(ierr); ierr = PCMGSetRhs(pcmg,0,x);CHKERRQ(ierr); B[0] = x; /* create matrix multiply for finest level */ ierr = MatCreateShell(PETSC_COMM_WORLD,N[0],N[0],N[0],N[0],(void*)0,&fmat);CHKERRQ(ierr); ierr = MatShellSetOperation(fmat,MATOP_MULT,(void(*)(void))amult);CHKERRQ(ierr); ierr = KSPSetOperators(kspmg,fmat,fmat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = CalculateSolution(N[0],&solution);CHKERRQ(ierr); ierr = CalculateRhs(B[levels-1]);CHKERRQ(ierr); ierr = VecSet(X[levels-1],0.0);CHKERRQ(ierr); ierr = residual((Mat)0,B[levels-1],X[levels-1],R[levels-1]);CHKERRQ(ierr); ierr = CalculateError(solution,X[levels-1],R[levels-1],e);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"l_2 error %G max error %G resi %G\n",e[0],e[1],e[2]);CHKERRQ(ierr); ierr = KSPSolve(kspmg,B[levels-1],X[levels-1]);CHKERRQ(ierr); ierr = KSPGetIterationNumber(kspmg,&its);CHKERRQ(ierr); ierr = residual((Mat)0,B[levels-1],X[levels-1],R[levels-1]);CHKERRQ(ierr); ierr = CalculateError(solution,X[levels-1],R[levels-1],e);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"its %D l_2 error %G max error %G resi %G\n",its,e[0],e[1],e[2]);CHKERRQ(ierr); ierr = PetscFree(N);CHKERRQ(ierr); ierr = VecDestroy(solution);CHKERRQ(ierr); /* note we have to keep a list of all vectors allocated, this is not ideal, but putting it in MGDestroy is not so good either*/ for (i=0; i<levels; i++) { ierr = VecDestroy(X[i]);CHKERRQ(ierr); ierr = VecDestroy(B[i]);CHKERRQ(ierr); if(i){ierr = VecDestroy(R[i]);CHKERRQ(ierr);} } for (i=0; i<levels-1; i++) { ierr = MatDestroy(mat[i]);CHKERRQ(ierr); } ierr = MatDestroy(cmat);CHKERRQ(ierr); ierr = MatDestroy(fmat);CHKERRQ(ierr); ierr = KSPDestroy(kspmg);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
int main(int argc,char **argv) { Mat A; /* eigenvalue problem matrix */ EPS eps; /* eigenproblem solver context */ EPSType type; PetscScalar delta1,delta2,L,h,value[3]; PetscInt N=30,n,i,col[3],Istart,Iend,nev; PetscBool FirstBlock=PETSC_FALSE,LastBlock=PETSC_FALSE; CTX_BRUSSEL *ctx; PetscErrorCode ierr; SlepcInitialize(&argc,&argv,(char*)0,help); ierr = PetscOptionsGetInt(NULL,"-n",&N,NULL);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"\nBrusselator wave model, n=%D\n\n",N);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Generate the matrix - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Create shell matrix context and set default parameters */ ierr = PetscNew(&ctx);CHKERRQ(ierr); ctx->alpha = 2.0; ctx->beta = 5.45; delta1 = 0.008; delta2 = 0.004; L = 0.51302; /* Look the command line for user-provided parameters */ ierr = PetscOptionsGetScalar(NULL,"-L",&L,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetScalar(NULL,"-alpha",&ctx->alpha,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetScalar(NULL,"-beta",&ctx->beta,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetScalar(NULL,"-delta1",&delta1,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetScalar(NULL,"-delta2",&delta2,NULL);CHKERRQ(ierr); /* Create matrix T */ ierr = MatCreate(PETSC_COMM_WORLD,&ctx->T);CHKERRQ(ierr); ierr = MatSetSizes(ctx->T,PETSC_DECIDE,PETSC_DECIDE,N,N);CHKERRQ(ierr); ierr = MatSetFromOptions(ctx->T);CHKERRQ(ierr); ierr = MatSetUp(ctx->T);CHKERRQ(ierr); ierr = MatGetOwnershipRange(ctx->T,&Istart,&Iend);CHKERRQ(ierr); if (Istart==0) FirstBlock=PETSC_TRUE; if (Iend==N) LastBlock=PETSC_TRUE; value[0]=1.0; value[1]=-2.0; value[2]=1.0; for (i=(FirstBlock? Istart+1: Istart); i<(LastBlock? Iend-1: Iend); i++) { col[0]=i-1; col[1]=i; col[2]=i+1; ierr = MatSetValues(ctx->T,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } if (LastBlock) { i=N-1; col[0]=N-2; col[1]=N-1; ierr = MatSetValues(ctx->T,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); } if (FirstBlock) { i=0; col[0]=0; col[1]=1; value[0]=-2.0; value[1]=1.0; ierr = MatSetValues(ctx->T,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(ctx->T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(ctx->T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatGetLocalSize(ctx->T,&n,NULL);CHKERRQ(ierr); /* Fill the remaining information in the shell matrix context and create auxiliary vectors */ h = 1.0 / (PetscReal)(N+1); ctx->tau1 = delta1 / ((h*L)*(h*L)); ctx->tau2 = delta2 / ((h*L)*(h*L)); ctx->sigma = 0.0; ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,n,PETSC_DECIDE,NULL,&ctx->x1);CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,n,PETSC_DECIDE,NULL,&ctx->x2);CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,n,PETSC_DECIDE,NULL,&ctx->y1);CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,n,PETSC_DECIDE,NULL,&ctx->y2);CHKERRQ(ierr); /* Create the shell matrix */ ierr = MatCreateShell(PETSC_COMM_WORLD,2*n,2*n,2*N,2*N,(void*)ctx,&A);CHKERRQ(ierr); ierr = MatShellSetOperation(A,MATOP_MULT,(void(*)())MatMult_Brussel);CHKERRQ(ierr); ierr = MatShellSetOperation(A,MATOP_SHIFT,(void(*)())MatShift_Brussel);CHKERRQ(ierr); ierr = MatShellSetOperation(A,MATOP_GET_DIAGONAL,(void(*)())MatGetDiagonal_Brussel);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the eigensolver and set various options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Create eigensolver context */ ierr = EPSCreate(PETSC_COMM_WORLD,&eps);CHKERRQ(ierr); /* Set operators. In this case, it is a standard eigenvalue problem */ ierr = EPSSetOperators(eps,A,NULL);CHKERRQ(ierr); ierr = EPSSetProblemType(eps,EPS_NHEP);CHKERRQ(ierr); /* Ask for the rightmost eigenvalues */ ierr = EPSSetWhichEigenpairs(eps,EPS_LARGEST_REAL);CHKERRQ(ierr); /* Set other solver options at runtime */ ierr = EPSSetFromOptions(eps);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the eigensystem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = EPSSolve(eps);CHKERRQ(ierr); /* Optional: Get some information from the solver and display it */ ierr = EPSGetType(eps,&type);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Solution method: %s\n\n",type);CHKERRQ(ierr); ierr = EPSGetDimensions(eps,&nev,NULL,NULL);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Number of requested eigenvalues: %D\n",nev);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Display solution and clean up - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = EPSPrintSolution(eps,NULL);CHKERRQ(ierr); ierr = EPSDestroy(&eps);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&ctx->T);CHKERRQ(ierr); ierr = VecDestroy(&ctx->x1);CHKERRQ(ierr); ierr = VecDestroy(&ctx->x2);CHKERRQ(ierr); ierr = VecDestroy(&ctx->y1);CHKERRQ(ierr); ierr = VecDestroy(&ctx->y2);CHKERRQ(ierr); ierr = PetscFree(ctx);CHKERRQ(ierr); ierr = SlepcFinalize(); return 0; }
void IBImplicitStaggeredHierarchyIntegrator::integrateHierarchy(const double current_time, const double new_time, const int cycle_num) { IBHierarchyIntegrator::integrateHierarchy(current_time, new_time, cycle_num); Pointer<INSStaggeredHierarchyIntegrator> ins_hier_integrator = d_ins_hier_integrator; TBOX_ASSERT(ins_hier_integrator); PetscErrorCode ierr; int n_local; const int coarsest_ln = 0; const int finest_ln = d_hierarchy->getFinestLevelNumber(); // const double half_time = current_time+0.5*(new_time-current_time); VariableDatabase<NDIM>* var_db = VariableDatabase<NDIM>::getDatabase(); Pointer<VariableContext> current_ctx = ins_hier_integrator->getCurrentContext(); Pointer<VariableContext> scratch_ctx = ins_hier_integrator->getScratchContext(); Pointer<VariableContext> new_ctx = ins_hier_integrator->getNewContext(); const int wgt_cc_idx = d_hier_math_ops->getCellWeightPatchDescriptorIndex(); const int wgt_sc_idx = d_hier_math_ops->getSideWeightPatchDescriptorIndex(); Pointer<Variable<NDIM> > u_var = ins_hier_integrator->getVelocityVariable(); // const int u_current_idx = var_db->mapVariableAndContextToIndex(u_var, current_ctx); const int u_scratch_idx = var_db->mapVariableAndContextToIndex(u_var, scratch_ctx); // const int u_new_idx = var_db->mapVariableAndContextToIndex(u_var, new_ctx); Pointer<Variable<NDIM> > p_var = ins_hier_integrator->getPressureVariable(); // const int p_current_idx = var_db->mapVariableAndContextToIndex(p_var, current_ctx); const int p_scratch_idx = var_db->mapVariableAndContextToIndex(p_var, scratch_ctx); // const int p_new_idx = var_db->mapVariableAndContextToIndex(p_var, new_ctx); // Skip all cycles in the INS solver --- we advance the state data here. ins_hier_integrator->skipCycle(current_time, new_time, cycle_num); // Setup Eulerian vectors used in solving the implicit IB equations. Pointer<SAMRAIVectorReal<NDIM, double> > eul_sol_vec = new SAMRAIVectorReal<NDIM, double>( d_object_name + "::eulerian_sol_vec", d_hierarchy, coarsest_ln, finest_ln); eul_sol_vec->addComponent(u_var, u_scratch_idx, wgt_sc_idx, d_hier_velocity_data_ops); eul_sol_vec->addComponent(p_var, p_scratch_idx, wgt_cc_idx, d_hier_pressure_data_ops); Pointer<SAMRAIVectorReal<NDIM, double> > eul_rhs_vec = eul_sol_vec->cloneVector(d_object_name + "::eulerian_rhs_vec"); eul_rhs_vec->allocateVectorData(current_time); d_u_scratch_vec = eul_sol_vec->cloneVector(d_object_name + "::u_scratch_vec"); d_f_scratch_vec = eul_rhs_vec->cloneVector(d_object_name + "::f_scratch_vec"); d_u_scratch_vec->allocateVectorData(current_time); d_f_scratch_vec->allocateVectorData(current_time); ins_hier_integrator->setupSolverVectors( eul_sol_vec, eul_rhs_vec, current_time, new_time, cycle_num); d_stokes_solver = ins_hier_integrator->getStokesSolver(); Pointer<KrylovLinearSolver> p_stokes_solver = d_stokes_solver; TBOX_ASSERT(p_stokes_solver); d_stokes_op = p_stokes_solver->getOperator(); TBOX_ASSERT(d_stokes_op); // Setup Lagrangian vectors used in solving the implicit IB equations. Vec lag_sol_petsc_vec, lag_rhs_petsc_vec; d_ib_implicit_ops->createSolverVecs(lag_sol_petsc_vec, lag_rhs_petsc_vec); d_ib_implicit_ops->setupSolverVecs(lag_sol_petsc_vec, lag_rhs_petsc_vec); // Indicate that the current approximation to position of the structure // should be used for Lagrangian-Eulerian coupling. d_ib_implicit_ops->updateFixedLEOperators(); // Setup multi-vec objects to store the composite solution and // right-hand-side vectors. Vec eul_sol_petsc_vec = PETScSAMRAIVectorReal::createPETScVector(eul_sol_vec, PETSC_COMM_WORLD); Vec eul_rhs_petsc_vec = PETScSAMRAIVectorReal::createPETScVector(eul_rhs_vec, PETSC_COMM_WORLD); Vec sol_petsc_vecs[] = { eul_sol_petsc_vec, lag_sol_petsc_vec }; Vec rhs_petsc_vecs[] = { eul_rhs_petsc_vec, lag_rhs_petsc_vec }; Vec composite_sol_petsc_vec, composite_rhs_petsc_vec, composite_res_petsc_vec; ierr = VecCreateMultiVec(PETSC_COMM_WORLD, 2, sol_petsc_vecs, &composite_sol_petsc_vec); IBTK_CHKERRQ(ierr); ierr = VecCreateMultiVec(PETSC_COMM_WORLD, 2, rhs_petsc_vecs, &composite_rhs_petsc_vec); IBTK_CHKERRQ(ierr); ierr = VecDuplicate(composite_rhs_petsc_vec, &composite_res_petsc_vec); IBTK_CHKERRQ(ierr); // Solve the implicit IB equations. d_ib_implicit_ops->preprocessSolveFluidEquations(current_time, new_time, cycle_num); SNES snes; ierr = SNESCreate(PETSC_COMM_WORLD, &snes); IBTK_CHKERRQ(ierr); ierr = SNESSetFunction(snes, composite_res_petsc_vec, compositeIBFunction_SAMRAI, this); IBTK_CHKERRQ(ierr); ierr = SNESSetOptionsPrefix(snes, "ib_"); IBTK_CHKERRQ(ierr); Mat jac; ierr = VecGetLocalSize(composite_sol_petsc_vec, &n_local); IBTK_CHKERRQ(ierr); ierr = MatCreateShell( PETSC_COMM_WORLD, n_local, n_local, PETSC_DETERMINE, PETSC_DETERMINE, this, &jac); IBTK_CHKERRQ(ierr); ierr = MatShellSetOperation( jac, MATOP_MULT, reinterpret_cast<void (*)(void)>(compositeIBJacobianApply_SAMRAI)); IBTK_CHKERRQ(ierr); ierr = SNESSetJacobian(snes, jac, jac, compositeIBJacobianSetup_SAMRAI, this); IBTK_CHKERRQ(ierr); Mat schur; ierr = VecGetLocalSize(lag_sol_petsc_vec, &n_local); IBTK_CHKERRQ(ierr); ierr = MatCreateShell( PETSC_COMM_WORLD, n_local, n_local, PETSC_DETERMINE, PETSC_DETERMINE, this, &schur); IBTK_CHKERRQ(ierr); ierr = MatShellSetOperation( schur, MATOP_MULT, reinterpret_cast<void (*)(void)>(lagrangianSchurApply_SAMRAI)); IBTK_CHKERRQ(ierr); ierr = KSPCreate(PETSC_COMM_WORLD, &d_schur_solver); IBTK_CHKERRQ(ierr); ierr = KSPSetOptionsPrefix(d_schur_solver, "ib_schur_"); IBTK_CHKERRQ(ierr); ierr = KSPSetOperators(d_schur_solver, schur, schur, SAME_PRECONDITIONER); IBTK_CHKERRQ(ierr); PC schur_pc; ierr = KSPGetPC(d_schur_solver, &schur_pc); IBTK_CHKERRQ(ierr); ierr = PCSetType(schur_pc, PCNONE); IBTK_CHKERRQ(ierr); ierr = KSPSetFromOptions(d_schur_solver); IBTK_CHKERRQ(ierr); KSP snes_ksp; ierr = SNESGetKSP(snes, &snes_ksp); IBTK_CHKERRQ(ierr); ierr = KSPSetType(snes_ksp, KSPFGMRES); IBTK_CHKERRQ(ierr); PC snes_pc; ierr = KSPGetPC(snes_ksp, &snes_pc); IBTK_CHKERRQ(ierr); ierr = PCSetType(snes_pc, PCSHELL); IBTK_CHKERRQ(ierr); ierr = PCShellSetContext(snes_pc, this); IBTK_CHKERRQ(ierr); ierr = PCShellSetApply(snes_pc, compositeIBPCApply_SAMRAI); IBTK_CHKERRQ(ierr); ierr = SNESSetFromOptions(snes); IBTK_CHKERRQ(ierr); ierr = SNESSolve(snes, composite_rhs_petsc_vec, composite_sol_petsc_vec); IBTK_CHKERRQ(ierr); ierr = SNESDestroy(&snes); IBTK_CHKERRQ(ierr); ierr = MatDestroy(&jac); IBTK_CHKERRQ(ierr); ierr = MatDestroy(&schur); IBTK_CHKERRQ(ierr); ierr = KSPDestroy(&d_schur_solver); IBTK_CHKERRQ(ierr); d_ib_implicit_ops->postprocessSolveFluidEquations(current_time, new_time, cycle_num); // Reset Eulerian solver vectors and Eulerian state data. ins_hier_integrator->resetSolverVectors( eul_sol_vec, eul_rhs_vec, current_time, new_time, cycle_num); // Interpolate the Eulerian velocity to the curvilinear mesh. d_ib_implicit_ops->setUpdatedPosition(lag_sol_petsc_vec); #if 0 d_hier_velocity_data_ops->linearSum(d_u_idx, 0.5, u_current_idx, 0.5, u_new_idx); if (d_enable_logging) plog << d_object_name << "::integrateHierarchy(): interpolating Eulerian velocity to the Lagrangian mesh\n"; d_ib_implicit_ops->interpolateVelocity(d_u_idx, getCoarsenSchedules(d_object_name+"::u::CONSERVATIVE_COARSEN"), getGhostfillRefineSchedules(d_object_name+"::u"), half_time); // Compute the final value of the updated positions of the Lagrangian // structure. d_ib_implicit_ops->midpointStep(current_time, new_time); #endif // Deallocate temporary data. ierr = VecDestroy(&composite_sol_petsc_vec); IBTK_CHKERRQ(ierr); ierr = VecDestroy(&composite_rhs_petsc_vec); IBTK_CHKERRQ(ierr); ierr = VecDestroy(&composite_res_petsc_vec); IBTK_CHKERRQ(ierr); PETScSAMRAIVectorReal::destroyPETScVector(eul_sol_petsc_vec); PETScSAMRAIVectorReal::destroyPETScVector(eul_rhs_petsc_vec); eul_rhs_vec->freeVectorComponents(); d_u_scratch_vec->freeVectorComponents(); d_f_scratch_vec->freeVectorComponents(); ierr = VecDestroy(&lag_sol_petsc_vec); IBTK_CHKERRQ(ierr); ierr = VecDestroy(&lag_rhs_petsc_vec); IBTK_CHKERRQ(ierr); // Execute any registered callbacks. executeIntegrateHierarchyCallbackFcns(current_time, new_time, cycle_num); return; } // integrateHierarchy
int main(int argc,char **args) { const PetscScalar xvals[] = {11,13},yvals[] = {17,19},zvals[] = {23,29}; const PetscInt inds[] = {0,1}; PetscScalar avals[] = {2,3,5,7}; Mat A,S,D[4],N; Vec X,Y,Z; User user; PetscInt i; PetscErrorCode ierr; PetscInitialize(&argc,&args,(char*)0,help); ierr = MatCreateSeqAIJ(PETSC_COMM_WORLD,2,2,2,NULL,&A); CHKERRQ(ierr); ierr = MatSetUp(A); CHKERRQ(ierr); ierr = MatSetValues(A,2,inds,2,inds,avals,INSERT_VALUES); CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_WORLD,2,&X); CHKERRQ(ierr); ierr = VecDuplicate(X,&Y); CHKERRQ(ierr); ierr = VecDuplicate(X,&Z); CHKERRQ(ierr); ierr = VecSetValues(X,2,inds,xvals,INSERT_VALUES); CHKERRQ(ierr); ierr = VecSetValues(Y,2,inds,yvals,INSERT_VALUES); CHKERRQ(ierr); ierr = VecSetValues(Z,2,inds,zvals,INSERT_VALUES); CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = VecAssemblyBegin(X); CHKERRQ(ierr); ierr = VecAssemblyBegin(Y); CHKERRQ(ierr); ierr = VecAssemblyBegin(Z); CHKERRQ(ierr); ierr = VecAssemblyEnd(X); CHKERRQ(ierr); ierr = VecAssemblyEnd(Y); CHKERRQ(ierr); ierr = VecAssemblyEnd(Z); CHKERRQ(ierr); ierr = PetscNew(struct _n_User,&user); CHKERRQ(ierr); user->B = A; ierr = MatCreateShell(PETSC_COMM_WORLD,2,2,2,2,user,&S); CHKERRQ(ierr); ierr = MatSetUp(S); CHKERRQ(ierr); ierr = MatShellSetOperation(S,MATOP_MULT,(void (*)(void))MatMult_User); CHKERRQ(ierr); ierr = MatShellSetOperation(S,MATOP_MULT_TRANSPOSE,(void (*)(void))MatMultTranspose_User); CHKERRQ(ierr); ierr = MatShellSetOperation(S,MATOP_GET_DIAGONAL,(void (*)(void))MatGetDiagonal_User); CHKERRQ(ierr); for (i=0; i<4; i++) { ierr = MatCreateSeqDense(PETSC_COMM_WORLD,1,1,&avals[i],&D[i]); CHKERRQ(ierr); } ierr = MatCreateNest(PETSC_COMM_WORLD,2,NULL,2,NULL,D,&N); CHKERRQ(ierr); ierr = MatSetUp(N); CHKERRQ(ierr); ierr = TestMatrix(S,X,Y,Z); CHKERRQ(ierr); ierr = TestMatrix(A,X,Y,Z); CHKERRQ(ierr); ierr = TestMatrix(N,X,Y,Z); CHKERRQ(ierr); for (i=0; i<4; i++) { ierr = MatDestroy(&D[i]); CHKERRQ(ierr); } ierr = MatDestroy(&A); CHKERRQ(ierr); ierr = MatDestroy(&S); CHKERRQ(ierr); ierr = MatDestroy(&N); CHKERRQ(ierr); ierr = VecDestroy(&X); CHKERRQ(ierr); ierr = VecDestroy(&Y); CHKERRQ(ierr); ierr = VecDestroy(&Z); CHKERRQ(ierr); ierr = PetscFree(user); CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }