SUBROUTINE OvrFEM (rholast, rho, nang, nbasis, xchanl, nangch, Phi_FEM, & Phi_ABM, vect, s, amatrx, nbasiss, neigmin, jrot, ThetAPH, chiaph, weight) USE Numbers_Module USE Narran_Module USE totj_Module USE Testing_Module USE FileUnits_Module ! ! P U R P O S E O F S U B R O U T I N E ! This routine determines the overlap matrix elements between surface ! functions at different rho values. ! I N P U T A R G U M E N T S ! rholast previous hyperradius. ! rho current hyperradius ! nang number of quadrature angles. ! nbasis number of raw primitive basis functions. ! nbasiss number of symmetry-adapted primitive 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+1. ! Phi_FEM primitive basis of previous rho at present quadrature pts. ! Phi_ABM primitive basis of present rho at present quadrature pts. ! vect coeffs of present surface functions. ! O U T P U T A R G U M E N T S ! s overlap matrix elements. IMPLICIT NONE CHARACTER(LEN=200) :: filename, prefix ! I N T E G E R S INTEGER :: nang, ibasis, jbasis, nbasis, iang, iangst1, iangend1, xchanl, nangch, jpar, neigmin INTEGER :: lnblnk, nbasiss, jrot, kbasis, nmode, irhfem, nprimabm, nprimfem, nabm, nfem, ndimen ! R E A L S REAL(Kind=WP_Kind) :: overlap, Phi_FEM, Phi_ABM, s, rholast, rho, vect,amatrx, xnorm, ThetAPH, chiaph, weight ! D I M E N S I O N S DIMENSION Phi_FEM (nang, nbasis), s (nbasiss, nbasiss), xchanl (nbasis), nangch (narran + 1) DIMENSION Phi_ABM (nang, nbasis), vect (nbasiss, nbasiss), amatrx (nbasiss, nbasiss), jrot (nbasis) DIMENSION ThetAPH (nang), chiaph (nang), weight (nang) REAL(Kind=WP_Kind) :: diagonal (1000) ! E X T E R N A L S EXTERNAL popt, mxoutf, sgemm_junk, rdwrsurb !----------------------------------------------------------------------- ! Determine printing options. !----------------------------------------------------------------------- LOGICAL :: little, medium, full, there INTEGER :: ithcall, ithsub DATA ithcall / 0 /, ithsub / 0 / DATA little / .false. /, medium / .false. /, full / .false. / CALL popt ('ovrfem ', little, medium, full, ithcall, ithsub) ndimen = nbasiss INQUIRE(file = '.FEM_to_ABM', exist = there) IF(there)THEN filename = '.FEM_to_ABM' ELSE CALL getenv ('APH3D_HOME', prefix) filename = prefix (:lnblnk (prefix) ) //'/default_data/.FEM_to_ABM ' ENDIF OPEN(Unit=FEM_TO_ABM_Unit,File=OutDIR(1:LEN(TRIM(OutDIR)))//filename, status = 'old') READ(FEM_TO_ABM_Unit, testing) CLOSE(unit=FEM_TO_ABM_Unit) IF(test=='ABM')THEN WRITE(Msg_Unit, * ) 'Testing ABM Surface Functions' WRITE(Out_unit, * ) 'Testing ABM Surface Functions' ELSEIF (test=='FEM')THEN WRITE(Msg_Unit, * ) 'Testing FEM Surface Functions' WRITE(Out_unit, * ) 'Testing FEM Surface Functions' ELSE WRITE(Msg_Unit, * ) 'Calculating FEM_TO_ABM transformation' WRITE(Out_unit, * ) 'Calculating FEM_TO_ABM transformation' ENDIF WRITE(Out_unit, * ) 'nangch=', nangch, ' nang=', nang CALL basfem (ThetAPH, chiaph, nang, Phi_FEM, nmode, rholast, irhfem) IF(symmetry)THEN CALL vscale (nang * ndimen, Phi_FEM, 1, One/SQRT(two) ) ENDIF !------------------------------------------------------------------- ! Only used to isolate inaccuracies in ABM or FEM basis. !------------------------------------------------------------------- IF(test=='ABM')THEN WRITE(Msg_Unit, * ) 'Both Phi_FEM and Phi_ABM are ABM s.f.' WRITE(Out_unit, * ) 'Both Phi_FEM and Phi_ABM are ABM s.f.' CALL vcopy (nang * ndimen, Phi_FEM, Phi_ABM) nabm = neigmin nfem = neigmin nprimfem = nbasiss nprimabm = nbasiss ELSEIF (test=='FEM')THEN WRITE(Msg_Unit, * ) 'Both Phi_FEM and Phi_ABM are FEM s.f.' WRITE(Out_unit, * ) 'Both Phi_FEM and Phi_ABM are FEM s.f.' CALL vcopy (nang * ndimen, Phi_ABM, Phi_FEM) nabm = nmode nfem = nmode nprimfem = nmode nprimabm = nmode ELSE nabm = neigmin nfem = nmode nprimfem = nmode nprimabm = nbasiss ENDIF WRITE(Out_unit, * ) 'Number of ABM Surface Functions =', nabm WRITE(Out_unit, * ) 'Number of FEM Surface Functions =', nfem WRITE(Out_unit, * ) 'Number of Primitive ABM Basis Functions=', nprimabm WRITE(Out_unit, * ) 'Number of Primitive FEM Basis Functions=', nprimfem ! ! Multiply the ABM and FEM surface functions by the weight. ! CALL weight_set (nang, nprimfem, Phi_FEM, weight) CALL weight_set (nang, nprimabm, Phi_ABM, weight) ! This will print weighted surface functions. IF(medium)THEN WRITE(Out_unit, * ) 'chanl,iang,Phi_FEM,Phi_ABM' iangst1 = nangch (xchanl (1) ) iangend1 = nangch (xchanl (1) + 1) - 1 WRITE(Out_unit, * ) 'iangst1,iangend1', iangst1, iangend1 DO 875 iang = iangst1, iangend1 IF(abs (Phi_FEM (iang, 1) ) >0.05.or.abs (Phi_ABM (iang, 1) ) >0.05)THEN WRITE(Out_unit, * ) xchanl (1), iang, Phi_FEM (iang, 1), Phi_ABM (iang, 1) ENDIF 875 ENDDO ENDIF ! ! -------------------------------------------------------------- ! evaluate overlaps of primitive bases of previous and present rho. ! -------------------------------------------------------------- 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 iangst1 = nangch (xchanl (ibasis) ) iangend1 = nangch (xchanl (ibasis) + 1) - 1 WRITE(Out_unit, * ) 'ibasis=', ibasis, iangst1, iangend1, xchanl ( ibasis) DO jbasis = 1, nprimfem overlap = 0.0d0 DO iang = iangst1, iangend1 IF(symmetry.AND.xchanl (ibasis) ==2)THEN kbasis = ibasis + nbasis - nbasiss IF(mod (jrot (ibasis), 2) ==jpar)THEN overlap = overlap + Phi_FEM (iang, jbasis) * (Phi_ABM (iang, ibasis) + Phi_ABM (iang, kbasis) ) * sqrt (two) ELSE overlap = overlap + Phi_FEM (iang, jbasis) * (Phi_ABM (iang, ibasis) - Phi_ABM (iang, kbasis) ) * sqrt (two) ENDIF ELSE overlap = overlap + Phi_FEM (iang, jbasis) * Phi_ABM (iang, ibasis) ENDIF ENDDO amatrx (jbasis, ibasis) = overlap ENDDO ENDDO WRITE(Msg_Unit, * ) 'Overlap integrals have been calculated' WRITE(Out_unit, * ) 'Overlap integrals have been calculated' !-------------------------------------------------------------------- ! Transform primitive overlaps integrals to actual overlaps. !-------------------------------------------------------------------- WRITE(Out_unit, * ) 'Overlaps of Primitive Basis' WRITE(Out_unit, * ) 'Matrix dimensions:', nprimfem, ' by', nprimabm CALL mxoutf (amatrx, nprimfem, nprimabm, ndimen, ndimen) IF(test/='FEM')THEN WRITE(Out_unit, * ) 'Coefficients of the primative basis' CALL mxoutf (vect, nprimabm, nabm, ndimen, ndimen) ENDIF IF(test/='FEM')THEN WRITE(Msg_Unit, * ) 'Transform primitive overlaps to actual overlaps' WRITE(Out_unit, * ) 'Transform primitive overlaps to actual overlaps' CALL sgemm_junk (nprimfem, nprimabm, nabm, amatrx, ndimen, vect, ndimen, s, ndimen, 0, 1) ELSEIF (test=='FEM')THEN CALL vcopy (ndimen * ndimen, s, amatrx) ENDIF IF(test=='ABM')THEN CALL sgemm_junk (nabm, nprimabm, nabm, vect, ndimen, s, ndimen, amatrx, ndimen, 4, 1) CALL vcopy (ndimen * ndimen, s, amatrx) ENDIF WRITE(Out_unit, * ) 'Overlaps Actual basis' WRITE(Out_unit, * ) 'Matrix dimensions:', nfem, ' by', nabm CALL mxoutf (s, nfem, nabm, ndimen, ndimen) ! -------------------------------------------------------------- ! WRITE overlap matrix on unit Ovrlp_FEM_Unit 'Ovrlp' ! -------------------------------------------------------------- WRITE(Ovrlp_FEM_Unit) 0, rholast, rho WRITE(Ovrlp_FEM_Unit) nabm, rholast, rho DO jbasis = 1, nabm WRITE(Ovrlp_FEM_Unit) (s (ibasis, jbasis), ibasis = 1, nfem) ENDDO WRITE(Out_unit,'(A)') 'Diagonal Elements of Overlap basis' DO ibasis = 1, min (nfem, nabm) diagonal (ibasis) = s (ibasis, ibasis) ENDDO WRITE(Out_unit,'(10ES11.4)') (diagonal (ibasis), ibasis = 1, min (nfem, nabm) ) !----------------------------------------------------------------------- ! IF desired WRITE out the overlap matrix. !----------------------------------------------------------------------- WRITE(Out_unit, * ) 'routine ovrbas' WRITE(Out_unit, * ) 'nfem = ', nfem WRITE(Out_unit, * ) 'nabm = ', nabm WRITE(Out_unit, * ) 'Part of the overlap matrix at rholast, rho = ', rholast, rho WRITE(Out_unit, * ) 'Matrix dimensions:', nfem, ' by', nabm CALL mxoutf (s, nfem, nabm, ndimen, ndimen) !-------------------------------------------------------------------- ! construct s*s(trans) to test completeness of new basis. !-------------------------------------------------------------------- WRITE(Out_unit,*) 'new basis completeness test. rholast, rho= ', rholast, rho CALL vsets (ndimen * ndimen, amatrx, 1, Zero) CALL sgemm_junk (nfem, nabm, nfem, s, ndimen, s, ndimen, amatrx, ndimen, 2, 1) CALL mxoutf (amatrx, nfem, nfem, ndimen, ndimen) WRITE(Out_unit, * ) 'Diagonal Contributions' DO ibasis = 1, nfem diagonal (ibasis) = amatrx (ibasis, ibasis) ENDDO WRITE(Out_unit, * ) (diagonal (ibasis), ibasis = 1, nfem) !-------------------------------------------------------------------- ! construct s(trans)*s to test completeness of old basis. !-------------------------------------------------------------------- WRITE(Out_unit,*) 'old basis completeness test. rholast, rho= ', rholast, rho CALL vsets (ndimen * ndimen, amatrx, 1, Zero) CALL sgemm_junk (nfem, nabm, nabm, s, ndimen, s, ndimen, amatrx, ndimen, 4, 1) CALL mxoutf (amatrx, nfem, nabm, ndimen, ndimen) WRITE(Out_unit, * ) 'Diagonal Contributions' DO ibasis = 1, nabm diagonal (ibasis) = amatrx (ibasis, ibasis) ENDDO WRITE(Out_unit, * ) (diagonal (ibasis), ibasis = 1, nabm) IF(test=='ABM')THEN WRITE(Out_unit, * ) 'END of ABM test' STOP 'ABM test' ELSEIF (test=='FEM')THEN WRITE(Out_unit, * ) 'END of FEM test' STOP 'FEM test' ELSE WRITE(Out_unit, * ) 'Calculated Matrix between FEM and ABM ', 'Surface Functions' ENDIF RETURN ENDSUBROUTINE ovrfem