2
subroutine aor_r1_beta_anl (rtdb, basis, geom, omega, lstatic,
3
& ncomp,g_smat0, g_sket1, g_vecB1, g_dipel, g_quadel, g_vectors,
4
& froct, epst, nbf, nmo, nocct, nvirt, lgiao, lquad, lanalyze,
5
& lvelocity ,lifetime, lmagpert, g_vecE1, g_vecE1_im)
7
c $Id: aor_r1_beta_anl.F 21176 2011-10-10 06:35:49Z d3y133 $
9
c =================================================================
11
c purpose: analyze beta tensor. See routine
12
c aor_r1_beta.F for additional comments.
13
c Use a molecular orientation in which the chiral
14
c response tensor is diagonal!
16
c called from: aoresponse_driver_new
18
c =================================================================
24
#include "mafdecls.fh"
34
c ---------------------
35
c subroutine arguments:
36
c ---------------------
38
integer rtdb ! [input] run-time database handle
39
integer basis ! [input] basis handle
40
integer geom ! [input] geometry handle
42
c These are all input, too
43
integer g_smat0, g_vectors(2), g_dipel,
44
& g_sket1, g_quadel, g_vecB1, g_vecE1(2), g_vecE1_im(2)
45
integer nfreq, response_order, nbf, nmo, ncomp
46
integer nocct(2), nvirt(2)
47
double precision froct(nbf,2), epst(nbf,2)
48
double precision gamwidth, omega
49
logical lgiao, lquad, lanalyze, lvelocity, lifetime, lmagpert,
56
c global array handles:
60
& g_temp, g_tmpanl, g_tran, g_vectmp(2)
62
integer l_diag, k_diag
64
c other local variables:
66
integer nmot(2), nocvir(2), nopen(2)
67
data nopen(1),nopen(2)/0,0/
69
integer dims(3), chunk(3)
70
integer alo(3), ahi(3), blo(3), bhi(3), clo(3), chi(3)
72
c dipole-quadrupole polarizability, cartesian rep.:
73
double precision dipquadre(3,6), dipquadim(3,6)
74
c traceless dipole-quadrupole tensor, full storage
75
double precision dqpol(3,3,3)
77
integer LCTensor(3,3,3)
79
double precision tmpmat(3,3)
81
character*(256) cstemp
83
character*(1) direction(3)
84
data direction/'x','y','z'/
87
integer ipm, nocc, nvir, nocv, imo, jmo, nmo1, idir, iresp,
89
logical debug, dbgmat,
90
& lzora, lantisym, lmo, status, oprint
91
double precision sum, scaling
92
double precision tenm8, one, two, three, zero, half, third, four
93
parameter (tenm8=1d-8, one=1d0, two=2d0, three=3d0,
94
& zero=0d0, half=one/two,
95
& third=one/three, four=4.0d0)
99
character*(256) lmotrans
101
external file_read_ga
103
double precision ga_trace_diag
104
external ga_trace_diag
106
c ====================================================================
108
debug = .false. ! .true. during development
109
dbgmat = .false. ! debug large matrices
110
oprint = ga_nodeid().eq.0
112
if (debug) write (luout,*) 'hello from aor_r1_beta_anl'
117
c make sure lvelocity.ne.T., we do not support that in this
118
c subroutine to keep the clutter at a manageable level.
122
& call errquit ('aor_beta: lvelocity set',1,INPUT_ERR)
125
& call errquit ('aor_beta: lmagpert set',1,INPUT_ERR)
128
c -------------------------
129
c define Levi-Civita tensor for quadrupole additions
130
c -------------------------
139
c define translation table for quadrupole incices in
141
c XX=1, XY=YX=2, XZ=ZX=3, YY=4, YZ=ZY=5, ZZ=6
152
c set parameters that control the various computational options
153
c (later we will set most of this by input)
154
nspin = 1 ! assume closed shell
155
lzora = .false. ! not yet available here
157
if (debug) write (luout,*) 'giao, velocity',
161
c -----------------------------------------
162
c determine number of occ * virt orbitals
163
c and nmot(1:2) and fix froct, if necessary
164
c -----------------------------------------
167
nocvir(ispin) = nocct(ispin) * nvirt(ispin)
169
if (nmo .lt.nbf) then
171
froct(imo,ispin) = 0d0
176
c ----------------------------------------------
177
c check if we have localized MOs on file. If yes
178
c read them, assuming nspin.eq.1
179
c ----------------------------------------------
182
status=rtdb_get(rtdb,'prop:pmlocalization',MT_INT,1,i)
185
if (oprint) write (luout,*) 'analysis: LMO switch found'
186
write (cstemp,'(a)') 'aor_beta: g_tran'
187
if(.not.ga_create(MT_DBL, nocct(1), nocct(1), trim(cstemp),
189
& call errquit (trim(cstemp),0,GA_ERR)
190
if (debug) write (luout,*) 'g_tran allocated'
191
call util_file_name('lmotrans',.true.,.true.,lmotrans)
192
if(.not.file_read_ga(lmotrans,g_tran)) call errquit
193
$ ('aor_r1_beta_anl: could not read lmotrans',0, DISK_ERR)
196
c ----------------------------------------------------
197
c start loop over spins (nspin=2 not yet supported !!!)
198
c ----------------------------------------------------
202
nmo1 = nmot(ispin) ! total no.of MOs for this spin
203
nocc = nocct(ispin) ! occupied MOs
204
nvir = nvirt(ispin) ! virtual MOs
205
nocv = nocvir(ispin) ! nocc * nvir
207
c ------------------------------
208
c allocate some temp. work space
209
c ------------------------------
215
write(cstemp,'(a)') 'work'
216
if (.not.nga_create(MT_DBL,2,dims,cstemp(1:4),chunk,
218
& errquit('aoresponse: nga_create failed: '//cstemp(1:4),
220
call ga_zero (g_work)
222
c allocate intermediate vector for matrix multiplications
223
c used to create the final results
225
write (cstemp,'(a)') 'aor_beta: temp1'
226
if(.not.ga_create(MT_DBL, nbf, nocc, trim(cstemp),
228
& call errquit (trim(cstemp),0,GA_ERR)
229
if (debug) write (luout,*) 'g_temp allocated'
231
c allocate matrix that accumulates the analysis data
233
write (cstemp,'(a)') 'aor_beta: g_anl'
234
if(.not.ga_create(MT_DBL, nocc, nocc, trim(cstemp),
236
& call errquit (trim(cstemp),0,GA_ERR)
237
if (debug) write (luout,*) 'g_anl allocated'
240
c diagonal elements of the last matrix
241
if (.not. ma_push_get(mt_dbl, nocc, 'diag', l_diag, k_diag))
242
& call errquit('error alloc MA diag', 0, MA_ERR)
244
c lmos: debug transformation
245
if (lmo .and. debug) then
246
call ga_print(g_tran)
247
call ga_dgemm('t', 'n', nocc, nocc, nocc,
248
$ 1.0d0, g_tran, g_tran, 0.0d0, g_anl)
252
c ---------------------------------------------------------
253
c solution of CPKS is in g_vecE1. Below we need
254
c only the sum of the +/- components so we add them here
255
c and store them in g_vecE1(1)
256
c ---------------------------------------------------------
259
call ga_add(1d0, g_vecE1(1), 1d0, g_vecE1(2),
262
call ga_add(1d0, g_vecE1_im(1), 1d0, g_vecE1_im(2),
267
c ------------------------------------------------
268
c for Buckingham-Dunn tensor we need the traceless
270
c ------------------------------------------------
274
c a) from trace -> g_work
275
call ga_zero(g_work) ! use for trace
282
alo(3) = qindex(iresp,iresp)
283
ahi(3) = qindex(iresp,iresp)
289
call nga_add_patch(one,g_quadel,alo,ahi,
290
& one,g_work,blo,bhi,g_work,blo,bhi)
293
c b) scale quadel by 3
294
call ga_scale(g_quadel,three)
296
c c) subtract trace from diagonal
304
alo(3) = qindex(iresp,iresp)
305
ahi(3) = qindex(iresp,iresp)
311
call nga_add_patch(one,g_quadel,alo,ahi,
312
& -one,g_work,blo,bhi,g_quadel,alo,ahi)
315
c d) divide the result by two, then by three
316
c because of the factor by which the result enters
317
c the Buckingham-Dunn tensor
319
call ga_scale(g_quadel, half*third)
321
! if (debug) call ga_print(g_quadel)
324
c ---------------------------------------------------------
325
c start loop over the components of the response tensor and
326
c calculate the final results
327
c ---------------------------------------------------------
329
do idir = 1,3 ! direction of the perturbing field
331
c g_anl is going to accumulate the results
335
& write (luout,'(1x,40(''-'')/1x,a,2i1)')
336
& 'MO analysis of OR tensor component ',idir,idir
338
c -------------------------------------------------------
339
c (A) calculate optical rotation beta from C(E) S(0) C(B)
340
c ------------------------------------------------------
352
blo(3) = idir ! pick magnetic field direction
360
call nga_matmul_patch('n','n',1d0,0d0,
365
if (debug) write (luout,*)
366
& 'beta: S(0) C(B) intermediate complete'
384
call nga_matmul_patch('t','n',1d0,0d0,
389
c the factor of two is for the orbital occupations,
390
c assuming that ispin is never equal to two
393
if (lstatic) scaling = four
394
call nga_add_patch(scaling,g_work,clo,chi,
395
& one,g_anl,clo,chi,g_anl,clo,chi)
397
if (debug) write (luout,*) 'beta: C(E) S(0) C(B) complete'
401
c --------------------------------------
402
c if we use GIAOs there is a second term
403
c in beta which is C(E) S(1ket) C(0)
404
c --------------------------------------
410
alo(3) = idir ! pick the correct sket1 direction
422
call nga_matmul_patch('n','n',1d0,0d0,
424
& g_vectors(ispin),blo,bhi,
427
if (debug) write (luout,*)
428
& 'beta: S(ket1) C(0) intermediate complete'
446
call nga_matmul_patch('t','n',1d0,0d0,
451
c the factor of two is for the orbital occupations,
452
c assuming that ispin is never equal to two
455
if (lstatic) scaling = four
456
call nga_add_patch(scaling,g_work,clo,chi,
457
& one,g_anl,clo,chi,g_anl,clo,chi)
459
if (debug) write (luout,*)
460
& 'beta: C(E) S(ket1) C(0) complete'
466
c ----------------------------------------------------
467
c if requested by input, add to OR beta the quadrupole
468
c polarizability terms
469
c ----------------------------------------------------
473
c add the quadrupole terms to the B.-D. tensor
477
if (LCtensor(idir,k,l).eq.0) goto 1000
479
iresp = qindex(l,idir)
485
alo(3) = iresp ! pick direction iresp for g_quadel
498
call nga_matmul_patch('n','n',1d0,0d0,
500
& g_vectors(ispin),blo,bhi,
503
if (debug) write (luout,*)
504
& 'quad: h(Q) C(0) intermediate complete'
510
alo(3) = k ! not idir, see equation
523
call nga_matmul_patch('t','n',1d0,0d0,
528
c the factor of two is for the orbital occupations,
529
c assuming that ispin is never equal to two
532
if (lstatic) scaling = -four
534
c Levi-Civita symbol:
535
scaling = scaling * LCtensor(idir,k,l)
537
if (debug) write (luout,*) 'scaling=',scaling
538
call nga_add_patch(scaling,g_work,clo,chi,
539
& one,g_anl,clo,chi,g_anl,clo,chi)
541
if (debug) write (luout,*)
542
& 'quad C(Q) h(E) C(0) complete'
544
1000 continue ! jump here if LCTensor(idir,k,l) is 0
551
c -----------------------------------------
552
c end loop over responding field components
553
c -----------------------------------------
555
c ---------------------
556
c Canonical MO analysis
557
c ---------------------
559
if (oprint) write (luout,
560
& '(/t12,a,t26,a/t11,6(''-''),t22,12(''-''))')
563
call ga_get_diagonal(g_anl, dbl_mb(k_diag) )
567
sum = sum + dbl_mb(k_diag+i-1)
568
if (oprint) write (luout,'(t11,i6,t22,f12.4)')
569
& i,dbl_mb(k_diag+i-1)
572
& write (luout,'(1x,a,2i1,a,f12.4)') 'Component ',idir,idir,
575
if (oprint) write (luout,'(1x,40(''-''))')
578
sum = ga_trace_diag(g_anl)
579
if (oprint) write (luout,*) 'sum from ga_trace: ',sum
582
c ---------------------
583
c Localized MO analysis
584
c ---------------------
588
c test: symmetrize the g_anl matrix before the LMO trafo:
590
& write (luout,*) 'Message from beta_anl: Symmetrizing X'
591
call ga_symmetrize(g_anl)
593
write (cstemp,'(a)') 'aor_beta: tmpanl'
594
if(.not.ga_create(MT_DBL, nocc, nocc, trim(cstemp),
596
& call errquit (trim(cstemp),0,GA_ERR)
597
if (debug) write (luout,*) 'g_tmpanl allocated'
599
call ga_zero(g_tmpanl)
600
call ga_dgemm('t', 'n', nocc, nocc, nocc,
601
$ 1.0d0, g_tran, g_anl, 0.0d0, g_tmpanl)
603
call ga_dgemm('n', 'n', nocc, nocc, nocc,
604
$ 1.0d0, g_tmpanl, g_tran, 0.0d0, g_anl)
606
if (.not.ga_destroy(g_tmpanl))
608
& ('aor_beta: ga_destroy failed g_tmpanl',
611
if (oprint) write (luout,
612
& '(/t12,a,t26,a/t11,6(''-''),t22,12(''-''))')
615
call ga_get_diagonal(g_anl, dbl_mb(k_diag) )
619
sum = sum + dbl_mb(k_diag+i-1)
620
if (oprint) write (luout,'(t11,i6,t22,f12.4)')
621
& i,dbl_mb(k_diag+i-1)
624
& write (luout,'(1x,a,2i1,a,f12.4)')
625
& 'Component ',idir,idir,': Sum = ',sum
627
if (oprint) write (luout,'(1x,40(''-''))')
630
sum = ga_trace_diag(g_anl)
631
if (oprint) write (luout,*) 'sum from ga_trace: ',sum
639
c -------------------------------------------
640
c end loop over perturbing E-field components
641
c -------------------------------------------
649
if (.not.ga_destroy(g_temp))
651
& ('aor_beta: ga_destroy failed g_temp',
655
if (.not.ga_destroy(g_work))
657
& errquit('aoresponse: ga_destroy failed g_work',
660
if (.not.ga_destroy(g_anl))
662
& ('aor_beta: ga_destroy failed g_anl',
665
if (.not. ma_pop_stack(l_diag))
666
& call errquit('error deloc MA diag',0, MA_ERR)
668
c ---------------------------------------------------
669
c part of the analysis is storing the perturbed
670
c MOs. As elsewhere, we assume a closed shell system.
671
c We write a lot of data here, e-field and b-field
672
c perturbed canonical MOs and, if applicable, LMOs
673
c ----------------------------------------------------
679
write(cstemp,'(a)') 'vectmp(1)'
680
if (.not.nga_create(MT_DBL,2,dims,cstemp(1:4),chunk,
682
& errquit('aoresponse: nga_create failed: '//cstemp(1:9),
684
call ga_zero (g_vectmp(1))
700
call ga_zero(g_vectmp(1))
701
call nga_copy_patch('n',g_vecE1,alo,ahi,g_vectmp(1),blo,bhi)
703
write(cstemp,'(a,i1,a)') 'cmo-efield',idir,'.movecs'
704
call hnd_vec_write(rtdb,geom,basis,nbf,nocct,nopen, nvirt
705
& ,'scf',g_vectmp,froct, epst,nmot, cstemp)
707
call ga_zero(g_vectmp(1))
708
call nga_copy_patch('n',g_vecB1,alo,ahi,g_vectmp(1),blo,bhi)
710
write(cstemp,'(a,i1,a)') 'cmo-bfield',idir,'.movecs'
711
call hnd_vec_write(rtdb,geom,basis,nbf,nocct,nopen, nvirt
712
& ,'scf',g_vectmp,froct, epst,nmot, cstemp)
731
call ga_zero(g_vectmp(1))
732
call nga_matmul_patch('n','n',1d0,0d0,
735
& g_vectmp(1),clo,chi)
737
write(cstemp,'(a,i1,a)') 'lmo-efield',idir,'.movecs'
738
call hnd_vec_write(rtdb,geom,basis,nbf,nocct,nopen, nvirt
739
& ,'scf',g_vectmp,froct, epst,nmot, cstemp)
741
call ga_zero(g_vectmp(1))
742
call nga_matmul_patch('n','n',1d0,0d0,
745
& g_vectmp(1),clo,chi)
747
write(cstemp,'(a,i1,a)') 'lmo-bfield',idir,'.movecs'
748
call hnd_vec_write(rtdb,geom,basis,nbf,nocct,nopen, nvirt
749
& ,'scf',g_vectmp,froct, epst,nmot, cstemp)
755
if (.not.ga_destroy(g_vectmp(1))) call errquit ('aor_beta:
756
& ga_destroy failed g_vectmp(1)', 0,GA_ERR)
758
c -------------------------------------------------
759
c un-add the frequency components in vec_E1 in case
760
c we reuse these arrays:
761
c -------------------------------------------------
764
call ga_add(1d0, g_vecE1(1), -1d0, g_vecE1(2),
767
call ga_add(1d0, g_vecE1_im(1), -1d0, g_vecE1_im(2),
773
enddo ! ispin = 1,2 from way above
775
c ---------------------------------------------------------------
776
c end loop over spin components (which we don't use right now
777
c since nspin is forced to be 1 at the beginning of this routine)
778
c ---------------------------------------------------------------
782
if (.not.ga_destroy(g_tran))
784
& ('aor_beta: ga_destroy failed g_tran',0,GA_ERR)
792
c ==================================================================