void lis_solve_f(LIS_MATRIX_F *A, LIS_VECTOR_F b, LIS_VECTOR_F x, LIS_SOLVER_F *solver, LIS_INT *ierr) { LIS_DEBUG_FUNC_IN; *ierr = lis_solve((LIS_MATRIX)LIS_V2P(A), (LIS_VECTOR)LIS_V2P(b), (LIS_VECTOR)LIS_V2P(x), (LIS_SOLVER)LIS_V2P(solver)); if( *ierr ) return; LIS_DEBUG_FUNC_OUT; return; }
LIS_INT main(LIS_INT argc, char* argv[]) { LIS_MATRIX A0,A,B; LIS_VECTOR x,b,u; LIS_SOLVER solver; LIS_INT nprocs,my_rank; int int_nprocs,int_my_rank; LIS_INT nsol,rhs,len,i,j,k,jj,kk,p,nrow_p,l,n; LIS_INT err,iter,iter_double,iter_quad; LIS_INT *iw,*nrow,*index,*ptr; LIS_SCALAR *s,t,*value; double times,itimes,ptimes,p_c_times,p_i_times; LIS_REAL resid; char solvername[128]; LIS_DEBUG_FUNC_IN; lis_initialize(&argc, &argv); #ifdef USE_MPI MPI_Comm_size(MPI_COMM_WORLD,&int_nprocs); MPI_Comm_rank(MPI_COMM_WORLD,&int_my_rank); nprocs = int_nprocs; my_rank = int_my_rank; #else nprocs = 1; my_rank = 0; #endif if( argc < 5 ) { if( my_rank==0 ) { printf("Usage: %s matrix_filename rhs_setting solution_filename residual_filename [options]\n", argv[0]); } CHKERR(1); } len = (LIS_INT)strlen(argv[2]); if( len==1 ) { if( argv[2][0]=='0' || argv[2][0]=='1' || argv[2][0]=='2' ) { rhs = atoi(argv[2]); } else { rhs = -1; } } else { rhs = -1; } if( my_rank==0 ) { printf("\n"); #ifdef _LONGLONG printf("number of processes = %lld\n",nprocs); #else printf("number of processes = %d\n",nprocs); #endif } #ifdef _OPENMP if( my_rank==0 ) { #ifdef _LONGLONG printf("max number of threads = %lld\n",omp_get_num_procs()); printf("number of threads = %lld\n",omp_get_max_threads()); #else printf("max number of threads = %d\n",omp_get_num_procs()); printf("number of threads = %d\n",omp_get_max_threads()); #endif } #endif /* read matrix and vectors from file */ err = lis_matrix_create(LIS_COMM_WORLD,&A); CHKERR(err); err = lis_vector_create(LIS_COMM_WORLD,&b); CHKERR(err); err = lis_vector_create(LIS_COMM_WORLD,&x); CHKERR(err); err = lis_input(A,b,x,argv[1]); CHKERR(err); err = lis_matrix_duplicate(A,&A0); CHKERR(err); lis_matrix_set_type(A0,LIS_MATRIX_CSR); err = lis_matrix_convert(A,A0); CHKERR(err); lis_matrix_destroy(A); A = A0; err = lis_vector_duplicate(A,&u); CHKERR(err); if( lis_vector_is_null(b) ) { lis_vector_destroy(b); lis_vector_duplicate(A,&b); CHKERR(err); if( rhs==0 ) { CHKERR(1); } else if( rhs==1 ) { err = lis_vector_set_all(1.0,b); } else { err = lis_vector_set_all(1.0,u); lis_matvec(A,u,b); } } if( rhs==-1 ) { lis_input_vector(b,argv[2]); } if( lis_vector_is_null(x) ) { lis_vector_destroy(x); err = lis_vector_duplicate(A,&x); CHKERR(err); } err = lis_solver_create(&solver); CHKERR(err); lis_solver_set_option("-print mem",solver); lis_solver_set_optionC(solver); err = lis_solve(A,b,x,solver); CHKERR(err); lis_solver_get_itersex(solver,&iter,&iter_double,&iter_quad); lis_solver_get_timeex(solver,×,&itimes,&ptimes,&p_c_times,&p_i_times); lis_solver_get_residualnorm(solver,&resid); lis_solver_get_solver(solver,&nsol); lis_solver_get_solvername(nsol,solvername); /* write results */ if( my_rank==0 ) { #ifdef _LONGLONG #ifdef _LONG__DOUBLE printf("%s: number of iterations = %lld \n",solvername, iter); #else printf("%s: number of iterations = %lld (double = %lld, quad = %lld)\n",solvername,iter, iter_double, iter_quad); #endif #else #ifdef _LONG__DOUBLE printf("%s: number of iterations = %d \n",solvername, iter); #else printf("%s: number of iterations = %d (double = %d, quad = %d)\n",solvername,iter, iter_double, iter_quad); #endif #endif printf("%s: elapsed time = %e sec.\n",solvername,times); printf("%s: preconditioner = %e sec.\n",solvername, ptimes); printf("%s: matrix creation = %e sec.\n",solvername, p_c_times); printf("%s: linear solver = %e sec.\n",solvername, itimes); #ifdef _LONG__DOUBLE printf("%s: relative residual 2-norm = %Le\n\n",solvername,resid); #else printf("%s: relative residual 2-norm = %e\n\n",solvername,resid); #endif } /* write solution */ lis_output_vector(x,LIS_FMT_MM,argv[3]); /* write residual */ lis_solver_output_rhistory(solver, argv[4]); lis_solver_destroy(solver); lis_vector_destroy(x); lis_vector_destroy(u); lis_vector_destroy(b); lis_matrix_destroy(A); lis_finalize(); LIS_DEBUG_FUNC_OUT; return 0; }
bool LisLinearSolver::solve(LisMatrix &A, LisVector &b, LisVector &x) { finalizeMatrixAssembly(A); INFO("------------------------------------------------------------------"); INFO("*** LIS solver computation"); // Create solver LIS_SOLVER solver; int ierr = lis_solver_create(&solver); if (!checkLisError(ierr)) return false; lis_solver_set_option( const_cast<char*>(_lis_option._option_string.c_str()), solver); #ifdef _OPENMP INFO("-> number of threads: %i", (int) omp_get_max_threads()); #endif { int precon; ierr = lis_solver_get_precon(solver, &precon); INFO("-> precon: %i", precon); } { int slv; ierr = lis_solver_get_solver(solver, &slv); INFO("-> solver: %i", slv); } // solve INFO("-> solve"); ierr = lis_solve(A.getRawMatrix(), b.getRawVector(), x.getRawVector(), solver); if (!checkLisError(ierr)) return false; LIS_INT linear_solver_status; ierr = lis_solver_get_status(solver, &linear_solver_status); if (!checkLisError(ierr)) return false; INFO("-> status: %d", linear_solver_status); { int iter = 0; ierr = lis_solver_get_iter(solver, &iter); if (!checkLisError(ierr)) return false; INFO("-> iteration: %d", iter); } { double resid = 0.0; ierr = lis_solver_get_residualnorm(solver, &resid); if (!checkLisError(ierr)) return false; INFO("-> residual: %g", resid); } { double time, itime, ptime, p_ctime, p_itime; ierr = lis_solver_get_timeex(solver, &time, &itime, &ptime, &p_ctime, &p_itime); if (!checkLisError(ierr)) return false; INFO("-> time total (s): %g", time); INFO("-> time iterations (s): %g", itime); INFO("-> time preconditioning (s): %g", ptime); INFO("-> time precond. create (s): %g", p_ctime); INFO("-> time precond. iter (s): %g", p_itime); } // Clear solver ierr = lis_solver_destroy(solver); if (!checkLisError(ierr)) return false; INFO("------------------------------------------------------------------"); return linear_solver_status == LIS_SUCCESS; }
LIS_INT main(LIS_INT argc, char* argv[]) { LIS_MATRIX A0,A; LIS_VECTOR x,b,u; LIS_SOLVER solver; LIS_INT m,n,nn,nnz; LIS_INT i,j,ii,jj,ctr; LIS_INT is,ie; LIS_INT nprocs,my_rank; int int_nprocs,int_my_rank; LIS_INT nsol; LIS_INT err,iter,mtype,iter_double,iter_quad; double time,itime,ptime,p_c_time,p_i_time; LIS_REAL resid; char solvername[128]; LIS_INT *ptr,*index; LIS_SCALAR *value; LIS_DEBUG_FUNC_IN; lis_initialize(&argc, &argv); #ifdef USE_MPI MPI_Comm_size(MPI_COMM_WORLD,&int_nprocs); MPI_Comm_rank(MPI_COMM_WORLD,&int_my_rank); nprocs = int_nprocs; my_rank = int_my_rank; #else nprocs = 1; my_rank = 0; #endif if( argc < 6 ) { if( my_rank==0 ) { printf("Usage: %s m n matrix_type solution_filename rhistory_filename [options]\n", argv[0]); } CHKERR(1); } m = atoi(argv[1]); n = atoi(argv[2]); mtype = atoi(argv[3]); if( m<=0 || n<=0 ) { #ifdef _LONGLONG if( my_rank==0 ) printf("m=%lld <=0 or n=%lld <=0\n",m,n); #else if( my_rank==0 ) printf("m=%d <=0 or n=%d <=0\n",m,n); #endif CHKERR(1); } if( my_rank==0 ) { printf("\n"); #ifdef _LONGLONG printf("number of processes = %lld\n",nprocs); #else printf("number of processes = %d\n",nprocs); #endif } #ifdef _OPENMP if( my_rank==0 ) { #ifdef _LONGLONG printf("max number of threads = %lld\n",omp_get_num_procs()); printf("number of threads = %lld\n",omp_get_max_threads()); #else printf("max number of threads = %d\n",omp_get_num_procs()); printf("number of threads = %d\n",omp_get_max_threads()); #endif } #endif /* create matrix and vectors */ nn = m*n; err = lis_matrix_create(LIS_COMM_WORLD,&A); err = lis_matrix_set_size(A,0,nn); CHKERR(err); ptr = (LIS_INT *)malloc((A->n+1)*sizeof(LIS_INT)); if( ptr==NULL ) CHKERR(1); index = (LIS_INT *)malloc(5*A->n*sizeof(LIS_INT)); if( index==NULL ) CHKERR(1); value = (LIS_SCALAR *)malloc(5*A->n*sizeof(LIS_SCALAR)); if( value==NULL ) CHKERR(1); lis_matrix_get_range(A,&is,&ie); ctr = 0; for(ii=is;ii<ie;ii++) { i = ii/m; j = ii - i*m; if( i>0 ) { jj = ii - m; index[ctr] = jj; value[ctr++] = -1.0;} if( i<n-1 ) { jj = ii + m; index[ctr] = jj; value[ctr++] = -1.0;} if( j>0 ) { jj = ii - 1; index[ctr] = jj; value[ctr++] = -1.0;} if( j<m-1 ) { jj = ii + 1; index[ctr] = jj; value[ctr++] = -1.0;} index[ctr] = ii; value[ctr++] = 4.0; ptr[ii-is+1] = ctr; } ptr[0] = 0; err = lis_matrix_set_csr(ptr[ie-is],ptr,index,value,A); CHKERR(err); err = lis_matrix_assemble(A); CHKERR(err); nnz = A->nnz; #ifdef USE_MPI MPI_Allreduce(&nnz,&i,1,LIS_MPI_INT,MPI_SUM,A->comm); nnz = i; #endif #ifdef _LONGLONG if( my_rank==0 ) printf("matrix size = %lld x %lld (%lld nonzero entries)\n\n",nn,nn,nnz); #else if( my_rank==0 ) printf("matrix size = %d x %d (%d nonzero entries)\n\n",nn,nn,nnz); #endif err = lis_matrix_duplicate(A,&A0); CHKERR(err); lis_matrix_set_type(A0,mtype); err = lis_matrix_convert(A,A0); CHKERR(err); lis_matrix_destroy(A); A = A0; err = lis_vector_duplicate(A,&u); CHKERR(err); err = lis_vector_duplicate(A,&b); CHKERR(err); err = lis_vector_duplicate(A,&x); CHKERR(err); err = lis_vector_set_all(1.0,u); lis_matvec(A,u,b); err = lis_solver_create(&solver); CHKERR(err); lis_solver_set_option("-print mem",solver); lis_solver_set_optionC(solver); err = lis_solve(A,b,x,solver); CHKERR(err); lis_solver_get_iterex(solver,&iter,&iter_double,&iter_quad); lis_solver_get_timeex(solver,&time,&itime,&ptime,&p_c_time,&p_i_time); lis_solver_get_residualnorm(solver,&resid); lis_solver_get_solver(solver,&nsol); lis_solver_get_solvername(nsol,solvername); if( my_rank==0 ) { #ifdef _LONGLONG #ifdef _LONG__DOUBLE printf("%s: number of iterations = %lld \n",solvername, iter); #else printf("%s: number of iterations = %lld (double = %lld, quad = %lld)\n",solvername,iter, iter_double, iter_quad); #endif #else #ifdef _LONG__DOUBLE printf("%s: number of iterations = %d \n",solvername, iter); #else printf("%s: number of iterations = %d (double = %d, quad = %d)\n",solvername,iter, iter_double, iter_quad); #endif #endif printf("%s: elapsed time = %e sec.\n",solvername,time); printf("%s: preconditioner = %e sec.\n",solvername, ptime); printf("%s: matrix creation = %e sec.\n",solvername, p_c_time); printf("%s: linear solver = %e sec.\n",solvername, itime); #ifdef _LONG__DOUBLE printf("%s: relative residual = %Le\n\n",solvername,resid); #else printf("%s: relative residual = %e\n\n",solvername,resid); #endif } /* write solution */ lis_output_vector(x,LIS_FMT_MM,argv[4]); /* write residual history */ lis_solver_output_rhistory(solver, argv[5]); lis_solver_destroy(solver); lis_matrix_destroy(A); lis_vector_destroy(b); lis_vector_destroy(x); lis_vector_destroy(u); lis_finalize(); LIS_DEBUG_FUNC_OUT; return 0; }
LIS_INT main(LIS_INT argc, char* argv[]) { LIS_MATRIX A; LIS_VECTOR x,b,u; LIS_SOLVER solver; LIS_INT k,n,gn,ii,jj; LIS_INT is,ie; LIS_INT nprocs,my_rank; int int_nprocs,int_my_rank; LIS_INT nsol; LIS_INT err,iter,iter_double,iter_quad; double time,itime,ptime,p_c_time,p_i_time; LIS_REAL resid; char solvername[128]; LIS_INT *ptr,*index; LIS_SCALAR *value,gamma; LIS_DEBUG_FUNC_IN; lis_initialize(&argc, &argv); #ifdef USE_MPI MPI_Comm_size(MPI_COMM_WORLD,&int_nprocs); MPI_Comm_rank(MPI_COMM_WORLD,&int_my_rank); nprocs = int_nprocs; my_rank = int_my_rank; #else nprocs = 1; my_rank = 0; #endif if( argc < 3 ) { if( my_rank==0 ) { printf("Usage: %s n gamma [options]\n", argv[0]); } CHKERR(1); } gn = atoi(argv[1]); gamma = atof(argv[2]); if( gn<=0 ) { #ifdef _LONGLONG if( my_rank==0 ) printf("n=%lld <=0 \n",gn); #else if( my_rank==0 ) printf("n=%d <=0 \n",gn); #endif CHKERR(1); } if( my_rank==0 ) { printf("\n"); #ifdef _LONGLONG printf("number of processes = %lld\n",nprocs); #else printf("number of processes = %d\n",nprocs); #endif } #ifdef _OPENMP if( my_rank==0 ) { #ifdef _LONGLONG printf("max number of threads = %lld\n",omp_get_num_procs()); printf("number of threads = %lld\n",omp_get_max_threads()); #else printf("max number of threads = %d\n",omp_get_num_procs()); printf("number of threads = %d\n",omp_get_max_threads()); #endif } #endif if(my_rank==0) { #ifdef _LONGLONG printf("n = %lld, gamma = %f\n\n",gn,gamma); #else printf("n = %d, gamma = %f\n\n",gn,gamma); #endif } /* create matrix and vectors */ err = lis_matrix_create(LIS_COMM_WORLD,&A); CHKERR(err); err = lis_matrix_set_size(A,0,gn); CHKERR(err); err = lis_matrix_get_size(A,&n,&gn); CHKERR(err); err = lis_matrix_malloc_csr(n,3*n,&ptr,&index,&value); CHKERR(err); err = lis_matrix_get_range(A,&is,&ie); CHKERR(err); k = 0; ptr[0] = 0; for(ii=is;ii<ie;ii++) { if( ii>1 ) { jj = ii - 2; index[k] = jj; value[k++] = gamma;} if( ii<gn-1 ) { jj = ii + 1; index[k] = jj; value[k++] = 1.0;} index[k] = ii; value[k++] = 2.0; ptr[ii-is+1] = k; } err = lis_matrix_set_csr(ptr[ie-is],ptr,index,value,A); CHKERR(err); err = lis_matrix_assemble(A); CHKERR(err); err = lis_vector_duplicate(A,&u); CHKERR(err); err = lis_vector_duplicate(u,&b); CHKERR(err); err = lis_vector_duplicate(u,&x); CHKERR(err); err = lis_vector_set_all(1.0,u); lis_matvec(A,u,b); err = lis_solver_create(&solver); CHKERR(err); lis_solver_set_option("-print mem",solver); lis_solver_set_optionC(solver); err = lis_solve(A,b,x,solver); CHKERR(err); lis_solver_get_iterex(solver,&iter,&iter_double,&iter_quad); lis_solver_get_timeex(solver,&time,&itime,&ptime,&p_c_time,&p_i_time); lis_solver_get_residualnorm(solver,&resid); lis_solver_get_solver(solver,&nsol); lis_solver_get_solvername(nsol,solvername); if( my_rank==0 ) { #ifdef _LONGLONG #ifdef _LONG__DOUBLE printf("%s: number of iterations = %lld \n",solvername, iter); #else printf("%s: number of iterations = %lld (double = %lld, quad = %lld)\n",solvername,iter, iter_double, iter_quad); #endif #else #ifdef _LONG__DOUBLE printf("%s: number of iterations = %d \n",solvername, iter); #else printf("%s: number of iterations = %d (double = %d, quad = %d)\n",solvername,iter, iter_double, iter_quad); #endif #endif printf("%s: elapsed time = %e sec.\n",solvername,time); printf("%s: preconditioner = %e sec.\n",solvername, ptime); printf("%s: matrix creation = %e sec.\n",solvername, p_c_time); printf("%s: linear solver = %e sec.\n",solvername, itime); #ifdef _LONG__DOUBLE printf("%s: relative residual = %Le\n\n",solvername,resid); #else printf("%s: relative residual = %e\n\n",solvername,resid); #endif } lis_solver_destroy(solver); lis_matrix_destroy(A); lis_vector_destroy(b); lis_vector_destroy(x); lis_vector_destroy(u); lis_finalize(); LIS_DEBUG_FUNC_OUT; return 0; }
LIS_INT main(LIS_INT argc, char* argv[]) { LIS_MATRIX A; LIS_VECTOR b,x,u; LIS_SOLVER solver; LIS_INT my_rank; #ifdef USE_MPI int int_nprocs,int_my_rank; #endif LIS_INT err,i,n,gn,is,ie,iter; n = 12; lis_initialize(&argc, &argv); #ifdef USE_MPI MPI_Comm_size(MPI_COMM_WORLD,&int_nprocs); MPI_Comm_rank(MPI_COMM_WORLD,&int_my_rank); my_rank = int_my_rank; #else my_rank = 0; #endif lis_matrix_create(LIS_COMM_WORLD,&A); err = lis_matrix_set_size(A,0,n); CHKERR(err); lis_matrix_get_size(A,&n,&gn); lis_matrix_get_range(A,&is,&ie); for(i=is;i<ie;i++) { if( i>0 ) lis_matrix_set_value(LIS_INS_VALUE,i,i-1,-1.0,A); if( i<gn-1 ) lis_matrix_set_value(LIS_INS_VALUE,i,i+1,-1.0,A); lis_matrix_set_value(LIS_INS_VALUE,i,i,2.0,A); } lis_matrix_set_type(A,LIS_MATRIX_CSR); lis_matrix_assemble(A); lis_vector_duplicate(A,&u); lis_vector_duplicate(A,&b); lis_vector_duplicate(A,&x); lis_vector_set_all(1.0,u); lis_matvec(A,u,b); lis_solver_create(&solver); lis_solver_set_option("-print mem",solver); lis_solver_set_optionC(solver); lis_solve(A,b,x,solver); lis_solver_get_iter(solver,&iter); if (my_rank==0) { #ifdef _LONG__LONG printf("number of iterations = %lld\n",iter); #else printf("number of iterations = %d\n",iter); #endif printf("\n"); } lis_vector_print(x); lis_matrix_destroy(A); lis_vector_destroy(b); lis_vector_destroy(x); lis_vector_destroy(u); lis_solver_destroy(solver); lis_finalize(); return 0; }
LIS_INT lis_esi_quad(LIS_ESOLVER esolver) { LIS_MATRIX A; LIS_VECTOR x, Ax; LIS_SCALAR xAx, xx, mu, lshift; LIS_INT ss; LIS_INT emaxiter; LIS_REAL tol; LIS_INT i,j,k; LIS_SCALAR evalue,dotvr; LIS_INT iter,giter,output,niesolver; LIS_INT nprocs,my_rank; LIS_REAL nrm2,dot,resid,resid0; LIS_QUAD_PTR qdot_vv, qdot_vr; LIS_VECTOR *v,r,q; LIS_SOLVER solver; LIS_PRECON precon; double times,itimes,ptimes,p_c_times,p_i_times; LIS_INT err; LIS_INT nsol, precon_type; char solvername[128], preconname[128]; LIS_DEBUG_FUNC_IN; A = esolver->A; x = esolver->x; ss = esolver->options[LIS_EOPTIONS_SUBSPACE]; emaxiter = esolver->options[LIS_EOPTIONS_MAXITER]; tol = esolver->params[LIS_EPARAMS_RESID - LIS_EOPTIONS_LEN]; lshift = esolver->lshift; output = esolver->options[LIS_EOPTIONS_OUTPUT]; niesolver = esolver->options[LIS_EOPTIONS_INNER_ESOLVER]; r = esolver->work[0]; q = esolver->work[1]; v = &esolver->work[2]; Ax = esolver->work[3]; LIS_QUAD_SCALAR_MALLOC(qdot_vv,0,1); LIS_QUAD_SCALAR_MALLOC(qdot_vr,1,1); lis_vector_set_all(1.0,r); lis_vector_nrm2(r, &nrm2); lis_vector_scale(1/nrm2,r); switch ( niesolver ) { case LIS_ESOLVER_II: lis_solver_create(&solver); lis_solver_set_option("-i bicg -p ilu -precision quad",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); if( A->my_rank==0 ) printf("local shift = %e\n", lshift); if (lshift != 0) lis_matrix_shift_diagonal(A, lshift); break; case LIS_ESOLVER_AII: lis_solver_create(&solver); lis_solver_set_option("-i bicg -p ilu -precision quad",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); if( A->my_rank==0 ) printf("local shift = %e\n", lshift); if (lshift != 0) lis_matrix_shift_diagonal(A, lshift); lis_vector_set_all(1.0,q); lis_solve(A, q, x, solver); lis_precon_create(solver, &precon); solver->precon = precon; break; case LIS_ESOLVER_RQI: lis_solver_create(&solver); lis_solver_set_option("-p ilu -precision quad -maxiter 10",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); if( A->my_rank==0 ) printf("local shift = %e\n", lshift); if (lshift != 0) lis_matrix_shift_diagonal(A, lshift); break; } giter=0; j=0; while (j<ss) { lis_vector_duplicate(A,&esolver->evector[j]); j = j+1; lis_vector_copy(r, v[j]); if (niesolver==LIS_ESOLVER_II || niesolver==LIS_ESOLVER_RQI) { /* create preconditioner */ solver->A = A; err = lis_precon_create(solver, &precon); if( err ) { lis_solver_work_destroy(solver); solver->retcode = err; return err; } } if (niesolver==LIS_ESOLVER_RQI) { lis_vector_nrm2(x, &nrm2); lis_vector_scale(1/nrm2, x); lis_matvec(A, x, Ax); lis_vector_dot(x, Ax, &xAx); lis_vector_dot(x, x, &xx); mu = xAx / xx; } iter = 0; while (iter<emaxiter) { /* diagonalization */ iter = iter+1; giter = giter+1; for (k=1;k<j;k++) { lis_vector_dotex_mmm(v[j], v[k], &qdot_vv); lis_quad_minus((LIS_QUAD *)qdot_vv.hi); lis_vector_axpyex_mmm(qdot_vv,v[k],v[j]); } switch( niesolver ) { case LIS_ESOLVER_PI: lis_matvec(A,v[j],r); break; case LIS_ESOLVER_II: lis_solve_kernel(A, v[j], r, solver, precon); break; case LIS_ESOLVER_AII: lis_psolve(solver, v[j], r); break; case LIS_ESOLVER_RQI: lis_vector_nrm2(v[j], &nrm2); lis_vector_scale(1/nrm2, v[j]); lis_matrix_shift_diagonal(A, -mu); lis_solve_kernel(A, v[j], r, solver, precon); lis_matrix_shift_diagonal(A, mu); break; } if ( j==1 && ( niesolver==LIS_ESOLVER_II || niesolver==LIS_ESOLVER_AII || niesolver==LIS_ESOLVER_RQI )) { 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_vector_nrm2(r, &nrm2); lis_vector_dotex_mmm(v[j], r, &qdot_vr); lis_quad_minus((LIS_QUAD *)qdot_vr.hi); lis_vector_axpyzex_mmmm(qdot_vr,v[j],r,q); lis_quad_minus((LIS_QUAD *)qdot_vr.hi); dotvr = qdot_vr.hi[0]; mu = mu + 1/dotvr; lis_vector_nrm2(q, &resid); resid = fabs(resid / dotvr); lis_vector_scale(1/nrm2,r); lis_vector_copy(r, v[j]); if ( j==1 ) { if( output & LIS_PRINT_MEM ) esolver->residual[iter] = resid; if( output & LIS_PRINT_OUT ) printf("iter: %5d residual = %e\n", iter, resid); esolver->iter = iter; esolver->resid = resid; } if (tol>resid) break; } if (niesolver==LIS_ESOLVER_II || niesolver==LIS_ESOLVER_RQI) { lis_precon_destroy(precon); } switch ( niesolver ) { case LIS_ESOLVER_PI: esolver->evalue[j-1] = dotvr; break; case LIS_ESOLVER_II: esolver->evalue[j-1] = 1/dotvr; break; case LIS_ESOLVER_AII: esolver->evalue[j-1] = 1/dotvr; break; case LIS_ESOLVER_RQI: esolver->evalue[j-1] = mu; break; } lis_vector_copy(v[j], esolver->evector[j-1]); if (A->my_rank==0 && ss>1) { #ifdef _LONGLONG printf("Subspace: mode number = %lld\n", j-1); #else printf("Subspace: mode number = %d\n", j-1); #endif printf("Subspace: eigenvalue = %e\n", esolver->evalue[j-1]); #ifdef _LONGLONG printf("Subspace: number of iterations = %lld\n",iter); #else printf("Subspace: number of iterations = %d\n",iter); #endif printf("Subspace: relative residual 2-norm = %e\n",resid); } } lis_vector_copy(esolver->evector[esolver->options[LIS_EOPTIONS_MODE]], esolver->x); switch ( niesolver ) { case LIS_ESOLVER_II: if (lshift != 0) lis_matrix_shift_diagonal(A, -lshift); lis_solver_destroy(solver); break; case LIS_ESOLVER_AII: if (lshift != 0) lis_matrix_shift_diagonal(A, -lshift); lis_precon_destroy(precon); lis_solver_destroy(solver); break; case LIS_ESOLVER_RQI: if (lshift != 0) lis_matrix_shift_diagonal(A, -lshift); lis_solver_destroy(solver); break; } LIS_DEBUG_FUNC_OUT; return LIS_SUCCESS; }
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; } }
int solveLis(DATA *data, threadData_t *threadData, int sysNumber) { void *dataAndThreadData[2] = {data, threadData}; LINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo->linearSystemData[sysNumber]); DATA_LIS* solverData = (DATA_LIS*)systemData->solverData; int i, ret, success = 1, ni, iflag = 1, n = systemData->size, eqSystemNumber = systemData->equationIndex; char *lis_returncode[] = {"LIS_SUCCESS", "LIS_ILL_OPTION", "LIS_BREAKDOWN", "LIS_OUT_OF_MEMORY", "LIS_MAXITER", "LIS_NOT_IMPLEMENTED", "LIS_ERR_FILE_IO"}; LIS_INT err; int indexes[2] = {1,eqSystemNumber}; infoStreamPrintWithEquationIndexes(LOG_LS, 0, indexes, "Start solving Linear System %d (size %d) at time %g with Lis Solver", eqSystemNumber, (int) systemData->size, data->localData[0]->timeValue); /* set old values as start value for the iteration */ for(i=0; i<n; i++) { err = lis_vector_set_value(LIS_INS_VALUE, i, systemData->x[i], solverData->x); } rt_ext_tp_tick(&(solverData->timeClock)); if (0 == systemData->method) { lis_matrix_set_size(solverData->A, solverData->n_row, 0); /* set A matrix */ systemData->setA(data, threadData, systemData); lis_matrix_assemble(solverData->A); /* set b vector */ systemData->setb(data, threadData, systemData); } else { lis_matrix_set_size(solverData->A, solverData->n_row, 0); /* calculate jacobian -> matrix A*/ if(systemData->jacobianIndex != -1) { getAnalyticalJacobianLis(data, threadData, sysNumber); } else { assertStreamPrint(threadData, 1, "jacobian function pointer is invalid" ); } lis_matrix_assemble(solverData->A); /* calculate vector b (rhs) */ memcpy(solverData->work, systemData->x, sizeof(double)*solverData->n_row); wrapper_fvec_lis(solverData->work, systemData->b, dataAndThreadData, sysNumber); /* set b vector */ for(i=0; i<n; i++) { err = lis_vector_set_value(LIS_INS_VALUE, i, systemData->b[i], solverData->b); } } infoStreamPrint(LOG_LS, 0, "### %f time to set Matrix A and vector b.", rt_ext_tp_tock(&(solverData->timeClock))); rt_ext_tp_tick(&(solverData->timeClock)); err = lis_solve(solverData->A,solverData->b,solverData->x,solverData->solver); infoStreamPrint(LOG_LS, 0, "Solve System: %f", rt_ext_tp_tock(&(solverData->timeClock))); if (err) { warningStreamPrint(LOG_LS_V, 0, "lis_solve : %s(code=%d)\n\n ", lis_returncode[err], err); printLisMatrixCSR(solverData->A, solverData->n_row); success = 0; } /* Log A*x=b */ if(ACTIVE_STREAM(LOG_LS_V)) { char *buffer = (char*)malloc(sizeof(char)*n*25); printLisMatrixCSR(solverData->A, n); /* b vector */ infoStreamPrint(LOG_LS_V, 1, "b vector [%d]", n); for(i=0; i<n; i++) { buffer[0] = 0; sprintf(buffer, "%s%20.12g ", buffer, solverData->b->value[i]); infoStreamPrint(LOG_LS_V, 0, "%s", buffer); } messageClose(LOG_LS_V); free(buffer); } /* print solution */ if (1 == success) { if (1 == systemData->method) { /* take the solution */ lis_vector_get_values(solverData->x, 0, solverData->n_row, systemData->x); for(i = 0; i < solverData->n_row; ++i) systemData->x[i] += solverData->work[i]; /* update inner equations */ wrapper_fvec_lis(systemData->x, solverData->work, dataAndThreadData, sysNumber); } else { /* write solution */ lis_vector_get_values(solverData->x, 0, solverData->n_row, systemData->x); } if (ACTIVE_STREAM(LOG_LS_V)) { infoStreamPrint(LOG_LS_V, 1, "Solution x:"); infoStreamPrint(LOG_LS_V, 0, "System %d numVars %d.", eqSystemNumber, modelInfoGetEquation(&data->modelData->modelDataXml,eqSystemNumber).numVar); for(i = 0; i < systemData->size; ++i) infoStreamPrint(LOG_LS_V, 0, "[%d] %s = %g", i+1, modelInfoGetEquation(&data->modelData->modelDataXml,eqSystemNumber).vars[i], systemData->x[i]); messageClose(LOG_LS_V); } } else { warningStreamPrint(LOG_STDOUT, 0, "Failed to solve linear system of equations (no. %d) at time %f, system status %d.", (int)systemData->equationIndex, data->localData[0]->timeValue, err); } return success; }