mrsfmntoia Subroutine

public subroutine mrsfmntoia(infos, fmrsf, pmo, va, vb, ivec)

Uses

  • proc~~mrsfmntoia~~UsesGraph proc~mrsfmntoia mrsfmntoia module~io_constants io_constants proc~mrsfmntoia->module~io_constants module~messages messages proc~mrsfmntoia->module~messages module~precision precision proc~mrsfmntoia->module~precision module~types types proc~mrsfmntoia->module~types module~messages->module~io_constants module~messages->module~precision comm_IOFILE comm_IOFILE module~messages->comm_IOFILE comm_PAR comm_PAR module~messages->comm_PAR iso_fortran_env iso_fortran_env module~precision->iso_fortran_env module~types->module~precision iso_c_binding iso_c_binding module~types->iso_c_binding module~atomic_structure_m atomic_structure_m module~types->module~atomic_structure_m module~basis_tools basis_tools module~types->module~basis_tools module~functionals functionals module~types->module~functionals module~parallel parallel module~types->module~parallel tagarray tagarray module~types->tagarray module~atomic_structure_m->iso_c_binding module~basis_tools->module~io_constants module~basis_tools->module~precision module~basis_tools->iso_fortran_env module~basis_tools->module~atomic_structure_m module~basis_tools->module~parallel module~constants constants module~basis_tools->module~constants module~functionals->module~precision module~functionals->iso_c_binding xc_f03_lib_m xc_f03_lib_m module~functionals->xc_f03_lib_m module~parallel->module~precision module~parallel->iso_c_binding module~parallel->iso_fortran_env mpi mpi module~parallel->mpi module~constants->module~precision

Arguments

Type IntentOptional Attributes Name
type(information), intent(in) :: infos
real(kind=dp), intent(in), target, dimension(:,:,:) :: fmrsf
real(kind=dp), intent(out), dimension(:,:) :: pmo
real(kind=dp), intent(in), dimension(:,:) :: va
real(kind=dp), intent(in), dimension(:,:) :: vb
integer, intent(in) :: ivec

Calls

proc~~mrsfmntoia~~CallsGraph proc~mrsfmntoia mrsfmntoia interface~show_message show_message proc~mrsfmntoia->interface~show_message proc~oqp_dgemm_i64 oqp_dgemm_i64 proc~mrsfmntoia->proc~oqp_dgemm_i64 proc~oqp_dgemv_i64 oqp_dgemv_i64 proc~mrsfmntoia->proc~oqp_dgemv_i64 proc~oqp_dgemm_i64->interface~show_message dgemm dgemm proc~oqp_dgemm_i64->dgemm proc~oqp_dgemv_i64->interface~show_message dgemv dgemv proc~oqp_dgemv_i64->dgemv

Called by

proc~~mrsfmntoia~~CalledByGraph proc~mrsfmntoia mrsfmntoia proc~tdhf_mrsf_energy tdhf_mrsf_energy proc~tdhf_mrsf_energy->proc~mrsfmntoia proc~tdhf_mrsf_energy_c tdhf_mrsf_energy_C proc~tdhf_mrsf_energy_c->proc~tdhf_mrsf_energy

Source Code

   subroutine mrsfmntoia(infos, fmrsf, pmo, va, vb, ivec)

    use precision, only: dp
    use types, only: information
    use messages, only: show_message, with_abort
    use io_constants, only: iw

    implicit none

    type(information), intent(in) :: infos
    real(kind=dp), intent(in), target, dimension(:,:,:) :: &
      fmrsf
    real(kind=dp), intent(out), dimension(:,:) :: pmo
    real(kind=dp), intent(in), dimension(:,:) :: va, vb
    integer, intent(in) :: ivec

    real(kind=dp), allocatable :: &
      scr(:,:), tmp(:), wrk(:,:)
    real(kind=dp), pointer, dimension(:,:) :: &
      adco1, adco2, ado1v, ado2v, agdlr, aco12, ao21v
    integer :: noca, nocb, mrst, i, ij, &
      j, lr1, lr2, nbf, ok
    real(kind=dp), parameter :: zero = 0.0_dp
    real(kind=dp), parameter :: one = 1.0_dp
    real(kind=dp), parameter :: sqrt2 = 1.0_dp/sqrt(2.0_dp)
    logical :: debug_mode

    nbf = infos%basis%nbf
    mrst = infos%tddft%mult
    noca = infos%mol_prop%nelec_a
    nocb = infos%mol_prop%nelec_b
    debug_mode = infos%tddft%debug_mode

    allocate(tmp(nbf), scr(nbf,nbf), wrk(nbf,nbf), source=0.0_dp, stat=ok)
    if (ok /= 0) call show_message('Cannot allocate memory', with_abort)

    agdlr => fmrsf(7,:,:)
    ado2v => fmrsf(1,:,:)
    ado1v => fmrsf(2,:,:)
    adco1 => fmrsf(3,:,:)
    adco2 => fmrsf(4,:,:)
    ao21v => fmrsf(5,:,:)
    aco12 => fmrsf(6,:,:)

    lr1 = noca-1
    lr2 = noca

    call dgemm('t','n',nbf,nbf,nbf, &
               one, va, nbf, &
                    agdlr,nbf, &
               zero, wrk, nbf)
    call dgemm('n','n',nbf,nbf,nbf, &
               one, wrk, nbf, &
                    vb, nbf, &
               zero, scr, nbf)

