TABLE OF CONTENTS
- ABINIT/m_cplxtools
- m_cplxtools/cplx_addtorho_dpc
- m_cplxtools/cplx_box2gsph_dpc
- m_cplxtools/cplx_box2gsph_spc
- m_cplxtools/cplx_filter
- m_cplxtools/cplx_fromreal
- m_cplxtools/cplx_gsph2box_dpc
- m_cplxtools/cplx_gsph2box_spc
- m_cplxtools/cplx_real_zdotc
- m_cplxtools/cplx_setaug_zero_dpc
- m_cplxtools/cplx_setaug_zero_spc
- m_cplxtools/cplx_zaxpby
- m_cplxtools/cplx_zgemm
- m_cplxtools/cplx_zgemv
ABINIT/m_cplxtools [ Modules ]
NAME
m_cplxtools
FUNCTION
This module defines helper functions to operate on complex arrays (mainly used in the GW code)
COPYRIGHT
Copyright (C) 1992-2024 ABINIT group (MG) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
NOTES
1) The convention about names of interfaced routine is: cplx_<name>, where <name> is equal to the name of the standard BLAS routine
m_cplxtools/cplx_addtorho_dpc [ Functions ]
[ Top ] [ m_cplxtools ] [ Functions ]
NAME
cplx_addtorho_dpc
FUNCTION
Add |ur|**2 to the ground-states density rho. rho = rho + weight_r * |ur|**2
INPUTS
nx,ny,nz=physical dimension of the FFT box. ldx,ldy,ldz=leading dimensions of the arrays. ndat=number of contributions to accumulate. weight_r=weight used for the accumulation of the density in real space ur(ldx,ldy,ldz*ndat)=wavefunctions in real space
SIDE EFFECTS
rho(ldx,ldy,ldz) = contains the input density at input, modified in input with the contribution gived by ur.
SOURCE
1046 subroutine cplx_addtorho_dpc(nx,ny,nz,ldx,ldy,ldz,ndat,weight_r,ur,rho) 1047 1048 !Arguments ------------------------------------ 1049 !scalars 1050 integer,intent(in) :: nx,ny,nz,ldx,ldy,ldz,ndat 1051 real(dp),intent(in) :: weight_r 1052 !arrays 1053 complex(dpc),intent(in) :: ur(ldx*ldy*ldz*ndat) 1054 real(dp),intent(inout) :: rho(ldx*ldy*ldz) 1055 1056 !Local variables------------------------------- 1057 !scalars 1058 integer :: ix,iy,iz,dat,ifft,ldxyz,pad_box,padz,pady 1059 1060 ! ************************************************************************* 1061 1062 ldxyz = ldx*ldy*ldz 1063 1064 if (ndat==1) then 1065 !$OMP PARALLEL DO PRIVATE(padz, pady, ifft) 1066 do iz=1,nz 1067 padz = (iz-1)*ldx*ldy 1068 do iy=1,ny 1069 pady = (iy-1)*ldx 1070 do ix=1,nx 1071 ifft = ix + pady + padz 1072 rho(ifft) = rho(ifft) + weight_r * (REAL(ur(ifft))**2 + AIMAG(ur(ifft))**2) 1073 end do 1074 end do 1075 end do 1076 1077 else 1078 ! It would be nice to use $OMP PARALLEL DO REDUCTION(+:rho) 1079 ! but it's risky as the private rho is allocated on the stack of the thread. 1080 !$OMP PARALLEL PRIVATE(pad_box, padz, pady, ifft) 1081 do dat=1,ndat 1082 pad_box = (dat-1)*ldxyz 1083 !$OMP DO 1084 do iz=1,nz 1085 padz = (iz-1)*ldx*ldy 1086 do iy=1,ny 1087 pady = (iy-1)*ldx 1088 do ix=1,nx 1089 ifft = ix + pady + padz 1090 rho(ifft) = rho(ifft) + weight_r * (REAL(ur(ifft+pad_box)**2 + AIMAG(ur(ifft+pad_box))**2)) 1091 end do 1092 end do 1093 end do 1094 !$OMP END DO NOWAIT 1095 end do 1096 !$OMP END PARALLEL 1097 end if 1098 1099 end subroutine cplx_addtorho_dpc
m_cplxtools/cplx_box2gsph_dpc [ Functions ]
[ Top ] [ m_cplxtools ] [ Functions ]
NAME
cplx_box2gsph_dpc
FUNCTION
Transfer data from the FFT box to the G-sphere. Target DPC complex array.
INPUTS
nx,ny,nz=physical dimension of the FFT box. ldx,ldy,ldz=Logical dimensions of the arrays. ndat=number of data in iarrbox npw_k=Number of planewaves in the G-sphere. kg_k(3,npw_k)=Reduced coordinates of the G-vectoes. iarrbox(ldx*ldy*ldz*ndat)=Complex Input arrays on the FFT box. [rscal] = Scaling factor
OUTPUT
oarrsph(npw_k*ndat)=Complex Data defined on the G-sphere.
SOURCE
506 subroutine cplx_box2gsph_dpc(nx,ny,nz,ldx,ldy,ldz,ndat,npw_k,kg_k,iarrbox,oarrsph,rscal) 507 508 !Arguments ------------------------------------ 509 !scalars 510 integer,intent(in) :: npw_k,nx,ny,nz,ldx,ldy,ldz,ndat 511 real(dp),optional,intent(in) :: rscal 512 !arrays 513 integer,intent(in) :: kg_k(3,npw_k) 514 complex(dpc),intent(in) :: iarrbox(ldx*ldy*ldz*ndat) 515 complex(dpc),intent(out) :: oarrsph(npw_k*ndat) 516 517 !Local variables------------------------------- 518 !scalars 519 integer :: ig,ix,iy,iz,dat,pad_sph,pad_box,ifft,ldxyz 520 521 ! ************************************************************************* 522 523 ldxyz = ldx*ldy*ldz 524 if (.not. PRESENT(rscal)) then 525 ! 526 if (ndat==1) then 527 !$OMP PARALLEL DO PRIVATE(ix,iy,iz,ifft) 528 do ig=1,npw_k 529 ix=kg_k(1,ig); if (ix<0) ix=ix+nx; ix=ix+1 530 iy=kg_k(2,ig); if (iy<0) iy=iy+ny; iy=iy+1 531 iz=kg_k(3,ig); if (iz<0) iz=iz+nz; iz=iz+1 532 ifft = ix + (iy-1)*ldx + (iz-1)*ldx*ldy 533 oarrsph(ig) = iarrbox(ifft) 534 end do 535 else 536 !$OMP PARALLEL DO PRIVATE(pad_sph,pad_box,ix,iy,iz,ifft) 537 do dat=1,ndat 538 pad_sph = (dat-1)*npw_k 539 pad_box = (dat-1)*ldxyz 540 do ig=1,npw_k 541 ix=kg_k(1,ig); if (ix<0) ix=ix+nx; ix=ix+1 542 iy=kg_k(2,ig); if (iy<0) iy=iy+ny; iy=iy+1 543 iz=kg_k(3,ig); if (iz<0) iz=iz+nz; iz=iz+1 544 ifft = ix + (iy-1)*ldx + (iz-1)*ldx*ldy 545 oarrsph(ig+pad_sph) = iarrbox(ifft+pad_box) 546 end do 547 end do 548 end if 549 ! 550 else 551 if (ndat==1) then 552 !$OMP PARALLEL DO PRIVATE(ix,iy,iz,ifft) 553 do ig=1,npw_k 554 ix=kg_k(1,ig); if (ix<0) ix=ix+nx; ix=ix+1 555 iy=kg_k(2,ig); if (iy<0) iy=iy+ny; iy=iy+1 556 iz=kg_k(3,ig); if (iz<0) iz=iz+nz; iz=iz+1 557 ifft = ix + (iy-1)*ldx + (iz-1)*ldx*ldy 558 oarrsph(ig) = iarrbox(ifft) * rscal 559 end do 560 else 561 !$OMP PARALLEL DO PRIVATE(pad_sph,pad_box,ix,iy,iz,ifft) 562 do dat=1,ndat 563 pad_sph = (dat-1)*npw_k 564 pad_box = (dat-1)*ldxyz 565 do ig=1,npw_k 566 ix=kg_k(1,ig); if (ix<0) ix=ix+nx; ix=ix+1 567 iy=kg_k(2,ig); if (iy<0) iy=iy+ny; iy=iy+1 568 iz=kg_k(3,ig); if (iz<0) iz=iz+nz; iz=iz+1 569 ifft = ix + (iy-1)*ldx + (iz-1)*ldx*ldy 570 oarrsph(ig+pad_sph) = iarrbox(ifft+pad_box) * rscal 571 end do 572 end do 573 end if 574 end if 575 576 end subroutine cplx_box2gsph_dpc
m_cplxtools/cplx_box2gsph_spc [ Functions ]
[ Top ] [ m_cplxtools ] [ Functions ]
NAME
cplx_box2gsph_spc
FUNCTION
Transfer data from the FFT box to the G-sphere. Target SPC complex array.
INPUTS
nx,ny,nz=physical dimension of the FFT box. ldx,ldy,ldz=Logical dimensions of the arrays. ndat=number of data in iarrbox npw_k=Number of planewaves in the G-sphere. kg_k(3,npw_k)=Reduced coordinates of the G-vectoes. iarrbox(ldx*ldy*ldz*ndat)=Complex Input arrays on the FFT box. [rscal] = Scaling factor
OUTPUT
oarrsph(npw_k*ndat)=Complex Data defined on the G-sphere.
SOURCE
408 subroutine cplx_box2gsph_spc(nx,ny,nz,ldx,ldy,ldz,ndat,npw_k,kg_k,iarrbox,oarrsph,rscal) 409 410 !Arguments ------------------------------------ 411 !scalars 412 integer,intent(in) :: npw_k,nx,ny,nz,ldx,ldy,ldz,ndat 413 real(sp),optional,intent(in) :: rscal 414 !arrays 415 integer,intent(in) :: kg_k(3,npw_k) 416 complex(spc),intent(in) :: iarrbox(ldx*ldy*ldz*ndat) 417 complex(spc),intent(out) :: oarrsph(npw_k*ndat) 418 419 !Local variables------------------------------- 420 !scalars 421 integer :: ig,ix,iy,iz,dat,pad_sph,pad_box,ifft,ldxyz 422 423 ! ************************************************************************* 424 425 ldxyz = ldx*ldy*ldz 426 if (.not. PRESENT(rscal)) then 427 ! 428 if (ndat==1) then 429 !$OMP PARALLEL DO PRIVATE(ix,iy,iz,ifft) 430 do ig=1,npw_k 431 ix=kg_k(1,ig); if (ix<0) ix=ix+nx; ix=ix+1 432 iy=kg_k(2,ig); if (iy<0) iy=iy+ny; iy=iy+1 433 iz=kg_k(3,ig); if (iz<0) iz=iz+nz; iz=iz+1 434 ifft = ix + (iy-1)*ldx + (iz-1)*ldx*ldy 435 oarrsph(ig) = iarrbox(ifft) 436 end do 437 else 438 !$OMP PARALLEL DO PRIVATE(pad_sph,pad_box,ix,iy,iz,ifft) 439 do dat=1,ndat 440 pad_sph = (dat-1)*npw_k 441 pad_box = (dat-1)*ldxyz 442 do ig=1,npw_k 443 ix=kg_k(1,ig); if (ix<0) ix=ix+nx; ix=ix+1 444 iy=kg_k(2,ig); if (iy<0) iy=iy+ny; iy=iy+1 445 iz=kg_k(3,ig); if (iz<0) iz=iz+nz; iz=iz+1 446 ifft = ix + (iy-1)*ldx + (iz-1)*ldx*ldy 447 oarrsph(ig+pad_sph) = iarrbox(ifft+pad_box) 448 end do 449 end do 450 end if 451 ! 452 else 453 if (ndat==1) then 454 !$OMP PARALLEL DO PRIVATE(ix,iy,iz,ifft) 455 do ig=1,npw_k 456 ix=kg_k(1,ig); if (ix<0) ix=ix+nx; ix=ix+1 457 iy=kg_k(2,ig); if (iy<0) iy=iy+ny; iy=iy+1 458 iz=kg_k(3,ig); if (iz<0) iz=iz+nz; iz=iz+1 459 ifft = ix + (iy-1)*ldx + (iz-1)*ldx*ldy 460 oarrsph(ig) = iarrbox(ifft) * rscal 461 end do 462 else 463 !$OMP PARALLEL DO PRIVATE(pad_sph,pad_box,ix,iy,iz,ifft) 464 do dat=1,ndat 465 pad_sph = (dat-1)*npw_k 466 pad_box = (dat-1)*ldxyz 467 do ig=1,npw_k 468 ix=kg_k(1,ig); if (ix<0) ix=ix+nx; ix=ix+1 469 iy=kg_k(2,ig); if (iy<0) iy=iy+ny; iy=iy+1 470 iz=kg_k(3,ig); if (iz<0) iz=iz+nz; iz=iz+1 471 ifft = ix + (iy-1)*ldx + (iz-1)*ldx*ldy 472 oarrsph(ig+pad_sph) = iarrbox(ifft+pad_box) * rscal 473 end do 474 end do 475 end if 476 end if 477 478 end subroutine cplx_box2gsph_spc
m_cplxtools/cplx_filter [ Functions ]
[ Top ] [ m_cplxtools ] [ Functions ]
NAME
cplx_filter
FUNCTION
Set all the elements of x to zero where mask is .TRUE.
INPUTS
n=Specifies the number of elements in vectors x and y. mask(n)=Logical array.
SIDE EFFECTS
x(n)=See description.
SOURCE
153 subroutine cplx_filter(n, x, mask) 154 155 !Arguments ------------------------------------ 156 !scalars 157 integer,intent(in) :: n 158 !arrays 159 complex(dpc),intent(inout) :: x(n) 160 logical,intent(in) :: mask(n) 161 162 ! ************************************************************************* 163 164 where (mask) 165 x = czero 166 end where 167 168 end subroutine cplx_filter
m_cplxtools/cplx_fromreal [ Functions ]
[ Top ] [ m_cplxtools ] [ Functions ]
NAME
cplx_fromreal
FUNCTION
Convert a real array with (real,imag) part to a complex array
INPUTS
n = Specifies the number of elements in ocplx ireal(2*n)=Input real array.
OUTPUT
ocplx(n)=Output complex array
SOURCE
112 subroutine cplx_fromreal(n,ireal,ocplx) 113 114 !Arguments ------------------------------------ 115 !scalars 116 integer,intent(in) :: n 117 !arrays 118 real(dp),intent(in) :: ireal(2,n) 119 complex(dpc),intent(out) :: ocplx(n) 120 121 !Local variables ------------------------------ 122 !scalars 123 integer :: ii 124 125 ! ************************************************************************* 126 127 !$OMP PARALLEL DO PRIVATE(ii) 128 do ii=1,n 129 ocplx(ii) = DCMPLX(ireal(1,ii),ireal(2,ii)) 130 end do 131 132 end subroutine cplx_fromreal
m_cplxtools/cplx_gsph2box_dpc [ Functions ]
[ Top ] [ m_cplxtools ] [ Functions ]
NAME
cplx_gsph2box_dpc
FUNCTION
Array iarrsph is defined in sphere with npw points. Insert iarrsph inside box of nx*ny*nz points to define array oarrbox for fft box. rest of oarrbox is filled with 0 s. targer: DPC complex arrays
INPUTS
iarrsph(2,npw*ndat)= contains values for npw G vectors in basis sphere ndat=number of FFT to perform. npw=number of G vectors in basis at this k point oarrbox(2,ldx*ldy*ldz*ndat) = fft box nx,ny,nz=physical dimension of the box (oarrbox) ldx,ldy,ldz=memory dimension of oarrbox kg_k(3,npw)=integer coordinates of G vectors in basis sphere istwf_k=option parameter that describes the storage of wfs
OUTPUT
oarrbox(ldx*ldy*ldz*ndat)
NOTES
If istwf_k differs from 1, then special storage modes must be taken into account, for symmetric wavefunctions coming from k=(0 0 0) or other special k points.
SOURCE
774 subroutine cplx_gsph2box_dpc(nx,ny,nz,ldx,ldy,ldz,ndat,npw,istwf_k,kg_k,iarrsph,oarrbox) 775 776 !Arguments ------------------------------------ 777 !scalars 778 integer,intent(in) :: istwf_k,nx,ny,nz,ldx,ldy,ldz,ndat,npw 779 !arrays 780 integer,intent(in) :: kg_k(3,npw) 781 complex(dpc),intent(in) :: iarrsph(npw*ndat) 782 complex(dpc),intent(out) :: oarrbox(ldx*ldy*ldz*ndat) 783 784 !Local variables------------------------------- 785 !scalars 786 integer,parameter :: me_g0=1 787 integer :: ix,ixinv,iy,iyinv,iz,izinv,dat,ipw,npwmin,pad_box,pad_sph,ifft,ifft_inv,ldxyz 788 !character(len=500) :: msg 789 !arrays 790 integer,allocatable :: ixinver(:),iyinver(:),izinver(:) 791 792 ! ************************************************************************* 793 794 !In the case of special k-points, invariant under time-reversal, 795 !but not Gamma, initialize the inverse coordinates 796 !Remember indeed that 797 !u_k(G) = u_{k+G0}(G-G0); u_{-k}(G) = u_k(G)^* 798 !and therefore: 799 !u_{G0/2}(G) = u_{G0/2}(-G-G0)^*. 800 if (istwf_k>=2) then 801 ABI_MALLOC(ixinver,(nx)) 802 ABI_MALLOC(iyinver,(ny)) 803 ABI_MALLOC(izinver,(nz)) 804 if ( ANY(istwf_k==(/2,4,6,8/)) ) then 805 ixinver(1)=1 806 do ix=2,nx 807 ixinver(ix)=nx+2-ix 808 end do 809 else 810 do ix=1,nx 811 ixinver(ix)=nx+1-ix 812 end do 813 end if 814 if (istwf_k>=2 .and. istwf_k<=5) then 815 iyinver(1)=1 816 do iy=2,ny 817 iyinver(iy)=ny+2-iy 818 end do 819 else 820 do iy=1,ny 821 iyinver(iy)=ny+1-iy 822 end do 823 end if 824 if ( ANY(istwf_k==(/2,3,6,7/)) ) then 825 izinver(1)=1 826 do iz=2,nz 827 izinver(iz)=nz+2-iz 828 end do 829 else 830 do iz=1,nz 831 izinver(iz)=nz+1-iz 832 end do 833 end if 834 end if 835 836 ldxyz = ldx*ldy*ldz 837 838 if (istwf_k==1) then 839 840 !$OMP PARALLEL DO PRIVATE(pad_sph,pad_box,ix,iy,iz,ifft) 841 do dat=1,ndat 842 pad_sph = (dat-1)*npw 843 pad_box = (dat-1)*ldxyz 844 oarrbox(1+pad_box:ldxyz+pad_box) = czero_dpc ! zero the sub-array 845 do ipw=1,npw 846 ix=kg_k(1,ipw); if (ix<0) ix=ix+nx; ix=ix+1 847 iy=kg_k(2,ipw); if (iy<0) iy=iy+ny; iy=iy+1 848 iz=kg_k(3,ipw); if (iz<0) iz=iz+nz; iz=iz+1 849 ifft = ix + (iy-1)*ldx + (iz-1)*ldx*ldy 850 #if defined __INTEL_COMPILER && defined HAVE_OPENMP 851 if (ifft==0) then 852 ABI_ERROR("prevent ifort+OMP from miscompiling this section on cronos") 853 end if 854 #endif 855 oarrbox(ifft+pad_box) = iarrsph(ipw+pad_sph) 856 end do 857 end do 858 859 else if (istwf_k>=2) then 860 ! 861 npwmin=1 862 if(istwf_k==2 .and. me_g0==1) then ! If gamma point, then oarrbox must be completed 863 do dat=1,ndat 864 pad_sph = (dat-1)*npw 865 pad_box = (dat-1)*ldxyz 866 oarrbox(1+pad_box) = REAL(iarrsph(1+pad_sph)) 867 end do 868 npwmin=2 869 end if 870 871 !$OMP PARALLEL DO PRIVATE(pad_sph,pad_box,ix,ixinv,iy,iyinv,iz,izinv,ifft) 872 do dat=1,ndat 873 pad_sph = (dat-1)*npw 874 pad_box = (dat-1)*ldxyz 875 oarrbox(npwmin+pad_box:ldxyz+pad_box) = czero_dpc 876 do ipw=npwmin,npw 877 ix=kg_k(1,ipw); if(ix<0)ix=ix+nx; ix=ix+1 878 iy=kg_k(2,ipw); if(iy<0)iy=iy+ny; iy=iy+1 879 iz=kg_k(3,ipw); if(iz<0)iz=iz+nz; iz=iz+1 880 ifft = ix + (iy-1)*ldx + (iz-1)*ldx*ldy 881 ! Construct the coordinates of -k-G 882 ixinv=ixinver(ix); iyinv=iyinver(iy); izinv=izinver(iz) 883 ifft_inv = ixinv + (iyinv-1)*ldx + (izinv-1)*ldx*ldy 884 #if defined __INTEL_COMPILER && defined HAVE_OPENMP 885 if (ifft==0 .or. ifft_inv==0) then 886 ABI_ERROR("prevent ifort+OMP from miscompiling this section on cronos") 887 end if 888 #endif 889 oarrbox(ifft +pad_box) = iarrsph(ipw+pad_sph) 890 oarrbox(ifft_inv+pad_box) = DCONJG(iarrsph(ipw+pad_sph)) 891 end do 892 end do 893 ! 894 else 895 ABI_ERROR("Wrong istwfk") 896 end if 897 898 if (istwf_k>=2) then 899 ABI_FREE(ixinver) 900 ABI_FREE(iyinver) 901 ABI_FREE(izinver) 902 end if 903 904 end subroutine cplx_gsph2box_dpc
m_cplxtools/cplx_gsph2box_spc [ Functions ]
[ Top ] [ m_cplxtools ] [ Functions ]
NAME
cplx_gsph2box_spc
FUNCTION
Array iarrsph is defined in sphere with npw points. Insert iarrsph inside box of nx*ny*nz points to define array oarrbox for fft box. rest of oarrbox is filled with 0 s. targer: SPC complex arrays
INPUTS
iarrsph(2,npw*ndat)= contains values for npw G vectors in basis sphere ndat=number of FFT to perform. npw=number of G vectors in basis at this k point oarrbox(2,ldx*ldy*ldz*ndat) = fft box nx,ny,nz=physical dimension of the box (oarrbox) ldx,ldy,ldz=memory dimension of oarrbox kg_k(3,npw)=integer coordinates of G vectors in basis sphere istwf_k=option parameter that describes the storage of wfs
OUTPUT
oarrbox(ldx*ldy*ldz*ndat)
NOTES
If istwf_k differs from 1, then special storage modes must be taken into account, for symmetric wavefunctions coming from k=(0 0 0) or other special k points.
SOURCE
610 subroutine cplx_gsph2box_spc(nx,ny,nz,ldx,ldy,ldz,ndat,npw,istwf_k,kg_k,iarrsph,oarrbox) 611 612 !Arguments ------------------------------------ 613 !scalars 614 integer,intent(in) :: istwf_k,nx,ny,nz,ldx,ldy,ldz,ndat,npw 615 !arrays 616 integer,intent(in) :: kg_k(3,npw) 617 complex(spc),intent(in) :: iarrsph(npw*ndat) 618 complex(spc),intent(out) :: oarrbox(ldx*ldy*ldz*ndat) 619 620 !Local variables------------------------------- 621 !scalars 622 integer,parameter :: me_g0=1 623 integer :: ix,ixinv,iy,iyinv,iz,izinv,dat,ipw,npwmin,pad_box,pad_sph,ifft,ifft_inv,ldxyz 624 !character(len=500) :: msg 625 !arrays 626 integer,allocatable :: ixinver(:),iyinver(:),izinver(:) 627 628 ! ************************************************************************* 629 630 !In the case of special k-points, invariant under time-reversal, 631 !but not Gamma, initialize the inverse coordinates 632 !Remember indeed that 633 !u_k(G) = u_{k+G0}(G-G0); u_{-k}(G) = u_k(G)^* 634 !and therefore: 635 !u_{G0/2}(G) = u_{G0/2}(-G-G0)^*. 636 if (istwf_k>=2) then 637 ABI_MALLOC(ixinver,(nx)) 638 ABI_MALLOC(iyinver,(ny)) 639 ABI_MALLOC(izinver,(nz)) 640 if ( ANY(istwf_k==(/2,4,6,8/)) ) then 641 ixinver(1)=1 642 do ix=2,nx 643 ixinver(ix)=nx+2-ix 644 end do 645 else 646 do ix=1,nx 647 ixinver(ix)=nx+1-ix 648 end do 649 end if 650 if (istwf_k>=2 .and. istwf_k<=5) then 651 iyinver(1)=1 652 do iy=2,ny 653 iyinver(iy)=ny+2-iy 654 end do 655 else 656 do iy=1,ny 657 iyinver(iy)=ny+1-iy 658 end do 659 end if 660 if ( ANY(istwf_k==(/2,3,6,7/)) ) then 661 izinver(1)=1 662 do iz=2,nz 663 izinver(iz)=nz+2-iz 664 end do 665 else 666 do iz=1,nz 667 izinver(iz)=nz+1-iz 668 end do 669 end if 670 end if 671 672 ldxyz = ldx*ldy*ldz 673 674 if (istwf_k==1) then 675 676 !$OMP PARALLEL DO PRIVATE(pad_sph,pad_box,ix,iy,iz,ifft) 677 do dat=1,ndat 678 pad_sph = (dat-1)*npw 679 pad_box = (dat-1)*ldxyz 680 oarrbox(1+pad_box:ldxyz+pad_box) = czero_spc ! zero the sub-array 681 do ipw=1,npw 682 ix=kg_k(1,ipw); if (ix<0) ix=ix+nx; ix=ix+1 683 iy=kg_k(2,ipw); if (iy<0) iy=iy+ny; iy=iy+1 684 iz=kg_k(3,ipw); if (iz<0) iz=iz+nz; iz=iz+1 685 ifft = ix + (iy-1)*ldx + (iz-1)*ldx*ldy 686 #if defined __INTEL_COMPILER && defined HAVE_OPENMP 687 if (ifft==0) then 688 ABI_ERROR("prevent ifort+OMP from miscompiling this section on cronos") 689 end if 690 #endif 691 oarrbox(ifft+pad_box) = iarrsph(ipw+pad_sph) 692 end do 693 end do 694 695 else if (istwf_k>=2) then 696 ! 697 npwmin=1 698 if(istwf_k==2 .and. me_g0==1) then ! If gamma point, then oarrbox must be completed 699 do dat=1,ndat 700 pad_sph = (dat-1)*npw 701 pad_box = (dat-1)*ldxyz 702 oarrbox(1+pad_box) = REAL(iarrsph(1+pad_sph)) 703 end do 704 npwmin=2 705 end if 706 707 !$OMP PARALLEL DO PRIVATE(pad_sph,pad_box,ix,ixinv,iy,iyinv,iz,izinv,ifft) 708 do dat=1,ndat 709 pad_sph = (dat-1)*npw 710 pad_box = (dat-1)*ldxyz 711 oarrbox(npwmin+pad_box:ldxyz+pad_box) = czero_spc 712 do ipw=npwmin,npw 713 ix=kg_k(1,ipw); if(ix<0)ix=ix+nx; ix=ix+1 714 iy=kg_k(2,ipw); if(iy<0)iy=iy+ny; iy=iy+1 715 iz=kg_k(3,ipw); if(iz<0)iz=iz+nz; iz=iz+1 716 ifft = ix + (iy-1)*ldx + (iz-1)*ldx*ldy 717 ! Construct the coordinates of -k-G 718 ixinv=ixinver(ix); iyinv=iyinver(iy); izinv=izinver(iz) 719 ifft_inv = ixinv + (iyinv-1)*ldx + (izinv-1)*ldx*ldy 720 #if defined __INTEL_COMPILER && defined HAVE_OPENMP 721 if (ifft==0 .or. ifft_inv==0) then 722 ABI_ERROR("prevent ifort+OMP from miscompiling this section on cronos") 723 end if 724 #endif 725 oarrbox(ifft +pad_box) = iarrsph(ipw+pad_sph) 726 oarrbox(ifft_inv+pad_box) = CONJG(iarrsph(ipw+pad_sph)) 727 end do 728 end do 729 ! 730 else 731 ABI_ERROR("Wrong istwfk") 732 end if 733 734 if (istwf_k>=2) then 735 ABI_FREE(ixinver) 736 ABI_FREE(iyinver) 737 ABI_FREE(izinver) 738 end if 739 740 end subroutine cplx_gsph2box_spc
m_cplxtools/cplx_real_zdotc [ Functions ]
[ Top ] [ m_cplxtools ] [ Functions ]
NAME
cplx_real_zdotc
FUNCTION
Perform a vector-vector operation defined as res = REAL (\Sigma (conjg(x)*y)) where x and y are n-element vectors.
INPUTS
n = Specifies the number of elements in vector x and y x,y = Input arrays.
OUTPUT
res=Real part of the scalar product.
SOURCE
189 function cplx_real_zdotc(n,x,y) result(res) 190 191 !Arguments ------------------------------------ 192 !scalars 193 integer,intent(in) :: n 194 !arrays 195 complex(dpc),intent(in) :: x(n) 196 complex(dpc),intent(in) :: y(n) 197 real(dp) :: res 198 199 !Local variables------------------------------- 200 real(dp),external :: ddot 201 202 ! ************************************************************************* 203 204 res = ddot(2*n,x,1,y,1) 205 206 end function cplx_real_zdotc
m_cplxtools/cplx_setaug_zero_dpc [ Functions ]
[ Top ] [ m_cplxtools ] [ Functions ]
NAME
cplx_setaug_zero_dpc
FUNCTION
Set to zero all elements of the array that are not in the FFT box.
INPUTS
nx,ny,nz=physical dimensions of the FFT box ldx,ldy,ldx=memory dimension of arr ndat=number of FFTs SIDE EFFECT arr(ldx,ldy,ldz*ndat)= all entries in the augmented region are set to zero
SOURCE
984 subroutine cplx_setaug_zero_dpc(nx,ny,nz,ldx,ldy,ldz,ndat,arr) 985 986 !Arguments ------------------------------------ 987 !scalars 988 integer,intent(in) :: nx,ny,nz,ldx,ldy,ldz,ndat 989 !arrays 990 complex(dpc),intent(inout) :: arr(ldx,ldy,ldz*ndat) 991 992 !Local variables------------------------------- 993 integer :: iy,iz,dat,padat 994 995 ! ************************************************************************* 996 997 if (nx /= ldx) then 998 do iz=1,ldz*ndat 999 do iy=1,ldy 1000 arr(nx+1:ldx,iy,iz) = czero_dpc 1001 end do 1002 end do 1003 end if 1004 1005 if (ny /= ldy) then 1006 do iz=1,ldz*ndat 1007 arr(:,ny+1:ldy,iz) = czero_dpc 1008 end do 1009 end if 1010 1011 if (nz /= ldz) then 1012 do dat=1,ndat 1013 padat = ldz*(dat-1) 1014 do iz=nz+1,ldz 1015 arr(:,:,iz+padat) = czero_dpc 1016 end do 1017 end do 1018 end if 1019 1020 end subroutine cplx_setaug_zero_dpc
m_cplxtools/cplx_setaug_zero_spc [ Functions ]
[ Top ] [ m_cplxtools ] [ Functions ]
NAME
cplx_setaug_zero_spc
FUNCTION
Set to zero all elements of the array that are not in the FFT box.
INPUTS
nx,ny,nz=physical dimensions of the FFT box ldx,ldy,ldx=memory dimension of arr ndat=number of FFTs SIDE EFFECT arr(ldx,ldy,ldz*ndat)= all entries in the augmented region are set to zero
SOURCE
926 subroutine cplx_setaug_zero_spc(nx,ny,nz,ldx,ldy,ldz,ndat,arr) 927 928 !Arguments ------------------------------------ 929 !scalars 930 integer,intent(in) :: nx,ny,nz,ldx,ldy,ldz,ndat 931 !arrays 932 complex(spc),intent(inout) :: arr(ldx,ldy,ldz*ndat) 933 934 !Local variables------------------------------- 935 integer :: iy,iz,dat,padat 936 937 ! ************************************************************************* 938 939 if (nx /= ldx) then 940 do iz=1,ldz*ndat 941 do iy=1,ldy 942 arr(nx+1:ldx,iy,iz) = czero_spc 943 end do 944 end do 945 end if 946 947 if (ny /= ldy) then 948 do iz=1,ldz*ndat 949 arr(:,ny+1:ldy,iz) = czero_spc 950 end do 951 end if 952 953 if (nz /= ldz) then 954 do dat=1,ndat 955 padat = ldz*(dat-1) 956 do iz=nz+1,ldz 957 arr(:,:,iz+padat) = czero_spc 958 end do 959 end do 960 end if 961 962 end subroutine cplx_setaug_zero_spc
m_cplxtools/cplx_zaxpby [ Functions ]
[ Top ] [ m_cplxtools ] [ Functions ]
NAME
cplx_zaxpby
FUNCTION
Scales two vectors, adds them to one another and stores result in the vector. y := a*x + b*y
INPUTS
n = the number of elements in vectors x and y. a = Specifies the scalar a. x = Array. b = Specifies the scalar b. y = Array
OUTPUT
y Contains the updated vector y.
SOURCE
231 subroutine cplx_zaxpby(n,a,x,b,y) 232 233 !Arguments ------------------------------------ 234 !scalars 235 integer,intent(in) :: n 236 complex(dpc),intent(in) :: a,b 237 !arrays 238 complex(dpc),intent(in) :: x(n) 239 complex(dpc),intent(inout) :: y(n) 240 241 ! ************************************************************************* 242 243 #ifdef HAVE_LINALG_AXPBY 244 call zaxpby(n, a, x, 1, b, y, 1) 245 #else 246 call zscal(n, b, y, 1) 247 call zaxpy(n, a, x, 1, y,1) 248 #endif 249 250 end subroutine cplx_zaxpby
m_cplxtools/cplx_zgemm [ Functions ]
[ Top ] [ m_cplxtools ] [ Functions ]
NAME
cplx_zgemm
FUNCTION
The ?gemm routines perform a matrix-matrix operation with general matrices. The operation is defined as C := alpha*op(A)*op(B) + beta*C, where: op(x) is one of op(x) = x, or op(x) = x', or op(x) = conjg(x'), alpha and beta are scalars, A, B and C are matrices: op(A) is an m-by-k matrix, op(B) is a k-by-n matrix, C is an m-by-n matrix.
INPUTS
OUTPUT
SOURCE
343 subroutine cplx_zgemm(transa,transb,npws,ncola,ncolb,amat,bmat,cmat,alpha,beta) 344 345 !Arguments ------------------------------------ 346 !scalars 347 integer,intent(in) :: npws,ncola,ncolb 348 complex(dpc),optional,intent(in) :: alpha,beta 349 character(len=1),intent(in) :: transa,transb 350 !arrays 351 complex(dpc),intent(in) :: amat(npws*ncola) 352 complex(dpc),intent(in) :: bmat(npws*ncolb) 353 complex(dpc),intent(inout) :: cmat(*) 354 355 !Local variables------------------------------- 356 !scalars 357 integer :: mm,nn,kk,lda,ldb,ldc 358 complex(dpc) :: my_alpha,my_beta 359 360 ! ************************************************************************* 361 362 lda = npws 363 ldb = npws 364 365 mm = npws 366 nn = ncolb 367 kk = ncola 368 369 if (toupper(transa) /= 'N') then 370 mm = ncola 371 kk = npws 372 end if 373 if (toupper(transb) /= 'N') nn = npws 374 375 ldc = mm 376 377 my_alpha = cone_dpc; if (PRESENT(alpha)) my_alpha = alpha 378 my_beta = czero_dpc; if (PRESENT(beta)) my_beta = beta 379 380 call ZGEMM(transa,transb,mm,nn,kk,my_alpha,amat,lda,bmat,ldb,my_beta,cmat,ldc) 381 382 end subroutine cplx_zgemm
m_cplxtools/cplx_zgemv [ Functions ]
[ Top ] [ m_cplxtools ] [ Functions ]
NAME
cplx_zgemv
FUNCTION
The ?gemv routines perform a matrix-vector operation defined as y := alpha*A*x + beta*y, or y := alpha*A'*x + beta*y, or y := alpha*conjg(A')*x + beta*y, where: alpha and beta are scalars, x and y are vectors, A is an m-by-n matrix.
INPUTS
OUTPUT
SOURCE
276 subroutine cplx_zgemv(trans,nrows,ncols,mat,vec,matvec,alpha,beta) 277 278 !Arguments ------------------------------------ 279 !scalars 280 integer,intent(in) :: nrows,ncols 281 complex(dpc),optional,intent(in) :: alpha,beta 282 character(len=1),intent(in) :: trans 283 !arrays 284 complex(dpc),intent(in) :: mat(nrows*ncols) 285 complex(dpc),intent(in) :: vec(*) 286 complex(dpc),intent(inout) :: matvec(*) 287 288 !Local variables------------------------------- 289 !scalars 290 integer :: mm,nn,kk,lda,ldb,ldc 291 complex(dpc) :: my_alpha,my_beta 292 293 ! ************************************************************************* 294 295 lda = nrows 296 mm = nrows 297 nn = 1 298 kk = ncols 299 300 if (toupper(trans) /= 'N') then 301 mm = ncols 302 kk = nrows 303 end if 304 305 ldb = kk 306 ldc = mm 307 308 my_alpha = cone_dpc; if (PRESENT(alpha)) my_alpha = alpha 309 my_beta = czero_dpc; if (PRESENT(beta)) my_beta = beta 310 311 call ZGEMM(trans,"N",mm,nn,kk,my_alpha,mat,lda,vec,ldb,my_beta,matvec,ldc) 312 313 !call ZGEMV(trans,mm,nn,my_alpha,mat,lda,vec,1,my_beta,matvec,1) 314 315 end subroutine cplx_zgemv