BEGIN_PROVIDER [ double precision, pt2_match_weight, (N_states) ] implicit none BEGIN_DOC ! Weights adjusted along the selection to make the PT2 contributions ! of each state coincide. END_DOC pt2_match_weight(:) = 1.d0 END_PROVIDER BEGIN_PROVIDER [ double precision, variance_match_weight, (N_states) ] implicit none BEGIN_DOC ! Weights adjusted along the selection to make the variances ! of each state coincide. END_DOC variance_match_weight(:) = 1.d0 END_PROVIDER subroutine update_pt2_and_variance_weights(pt2_data, N_st) implicit none use selection_types BEGIN_DOC ! Updates the PT2- and Variance- matching weights. END_DOC integer, intent(in) :: N_st type(pt2_type), intent(in) :: pt2_data double precision :: pt2(N_st) double precision :: variance(N_st) double precision :: avg, element, dt, x integer :: k integer, save :: i_iter=0 integer, parameter :: i_itermax = 1 double precision, allocatable, save :: memo_variance(:,:), memo_pt2(:,:) pt2(:) = pt2_data % pt2(:) variance(:) = pt2_data % variance(:) if (i_iter == 0) then allocate(memo_variance(N_st,i_itermax), memo_pt2(N_st,i_itermax)) memo_pt2(:,:) = 1.d0 memo_variance(:,:) = 1.d0 endif i_iter = i_iter+1 if (i_iter > i_itermax) then i_iter = 1 endif dt = 2.0d0 avg = sum(pt2(1:N_st)) / dble(N_st) - 1.d-32 ! Avoid future division by zero do k=1,N_st element = exp(dt*(pt2(k)/avg -1.d0)) element = min(2.0d0 , element) element = max(0.5d0 , element) memo_pt2(k,i_iter) = element pt2_match_weight(k) *= product(memo_pt2(k,:)) enddo avg = sum(variance(1:N_st)) / dble(N_st) + 1.d-32 ! Avoid future division by zero do k=1,N_st element = exp(dt*(variance(k)/avg -1.d0)) element = min(2.0d0 , element) element = max(0.5d0 , element) memo_variance(k,i_iter) = element variance_match_weight(k) *= product(memo_variance(k,:)) enddo if (N_det < 100) then ! For tiny wave functions, weights are 1.d0 pt2_match_weight(:) = 1.d0 variance_match_weight(:) = 1.d0 endif threshold_davidson_pt2 = min(1.d-6, & max(threshold_davidson, 1.e-1 * PT2_relative_error * minval(abs(pt2(1:N_states)))) ) SOFT_TOUCH pt2_match_weight variance_match_weight threshold_davidson_pt2 end BEGIN_PROVIDER [ double precision, selection_weight, (N_states) ] implicit none BEGIN_DOC ! Weights used in the selection criterion END_DOC select case (weight_selection) case (0) print *, 'Using input weights in selection' selection_weight(1:N_states) = c0_weight(1:N_states) * state_average_weight(1:N_states) case (1) print *, 'Using 1/c_max^2 weight in selection' selection_weight(1:N_states) = c0_weight(1:N_states) case (2) print *, 'Using pt2-matching weight in selection' selection_weight(1:N_states) = c0_weight(1:N_states) * pt2_match_weight(1:N_states) print *, '# PT2 weight ', real(pt2_match_weight(:),4) case (3) print *, 'Using variance-matching weight in selection' selection_weight(1:N_states) = c0_weight(1:N_states) * variance_match_weight(1:N_states) print *, '# var weight ', real(variance_match_weight(:),4) case (4) print *, 'Using variance- and pt2-matching weights in selection' selection_weight(1:N_states) = c0_weight(1:N_states) * sqrt(variance_match_weight(1:N_states) * pt2_match_weight(1:N_states)) print *, '# PT2 weight ', real(pt2_match_weight(:),4) print *, '# var weight ', real(variance_match_weight(:),4) case (5) print *, 'Using variance-matching weight in selection' selection_weight(1:N_states) = c0_weight(1:N_states) * variance_match_weight(1:N_states) print *, '# var weight ', real(variance_match_weight(:),4) case (6) print *, 'Using CI coefficient-based selection' selection_weight(1:N_states) = c0_weight(1:N_states) case (7) print *, 'Input weights multiplied by variance- and pt2-matching' selection_weight(1:N_states) = c0_weight(1:N_states) * sqrt(variance_match_weight(1:N_states) * pt2_match_weight(1:N_states)) * state_average_weight(1:N_states) print *, '# PT2 weight ', real(pt2_match_weight(:),4) print *, '# var weight ', real(variance_match_weight(:),4) case (8) print *, 'Input weights multiplied by pt2-matching' selection_weight(1:N_states) = c0_weight(1:N_states) * pt2_match_weight(1:N_states) * state_average_weight(1:N_states) print *, '# PT2 weight ', real(pt2_match_weight(:),4) case (9) print *, 'Input weights multiplied by variance-matching' selection_weight(1:N_states) = c0_weight(1:N_states) * variance_match_weight(1:N_states) * state_average_weight(1:N_states) print *, '# var weight ', real(variance_match_weight(:),4) end select print *, '# Total weight ', real(selection_weight(:),4) END_PROVIDER