SUBROUTINE ovrdvr (Rho_DVR, Rho_ABM, Nang_ABM, nbasis, xchanl, nangch, Phi_DVR, Phi_ABM, & vect, Overlap_DVR2ABM, amatrx, nbasiss, & neigmin, jrot, Theta_ABM, Chi_ABM, Weight_ABM) USE FileUnits_Module USE Parms_Module USE TotJ_Module USE FBR_Module USE Testing_Module USE InputFile_Module ! ! P U R P O S E O F S U B R O U T I N E ! Determines dvr to abm overlap matrix elements ! using abm quadratures and angles. ! I N P U T A R G U M E N T S ! Rho_DVR previous hyperradius. ! Rho_ABM current hyperradius ! Nang_ABM number of ABM quadrature angles. ! nbasis number of raw primitive ABM basis functions. ! nbasiss number of symmetry-adapted primitive ABM basis functions. ! narran number of arrangement channels. ! xchanl an array giving the channel number of each basis function. ! nangch an array containing the starting position of the ! angles for each of the arrangement channels. ! nangch(narran+1) is equal to Nang_ABM+1. ! Phi_DVR primitive basis at Rho_DVR at ABM quadrature pts. ! Phi_ABM primitive basis at Rho_ABM at ABM quadrature pts. ! vect coeffs of present surface functions. ! O U T P U T A R G U M E N T S ! Overlap_DVR2ABM overlap matrix elements. IMPLICIT NONE CHARACTER(LEN=200) filename, prefix ! I N T E G E R S INTEGER Nang_ABM, ibasis, jbasis, nbasis, iang, iangst1, iangend1, jpar, neigmin, lnblnk INTEGER nbasiss, nmode, nprimabm, nprimdvr, nabm, ndvr, isav, IErr INTEGER xchanl(nbasiss), nangch(narran+1), jrot(nbasiss) ! R E A L S REAL(Kind=WP_Kind) overlap, Rho_DVR, Rho_ABM, zero, half, two, xnorm, xfac REAL(Kind=WP_Kind) Phi_DVR(Nang_ABM, nbasiss), Overlap_DVR2ABM(nbasiss, nbasiss), Phi_ABM(Nang_ABM, nbasiss) REAL(Kind=WP_Kind) vect(nbasiss, nbasiss), amatrx(nbasiss,nbasiss) REAL(Kind=WP_Kind) Theta_ABM(Nang_ABM), Chi_ABM(Nang_ABM), Weight_ABM(Nang_ABM) REAL(Kind=WP_Kind) diagonal(1000) ! E X T E R N A L S EXTERNAL popt, mxoutf, sgemm_junk, rdwrsurb ! P A R A M E T E R S PARAMETER (zero=0.0d0, half=0.5d0, two=2.0d0) !----------------------------------------------------------------------- ! Determine printing options. !----------------------------------------------------------------------- LOGICAL little, medium, full, there INTEGER ithcall, ithsub DATA ithcall /0/, ithsub /0/, isav /-1/ DATA little /.false./, medium /.false./, full /.false./ CALL popt ('ovrdvr ', little, medium, full, ithcall, ithsub) xnorm = sqrt(half) xfac = sqrt(two) INQUIRE(file=InputDIR(1:LEN(TRIM(InputDIR)))//InputFile, exist = there) IF(there)THEN OPEN(Unit=In_Unit,File=InputDIR(1:LEN(TRIM(InputDIR)))//InputFile,status='old') READ(In_Unit,NML=testing, IOSTAT=IERR) IF(IERR==-1)THEN test='nul' ENDIF CLOSE(Unit=In_Unit) WRITE(Out_Unit,NML=testing) ELSE STOP 'Stopping in DVR_to_ABM' ENDIF IF(test=='ABM')THEN WRITE(Msg_Unit,*)'Testing ABM Surface Functions' WRITE(Out_Unit,*)'Testing ABM Surface Functions' WRITE(Msg_Unit,*)'Warning! Not normalized for this case!' WRITE(Out_Unit,*)'Warning! Not normalized for this case!' ELSEIF(test=='DVR')THEN WRITE(Msg_Unit,*)'Testing DVR Surface Functions' WRITE(Out_Unit,*)'Testing DVR Surface Functions' WRITE(Msg_Unit,*)'Warning! Not normalized for this case!' WRITE(Out_Unit,*)'Warning! Not normalized for this case!' ELSE WRITE(Msg_Unit,*)'Calculating DVR_TO_ABM transformation' WRITE(Out_Unit,*)'Calculating DVR_TO_ABM transformation' ENDIF !--------------------------------------------------------------- ! READ the number of fbr(dvr) functions to be used. !--------------------------------------------------------------- INQUIRE(file=InputDIR(1:LEN(TRIM(InputDIR)))//InputFile,exist=there) IF(there)THEN OPEN(Unit=In_Unit,File=InputDIR(1:LEN(TRIM(InputDIR)))//InputFile,status='old') READ(In_Unit,NML=fbr, IOSTAT=IERR) IF(IERR==-1)THEN CALL NameList_Default(Out_Unit, 'FBR') NSfunc=105 !TmpModGregParker2 lmax=20 mmax=40 nsym=1 ELSEIF(IERR/=0)THEN WRITE(Out_Unit,*)'ERROR with Namelist FBR' WRITE(Msg_Unit,*)'ERROR with Namelist FBR' STOP 'OvrDVR: FBR' ENDIF nmode = nsfunc CLOSE(Unit=In_Unit) WRITE(Out_Unit,NML=fbr) ELSE WRITE(Msg_Unit,*)'Error InputFile does not exist (ovrdvr):',InputDIR(1:LEN(TRIM(InputDIR)))//InputFile STOP 'ovrdvr' ENDIF WRITE(Out_Unit,*)'nangch=',nangch,' Nang_ABM=',Nang_ABM !---------------------------------------------------------------- ! construct the fbr(dvr) functions at the abm quadrature points. !---------------------------------------------------------------- CALL intdvr (Nang_ABM, Chi_ABM, Theta_ABM, Phi_DVR, nmode, Rho_DVR) CALL weight_unset (Nang_ABM, nprimabm, Phi_ABM, Weight_ABM) !------------------------------------------------------------------- ! The following only used to isolate inaccuracies in ABM or DVR basis. !------------------------------------------------------------------- IF(test=='ABM')THEN WRITE(Msg_Unit,*)'Both Phi_DVR and Phi_ABM are ABM s.f.' WRITE(Out_Unit,*)'Both Phi_DVR and Phi_ABM are ABM s.f.' CALL vcopy(Nang_ABM*NBasiss, Phi_DVR, Phi_ABM) nabm = neigmin ndvr = neigmin nprimdvr = nbasiss nprimabm = nbasiss ELSEIF(test=='DVR')THEN WRITE(Msg_Unit,*)'Both Phi_DVR and Phi_ABM are DVR s.f.' WRITE(Out_Unit,*)'Both Phi_DVR and Phi_ABM are DVR s.f.' CALL vcopy(Nang_ABM*NBasiss, Phi_ABM, Phi_DVR) nabm = nmode ndvr = nmode nprimdvr = nmode nprimabm = nmode ELSE WRITE(Msg_Unit,*)'dvr to abm case' WRITE(Out_Unit,*)'dvr to abm case' nabm = neigmin ndvr = nmode nprimdvr = nmode nprimabm = nbasiss ENDIF IF(ndvr>NBasiss.or.nabm>NBasiss.or.NEigmin>NBasiss.or.NMode>NBasiss)THEN WRITE(Out_Unit,*)'ndvr>NBasiss.or.nabm>NBasiss.or.NEigmin>NBasiss.or.NMode>NBasiss' WRITE(Out_Unit,*)ndvr,nabm,NEigmin,NMode,NBasiss WRITE(Msg_Unit,*)'ndvr>NBasiss.or.nabm>NBasiss.or.NEigmin>NBasiss.or.NMode>NBasiss' WRITE(Msg_Unit,*)ndvr,nabm,NEigmin,NMode,NBasiss STOP "Stopping in OvrDVR" ENDIF WRITE(Out_Unit,*)'Number of ABM Surface Functions =',nabm WRITE(Out_Unit,*)'Number of DVR Surface Functions =',ndvr WRITE(Out_Unit,*)'Number of Primitive ABM Basis Functions=',nprimabm WRITE(Out_Unit,*)'Number of Primitive DVR Basis Functions=',nprimdvr CALL SFPlots(Nang_ABM, Theta_ABM, Chi_ABM, Phi_DVR, "DVR_AA") CALL SFPlots(Nang_ABM, Theta_ABM, Chi_ABM, Phi_ABM, "ABM_AA") ! ! Multiply the ABM and DVR surface functions by the weight. ! CALL weight_set (Nang_ABM, nprimdvr, Phi_DVR, Weight_ABM) CALL weight_set (Nang_ABM, nprimabm, Phi_ABM, Weight_ABM) ! This will print weighted surface functions. medium=.true. IF(medium)THEN WRITE(Out_Unit,*)'chanl, iang, Phi_DVR, Phi_ABM' iangst1 = nangch(xchanl(1)) iangend1 = nangch(xchanl(1)+1)-1 WRITE(Out_Unit,*)'iangst1,iangend1',iangst1,iangend1 WRITE(Out_Unit,'(2x,A,3x,A,4x,A,5x,A)')"xchanl", "iang", "Phi_DVR", "Phi_ABM" DO iang = iangst1, iangend1 IF(ABS(Phi_DVR(iang,1))>0.05.or. ABS(Phi_ABM(iang,1))>0.05)THEN WRITE(Out_Unit,'(2I5,2ES15.7)')xchanl(1), iang, Phi_DVR(iang,1),Phi_ABM(iang,1) ENDIF ENDDO ENDIF ! ! -------------------------------------------------------------- ! evaluate overlaps of dvr surface functions and primitive abm basis. ! -------------------------------------------------------------- WRITE(Msg_Unit,*)'Calculate overlap integrals' WRITE(Out_Unit,*)'Calculate overlap integrals' WRITE(Out_Unit,*)'Symmetry=',symmetry IF(symmetry)THEN IF(jeven)THEN jpar = 0 ELSE jpar = 1 ENDIF ENDIF DO ibasis = 1, nprimabm ! start loop over abm primitive basis iangst1 = nangch(xchanl(ibasis)) iangend1 = nangch(xchanl(ibasis)+1)-1 IF(iangst1/=isav.or.ibasis==nprimabm)WRITE(Out_Unit,*)'ibasis=',ibasis,iangst1,iangend1,xchanl(ibasis) isav=iangst1 DO jbasis =1,nprimdvr ! start loop over dvr surface functions overlap = 0.0d0 DO iang = iangst1, iangend1 ! quadrature loop overlap = overlap + Phi_DVR(iang, jbasis)* Phi_ABM(iang,ibasis) ENDDO ! ! The following makes use of the fact that the dvr surface functions ! and the abm primitives in channel 1 have the full symmetry, and the ! quadrature in channel 1 automatically covers half the space and doubles ! the result, so no renormalization is needed. ! the quadratures done in channel 2 cover the whole space but only use ! one of the pair of primitives necessary to have proper symmetry. ! They must be multiplied by 2/sqrt2. R. T Pack, Feb. 1993. ! IF(symmetry.AND.xchanl(ibasis)==2) overlap=xfac*overlap amatrx(jbasis, ibasis) = overlap ENDDO ENDDO WRITE(Msg_Unit,*)'Overlap integrals have been calculated' WRITE(Out_Unit,*)'Overlap integrals have been calculated' WRITE(Out_Unit,*)'Overlaps of Primitive Basis in ovrdvr' WRITE(Out_Unit,*)'Matrix dimensions:',nprimdvr,' by',nprimabm CALL mxoutf (amatrx, nprimdvr, nprimabm, NBasiss, NBasiss) !-------------------------------------------------------------------- ! Transform primitive overlaps integrals to actual overlaps. !-------------------------------------------------------------------- IF(test/='DVR')THEN WRITE(Out_Unit,*)'Coefficients of the primitive basis' CALL mxoutf(vect, nprimdvr, nabm, NBasiss, Nabm) ENDIF IF(test/='DVR')THEN WRITE(Msg_Unit,*)'Transform primitive overlaps to actual overlaps' WRITE(Out_Unit,*)'Transform primitive overlaps to actual overlaps' CALL DGEMM('N','N',nprimdvr,nabm,nprimabm,1.d0,amatrx,nprimabm,vect,NBasiss,0.d0,Overlap_DVR2ABM,NBasiss) ELSEIF(test=='DVR')THEN Overlap_DVR2ABM=0.d0 CALL vcopy(Nbasiss*NBasiss, Overlap_DVR2ABM, amatrx) ENDIF IF(test=='ABM')THEN CALL DGEMM('T','N',nabm,nabm,nprimabm,1.d0,vect,nabm,Overlap_DVR2ABM,nprimabm,0.d0,amatrx,NBasiss) Overlap_DVR2ABM=0.d0 CALL vcopy(NBasiss*NBasiss, Overlap_DVR2ABM, amatrx) ENDIF !----------------------------------------------------------------------- ! IF desired WRITE out the overlap matrix. !----------------------------------------------------------------------- WRITE(Out_Unit,*)'routine ovrdvr' WRITE(Out_Unit,*)'ndvr = ', ndvr WRITE(Out_Unit,*)'nabm = ', nabm WRITE(Out_Unit,*)'Overlaps Actual basis' WRITE(Out_Unit,*) 'Part of the overlap matrix at Rho_DVR, Rho_ABM = ', Rho_DVR, Rho_ABM WRITE(Out_Unit,*)'Matrix dimensions:',ndvr,' by',nabm CALL mxoutf(Overlap_DVR2ABM, ndvr, nabm, NBasiss, NBasiss) ! -------------------------------------------------------------- ! WRITE overlap matrix on unit Ovr_Unit 'Ovrlp' ! -------------------------------------------------------------- WRITE(Ovr_Unit) 0, Rho_DVR, Rho_ABM WRITE(Ovr_Unit) nabm, Rho_DVR, Rho_ABM DO jbasis=1,nabm WRITE(Ovr_Unit)(Overlap_DVR2ABM(ibasis,jbasis),ibasis=1,ndvr) ENDDO WRITE(Out_Unit,'(A)')'Diagonal Elements of Overlap basis' DO ibasis = 1, min(ndvr,nabm) diagonal(ibasis)=Overlap_DVR2ABM(ibasis,ibasis) ENDDO WRITE(Out_Unit,'(10ES11.4)')(diagonal(ibasis),ibasis=1,min(ndvr,nabm)) !-------------------------------------------------------------------- ! construct Overlap_DVR2ABM*Overlap_DVR2ABM(trans) to test completeness of new basis. !-------------------------------------------------------------------- WRITE(Out_Unit,*) 'new basis completeness test. Rho_DVR, Rho_ABM= ',Rho_DVR, Rho_ABM CALL vsets(NBasiss*NBasiss, amatrx, 1, 0.d0) CALL DGEMM('N','T',ndvr,ndvr,nabm,1.d0,Overlap_DVR2ABM,NBasiss,Overlap_DVR2ABM,NBasiss,0.d0,amatrx,NBasiss) CALL mxoutf (amatrx, ndvr, ndvr, NBasiss, NBasiss) WRITE(Out_Unit,'(A)')'Diagonals of new basis completeness test' DO ibasis = 1, ndvr diagonal(ibasis)=amatrx(ibasis,ibasis) ENDDO WRITE(Out_Unit,'(10ES11.3)')(diagonal(ibasis),ibasis=1,ndvr) !-------------------------------------------------------------------- ! construct Overlap_DVR2ABM(trans)*Overlap_DVR2ABM to test completeness of old basis. !-------------------------------------------------------------------- WRITE(Out_Unit,'(A,2ES15.7)') 'old basis completeness test at Rho_DVR, Rho_ABM= ', Rho_DVR, Rho_ABM CALL vsets(NBasiss*NBasiss, amatrx, 1, 0.d0) CALL DGEMM('T','N',nabm,ndvr,nabm,1.d0,Overlap_DVR2ABM,NBasiss,Overlap_DVR2ABM,NBasiss,0.d0,amatrx,NBasiss) CALL mxoutf (amatrx, nabm, nabm, NBasiss, NBasiss) WRITE(Out_Unit,'(A)')'Diagonals of old basis completeness test' DO ibasis = 1, nabm diagonal(ibasis)=amatrx(ibasis,ibasis) ENDDO WRITE(Out_Unit,'(10ES11.3)')(diagonal(ibasis),ibasis=1,nabm) IF(test=='ABM')THEN WRITE(Out_Unit,*)'END of ABM test' STOP 'ABM test' ELSEIF(test=='DVR')THEN WRITE(Out_Unit,*)'END of DVR test' STOP 'DVR test' ELSE WRITE(Out_Unit,'(A)')'Calculated Matrix between DVR and ABM Surface Functions' ENDIF RETURN END