! 1
!   ----- (m,n) to (i+,n) -----
    wrk = scr

! 3
    call dgemv('n',nbf,nbf,one,ado1v,nbf,vb(:,lr2),1,zero,tmp,1)
    call dgemv('n',nbf,nbf,one,aco12,nbf,vb(:,lr1),1,one,tmp,1)
    do i = 1, noca-2
      wrk(i,lr2) = wrk(i,lr2) + dot_product(va(:,i),tmp(:))
    end do
! 4
    call dgemv('n',nbf,nbf,one,aco12,nbf,vb(:,lr2),1,zero,tmp,1)
    call dgemv('n',nbf,nbf,one,ado2v,nbf,vb(:,lr1),1,-one,tmp,1)
    do i = 1, noca-2
      wrk(i,lr1) = wrk(i,lr1) + dot_product(va(:,i),tmp(:))
    end do
! 5
    call dgemv('t',nbf,nbf,one,adco2,nbf,va(:,lr1),1,zero,tmp,1)
    call dgemv('t',nbf,nbf,one,ao21v,nbf,va(:,lr2),1, one,tmp,1)
    do j = noca+1, nbf
      wrk(lr1,j) = wrk(lr1,j) + dot_product(vb(:,j),tmp(:))
    end do
! 6
    call dgemv('t',nbf,nbf,one,ao21v,nbf,va(:,lr1),1,zero,tmp,1)
    call dgemv('t',nbf,nbf,one,adco1,nbf,va(:,lr2),1,-one,tmp,1)
    do j = noca+1, nbf
       wrk(lr2,j) = wrk(lr2,j) + dot_product(vb(:,j),tmp(:))
    end do

    if (mrst==1) then
      wrk(lr1,lr1) = (scr(lr1,lr1)-scr(lr2,lr2))*sqrt2
      wrk(lr2,lr2) = 0.0_dp
    else if (mrst==3) then
      wrk(lr1,lr1) = (scr(lr1,lr1)+scr(lr2,lr2))*sqrt2
      wrk(lr2,lr1) = 0.0_dp
      wrk(lr1,lr2) = 0.0_dp
      wrk(lr2,lr2) = 0.0_dp
    end if

    pmo(:,ivec) = 0.0_dp

    ij = 0
    do j = nocb+1, nbf
      do i = 1, noca
        ij = ij+1
        pmo(ij,ivec) = pmo(ij,ivec) + wrk(i,j)
      end do
    end do

    if (debug_mode) then
      write(iw,*) 'Check sum = ivec', ivec
      write(iw,*) 'Check sum = agdlr', sum(abs(agdlr))
      write(iw,*) 'Check sum = ao21v', sum(abs(ao21v))
      write(iw,*) 'Check sum = aco12', sum(abs(aco12))
      write(iw,*) 'Check sum = ado2v', sum(abs(ado2v))
      write(iw,*) 'Check sum = ado1v', sum(abs(ado1v))
      write(iw,*) 'Check sum = adco1', sum(abs(adco1))
      write(iw,*) 'Check sum = adco2', sum(abs(adco2))
      write(iw,*) 'Check sum = pmo', sum(abs(pmo(:,ivec)))
    end if

    return

  end subroutine mrsfmntoia