25#include "./base/base_uses.f90"
45 CALL dbcsr_copy(pao%matrix_G_prev, pao%matrix_D)
47 IF (pao%precondition)
THEN
48 CALL dbcsr_copy(pao%matrix_D_preconed, pao%matrix_D)
52 CALL pao_opt_init_bfgs(pao)
60 SUBROUTINE pao_opt_init_bfgs(pao)
63 INTEGER,
DIMENSION(:),
POINTER :: nparams
68 template=pao%matrix_X, &
69 row_blk_size=nparams, &
70 col_blk_size=nparams, &
71 name=
"PAO matrix_BFGS")
77 END SUBROUTINE pao_opt_init_bfgs
88 IF (pao%precondition) &
103 INTEGER,
INTENT(IN) :: icycle
105 CHARACTER(len=*),
PARAMETER :: routinen =
'pao_opt_new_dir'
110 CALL timeset(routinen, handle)
112 IF (pao%precondition)
THEN
115 CALL dbcsr_copy(matrix_g_preconed, pao%matrix_G)
116 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, pao%matrix_precon, pao%matrix_G, &
117 0.0_dp, matrix_g_preconed, retain_sparsity=.true.)
118 CALL pao_opt_new_dir_low(pao, icycle, matrix_g_preconed, pao%matrix_G_prev, pao%matrix_D_preconed)
119 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, pao%matrix_precon, pao%matrix_D_preconed, &
120 0.0_dp, pao%matrix_D, retain_sparsity=.true.)
123 CALL dbcsr_copy(pao%matrix_G_prev, matrix_g_preconed)
126 IF (pao%iw > 0)
WRITE (pao%iw, *)
"PAO| norm of preconditioned gradient:", pao%norm_G
130 CALL pao_opt_new_dir_low(pao, icycle, pao%matrix_G, pao%matrix_G_prev, pao%matrix_D)
131 CALL dbcsr_copy(pao%matrix_G_prev, pao%matrix_G)
133 IF (pao%iw > 0)
WRITE (pao%iw, *)
"PAO| norm of gradient:", pao%norm_G
136 CALL timestop(handle)
148 SUBROUTINE pao_opt_new_dir_low(pao, icycle, matrix_G, matrix_G_prev, matrix_D)
150 INTEGER,
INTENT(IN) :: icycle
151 TYPE(
dbcsr_type) :: matrix_g, matrix_g_prev, matrix_d
153 SELECT CASE (pao%optimizer)
155 CALL pao_opt_newdir_cg(pao, icycle, matrix_g, matrix_g_prev, matrix_d)
157 CALL pao_opt_newdir_bfgs(pao, icycle, matrix_g, matrix_g_prev, matrix_d)
159 cpabort(
"PAO: unknown optimizer")
162 END SUBROUTINE pao_opt_new_dir_low
172 SUBROUTINE pao_opt_newdir_cg(pao, icycle, matrix_G, matrix_G_prev, matrix_D)
174 INTEGER,
INTENT(IN) :: icycle
175 TYPE(
dbcsr_type) :: matrix_g, matrix_g_prev, matrix_d
177 REAL(kind=
dp) :: beta, change, trace_d, trace_d_gnew, &
178 trace_g_mix, trace_g_new, trace_g_prev
181 IF (icycle <= pao%cg_init_steps)
THEN
182 IF (pao%iw_opt > 0)
WRITE (pao%iw_opt, *)
"PAO|CG| warming up with steepest descent"
185 CALL dbcsr_dot(matrix_g, matrix_g, trace_g_new)
186 CALL dbcsr_dot(matrix_g_prev, matrix_g_prev, trace_g_prev)
187 CALL dbcsr_dot(matrix_g, matrix_g_prev, trace_g_mix)
188 CALL dbcsr_dot(matrix_d, matrix_g, trace_d_gnew)
189 CALL dbcsr_dot(matrix_d, matrix_d, trace_d)
190 IF (pao%iw_opt > 0)
WRITE (pao%iw_opt, *)
"PAO|CG| trace_G_new ", trace_g_new
191 IF (pao%iw_opt > 0)
WRITE (pao%iw_opt, *)
"PAO|CG| trace_G_prev ", trace_g_prev
192 IF (pao%iw_opt > 0)
WRITE (pao%iw_opt, *)
"PAO|CG| trace_G_mix ", trace_g_mix
193 IF (pao%iw_opt > 0)
WRITE (pao%iw_opt, *)
"PAO|CG| trace_D ", trace_d
194 IF (pao%iw_opt > 0)
WRITE (pao%iw_opt, *)
"PAO|CG| trace_D_Gnew", trace_d_gnew
196 IF (trace_g_prev /= 0.0_dp)
THEN
197 beta = (trace_g_new - trace_g_mix)/trace_g_prev
200 IF (beta < 0.0_dp)
THEN
201 IF (pao%iw_opt > 0)
WRITE (pao%iw_opt, *)
"PAO|CG| resetting because beta < 0"
205 change = trace_d_gnew**2/trace_d*trace_g_new
206 IF (change > pao%cg_reset_limit)
THEN
207 IF (pao%iw_opt > 0)
WRITE (pao%iw_opt, *)
"PAO|CG| resetting because change > CG_RESET_LIMIT"
213 IF (pao%iw_opt > 0)
WRITE (pao%iw_opt, *)
"PAO|CG| beta: ", beta
216 CALL dbcsr_add(matrix_d, matrix_g, beta, -1.0_dp)
218 END SUBROUTINE pao_opt_newdir_cg
228 SUBROUTINE pao_opt_newdir_bfgs(pao, icycle, matrix_G, matrix_G_prev, matrix_D)
230 INTEGER,
INTENT(IN) :: icycle
231 TYPE(
dbcsr_type) :: matrix_g, matrix_g_prev, matrix_d
233 CHARACTER(len=*),
PARAMETER :: routinen =
'pao_opt_newdir_bfgs'
236 LOGICAL :: arnoldi_converged
237 REAL(
dp) :: eval_max, eval_min, theta, trace_ry, &
238 trace_sy, trace_yhy, trace_yy
239 TYPE(
dbcsr_type) :: matrix_hy, matrix_hyr, matrix_r, &
240 matrix_rr, matrix_ryh, matrix_ryhyr, &
241 matrix_s, matrix_y, matrix_yr
243 CALL timeset(routinen, handle)
251 CALL dbcsr_add(matrix_y, matrix_g_prev, 1.0_dp, -1.0_dp)
255 CALL dbcsr_scale(matrix_s, pao%linesearch%step_size)
258 CALL dbcsr_dot(matrix_s, matrix_y, trace_sy)
261 IF (icycle == 2)
THEN
262 CALL dbcsr_dot(matrix_y, matrix_y, trace_yy)
263 CALL dbcsr_scale(pao%matrix_BFGS, trace_sy/trace_yy)
264 IF (pao%iw_opt > 0)
WRITE (pao%iw_opt, *)
"PAO|BFGS| Initializing with:", trace_sy/trace_yy
268 CALL dbcsr_create(matrix_hy, template=matrix_g, matrix_type=
"N")
269 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, pao%matrix_BFGS, matrix_y, 0.0_dp, matrix_hy)
272 CALL dbcsr_dot(matrix_y, matrix_hy, trace_yhy)
277 IF (trace_sy < 0.2_dp*trace_yhy)
THEN
278 theta = 0.8_dp*trace_yhy/(trace_yhy - trace_sy)
279 IF (pao%iw_opt > 0)
WRITE (pao%iw_opt, *)
"PAO|BFGS| Dampening theta:", theta
286 CALL dbcsr_add(matrix_r, matrix_hy, theta, (1.0_dp - theta))
289 CALL dbcsr_dot(matrix_r, matrix_y, trace_ry)
290 cpassert(trace_ry > 0.0_dp)
293 CALL dbcsr_create(matrix_yr, template=pao%matrix_BFGS, matrix_type=
"N")
294 CALL dbcsr_multiply(
"N",
"T", 1.0_dp, matrix_y, matrix_r, 0.0_dp, matrix_yr)
297 CALL dbcsr_create(matrix_hyr, template=pao%matrix_BFGS, matrix_type=
"N")
298 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, pao%matrix_BFGS, matrix_yr, 0.0_dp, matrix_hyr)
301 CALL dbcsr_create(matrix_ryh, template=pao%matrix_BFGS, matrix_type=
"N")
302 CALL dbcsr_multiply(
"T",
"N", 1.0_dp, matrix_yr, pao%matrix_BFGS, 0.0_dp, matrix_ryh)
305 CALL dbcsr_create(matrix_ryhyr, template=pao%matrix_BFGS, matrix_type=
"N")
306 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_ryh, matrix_yr, 0.0_dp, matrix_ryhyr)
309 CALL dbcsr_create(matrix_rr, template=pao%matrix_BFGS, matrix_type=
"N")
310 CALL dbcsr_multiply(
"N",
"T", 1.0_dp, matrix_r, matrix_r, 0.0_dp, matrix_rr)
313 CALL dbcsr_add(pao%matrix_BFGS, matrix_hyr, 1.0_dp, -1.0_dp/trace_ry)
314 CALL dbcsr_add(pao%matrix_BFGS, matrix_ryh, 1.0_dp, -1.0_dp/trace_ry)
315 CALL dbcsr_add(pao%matrix_BFGS, matrix_ryhyr, 1.0_dp, +1.0_dp/(trace_ry**2))
316 CALL dbcsr_add(pao%matrix_BFGS, matrix_rr, 1.0_dp, +1.0_dp/trace_ry)
333 threshold=1e-2_dp, converged=arnoldi_converged)
334 IF (arnoldi_converged)
THEN
335 IF (pao%iw_opt > 0)
WRITE (pao%iw_opt, *)
"PAO|BFGS| evals of inv. Hessian: min, max, max/min", &
336 eval_min, eval_max, eval_max/eval_min
338 IF (pao%iw_opt > 0)
WRITE (pao%iw_opt, *)
"PAO|BFGS| arnoldi of inv. Hessian did not converged."
343 CALL dbcsr_multiply(
"N",
"N", -1.0_dp, pao%matrix_BFGS, matrix_g, &
344 0.0_dp, matrix_d, retain_sparsity=.true.)
346 CALL timestop(handle)
347 END SUBROUTINE pao_opt_newdir_bfgs
arnoldi iteration using dbcsr
subroutine, public arnoldi_extremal(matrix_a, max_ev, min_ev, converged, threshold, max_iter)
simple wrapper to estimate extremal eigenvalues with arnoldi, using the old lanczos interface this hi...
subroutine, public dbcsr_scale(matrix, alpha_scalar)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_multiply(transa, transb, alpha, matrix_a, matrix_b, beta, matrix_c, first_row, last_row, first_column, last_column, first_k, last_k, retain_sparsity, filter_eps, flop)
...
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
subroutine, public dbcsr_add_on_diag(matrix, alpha)
Adds the given scalar to the diagonal of the matrix. Reserves any missing diagonal blocks.
real(dp) function, public dbcsr_frobenius_norm(matrix)
Compute the frobenius norm of a dbcsr matrix.
subroutine, public dbcsr_dot(matrix_a, matrix_b, trace)
Computes the dot product of two matrices, also known as the trace of their matrix product.
subroutine, public dbcsr_reserve_diag_blocks(matrix)
Reserves all diagonal blocks.
Defines the basic variable types.
integer, parameter, public dp
Optimizers used by pao_main.F.
subroutine, public pao_opt_init(pao)
Initialize the optimizer.
subroutine, public pao_opt_finalize(pao)
Finalize the optimizer.
subroutine, public pao_opt_new_dir(pao, icycle)
Calculates the new search direction.
Types used by the PAO machinery.