10
0
mirror of https://github.com/LCPQ/quantum_package synced 2024-07-04 10:25:58 +02:00
quantum_package/plugins/dress_zmq/dress_stoch_routines.irp.f

533 lines
15 KiB
Fortran
Raw Normal View History

2018-08-29 20:54:58 +02:00
BEGIN_PROVIDER [ integer, dress_stoch_istate ]
2017-12-15 16:21:04 +01:00
implicit none
2018-08-29 20:54:58 +02:00
dress_stoch_istate = 1
END_PROVIDER
BEGIN_PROVIDER [ integer, pt2_N_teeth ]
&BEGIN_PROVIDER [ integer, pt2_minDetInFirstTeeth ]
&BEGIN_PROVIDER [ integer, pt2_n_tasks_max ]
&BEGIN_PROVIDER [ integer, pt2_F, (N_det_generators) ]
implicit none
pt2_F(:) = 1
pt2_F(:N_det_generators/100 + 1) = 1
pt2_n_tasks_max = N_det_generators/100 + 1
if(N_det_generators < 256) then
pt2_minDetInFirstTeeth = 1
pt2_N_teeth = 1
else
pt2_minDetInFirstTeeth = 5
pt2_N_teeth = 16
end if
2017-12-15 16:21:04 +01:00
END_PROVIDER
2018-08-29 20:54:58 +02:00
BEGIN_PROVIDER [ integer, dress_N_cp_max ]
dress_N_cp_max = 100
END_PROVIDER
BEGIN_PROVIDER[ integer, dress_M_m, (dress_N_cp_max)]
implicit none
integer :: i
do i=1,dress_N_cp_max-1
dress_M_m(i) = N_det_generators * i / (dress_N_cp_max+1)
end do
dress_M_m(1) = 1
dress_M_m(dress_N_cp_max) = N_det_generators+1
END_PROVIDER
BEGIN_PROVIDER[ integer, pt2_J, (N_det_generators)]
&BEGIN_PROVIDER[ double precision, pt2_u, (N_det_generators)]
&BEGIN_PROVIDER[ integer, dress_R, (0:N_det_generators)]
&BEGIN_PROVIDER[ integer, dress_R1, (0:N_det_generators)]
&BEGIN_PROVIDER[ double precision, dress_M_mi, (dress_N_cp_max, N_det_generators+1)]
&BEGIN_PROVIDER [ integer, dress_P, (N_det_generators) ]
&BEGIN_PROVIDER [ integer, dress_T, (N_det_generators) ]
&BEGIN_PROVIDER [ integer, dress_N_cp ]
implicit none
integer :: N_c, N_j, U, t, i, m
double precision :: v
double precision, allocatable :: tilde_M(:)
logical, allocatable :: d(:)
integer, external :: dress_find_sample
allocate(d(N_det_generators), tilde_M(N_det_generators))
dress_M_mi = 0d0
tilde_M = 0d0
dress_R(:) = 0
dress_R1(:) = 0
N_c = 0
N_j = pt2_n_0(1)
d(:) = .false.
do i=1,N_j
d(i) = .true.
pt2_J(i) = i
end do
call random_seed(put=(/3211,64,6566,321,65,321,654,65,321,6321,654,65,321,621,654,65,321,65,654,65,321,65/))
call RANDOM_NUMBER(pt2_u)
call RANDOM_NUMBER(pt2_u)
U = 0
m = 1
do while(N_j < N_det_generators)
!ADD_COMB
N_c += 1
do t=0, pt2_N_teeth-1
v = pt2_u_0 + pt2_W_T * (dble(t) + pt2_u(N_c))
i = dress_find_sample(v, pt2_cW)
tilde_M(i) += 1d0
if(.not. d(i)) then
N_j += 1
pt2_J(N_j) = i
d(i) = .true.
end if
end do
!FILL_TOOTH
do while(U < N_det_generators)
U += 1
if(.not. d(U)) then
N_j += 1
pt2_J(N_j) = U
d(U) = .true.
exit;
end if
end do
if(N_c == dress_M_m(m)) then
dress_R1(m) = N_j
dress_R(N_j) = N_c
dress_M_mi(m, :N_det_generators) = tilde_M(:)
m += 1
end if
enddo
dress_N_cp = m-1
dress_R1(dress_N_cp) = N_j
!!!!!!!!!!!!!!
do m=1,dress_N_cp
do i=dress_R1(m-1)+1, dress_R1(m)
dress_P(pt2_J(i)) = m
end do
end do
do i=1, pt2_n_0(1)
dress_T(i) = 0
end do
do t=2,pt2_N_teeth+1
do i=pt2_n_0(t-1)+1, pt2_n_0(t)
dress_T(i) = t-1
end do
end do
!!!!!!!!!!!!!
END_PROVIDER
! BEGIN_PROVIDER [double precision, dress_e, (N_det_generators, dress_N_cp)]
!&BEGIN_PROVIDER [integer, dress_dot_t, (0:dress_N_cp)]
!&BEGIN_PROVIDER [integer, dress_dot_n_0, (0:dress_N_cp)]
! implicit none
! dress_e(:,:) = 1d0
! dress_dot_t(:) = 0
! dress_dot_n_0(:) = 0
!
! integer :: U, m, t, i
!
! U = pt2_n_0(1)+1
!
! do m=1,dress_N_cp
! do while(dress_M_mi(m, U) /= 0d0)
! U = U+1
! end do
! dress_dot_t(m) = pt2_N_teeth + 1
! dress_dot_n_0(m) = N_det_generators
!!
! do t = 2, pt2_N_teeth+1
! if(U <= pt2_n_0(t)) then
! dress_dot_t(m) = t-1
! dress_dot_n_0(m) = pt2_n_0(t-1)
! exit
! end if
! end do
! do t=dress_dot_t(m), pt2_N_teeth
! do i=pt2_n_0(t)+1, pt2_n_0(t+1)
! dress_e(i,m) = pt2_W_T * dress_M_mi(m,i) / pt2_w(i)
! end do
! end do
! end do
! do m=dress_N_cp, 2, -1
! dress_e(:,m) -= dress_e(:,m-1)
! end do
!END_PROVIDER
subroutine ZMQ_dress(E, dress, delta_out, delta_s2_out, relative_error)
2017-12-15 16:21:04 +01:00
use f77_zmq
implicit none
character(len=64000) :: task
integer(ZMQ_PTR) :: zmq_to_qp_run_socket, zmq_socket_pull
integer, external :: omp_get_thread_num
2018-03-05 17:04:26 +01:00
double precision, intent(in) :: E(N_states), relative_error
2017-12-15 16:21:04 +01:00
double precision, intent(out) :: dress(N_states)
2018-03-23 13:37:03 +01:00
double precision, intent(out) :: delta_out(N_states, N_det)
double precision, intent(out) :: delta_s2_out(N_states, N_det)
2017-12-15 16:21:04 +01:00
2018-03-23 13:37:03 +01:00
double precision, allocatable :: delta(:,:)
double precision, allocatable :: delta_s2(:,:)
2017-12-15 16:21:04 +01:00
integer :: i, j, k, Ncp
2018-03-05 17:04:26 +01:00
integer, external :: add_task_to_taskserver
double precision :: state_average_weight_save(N_states)
2018-04-27 12:41:39 +02:00
task(:) = CHAR(0)
2018-05-17 16:02:51 +02:00
allocate(delta(N_states,N_det), delta_s2(N_states, N_det))
2018-03-05 17:04:26 +01:00
state_average_weight_save(:) = state_average_weight(:)
do dress_stoch_istate=1,N_states
SOFT_TOUCH dress_stoch_istate
state_average_weight(:) = 0.d0
state_average_weight(dress_stoch_istate) = 1.d0
TOUCH state_average_weight
2018-05-17 16:02:51 +02:00
!provide psi_coef_generators
2018-08-29 20:54:58 +02:00
provide nproc mo_bielec_integrals_in_map mo_mono_elec_integral psi_selectors
2018-05-17 16:02:51 +02:00
!print *, dress_e0_denominator
2018-03-05 17:04:26 +01:00
print *, '========== ================= ================= ================='
print *, ' Samples Energy Stat. Error Seconds '
print *, '========== ================= ================= ================='
2018-05-17 16:02:51 +02:00
2018-03-05 17:04:26 +01:00
call new_parallel_job(zmq_to_qp_run_socket,zmq_socket_pull, 'dress')
integer, external :: zmq_put_psi
integer, external :: zmq_put_N_det_generators
integer, external :: zmq_put_N_det_selectors
integer, external :: zmq_put_dvector
integer, external :: zmq_set_running
2018-05-17 16:02:51 +02:00
2018-03-05 17:04:26 +01:00
if (zmq_put_psi(zmq_to_qp_run_socket,1) == -1) then
stop 'Unable to put psi on ZMQ server'
endif
if (zmq_put_N_det_generators(zmq_to_qp_run_socket, 1) == -1) then
stop 'Unable to put N_det_generators on ZMQ server'
endif
if (zmq_put_N_det_selectors(zmq_to_qp_run_socket, 1) == -1) then
stop 'Unable to put N_det_selectors on ZMQ server'
endif
if (zmq_put_dvector(zmq_to_qp_run_socket,1,'energy',dress_e0_denominator,size(dress_e0_denominator)) == -1) then
stop 'Unable to put energy on ZMQ server'
endif
2018-05-17 16:02:51 +02:00
if (zmq_put_dvector(zmq_to_qp_run_socket,1,"state_average_weight",state_average_weight,N_states) == -1) then
stop 'Unable to put state_average_weight on ZMQ server'
endif
if (zmq_put_dvector(zmq_to_qp_run_socket,1,"dress_stoch_istate",real(dress_stoch_istate,8),1) == -1) then
stop 'Unable to put dress_stoch_istate on ZMQ server'
endif
2018-03-05 17:04:26 +01:00
integer(ZMQ_PTR), external :: new_zmq_to_qp_run_socket
2018-08-29 20:54:58 +02:00
do i=1,N_det_generators
do j=1,pt2_F(i) !!!!!!!!!!!!
write(task(1:20),'(I9,1X,I9''|'')') j, pt2_J(i)
if (add_task_to_taskserver(zmq_to_qp_run_socket,trim(task(1:20))) == -1) then
stop 'Unable to add task to task server'
endif
end do
2018-03-05 17:04:26 +01:00
end do
if (zmq_set_running(zmq_to_qp_run_socket) == -1) then
print *, irp_here, ': Failed in zmq_set_running'
endif
2018-04-30 13:25:58 +02:00
!!$OMP PARALLEL DEFAULT(shared) NUM_THREADS(nproc) &
! !$OMP PRIVATE(i)
!i = omp_get_thread_num()
!if (i==0) then
2018-03-05 17:04:26 +01:00
call dress_collector(zmq_socket_pull,E, relative_error, delta, delta_s2, dress,&
2018-05-17 16:02:51 +02:00
dress_stoch_istate)
2018-04-30 13:25:58 +02:00
!else
! call dress_slave_inproc(i)
!endif
!!$OMP END PARALLEL
2018-03-23 13:37:03 +01:00
delta_out(dress_stoch_istate,1:N_det) = delta(dress_stoch_istate,1:N_det)
2018-05-17 16:02:51 +02:00
delta_s2_out(dress_stoch_istate,1:N_det) = delta_s2(dress_stoch_istate,1:N_det)
2018-03-05 17:04:26 +01:00
call end_parallel_job(zmq_to_qp_run_socket, zmq_socket_pull, 'dress')
print *, '========== ================= ================= ================='
enddo
FREE dress_stoch_istate
state_average_weight(:) = state_average_weight_save(:)
TOUCH state_average_weight
2018-03-23 13:37:03 +01:00
deallocate(delta,delta_s2)
2017-12-15 16:21:04 +01:00
end subroutine
subroutine dress_slave_inproc(i)
implicit none
integer, intent(in) :: i
2018-03-05 17:04:26 +01:00
2017-12-15 16:21:04 +01:00
call run_dress_slave(1,i,dress_e0_denominator)
end
2018-08-29 20:54:58 +02:00
BEGIN_PROVIDER [double precision, dress_e, (N_det_generators, dress_N_cp)]
&BEGIN_PROVIDER [integer, dress_dot_t, (0:dress_N_cp)]
&BEGIN_PROVIDER [integer, dress_dot_n_0, (0:dress_N_cp)]
&BEGIN_PROVIDER [integer, dress_dot_F, (dress_N_cp)]
implicit none
logical, allocatable :: d(:)
integer :: U, m, t, i
allocate(d(N_det_generators+1))
dress_e(:,:) = 1d0
dress_dot_t(:) = 0
dress_dot_n_0(:) = 0
dress_dot_F = 0
d(:) = .false.
U=0
do m=1,dress_N_cp
do i=dress_R1(m-1)+1,dress_R1(m)
dress_dot_F(m) += pt2_F(pt2_J(i))
d(pt2_J(i)) = .true.
end do
do while(d(U+1))
U += 1
end do
dress_dot_t(m) = pt2_N_teeth + 1
dress_dot_n_0(m) = N_det_generators
do t = 2, pt2_N_teeth+1
if(U < pt2_n_0(t)) then
dress_dot_t(m) = t-1
dress_dot_n_0(m) = pt2_n_0(t-1)
exit
end if
end do
do t=dress_dot_t(m), pt2_N_teeth
do i=pt2_n_0(t)+1, pt2_n_0(t+1)
dress_e(i,m) = pt2_W_T * dress_M_mi(m,i) / pt2_w(i)
end do
end do
end do
do m=dress_N_cp, 2, -1
dress_e(:,m) -= dress_e(:,m-1)
end do
END_PROVIDER
2017-12-15 16:21:04 +01:00
2018-03-05 17:04:26 +01:00
subroutine dress_collector(zmq_socket_pull, E, relative_error, delta, delta_s2, dress, istate)
2017-12-15 16:21:04 +01:00
use f77_zmq
use bitmasks
implicit none
integer(ZMQ_PTR), intent(in) :: zmq_socket_pull
2018-03-05 17:04:26 +01:00
integer, intent(in) :: istate
2017-12-15 16:21:04 +01:00
2018-03-05 17:04:26 +01:00
double precision, intent(in) :: relative_error, E(N_states)
2017-12-15 16:21:04 +01:00
double precision, intent(out) :: dress(N_states)
double precision, allocatable :: cp(:,:,:,:)
double precision, intent(out) :: delta(N_states, N_det)
double precision, intent(out) :: delta_s2(N_states, N_det)
2018-08-29 20:54:58 +02:00
double precision, allocatable :: breve_delta_m(:,:,:), S(:), S2(:)
double precision, allocatable :: edI(:,:), edI_task(:,:)
integer, allocatable :: edI_index(:)
2017-12-15 16:21:04 +01:00
integer(ZMQ_PTR),external :: new_zmq_to_qp_run_socket
integer(ZMQ_PTR) :: zmq_to_qp_run_socket
2018-08-30 10:58:17 +02:00
integer(ZMQ_PTR), external :: new_zmq_pull_socket, zmq_abort
2017-12-15 16:21:04 +01:00
integer :: more
2018-08-29 20:54:58 +02:00
integer :: i, c, j, k, f, t, m, p, m_task
integer :: task_id, n_tasks
double precision :: E0, error, x, v, time, time0
double precision :: avg, eqt
2017-12-15 16:21:04 +01:00
double precision, external :: omp_get_wtime
2018-08-29 20:54:58 +02:00
integer, allocatable :: dot_f(:)
integer, external :: zmq_delete_tasks, dress_find_sample
2018-08-30 10:58:17 +02:00
2017-12-15 16:21:04 +01:00
delta = 0d0
delta_s2 = 0d0
2018-08-29 20:54:58 +02:00
allocate(cp(N_states, N_det, dress_N_cp, 2), edI(N_states, N_det))
allocate(edI_task(N_states, N_det), edI_index(N_det))
allocate(breve_delta_m(N_states, N_det, 2))
allocate(dot_f(dress_N_cp))
allocate(S(pt2_N_teeth+1), S2(pt2_N_teeth+1))
2018-08-30 10:07:02 +02:00
edI = 0d0
2018-08-29 20:54:58 +02:00
2017-12-15 16:21:04 +01:00
cp = 0d0
2018-08-29 20:54:58 +02:00
dot_f(:) = dress_dot_F(:)
2017-12-15 16:21:04 +01:00
zmq_to_qp_run_socket = new_zmq_to_qp_run_socket()
more = 1
2018-08-29 20:54:58 +02:00
m = 1
c = 0
S(:) = 0d0
S2(:) = 0d0
time0 = omp_get_wtime()
2018-08-30 10:58:17 +02:00
more = 1
do while (m <= dress_N_cp .and. more == 1)
2018-08-29 20:54:58 +02:00
if(dot_f(m) == 0) then
E0 = 0
do i=dress_dot_n_0(m),1,-1
E0 += edI(dress_stoch_istate, i)
end do
2018-08-29 20:54:58 +02:00
do while(c < dress_M_m(m))
c = c+1
x = 0d0
do p=pt2_N_teeth, 1, -1
v = pt2_u_0 + pt2_W_T * (pt2_u(c) + dble(p-1))
i = dress_find_sample(v, pt2_cW)
x += edI(dress_stoch_istate, i) * pt2_W_T / pt2_w(i)
S(p) += x
S2(p) += x**2
end do
2017-12-15 16:21:04 +01:00
end do
2018-08-29 20:54:58 +02:00
t = dress_dot_t(m)
avg = S(t) / dble(c)
eqt = (S2(t) / c) - (S(t)/c)**2
eqt = sqrt(eqt / dble(c-1))
error = eqt
time = omp_get_wtime()
print '(G10.3, 2X, F16.10, 2X, G16.3, 2X, F16.4, A20)', c, avg+E0+E(dress_stoch_istate), eqt, time-time0, ''
2018-08-30 10:58:17 +02:00
m += 1
if(eqt < relative_error) then
if (zmq_abort(zmq_to_qp_run_socket) == -1) then
call sleep(1)
if (zmq_abort(zmq_to_qp_run_socket) == -1) then
print *, irp_here, ': Error in sending abort signal (2)'
endif
endif
end if
2018-08-29 20:54:58 +02:00
else
task_id = 0
do
call pull_dress_results(zmq_socket_pull, m_task, f, edI_task, edI_index, breve_delta_m, task_id, n_tasks)
if(task_id == 0) exit
if (zmq_delete_tasks(zmq_to_qp_run_socket,zmq_socket_pull,task_id,n_tasks,more) == -1) then
stop 'Unable to delete tasks'
endif
2017-12-15 16:21:04 +01:00
end do
2018-08-29 20:54:58 +02:00
do i=1,n_tasks
2018-08-30 10:07:02 +02:00
edI(:, edI_index(i)) += edI_task(:, i)
2018-08-29 20:54:58 +02:00
end do
cp(:,:,m_task,1) += breve_delta_m(:,:,1)
cp(:,:,m_task,2) += breve_delta_m(:,:,2)
2018-08-29 20:54:58 +02:00
dot_f(m_task) -= f
2017-12-15 16:21:04 +01:00
end if
2018-08-29 20:54:58 +02:00
end do
2017-12-15 16:21:04 +01:00
2018-08-29 20:54:58 +02:00
delta(:,:) = cp(:,:,m-1,1)
delta_s2(:,:) = cp(:,:,m-1,2)
2018-05-14 13:00:04 +02:00
dress(istate) = E(istate)+E0+avg
2017-12-15 16:21:04 +01:00
call end_zmq_to_qp_run_socket(zmq_to_qp_run_socket)
end subroutine
2018-08-29 20:54:58 +02:00
integer function dress_find_sample(v, w)
2017-12-15 16:21:04 +01:00
implicit none
2018-08-29 20:54:58 +02:00
double precision, intent(in) :: v, w(0:N_det_generators)
2017-12-15 16:21:04 +01:00
integer :: i,l,h
integer, parameter :: block=64
2018-08-29 20:54:58 +02:00
l = 0
h = N_det_generators
2017-12-15 16:21:04 +01:00
do while(h-l >= block)
i = ishft(h+l,-1)
if(w(i+1) > v) then
h = i-1
else
l = i+1
end if
end do
!DIR$ LOOP COUNT (64)
2018-08-29 20:54:58 +02:00
do dress_find_sample=l,h
if(w(dress_find_sample) >= v) then
2017-12-15 16:21:04 +01:00
exit
end if
end do
end function
2018-08-29 20:54:58 +02:00
BEGIN_PROVIDER [ double precision, pt2_w, (N_det_generators) ]
&BEGIN_PROVIDER [ double precision, pt2_cW, (0:N_det_generators) ]
&BEGIN_PROVIDER [ double precision, pt2_W_T ]
&BEGIN_PROVIDER [ double precision, pt2_u_0 ]
&BEGIN_PROVIDER [ integer, pt2_n_0, (pt2_N_teeth+1) ]
2017-12-15 16:21:04 +01:00
implicit none
2018-08-29 20:54:58 +02:00
integer :: i, t
double precision, allocatable :: tilde_w(:), tilde_cW(:)
double precision :: r, tooth_width
integer, external :: dress_find_sample
2017-12-15 16:21:04 +01:00
2018-08-29 20:54:58 +02:00
allocate(tilde_w(N_det_generators), tilde_cW(0:N_det_generators))
2017-12-15 16:21:04 +01:00
2018-08-29 20:54:58 +02:00
tilde_cW(0) = 0d0
2017-12-15 16:21:04 +01:00
do i=1,N_det_generators
2018-08-29 20:54:58 +02:00
tilde_w(i) = psi_coef_generators(i,dress_stoch_istate)**2
tilde_cW(i) = tilde_cW(i-1) + tilde_w(i)
2017-12-15 16:21:04 +01:00
enddo
2018-08-29 20:54:58 +02:00
pt2_n_0(1) = 0
do
pt2_u_0 = tilde_cW(pt2_n_0(1))
r = tilde_cW(pt2_n_0(1) + pt2_minDetInFirstTeeth)
pt2_W_T = (1d0 - pt2_u_0) / dble(pt2_N_teeth)
if(pt2_W_T >= r - pt2_u_0) then
2017-12-15 16:21:04 +01:00
exit
end if
2018-08-29 20:54:58 +02:00
pt2_n_0(1) += 1
if(N_det_generators - pt2_n_0(1) < pt2_minDetInFirstTeeth * pt2_N_teeth) then
stop "teeth building failed"
end if
2017-12-15 16:21:04 +01:00
end do
2018-08-29 20:54:58 +02:00
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
do t=2, pt2_N_teeth
r = pt2_u_0 + pt2_W_T * dble(t-1)
pt2_n_0(t) = dress_find_sample(r, tilde_cW)
end do
pt2_n_0(pt2_N_teeth+1) = N_det_generators
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
pt2_w(:pt2_n_0(1)) = tilde_w(:pt2_n_0(1))
do t=1, pt2_N_teeth
tooth_width = tilde_cW(pt2_n_0(t+1)) - tilde_cW(pt2_n_0(t))
do i=pt2_n_0(t)+1, pt2_n_0(t+1)
pt2_w(i) = tilde_w(i) * pt2_W_T / tooth_width
end do
2017-12-15 16:21:04 +01:00
end do
2018-08-29 20:54:58 +02:00
pt2_cW(0) = 0d0
2017-12-15 16:21:04 +01:00
do i=1,N_det_generators
2018-08-29 20:54:58 +02:00
pt2_cW(i) = pt2_cW(i-1) + pt2_w(i)
2017-12-15 16:21:04 +01:00
end do
2018-08-29 20:54:58 +02:00
pt2_n_0(pt2_N_teeth+1) = N_det_generators
2017-12-15 16:21:04 +01:00
END_PROVIDER