LIS_INT main(LIS_INT argc, char* argv[]) { LIS_SCALAR *a,*q,*r; LIS_INT m,n,nn; LIS_INT i,j,ii,jj,nnz,qriter; double time,time0; LIS_REAL qrerr; LIS_DEBUG_FUNC_IN; lis_initialize(&argc, &argv); if( argc < 3 ) { printf("Usage: %s m n\n", argv[0]); CHKERR(1); } m = atoi(argv[1]); n = atoi(argv[2]); if( m<=0 || n<=0 ) { printf("m=%d <=0 or n=%d <=0\n", m,n); CHKERR(1); } printf("\n"); /* create arrays */ nn = m*n; a = (LIS_SCALAR *)malloc(nn*nn*sizeof(LIS_SCALAR)); q = (LIS_SCALAR *)malloc(nn*nn*sizeof(LIS_SCALAR)); r = (LIS_SCALAR *)malloc(nn*nn*sizeof(LIS_SCALAR)); /* define two-dimensional Laplacian */ lis_array_set_all(nn*nn,(LIS_SCALAR)0.0,a); nnz = 0; for(ii=0;ii<nn;ii++) { i = ii/m; j = ii - i*m; if( i>0 ) { jj = ii - m; a[ii + jj * nn] = -1.0; nnz++;} if( i<n-1 ) { jj = ii + m; a[ii + jj * nn] = -1.0; nnz++;} if( j>0 ) { jj = ii - 1; a[ii + jj * nn] = -1.0; nnz++;} if( j<m-1 ) { jj = ii + 1; a[ii + jj * nn] = -1.0; nnz++;} jj = ii; a[ii + jj * nn] = 4.0; nnz++; } printf("matrix size = %d x %d (%d nonzero entries)\n\n", nn,nn,nnz); /* solve eigenproblem */ time0 = lis_wtime(); lis_array_qr(nn,a,q,r,&qriter,&qrerr); time = lis_wtime() - time0; printf("QR : number of iterations = %d\n", qriter); printf("QR : elapsed time = %e sec.\n", time); printf("QR : eigensolver = %e sec.\n", time); #ifdef _LONG__DOUBLE printf("QR : 2-norm of A(2,1) = %Le\n\n", qrerr); #else printf("QR : 2-norm of A(2,1) = %e\n\n", qrerr); #endif lis_finalize(); LIS_DEBUG_FUNC_OUT; return 0; }
LIS_INT lis_ecg(LIS_ESOLVER esolver) { LIS_MATRIX A; LIS_VECTOR x; LIS_SCALAR evalue; LIS_INT emaxiter; LIS_REAL tol; LIS_INT iter,iter3,nsolver,i,j,output; LIS_INT nprocs,my_rank; LIS_REAL nrm2,resid,resid3; LIS_SCALAR lshift; LIS_VECTOR b,D,r,w,p,Aw,Ax,Ap,ones,Ds; LIS_SCALAR *SA, *SB, *SW, *v3, *SAv3, *SBv3, *z3, *q3, *SBz3, evalue3, ievalue3; LIS_SOLVER solver; LIS_PRECON precon; LIS_MATRIX A0; LIS_VECTOR x0,z,q; double times,itimes,ptimes,p_c_times,p_i_times; LIS_INT nsol, precon_type; char solvername[128], preconname[128]; A = esolver->A; x = esolver->x; emaxiter = esolver->options[LIS_EOPTIONS_MAXITER]; tol = esolver->params[LIS_EPARAMS_RESID - LIS_EOPTIONS_LEN]; output = esolver->options[LIS_EOPTIONS_OUTPUT]; lshift = esolver->lshift; if( A->my_rank==0 ) printf("local shift = %e\n", lshift); if (lshift != 0) lis_matrix_shift_diagonal(A, lshift); SA = (LIS_SCALAR *)lis_malloc(3*3*sizeof(LIS_SCALAR), "lis_ecg::SA"); SB = (LIS_SCALAR *)lis_malloc(3*3*sizeof(LIS_SCALAR), "lis_ecg::SB"); SW = (LIS_SCALAR *)lis_malloc(3*3*sizeof(LIS_SCALAR), "lis_ecg::SW"); v3 = (LIS_SCALAR *)lis_malloc(3*sizeof(LIS_SCALAR), "lis_ecg::v3"); SAv3 = (LIS_SCALAR *)lis_malloc(3*sizeof(LIS_SCALAR), "lis_ecg::SAv3"); SBv3 = (LIS_SCALAR *)lis_malloc(3*sizeof(LIS_SCALAR), "lis_ecg::SBv3"); SBz3 = (LIS_SCALAR *)lis_malloc(3*sizeof(LIS_SCALAR), "lis_ecg::SBz3"); z3 = (LIS_SCALAR *)lis_malloc(3*sizeof(LIS_SCALAR), "lis_ecg::z3"); q3 = (LIS_SCALAR *)lis_malloc(3*sizeof(LIS_SCALAR), "lis_ecg::q3"); b = esolver->work[0]; D = esolver->work[1]; Ds = esolver->work[2]; r = esolver->work[3]; w = esolver->work[4]; p = esolver->work[5]; Aw = esolver->work[6]; Ax = esolver->work[7]; Ap = esolver->work[8]; lis_vector_set_all(1.0,b); lis_vector_nrm2(b, &nrm2); lis_vector_scale(1/nrm2, b); lis_solver_create(&solver); lis_solver_set_option("-i bicg -p ilu",solver); lis_solver_set_optionC(solver); lis_solver_get_solver(solver, &nsol); lis_solver_get_precon(solver, &precon_type); lis_get_solvername(nsol, solvername); lis_get_preconname(precon_type, preconname); printf("solver : %s %d\n", solvername, nsol); printf("precon : %s %d\n", preconname, precon_type); lis_solve(A, b, x, solver); lis_vector_copy(b,Ax); lis_vector_nrm2(x, &nrm2); lis_vector_set_all(0.0,p); lis_vector_set_all(0.0,Ap); lis_precon_create(solver, &precon); solver->precon = precon; iter=0; while (iter<emaxiter) { iter = iter + 1; lis_vector_dot(x,Ax,&evalue); lis_vector_axpyz(-(evalue),x,Ax,r); lis_vector_nrm2(r, &nrm2); resid = fabs(nrm2/(evalue)); if( output ) { if( output & LIS_EPRINT_MEM ) esolver->residual[iter] = resid; if( output & LIS_EPRINT_OUT && A->my_rank==0 ) printf("iter: %5d residual = %e\n", iter, resid); } if (resid<tol) break; lis_psolve(solver, x, w); lis_vector_copy(x,Aw); lis_vector_nrm2(w, &nrm2); lis_vector_dot(w,Aw,&SA[0]); lis_vector_dot(x,Aw,&SA[3]); lis_vector_dot(p,Aw,&SA[6]); SA[1] = SA[3]; lis_vector_dot(x,Ax,&SA[4]); lis_vector_dot(p,Ax,&SA[7]); SA[2] = SA[6]; SA[5] = SA[7]; lis_vector_dot(p,Ap,&SA[8]); lis_vector_dot(w,w,&SB[0]); lis_vector_dot(x,w,&SB[3]); lis_vector_dot(p,w,&SB[6]); SB[1] = SB[3]; lis_vector_dot(x,x,&SB[4]); lis_vector_dot(p,x,&SB[7]); SB[2] = SB[6]; SB[5] = SB[7]; lis_vector_dot(p,p,&SB[8]); lis_array_set_all(3, 1.0, v3); iter3=0; while (iter3<emaxiter) { iter3 = iter3 + 1; lis_array_nrm2(3, v3, &nrm2); lis_array_scale(3, 1/nrm2, v3); lis_array_matvec(3, SB, v3, SBv3, LIS_INS_VALUE); lis_array_invvec(3, SA, SBv3, z3); lis_array_dot2(3, SBv3, z3, &ievalue3); if (ievalue3==0) { printf("ievalue3 is zero\n"); lis_precon_destroy(precon); lis_solver_destroy(solver); esolver->iter = iter; esolver->resid = resid; esolver->evalue[0] = evalue; if (lshift != 0) lis_matrix_shift_diagonal(A, -lshift); lis_free(SA); lis_free(SB); lis_free(SW); lis_free(v3); lis_free(SAv3); lis_free(SBv3); lis_free(SBz3); lis_free(z3); lis_free(q3); return LIS_BREAKDOWN; } lis_array_axpyz(3, -ievalue3, SBv3, z3, q3); lis_array_nrm2(3, q3, &resid3); resid3 = fabs(resid3 / ievalue3); if (resid3<1e-12) break; lis_array_copy(3,z3,v3); } evalue3 = 1 / ievalue3; lis_vector_scale(v3[0],w); lis_vector_axpy(v3[2],p,w); lis_vector_xpay(w,v3[1],x); lis_vector_copy(w,p); lis_vector_scale(v3[0],Aw); lis_vector_axpy(v3[2],Ap,Aw); lis_vector_xpay(Aw,v3[1],Ax); lis_vector_copy(Aw,Ap); lis_vector_nrm2(x,&nrm2); lis_vector_scale(1/nrm2,x); lis_vector_scale(1/nrm2,Ax); lis_vector_nrm2(p,&nrm2); lis_vector_scale(1/nrm2,p); lis_vector_scale(1/nrm2,Ap); lis_solver_get_timeex(solver,×,&itimes,&ptimes,&p_c_times,&p_i_times); esolver->ptimes += solver->ptimes; esolver->itimes += solver->itimes; esolver->p_c_times += solver->p_c_times; esolver->p_i_times += solver->p_i_times; } lis_precon_destroy(precon); lis_solver_destroy(solver); esolver->iter = iter; esolver->resid = resid; esolver->evalue[0] = evalue; if (lshift != 0) lis_matrix_shift_diagonal(A, -lshift); lis_free(SA); lis_free(SB); lis_free(SW); lis_free(v3); lis_free(SAv3); lis_free(SBv3); lis_free(SBz3); lis_free(z3); lis_free(q3); if (resid<tol) { esolver->retcode = LIS_SUCCESS; return LIS_SUCCESS; } else { esolver->retcode = LIS_MAXITER; return LIS_MAXITER; } }