2014-05-13 13:57:58 +02:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
|
|
import os
|
|
|
|
file = open(os.environ["QPACKAGE_ROOT"]+'/src/Dets/H_apply_template.f','r')
|
|
|
|
template = file.read()
|
|
|
|
file.close()
|
|
|
|
|
|
|
|
keywords = """
|
|
|
|
subroutine
|
|
|
|
parameters
|
2014-05-25 01:18:41 +02:00
|
|
|
params_main
|
2014-05-13 13:57:58 +02:00
|
|
|
initialization
|
|
|
|
declarations
|
2014-05-25 01:18:41 +02:00
|
|
|
decls_main
|
2014-05-24 02:39:18 +02:00
|
|
|
keys_work
|
2014-05-25 01:18:41 +02:00
|
|
|
copy_buffer
|
2014-05-13 13:57:58 +02:00
|
|
|
finalization
|
2014-05-25 01:18:41 +02:00
|
|
|
generate_psi_guess
|
2014-05-13 13:57:58 +02:00
|
|
|
""".split()
|
|
|
|
|
2014-05-17 14:20:55 +02:00
|
|
|
class H_apply(object):
|
|
|
|
|
|
|
|
def __init__(self,sub,openmp=True):
|
|
|
|
s = {}
|
2014-05-13 13:57:58 +02:00
|
|
|
for k in keywords:
|
|
|
|
s[k] = ""
|
2014-05-17 14:20:55 +02:00
|
|
|
s["subroutine"] = "H_apply_%s"%(sub)
|
2014-05-25 01:18:41 +02:00
|
|
|
s["params_post"] = ""
|
2014-05-17 14:20:55 +02:00
|
|
|
self.openmp = openmp
|
2014-05-21 16:37:54 +02:00
|
|
|
|
|
|
|
self.selection_pt2 = None
|
2014-05-17 14:20:55 +02:00
|
|
|
self.perturbation = None
|
2014-05-21 16:37:54 +02:00
|
|
|
|
2014-05-13 13:57:58 +02:00
|
|
|
#s["omp_parallel"] = """!$OMP PARALLEL DEFAULT(NONE) &
|
|
|
|
s["omp_parallel"] = """!$OMP PARALLEL DEFAULT(SHARED) &
|
|
|
|
!$OMP PRIVATE(i,j,k,l,keys_out,hole,particle, &
|
|
|
|
!$OMP occ_particle,occ_hole,j_a,k_a,other_spin, &
|
2014-05-26 13:09:32 +02:00
|
|
|
!$OMP hole_save,ispin,jj,l_a, &
|
2014-05-13 13:57:58 +02:00
|
|
|
!$OMP accu,i_a,hole_tmp,particle_tmp,occ_particle_tmp, &
|
|
|
|
!$OMP occ_hole_tmp,key_idx,i_b,j_b,key,N_elec_in_key_part_1,&
|
|
|
|
!$OMP N_elec_in_key_hole_1,N_elec_in_key_part_2, &
|
2014-05-24 02:39:18 +02:00
|
|
|
!$OMP N_elec_in_key_hole_2,ia_ja_pairs,iproc) &
|
2014-05-21 16:37:54 +02:00
|
|
|
!$OMP SHARED(key_in,N_int,elec_num_tab,mo_tot_num, &
|
2014-05-13 13:57:58 +02:00
|
|
|
!$OMP hole_1, particl_1, hole_2, particl_2, &
|
2014-05-27 17:30:44 +02:00
|
|
|
!$OMP thresh,elec_alpha_num,i_generator)"""
|
2014-05-13 13:57:58 +02:00
|
|
|
s["omp_end_parallel"] = "!$OMP END PARALLEL"
|
|
|
|
s["omp_master"] = "!$OMP MASTER"
|
|
|
|
s["omp_end_master"] = "!$OMP END MASTER"
|
|
|
|
s["omp_barrier"] = "!$OMP BARRIER"
|
|
|
|
s["omp_do"] = "!$OMP DO SCHEDULE (static)"
|
|
|
|
s["omp_enddo"] = "!$OMP ENDDO NOWAIT"
|
|
|
|
|
2014-05-25 01:18:41 +02:00
|
|
|
s["keys_work"] += "call fill_H_apply_buffer_no_selection(key_idx,keys_out,N_int,iproc)"
|
|
|
|
|
|
|
|
s["generate_psi_guess"] = """
|
|
|
|
! Sort H_jj to find the N_states lowest states
|
|
|
|
integer :: i,k
|
|
|
|
integer, allocatable :: iorder(:)
|
|
|
|
double precision, allocatable :: H_jj(:)
|
|
|
|
double precision, external :: diag_h_mat_elem
|
|
|
|
allocate(H_jj(N_det),iorder(N_det))
|
|
|
|
!$OMP PARALLEL DEFAULT(NONE) &
|
|
|
|
!$OMP SHARED(psi_det,N_int,H_jj,iorder,N_det) &
|
|
|
|
!$OMP PRIVATE(i)
|
|
|
|
!$OMP DO
|
|
|
|
do i = 1, N_det
|
|
|
|
H_jj(i) = diag_h_mat_elem(psi_det(1,1,i),N_int)
|
|
|
|
iorder(i) = i
|
|
|
|
enddo
|
|
|
|
!$OMP END DO
|
|
|
|
!$OMP END PARALLEL
|
|
|
|
|
|
|
|
call dsort(H_jj,iorder,N_det)
|
|
|
|
do k=1,N_states
|
|
|
|
psi_coef(iorder(k),k) = 1.d0
|
|
|
|
enddo
|
|
|
|
deallocate(H_jj,iorder)
|
|
|
|
"""
|
|
|
|
|
2014-05-13 13:57:58 +02:00
|
|
|
if not openmp:
|
|
|
|
for k in s:
|
|
|
|
s[k] = ""
|
|
|
|
s["size_max"] = str(1024*128)
|
|
|
|
s["set_i_H_j_threshold"] = """
|
|
|
|
thresh = H_apply_threshold
|
|
|
|
"""
|
2014-05-25 01:18:41 +02:00
|
|
|
s["copy_buffer"] = "call copy_h_apply_buffer_to_wf"
|
2014-05-17 14:20:55 +02:00
|
|
|
self.data = s
|
2014-05-13 13:57:58 +02:00
|
|
|
|
2014-05-17 14:20:55 +02:00
|
|
|
def __setitem__(self,key,value):
|
|
|
|
self.data[key] = value
|
2014-05-13 13:57:58 +02:00
|
|
|
|
2014-05-17 14:20:55 +02:00
|
|
|
def __getitem__(self,key):
|
|
|
|
return self.data[key]
|
2014-05-13 13:57:58 +02:00
|
|
|
|
2014-05-17 14:20:55 +02:00
|
|
|
def __repr__(self):
|
2014-05-13 13:57:58 +02:00
|
|
|
buffer = template
|
2014-05-17 14:20:55 +02:00
|
|
|
for key,value in self.data.items():
|
|
|
|
buffer = buffer.replace('$'+key, value)
|
|
|
|
return buffer
|
2014-05-13 13:57:58 +02:00
|
|
|
|
2014-05-17 14:20:55 +02:00
|
|
|
def set_perturbation(self,pert):
|
2014-05-21 16:37:54 +02:00
|
|
|
if self.perturbation is not None:
|
|
|
|
raise
|
2014-05-17 14:20:55 +02:00
|
|
|
self.perturbation = pert
|
|
|
|
if pert is not None:
|
|
|
|
self.data["parameters"] = ",sum_e_2_pert_in,sum_norm_pert_in,sum_H_pert_diag_in,N_st,Nint"
|
|
|
|
self.data["declarations"] = """
|
|
|
|
integer, intent(in) :: N_st,Nint
|
|
|
|
double precision, intent(inout) :: sum_e_2_pert_in(N_st)
|
|
|
|
double precision, intent(inout) :: sum_norm_pert_in(N_st)
|
|
|
|
double precision, intent(inout) :: sum_H_pert_diag_in
|
|
|
|
double precision :: sum_e_2_pert(N_st)
|
|
|
|
double precision :: sum_norm_pert(N_st)
|
|
|
|
double precision :: sum_H_pert_diag
|
2014-05-21 16:37:54 +02:00
|
|
|
double precision :: e_2_pert_buffer(N_st,size_max)
|
|
|
|
double precision :: coef_pert_buffer(N_st,size_max)
|
2014-05-17 14:20:55 +02:00
|
|
|
"""
|
|
|
|
self.data["size_max"] = "256"
|
|
|
|
self.data["initialization"] = """
|
|
|
|
sum_e_2_pert = sum_e_2_pert_in
|
|
|
|
sum_norm_pert = sum_norm_pert_in
|
|
|
|
sum_H_pert_diag = sum_H_pert_diag_in
|
2014-05-27 17:30:44 +02:00
|
|
|
PROVIDE CI_electronic_energy psi_selectors_coef psi_selectors
|
2014-05-17 14:20:55 +02:00
|
|
|
"""
|
2014-05-26 13:09:32 +02:00
|
|
|
self.data["keys_work"] = """
|
2014-05-27 17:30:44 +02:00
|
|
|
call perturb_buffer_%s(i_generator,keys_out,key_idx,e_2_pert_buffer,coef_pert_buffer,sum_e_2_pert, &
|
2014-05-17 14:20:55 +02:00
|
|
|
sum_norm_pert,sum_H_pert_diag,N_st,Nint)
|
|
|
|
"""%(pert,)
|
|
|
|
self.data["finalization"] = """
|
|
|
|
sum_e_2_pert_in = sum_e_2_pert
|
|
|
|
sum_norm_pert_in = sum_norm_pert
|
|
|
|
sum_H_pert_diag_in = sum_H_pert_diag
|
|
|
|
"""
|
2014-05-25 01:18:41 +02:00
|
|
|
self.data["copy_buffer"] = ""
|
|
|
|
self.data["generate_psi_guess"] = ""
|
|
|
|
|
|
|
|
self.data["params_main"] = "pt2, norm_pert, H_pert_diag, N_st"
|
|
|
|
self.data["params_post"] = ","+self.data["params_main"] +", N_int"
|
|
|
|
self.data["decls_main"] = """ integer, intent(in) :: N_st
|
|
|
|
double precision, intent(inout):: pt2(N_st)
|
|
|
|
double precision, intent(inout):: norm_pert(N_st)
|
|
|
|
double precision, intent(inout):: H_pert_diag
|
2014-05-26 13:09:32 +02:00
|
|
|
PROVIDE CI_electronic_energy N_det_generators key_pattern_not_in_ref
|
2014-05-25 01:18:41 +02:00
|
|
|
pt2 = 0.d0
|
|
|
|
norm_pert = 0.d0
|
|
|
|
H_pert_diag = 0.d0
|
|
|
|
"""
|
|
|
|
|
2014-05-17 14:20:55 +02:00
|
|
|
if self.openmp:
|
|
|
|
self.data["omp_parallel"] += """&
|
2014-05-21 16:37:54 +02:00
|
|
|
!$OMP SHARED(N_st,Nint) PRIVATE(e_2_pert_buffer,coef_pert_buffer) &
|
2014-05-17 14:20:55 +02:00
|
|
|
!$OMP REDUCTION(+:sum_e_2_pert, sum_norm_pert, sum_H_pert_diag)"""
|
2014-05-13 13:57:58 +02:00
|
|
|
|
2014-05-21 16:37:54 +02:00
|
|
|
def set_selection_pt2(self,pert):
|
|
|
|
if self.selection_pt2 is not None:
|
|
|
|
raise
|
|
|
|
self.set_perturbation(pert)
|
|
|
|
self.selection_pt2 = pert
|
|
|
|
if pert is not None:
|
|
|
|
self.data["size_max"] = str(1024*128)
|
2014-05-25 01:18:41 +02:00
|
|
|
self.data["copy_buffer"] = """
|
|
|
|
call copy_h_apply_buffer_to_wf
|
|
|
|
selection_criterion_min = selection_criterion_min*0.1d0
|
|
|
|
selection_criterion = selection_criterion_min
|
2014-05-27 00:19:03 +02:00
|
|
|
call remove_small_contributions
|
2014-05-25 01:18:41 +02:00
|
|
|
"""
|
2014-05-24 02:39:18 +02:00
|
|
|
self.data["keys_work"] = """
|
2014-05-21 16:37:54 +02:00
|
|
|
e_2_pert_buffer = 0.d0
|
|
|
|
coef_pert_buffer = 0.d0
|
2014-05-24 02:39:18 +02:00
|
|
|
""" + self.data["keys_work"]
|
|
|
|
self.data["keys_work"] += """
|
|
|
|
call fill_H_apply_buffer_selection(key_idx,keys_out,e_2_pert_buffer,coef_pert_buffer,N_st,N_int,iproc)
|
2014-05-21 16:37:54 +02:00
|
|
|
"""
|
2014-05-13 13:57:58 +02:00
|
|
|
|
|
|
|
|