104 subroutine diagonalize_slepc (this, matrix_elements, num_eigenpair, dresult, all_procs, option, integrals)
105 class(slepcdiagonalizer) :: this
106 class(diagonalizerresult) :: dresult
107 class(basematrix),
intent(in) :: matrix_elements
108 class(baseintegral),
intent(in) :: integrals
109 type(options),
intent(in) :: option
110 integer,
intent(in) :: num_eigenpair
111 logical,
intent(in) :: all_procs
113 integer :: mat_dimen, number_solved
114 integer(blasint) :: grid_master_context
115 real(wp),
allocatable :: diagonal_temp(:), eigen(:)
117 type(civect) :: eigenvector
124 epsconvergedreason :: conv_reason
125 petscreal :: maxtol,tol, error
126 petscscalar :: kr, ki, current_shift
127 petscscalar,
pointer :: xx_v(:)
129 petscint :: nev, maxit, its, nconv, matrix_size, ido, n
130 petscerrorcode :: ierr
135 maxit = option % max_iterations
136 maxtol = option % max_tolerance
138 if (maxit < 0) maxit = petsc_default_integer
140 matrix_size = matrix_elements % get_matrix_size()
141 mat_dimen = matrix_size
144 write (stdout,
"('-----------WARNING----------------------- ')")
145 write (stdout,
"('When dealing with symmetries that are degenerate SLEPC may give incorrect values')")
146 write (stdout,
"('YOU HAVE BEEN WARNED')")
147 write (stdout,
"('---------------------------------------- ')")
148 write (stdout,
"('N: ',i8)") matrix_size
149 write (stdout,
"('Requested # of eigenpairs',i8)") num_eigenpair
150 write (stdout,
"('Maximum iterations',i8)") maxit
151 write (stdout,
"('Maximum tolerance',es9.2)") maxtol
154 select type(matrix_elements)
155 type is (slepcmatrix)
156 call this % UseSLEPCMat(matrix_elements, a)
157 class is (basematrix)
158 stop
"Matrix format not yet implemented for SLEPC"
163 call matcreatevecs(a, xr, xi, ierr)
166 call vecscattercreatetoall(xr, vsctx, f_xr, ierr)
168 call vecscattercreatetozero(xr, vsctx, f_xr, ierr)
171 call epscreate(int(grid % gcomm, kind(petsc_comm_world)), eps, ierr)
172 call this % SelectEPS(eps)
173 call epssetoperators(eps, a, petsc_null_mat, ierr)
174 call epssetproblemtype(eps, eps_hep, ierr)
207 call epssetdimensions(eps, n, petsc_decide, petsc_decide, ierr)
209 call epssettolerances(eps, maxtol, maxit, ierr)
210 call master_timer % start_timer(
"SLEPC solve")
212 call epssolve(eps, ierr)
214 call mpi_xermsg(
'SLEPCDiagonalizer_module',
'SelectEPS',
'Failed to select eigensolver', int(ierr), 1)
216 call master_timer % stop_timer(
"SLEPC solve")
220 call epsgetiterationnumber(eps, its, ierr)
221 call epsgettolerances(eps, tol, maxit, ierr)
223 if (grid % grank == master)
then
225 write (stdout,
"(('/ Stopping condition: tol=',1P,E11.4,', maxit=',I0,', stopped at it=',I0))") tol, maxit, its
228 call epsgetconverged(eps, nconv, ierr)
230 if (nconv < num_eigenpair)
then
231 write (stdout, *)
'Not all requested eigenpairs have converged!!!!'
232 write (stdout, *)
'Only ', nconv,
' have converged against ', num_eigenpair,
' requested'
233 stop
"Diagoanlization not completed"
236 allocate(eigen(num_eigenpair))
238 do ido = 0, min(nconv, n) - 1
241 call epsgeteigenpair(eps, ido, kr, ki, xr, xi, ierr)
242 eigen(ido + 1) = petscrealpart(kr)
247 call dresult % export_header(option, integrals)
251 if (grid % grank == master)
then
252 call dresult % write_header(option, integrals)
256 if (all_procs .or. grid % grank == master)
then
257 call dresult % handle_eigenvalues(eigen, matrix_elements % diagonal, num_eigenpair, mat_dimen)
264 grid_master_context = grid % gcntxt
265#if defined(usempi) && defined(scalapack)
266 call blacs_gridinit(grid_master_context,
'R', 1_blasint, 1_blasint)
270 eigenvector % blacs_context = grid_master_context
271 eigenvector % CV_is_scalapack = .true.
272 call eigenvector % init_CV(mat_dimen, 1)
275 dresult % ci_vec % blacs_context = grid % gcntxt
276 dresult % ci_vec % CV_is_scalapack = .true.
277 call dresult % ci_vec % init_CV(mat_dimen, num_eigenpair)
281 do ido = 0, min(nconv, n) - 1
284 call epsgeteigenpair(eps, ido, kr, ki, xr, xi, ierr)
294 call vecscatterbegin(vsctx, xr, f_xr, insert_values, scatter_forward, ierr)
295 call vecscatterend(vsctx, xr, f_xr, insert_values, scatter_forward, ierr)
296 if (all_procs .or. grid % grank == master)
then
297 call vecgetarrayread(f_xr, xx_v, ierr)
298 call dresult % handle_eigenvector(xx_v(1:mat_dimen), mat_dimen)
301 if (grid % grank == master)
then
302 eigenvector % CV(1:mat_dimen, 1) = xx_v(1:mat_dimen)
304 call dresult % ci_vec % redistribute(eigenvector, grid % gcntxt, mat_dimen, 1, 1, 1, 1, ido + 1)
306 if (all_procs .or. grid % grank == master)
then
307 call vecrestorearrayread(f_xr, xx_v, ierr)
312 call dresult % export_eigenvalues(eigen(1:num_eigenpair), matrix_elements % diagonal, num_eigenpair, &
313 mat_dimen, dresult % ci_vec % ei, dresult % ci_vec % iphz)
314 write (stdout,
'(/," Eigensolutions exported into the CIVect structure.",/)')
318 if (grid % grank == master)
then
319 call dresult % finalize_solutions(option)
322 call epsdestroy(eps, ierr)
323 call vecdestroy(xr, ierr)
324 call vecdestroy(xi, ierr)