CONGEN 5.0
Configuration generation for SCATCI
Loading...
Searching...
No Matches
congen_projection.f90
Go to the documentation of this file.
1! Copyright 2019
2!
3! For a comprehensive list of the developers that contributed to these codes
4! see the UK-AMOR website.
5!
6! This file is part of UKRmol-in (UKRmol+ suite).
7!
8! UKRmol-in is free software: you can redistribute it and/or modify
9! it under the terms of the GNU General Public License as published by
10! the Free Software Foundation, either version 3 of the License, or
11! (at your option) any later version.
12!
13! UKRmol-in is distributed in the hope that it will be useful,
14! but WITHOUT ANY WARRANTY; without even the implied warranty of
15! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16! GNU General Public License for more details.
17!
18! You should have received a copy of the GNU General Public License
19! along with UKRmol-in (in source/COPYING). Alternatively, you can also visit
20! <https://www.gnu.org/licenses/>.
21!> \brief Projection on spin states.
22!>
23!> Routines in this module, most prominently the central subroutine \ref projec, read back all CSFs
24!> generated in the previous part of CONGEN execution and recombine the determinants to satisfy spin
25!> composition rules. While doing that, several new combinations of spin-orbitals (determinants) may
26!> be added if there are any open shells where the electrons spins can be freely permuted. Also, the
27!> routines apply a threshold for final selection of contributing determinants, so the output can be
28!> even smaller than the input (though this mostly signalizes some error in setup).
29!>
31
32 implicit none
33
34 ! entry point of the module
35 public projec
36
37 ! support routines called from "projec"
38 private cntrct
39 private dophz
40 private dophz0
41 private iphase
42 private mkorbs
43 private pkwf
44 private pmkorbs
45 private popnwf
46 private prjct
47 private ptpwf
48 private qsort
49 private rdwf
50 private rdwf_getsize
51 private rfltn
52 private snrm2
53 private stmrg
54 private wfgntr
55 private wrnfto
56 private wrwf
57
58contains
59
60
61 !> \brief Throw away determinants with negligible contribution.
62 !>
63 !> Scans the store of determinants, discard such whose contribution (multiplication factor) is below
64 !> given tolerance, and bubbles out the vacated intervals from the storage arrays.
65 !>
66 subroutine cntrct (nelt, no, ndo, cdo, thres)
67
68 use precisn, only : wp
69
70 integer :: nelt, no
71 real(kind=wp) :: thres
72 real(kind=wp), dimension(*) :: cdo
73 integer, dimension(*) :: ndo
74 intent (in) nelt, thres
75 intent (inout) cdo, ndo, no
76
77 integer :: i, j, md, mdd, mov
78
79 mov = 0 ! number of determinants discarded so far due to the threshold
80 md = 0 ! current position in determinant storage array
81 mdd = 0 ! position of next determinant position vacated due to threshold
82
83 ! loop over all determinants
84 do i = 1, no
85 if (abs(cdo(i)) <= thres) then
86 mov = mov + 1 ! increment number of discarded determinants
87 else if (mov /= 0) then
88 mdd = md - nelt * mov ! position of next determinant position vacated due to threshold
89 cdo(i-mov) = cdo(i) ! move the next determinant factor to vacated space
90 ndo(mdd+1:mdd+nelt) = ndo(md+1:md+nelt) ! move the next determinant data to vacated space
91 end if
92 md = md + nelt ! jump to the next determinant
93 end do
94
95 no = no - mov ! update number of stored determinants
96
97 end subroutine cntrct
98
99
100 !> \brief Phase factor.
101 !>
102 !> Compute phase factor implied by placing continuum spin-orbital after all target spin-orbitals
103 !>
104 !> \note MAL 10/05/2011 Changes made are in order to bring dophz into line
105 !> with the changes made in 'projec' in order to utilize dynamic memory
106 !>
107 subroutine dophz (nftw, nocsf, nelt, ndtrf, nconf, indo, ndo, lenndo, icdo, cdo, lencdo, iphz, leniphz, iphz0, &
108 leniphz0, nctarg, nctgt, notgt, mrkorb, mdegen, ntgsym, mcont, symtyp, npflg)
109
110 use precisn, only : wp
111
112 integer :: symtyp,i,n,ntci,nt,marked,nc,mb,md,m,na,mark1,iloc,inum, &
113 ntci1, ntci0,nftw,nctarg,iph,npflg,nocsf,nelt, &
114 leniphz,leniphz0,ntgsym,lenndo,lencdo
115 integer, dimension(nelt) :: ndtrf,nconf
116 integer, dimension(lenndo) :: ndo
117 integer, dimension(nocsf) :: indo,icdo
118 real(kind=wp), allocatable :: cdo(:)
119 integer, dimension(leniphz) :: iphz
120 integer, dimension(ntgsym) :: nctgt,mrkorb,mcont,notgt,mdegen
121 integer, dimension(leniphz0) :: iphz0
122 real(kind=wp), parameter :: zero = 0.0_wp
123 logical, parameter :: zdebug = .false.
124
125 ! Debug banner header
126 write(nftw,'(/,5x,"Phase analysis for total wavefunction:",/)')
127 write(nftw,'( 5x," ")')
128 write(nftw,'( 5x," Number of CSFS (nocsf) = ",I8)') nocsf
129 write(nftw,'( 5x," Number of electrons (nelt) = ",I8)') nelt
130 write(nftw,'( 5x," Number of target states (ntgsym) = ",I8)') ntgsym
131 write(nftw,'( 5x," Spatial group type (symtyp) = ",I8)') symtyp
132 write(nftw,'( 5x," Size of packed dets (lenndo) = ",I8)') lenndo
133 write(nftw,'( 5x," Size of cdo (#dets) (lencdo) = ",I8)') lencdo
134 write(nftw,'( 5x," (nctarg) = ",I8,/)') nctarg
135 write(nftw,'( 5x,"Structure of wavefunction:",/)')
136 write(nftw,'( 5x,"Target #CSFs #Continuum Spatial Sym ")')
137 write(nftw,'( 5x,"State targ functions continuum ")')
138 write(nftw,'( 5x,"------ ------- ---------- ----------- ")')
139 do i = 1, ntgsym
140 write(nftw,'(5x,I6,2x,I7,3x,I10,2x,I10)') i, nctgt(i), notgt(i), mcont(i)
141 end do
142 write(nftw,'(/,5x,"**** End of structure of wavefunction",/)')
143
144 n = 1
145 ntci = 0
146
147 ! Descend into loop over target states
148 do nt = 1, ntgsym
149 marked = mrkorb(nt)
150
151 ! Descend into loop over number of continuum orbs
152 do nc = 1, nctgt(nt)
153
154 ! First load reference determinant
155 nconf(1:nelt) = ndtrf(1:nelt)
156
157 ! Now make substitutions
158 mb = indo(n)
159 md = ndo(mb)
160
161 cyc1: do m = 1, md
162 na = ndo(mb + m)
163 do i = 1, nelt
164 if (na == ndtrf(i)) then
165 nconf(i) = ndo(mb + md + m)
166 cycle cyc1
167 end if
168 end do
169 write(nftw,*) 'DOPHZ: help I should not have got here!!! na =', na
170 write(nftw,*) ' ndtrf ', ndtrf
171 write(nftw,*) ' nconf ', nconf
172 end do cyc1
173
174 ! We have the present configuration, find the marked orbital
175 m = merge(4, 2, symtyp <= 1 .or. mcont(nt) /= 0) ! number of tries (different spins)
176 do mark1 = marked + 0, marked + m
177 if (mark1 == marked + m) then
178 ! Not found anywhere, stop!
179 write(nftw,*) ' Configuration is ', nconf
180 stop
181 else if (any(nconf(1:nelt) == mark1)) then
182 ! Found, let's continue!
183 exit
184 end if
185 end do
186
187 ! Phase depends on where the marked orbital is in the determinant
188 ntci = ntci + 1
189 inum = count(nconf(1:nelt) > mark1)
190 if (mdegen(nt) >= 0) then
191 iph = merge(iphase(nconf,nelt), -iphase(nconf,nelt), cdo(icdo(n)) > zero)
192 iphz(ntci) = merge(iph, -iph, mod(inum, 2) == 0)
193 else
194 ! treat phase factor caused by coupling down rather than up for second
195 ! continua in degenerate symmetry/degenerate target as special case
196 iphz(ntci) = merge(iphz0(nc), -iphz0(nc), mod(inum, 2) == 0)
197 end if
198 n = n + notgt(nt)
199
200 end do ! End of loop over target states
201 end do
202
203 ! Having completed the computation, print results.
204 if (npflg > 0) then
205 write(nftw,'(//," Phase factors for CI target states:")')
206 ntci1 = 0
207 do nt = 1, ntgsym
208 ntci0 = ntci1 + 1
209 ntci1 = ntci1 + nctgt(nt)
210 write(nftw,'(/," Target symmetry",I3,/)') nt
211 write(nftw,'(25I3)') (iphz(ntci), ntci=ntci0,ntci1)
212 end do
213 write(nftw,'(//)')
214 end if
215
216 ! Subroutine return point
217 if (zdebug) then
218 write(nftw, '(/,5x,"***** dophz() - completed ",/)')
219 end if
220
221 end subroutine dophz
222
223
224 !> \brief Phase factor.
225 !>
226 !> Compute phase factor for target CSFs - given by reordering spin-orbitals in ascending order.
227 !>
228 !> \todo MAL 10/05/2011: Changes have been made to this subroutine to bring
229 !> it into line with the changes made to 'projec' and ensure to compliance
230 !> with F95 standards
231 !>
232 subroutine dophz0 (nftw, nocsf, nelt, ndtrf, nconf, indo, ndo, lenndo, icdo, cdo, lencdo, iphz, npflg)
233
234 use precisn, only : wp
235
236 integer :: n, i, mb, md, m, na, nftw, npflg, nocsf, nelt, lenndo, lencdo
237 integer, dimension(nelt) :: ndtrf,nconf
238 integer, dimension(nocsf) :: indo,icdo,iphz
239 integer, dimension(lenndo) :: ndo
240 real(kind=wp), parameter :: zero = 0.0_wp
241 real(kind=wp),dimension(lencdo) :: cdo(lencdo)
242
243 do n = 1, nocsf
244
245 ! First load reference determinant
246 nconf(1:nelt) = ndtrf(1:nelt)
247
248 ! Then make substitutions
249 mb = indo(n)
250 md = ndo(mb)
251
252 cyc1: do m = 1,md
253 na = ndo(mb + m)
254 do i = 1, nelt
255 if (na == ndtrf(i)) then
256 nconf(i) = ndo(mb + md + m)
257 cycle cyc1
258 end if
259 end do
260 write(nftw,*) 'DOPHZ0: help I should not have got here!!! na =', na
261 write(nftw,*) ' ndtrf ', ndtrf
262 write(nftw,*) ' nconf ', nconf
263 stop
264 end do cyc1
265
266 iphz(n) = merge(iphase(nconf,nelt), -iphase(nconf,nelt), cdo(icdo(n)) > zero)
267
268 end do
269
270 if (npflg > 0) then
271 write(nftw,'(5x,"Phz factor, per target CSF (",I7,"), for future use:")') nocsf
272 write(nftw,'((5x,15(I3,1x)))') (iphz(n), n=1,nocsf)
273 write(nftw,'(/)')
274 end if
275
276 end subroutine dophz0
277
278
279 !> \brief Sequence phase factor
280 !>
281 !> Compute phase factor (if any) due to out of sequence ordering of spin-orbitals in CSF stored in nconf.
282 !>
283 function iphase (nconf, nelt)
284
285 integer :: nelt
286 integer :: iphase
287 integer, dimension(nelt) :: nconf
288 intent (in) nconf, nelt
289
290 integer :: iso, iswap, m, n, nst
291
292 ! first check if there are any spin-orbitals out of sequence
293 do n = 1, nelt
294 if (n == nelt) then
295 ! all spin-orbitals are in ascending order: no phase
296 iphase = 1
297 return
298 else if (nconf(n) > nconf(n+1)) then
299 ! there is a possible phase factor!
300 exit
301 end if
302 end do
303
304 ! can we eliminate some electrons from the phase computation?
305 nst = 1
306 do n = 1, nelt
307 if (nconf(n) /= n) exit
308 nst = nst + 1
309 end do
310
311 ! logic says you can't reach this statement
312 iswap = 0
313 do m = nelt, nst + 1, -1
314 iso = nconf(m)
315 do n = nst, m - 1
316 if (iso < nconf(n)) iswap = iswap + 1
317 end do
318 end do
319
320 ! phase given by whether number of swaps is odd or even
321 iphase = merge(1, -1, mod(iswap, 2) == 0)
322
323 end function iphase
324
325
326 !> \brief Compute the orbital table.
327 !>
328 !> Computes the orbital table which is then used in the projection step. This is called from projec().
329 !> \verbatim
330 !> Input data:
331 !> ISYMTYP Switch for C-inf-v (=0 or 1) / Abelian point group (=2
332 !> NOB Number of orbitals per symmetry
333 !> NSYM Number of symmetries in the orbital set
334 !> NPFLG Flag controlling printing of computed orbital table
335 !>
336 !> Output data:
337 !> MN Orbital number associated with each spin-orbital
338 !> MG G/U designation for each spin-orbital (C-inf-v only)
339 !> Actually this is always zero because C-inf-v does not
340 !> distinguish between g/u. It exists because original
341 !> version of Alchemy tried to use it for D-inf-h too;
342 !> all CI evauation is doen in C-inf-v now because CONGE
343 !> converts D-inf-h to C-inf-v data.
344 !> MM Symmetry quantum number associated with each spin-orb
345 !> MS Spin function ( alpha or beta ) associated with each
346 !> spin orbital
347 !>
348 !> Notes:
349 !>
350 !> The orbital table establishes orbital and quantum number data for
351 !> each spin orbital in the set.
352 !>
353 !> e.g. C-inf-v symmetry with NSYM=2, NOB=3,1, yields ten spin
354 !> orbitals which are designated as follows by this routine:
355 !>
356 !> Spin orb. MN MG MM MS Comments
357 !> 1 1 0 0 0 1 sigma spin up
358 !> 2 1 0 0 1 1 sigma spin down
359 !> 3 2 0 0 0 2 sigma spin up
360 !> 4 2 0 0 1 2 sigma spin down
361 !> 5 3 0 0 0 3 sigma spin up
362 !> 6 3 0 0 1 3 sigma spin down
363 !> 7 4 0 1 0 1 pi(lambda=+1) spin up
364 !> 8 4 0 1 1 1 pi(lambda=+1) spin down
365 !> 9 4 0 -1 0 1 pi(lambda=-1) spin up
366 !> 10 4 0 -1 1 1 pi(lambda=-1) spin down
367 !> \endverbatim
368 !> \note MAL 11/05/2011 : Changes made here are to bring the subroutine into
369 !> line with the changes that were made in 'projec' in order to utilize
370 !> dynamic memory and also to comply with the F95 standard
371 !>
372 subroutine mkorbs (nob, nsym, mn, mg, mm, ms, norb, nsrb_in, map, mpos, iposit, nobl, nob0l, symtyp)
373
374 use precisn, only : wp
375 use congen_data, only : nftw
376
377 integer :: nsym
378 integer :: iposit
379 integer :: symtyp
380 integer :: norb
381 integer :: nsrb_in
382 integer :: nob(nsym)
383 integer :: mn(nsrb_in)
384 integer :: mg(nsrb_in)
385 integer :: mm(nsrb_in)
386 integer :: ms(nsrb_in)
387 integer :: map(norb)
388 integer :: mpos(nsrb_in)
389 integer :: nobl(*)
390 integer :: nob0l(nsym)
391
392 integer i, ik, ikp, ipos, is, ic, iso
393 integer j, k
394 integer m, ma, mb, m1, n, nep
395 integer ierr
396 integer len_noblj
397
398 integer :: nsrb
399 integer, allocatable :: noblj(:)
400 integer, parameter :: iwrite = 6
401 logical, parameter :: zdebug = .false.
402
403 ! Debug banner header
404
405 if (zdebug) then
406 write(nftw,'(/,10x,"====> mkorbs() <====",/)')
407 write(nftw,'(/,10x,"Input data: " )')
408 write(nftw,'( 10x," nsym = ",I6 )') nsym
409 write(nftw,'( 10x," symtyp = ",I6 )') symtyp
410 write(nftw,'( 10x," iposit = ",I6 )') iposit
411 write(nftw,'( 10x," norbs = ",I6 )') norb
412 write(nftw,'( 10x," nsrb_in = ",I6,/)') nsrb_in
413 write(nftw,'(12x,"nob: ",1x,20(I3,1x))') (nob(i), i=1,nsym)
414 if (symtyp == 1) then
415 write(nftw,'(12x,"nobl: ",1x,20(I3,1x))') (nobl(i), i=1,nsym)
416 else
417 write(nftw,'(12x,"nobl: ",1x,20(I3,1x))') (nobl(i), i=1,2*nsym)
418 end if
419 write(nftw,'(/,10x,"**** End of input data",/)')
420 end if
421
422 ! Copy the contents of input array nobl() to local storage noblj()
423 ! - When we are working with D-inf-h we need to remember that
424 ! nsym and nob refer to the C-inf-v representation, whereas
425 ! nobl() holds the D-inf-h representation. Thus we need to
426 ! double "nsym".
427
428 if (symtyp == 1) then
429 len_noblj = 2 * nsym
430 else
431 len_noblj = nsym
432 end if
433
434 allocate(noblj(len_noblj), stat = ierr)
435
436 if (ierr /= 0) then
437 write(nftw,'(/,10x,"**** Error in mkorbs() ",/)')
438 write(nftw,'(/,10x,"Cannot allocate noblj - ierr = ",I6,/)') ierr
439 stop
440 end if
441
442 noblj(1:len_noblj) = nobl(1:len_noblj)
443
444 if (iposit /= 0) then
445 do is = 1, nsym
446 noblj(is) = nobl(is) / 2
447 end do
448 end if
449
450 !======================================================================
451 !
452 ! E L E C T R O N I C O R B I T A L S
453 !
454 !======================================================================
455
456 if (symtyp == 0) then
457 ic = 1
458 iso = 4
459 else if (symtyp == 1) then
460 ic = 2
461 iso = 4
462 else
463 ic = 1
464 iso = 2
465 end if
466 if (iposit /= 0) then
467 do is = 1, nsym*ic
468 noblj(is) = nobl(is) / 2
469 end do
470 else
471 do is = 1, nsym*ic
472 noblj(is) = nobl(is)
473 end do
474 end if
475
476 ! First of all we loop over all non-degenerate electron orbitals and build the table of spin-orbitals for them.
477 ! We set mpos() to be zero for "electron" orbitals.
478 ! For linear molecules this is
479 ! C-inf-v : Sigma type
480 ! D-inf-h : Sigma_g and Sigma_u
481 ! Actually the code also handle here the first IRR of Abelian point groups too.
482
483 i = 1
484 ma = 0
485
486 do j = 1, ic
487 m1 = ma + 1
488 ma = ma + noblj(j)
489 ipos = 0
490
491 do n = m1, ma
492 map(n) = n
493
494 ! Spin orbital with spin-up
495
496 mn(i) = n
497 mg(i) = 0
498 mm(i) = 0
499 ms(i) = 0
500 mpos(i) = ipos
501
502 ! Spin orbital with spin-down
503
504 i = i + 1
505
506 mn(i) = n
507 mg(i) = 0
508 mm(i) = 0
509 ms(i) = 1
510 mpos(i) = ipos
511
512 i = i + 1
513 end do
514 end do
515
516 ! Process remaining orbitals
517 ! C-inf-v: Pi, Delta, ....
518 ! D-inf-h: Pi_u, Pi_g, Delta_g, ...
519 ! Abelian: irr = 2, 3, 4,
520
521 k = ma + 1
522
523 do m = ic + 1, nsym * ic
524 ma = noblj(m)
525 mb = (m - 1) / ic
526 ipos = 0
527 do n = 1, ma
528 map(k) = k
529 do j = 1, iso
530 mn(i) = k
531 mg(i) = 0
532 mm(i) = mb
533 ms(i) = 0
534 mpos(i) = ipos
535 i = i + 1
536 end do
537 k = k + 1
538 ms(i - 1) = 1
539 if (symtyp <= 1) then
540 mm(i - 1) = -mb
541 mm(i - 2) = -mb
542 ms(i - 3) = 1
543 end if
544 end do
545 end do
546
547 ! Compute the total number of electron type spin orbitals.
548
549 nsrb = i - 1
550
551 !======================================================================
552 !
553 ! P O S I T R O N I C O R B I T A L S
554 !
555 !======================================================================
556
557 if (iposit /= 0) then
558 write(nftw,*) ' MAP : OLD, NEW'
559 ik = k - 1
560 ikp = ik + 1
561 nep = ik + ik ! total number of orbitals (electron + positron)
562 do n = ikp, nep
563 map(n) = map(n - ik)
564 end do
565 write(nftw,*) ' MAP : OLD, NEW'
566 do n = 1, nep
567 write(nftw,*) n,map(n)
568 end do
569 DO n = ikp, nep
570 mn(ik + ikp) = n
571 ik = ik + 1
572 mn(ik + ikp) = n
573 ik = ik + 1
574 end do
575 do j=1, nep
576 mg(j+nep)=mg(j)
577 mm(j+nep)=mm(j)
578 ms(j+nep)=ms(j)
579 mpos(j+nep)=1
580 end do
581 nsrb = 2 * nsrb
582 end if
583
584
585 ! Now print-out a table of the spin-orbitals
586
587 write(nftw,*) ' I N G M S MPOS '
588
589 do j = 1, nsrb
590 write(iwrite,'(10x,7I10)') j, mn(j), mg(j), mm(j), ms(j), mpos(j)
591 end do
592
593 if (nsrb /= nsrb_in) then
594 write(iwrite,'(" HELP!!! MKORBS: NSRB, NSRBD = ",2I6)') nsrb, nsrb_in
595 stop 999
596 end if
597
598
599 ! Return point
600 ! - Release any allocated storage
601
602 if (allocated(noblj)) then
603 deallocate(noblj, stat = ierr)
604
605 if (0 /= ierr) then
606 write(iwrite,'(/,10x,"**** Error in mkorbs() ",/)')
607 write(iwrite,'(/,10x,"Cannot deallocate noblj - ierr = ",I6,/)') ierr
608 stop 999
609 end if
610 end if
611
612 if (zdebug) then
613 write(iwrite,'(/,10x,"***** Completed - mkorbs() ",/)')
614 end if
615
616 end subroutine mkorbs
617
618
619 !> \brief Pack wave function.
620 !>
621 !> Reformats (packs) the CSF expression into the style used throughout the rest of Alchemy, that is as a set of
622 !> replacements from the reference determinant. Adds this to the end of the array ntdo() from location "ndo".
623 !>
624 !> On entry to this routine we have the CSF defined for us as follows (from the projection step):
625 !> 1. there are "nod" determinants
626 !> 2. each determinant is of length "ieltp".
627 !> 3. "cdo" contains the coefficient which multiplies each determinant. This is derived from the coupling process.
628 !> 4. the determinants are stored in "mdo", as a list of spin orbitals - so it is of lenth nod*ieltp
629 !>
630 !> The above information is complemented by the analysis in the calling routine which classifies spin orbitals in this CSF
631 !> wrt the reference determinant:
632 !>
633 !> 5. "idopl" is the number of spin orbs in the reference det but not present in this CSF;
634 !> "mdop()" is the list of those spin orbitals
635 !> 6. "idcpl" is the number of spin orbs in this CSF but not present in the reference determinant;
636 !> "mdcp()" is the list of those spin orbitals.
637 !>
638 !> So, given all of the above information, the determinants in "mdo" are processed and each expressed in the format
639 !> - number of replacements from ref determinant
640 !> - list of replaced spin orbitals
641 !> - list of replacing spin orbitals
642 !>
643 !> The output is placed into array "ndto". The length available in "ndto" is passed into the routing in "len_ndto" and this is
644 !> monitored to be sure we do not overflow it.
645 !>
646 !> During the process, it may be necessary to multiply "cdo" by -1 as we order spin orbitals. cdo() holds the coefficients
647 !> associated with each determinant. These were constructed earlier in the spin projection - note we only receive the relevant
648 !> "piece" of the cdo(0 array in the arglist, the bit for this CSF, not all of it for all CSFs, as is the case with "ndto()".
649 !> "nftw" is the logical unit for the printer
650 !>
651 !> \note MAL 11/05/2011: Changes made here are to bring the subroutine into
652 !> line with the changes that were made in 'projec' in order to utilize
653 !> dynamic memory and to comply with the F95 standard.
654 !>
655 subroutine pkwf (nod, ieltp, cdo, mdo, idopl, mdop, idcpl, mdcp, nftw, ndo, ndto, len_ndto, ithis_csf)
656
657 use precisn, only : wp
658
659 integer nod ! number of determinants
660 integer ieltp ! number of electrons in each determinant
661 integer idopl, mdop(idopl) ! S.O.s in refdet but not in this CSF.
662 integer idcpl, mdcp(idcpl) ! S.O.s in this CSF but not ref det.
663 integer mdo(nod*ieltp) ! the determinants on input
664 integer nftw ! logical unit for the printer
665 integer len_ndto, ndto(len_ndto) ! the determinants on output
666 integer ndo ! On output points to the highest location used in array ndto
667 integer ithis_csf ! The present CSF index - helpful in error msgs.
668
669 real(kind=wp) :: cdo(nod) ! coupling coeffs for each deterinant
670
671 integer i, j, k, n, nc, nd, md, mdopi
672 integer mdi(idcpl+ieltp) ! Temporary workspace array
673 integer nt(idopl) ! Temporary workspace array
674
675 logical, parameter :: zdebug = .false.
676
677 ! Debug banner header
678 if (zdebug) then
679 write(nftw,'(/,10x,"====> PKWF() <====",/)')
680 write(nftw,'( 10x,"Input data: ")')
681 write(nftw,'( 10x," No. of determinants (nod) = ",I5)') nod
682 write(nftw,'( 10x," No of electrons per det (ieltp) = ",I5)') ieltp
683 write(nftw,'( 10x," Input determinants: ")')
684 md = 0
685 do i = 1, nod
686 write(nftw,'(/,10x," Determinant ",I5," Coeffcient = ",F13.6,/)') i, cdo(i)
687 write(nftw,'( 10x," Spin orbs: ",20(I3,1x),/,(25x,20(I3,1x)))') (mdo(md+j), j=1,ieltp)
688 md = md + ieltp
689 end do
690 write(nftw,'(/,10x," No. spin orbs in the reference det ")')
691 write(nftw,'( 10x," but not present in this CSF (idopl) = ",I5,/)') idopl
692 write(nftw,'( 10x," mdop: ",10(I3,1x),/,(16x,10(i3,1x)))') (mdop(i), i=1,idopl)
693 write(nftw,'(/,10x," No. spin orbs in this CSF but ")')
694 write(nftw,'( 10x," not present in ref det (idcpl) = ",I5,/)') idcpl
695 write(nftw,'( 10x," mdcp: ",10(I3,1x),/,(16x,10(I3,1x)))') (mdcp(i), i=1,idcpl)
696 write(nftw,'(/,10x,"Space available in ndto() = ",I10,/)') len_ndto
697 end if
698
699 ! Special case is where idopl is 0. There is no work to be done.
700 ! We have same spin orbitals as the reference determinant.
701
702 if (idopl == 0) then
703
704 ndto(ndo) = 0
705 ndo = ndo + 1
706
707 else
708
709 ! Loop over all determinants in this CSF
710 !
711 ! "md" points at the location of the input determinant as we work though the list. Remember that each is
712 ! of length ieltp.
713
714 md = 0
715
716 do k = 1, nod
717
718 ! Populate mdi() with the list of spin orbitals in this CSF but not in the reference determinant.
719 mdi(1:idcpl) = mdcp(1:idcpl)
720
721 nd = idcpl
722
723 ! Copy the current determinant onto the end of array mdi()
724 do i = 1, ieltp
725 nd = nd + 1
726 mdi(nd) = mdo(md + i)
727 end do
728
729 ! Extract the list of spin orbitals which have replaced those in the reference determinant but not present in
730 ! this CSF - as defined by array MDOP().
731 !
732 ! We build "nt()" are a set pointers into mdi().
733
734 nd = 0
735
736 outer_loop: do i = 1, idopl
737 mdopi = mdop(i)
738 inner_loop: do j = 1, idopl
739 if (mdi(j) == mdopi) then
740 if (i /= j) then
741 cdo(k) = -cdo(k)
742 mdi(j) = mdi(i)
743 end if
744 mdi(i) = 0
745 cycle outer_loop
746 end if
747 end do inner_loop
748 nd = nd + 1
749 nt(nd) = i
750 end do outer_loop
751
752 ! Ok, we now know how long the "packed" determinant is.
753 ! Let's check that we have enough space available in NDTO in which to store the data.
754 !
755 ! This data is:
756 !
757 ! number of replacements
758 ! list of replaced spin orbs
759 ! list of replacing spin orbs
760
761 if (ndo + 2 * nd > len_ndto) then
762 write(nftw,'(/,10x,"***** Error in: PKWF() ",/)')
763 write(nftw,'( 10x,"There is not enough space in NDTO to store the ")')
764 write(nftw,'( 10x,"present determinant (",I4," of ",I4," ). ")') k, nod
765 write(nftw,'( 10x,"Space needed = ",I8," Given (len_ndto) = ",I8)') ndo+2*nd, len_ndto
766 write(nftw,'( 10x,"This present CSF number = ",I10,/)') ithis_csf
767 stop 999
768 end if
769
770 ! Copy the determinant into place in NDTO
771 ! It is useful to remember that "nd" is the number of replacements from the reference determinant
772
773 ndto(ndo) = nd
774 nc = ndo + nd
775
776 do i = 1, nd
777 n = nt(i)
778 ndto(ndo+i) = mdop(n)
779 ndto(nc+i) = mdi(n)
780 end do
781
782 if (zdebug) then
783 write(nftw,'(/,10x,"Packed format for determinant ",I5,": ",/)') k
784 write(nftw,'( 10x,20(I3,1x))') (ndto(i), i =ndo,ndo+2*nd)
785 end if
786
787 ndo = ndo + nd + nd + 1
788
789 ! Augment the pointer for the next determinant
790 md = md + ieltp
791
792 end do ! End of loop over determinants in this CSF
793
794 end if
795
796 ! Subroutine return point
797
798 if (zdebug) then
799 write(nftw,'(/,10x,"On output: ")')
800 write(nftw,'( 10x," Highest location in ndto() (ndo) = ",i10,/)') ndo
801 write(nftw,'(/,10x,"**** PKWF() - completed",/)')
802 end if
803
804 end subroutine pkwf
805
806
807 !> \brief ?
808 !>
809 subroutine pmkorbs (nob, nobe, nsym, mn, mg, mm, ms, nsrb, norb, nsrbd, map, mpos, iposit, symtyp)
810
811 use congen_data, only : nftw
812
813 integer :: symtyp, maxspin, imo, emo, ispin, iso, ipos, isym, j, jmo, maxmo, minmo, n, amo, nsrbd, &
814 nsym, iposit, norb, nsrb
815 integer :: nob(nsym), nobe(nsym), mpos(nsrb), map(norb)
816 integer :: mn(nsrb), mg(nsrb), mm(nsrb), ms(nsrb)
817
818 ! Setting up the following arrays:
819 !
820 ! mn() = orbital number
821 ! mg() = ??? distinguish gerade and ungerade
822 ! mm() = ??? m-quantum number for degenerate MOs
823 ! ms() = spin (for alpha=0, for beta=1)
824 ! mpos() = flag for positron (for e-=0, for p+=1)
825 !
826 ! NOTE: only implemented for poly-atomic code (symtyp=2)
827
828 if (symtyp /= 2) then
829 write(nftw,*) ' ERROR in PMKORBS: calculation with positrons'
830 write(nftw,*) ' only possible for SYMTYP=2'
831 write(nftw,*) ' (abelian groups).'
832 write(nftw,*) ' here: SYMTYP=',symtyp
833 stop
834 end if
835
836 maxspin = 2
837
838 ! imo = mo-number
839 ! iso = so-number
840 ! ipos = positron-flag
841 ! = 0 for 1..nobe(isym)
842 ! = 1 for nobe(isym)..nob(isym)
843
844 imo = 0
845 iso = 0
846 emo = 0
847
848 do isym = 1, nsym
849
850 ! electronic MOs
851 ipos = 0
852 maxmo = nobe(isym)
853 amo = emo
854 do jmo = 1, maxmo
855 imo = imo + 1
856 emo = emo + 1
857 map(imo) = emo
858 do ispin = 1, maxspin
859 iso = iso + 1
860 mn(iso) = imo
861 mg(iso) = 0
862 mm(iso) = isym - 1
863 ms(iso) = ispin - 1
864 mpos(iso) = ipos
865 end do
866 end do
867
868 ! positronic MOs
869 ipos = 1
870 minmo = nobe(isym) + 1
871 maxmo = nob(isym)
872 !shift=ipos*nobe(isym)
873 emo = amo
874 do jmo = minmo, maxmo
875 imo = imo + 1
876 emo = emo + 1
877 !map(imo) = imo - shift
878 map(imo) = emo
879 do ispin = 1, maxspin
880 iso = iso + 1
881 mn(iso) = imo
882 mg(iso) = 0
883 mm(iso) = isym - 1
884 ms(iso) = ispin - 1
885 mpos(iso) = ipos
886 end do
887 end do
888
889 end do
890
891 nsrb = iso
892
893 ! output the labels
894 write(nftw,*) ' MAP : OLD, NEW'
895 do n = 1, norb
896 write(nftw,*) n, map(n)
897 end do
898
899 write(6,*) ' I N G M S MPOS '
900
901 do j = 1, nsrb
902 write(6,'(10X,7I10)') j, mn(j), mg(j), mm(j), ms(j), mpos(j)
903 end do
904
905 ! Control number of spin orbitals
906 write(6,*) 'GIVEN NSRBD=', nsrbd
907 write(6,*) 'CALCULATED NSRB=', nsrb
908
909 if (nsrb /= nsrbd) then
910 write(6,'(" HELP!!! MKORBS: NSRB, NSRBD = ",2I6)') nsrb, nsrbd
911 stop
912 end if
913
914 end subroutine pmkorbs
915
916
917 !> \brief Get open-shell part of determinants.
918 !>
919 !> Fills the array \c mop with subset of specification of every determinant for the current CSF. Only spin-orbitals
920 !> that are in open shells are used, as the rest does not participate in spin composition done later in \ref prjct.
921 !> The written spin-orbitals are also immediately sorted in non-descending order. The even or odd number of swaps needed
922 !> for sorting is returned (as .false. and .true., respectively) via the logical array \c flip, so that the sign of
923 !> determinant coefficients within this CSF can be adjusted to the used order.
924 !>
925 !> \verbatim
926 !> OUTPUT IDOP NO OF SO IN DR BUT NOT IN DC
927 !> MDOP(NELT) SO IN DR BUT NOT IN DC
928 !> IDCP NO OF SO IN DC BUT NOT IN DR
929 !> MDCP(NELT) SO IN DC BUT NOT IN DR
930 !> IELTP NO OF SO IN OPEN SHELLS FOR A DTR
931 !> MOP(MOPMX) SO
932 !> \endverbatim
933 !>
934 !> \note In the original code there was a common block
935 !> \verbatim
936 !> /OWF/ IDOP,IDCP,IELTP
937 !> \endverbatim
938 !> which was used to pass three integer values back to the
939 !> caling routine. these have now been placed into the
940 !> argument list; correspondingly the routine WFGNTR has
941 !> been modified. It is the only routine whihc calls this
942 !> one. the purpose of the variables is as follows:
943 !> \verbatim
944 !> IDOP holds the number of entries in MDOP
945 !> IDCP holds the number of entries in MDCP
946 !> IELTP is the number of electrons in open shell
947 !> \endverbatim
948 !>
949 subroutine popnwf (nsrb, nsrbs, nelt, ndtrf, mopmx, mdop, mdcp, mop, mdc, mdo, ndta, nod, nda, idop, idcp, ieltp, flip, nalm)
950
951 use precisn, only : wp
952
953 integer nsrb
954 integer nsrbs
955 integer nelt
956 integer nod ! Number of replacements from reference
957 integer nalm ! Output - return code
958 ! =0, normal exit
959 ! =1, different neltp
960 ! =2, need more space for mop
961 ! =3, neltp=0, but nod not =1
962
963 integer :: ndtrf(nelt) ! Input: the reference determinant
964 integer :: mdc(nsrb) ! Workspace: spin orbs in closed shell, common to all determinants
965 integer :: mdo(nsrb) ! Workspace: Union of all spin-orbs in open shell
966 integer :: ndta(nsrb) ! Workspace: to expand to full determinant (how many times each spin-orbital is used in CSF)
967 integer :: mopmx ! Maximum size of the mop() array
968 integer :: mop(mopmx) ! Spin-orbs
969 integer :: mdop(nelt)
970 integer :: mdcp(nelt)
971 logical :: flip(nod) ! Sign-correction factor for each determinant
972 integer :: nda(*) ! Input - the array of packed determinants on which we work
973
974 integer idop, idcp, ieltp
975
976 integer i, k, m, md, me, n, na, nb, ndo, ndc, nod2, nd, no, no0
977 integer ndop, ndcp, neltp
978
979 integer, parameter :: nftw = 6 ! logical unit for printer
980
981 logical, parameter :: zdebug = .false.
982
983 ! Debug banner header
984 if (zdebug) then
985 write(nftw,'(/,25x,"====> POPNWF() <====",/)')
986 write(nftw,'(/,25x,"Input data: ")')
987 write(nftw,'( 25x," No. of spin orbitals (nsrb) = ",I10)') nsrb
988 write(nftw,'( 25x," No .of sigma-type spin orbs (nsrbs) = ",I10)') nsrbs
989 write(nftw,'( 25x," No. of electrons (nelt) = ",I10)') nelt
990 write(nftw,'( 25x," Units available in mop() (mopmx) = ",I10)') mopmx
991 write(nftw,'( 25x," No. of dets in this CSF (nod) = ",I10,/)') nod
992 write(nftw,'( 25x," Ref det = ",10(I5,1x),/,(37x,10(I5,1x)))') (ndtrf(i), i=1,nelt)
993 end if
994
995 ! Initialize the return data
996 idop = 0
997 idcp = 0
998 ieltp = 0
999 nalm = 0
1000
1001 ! Initialize local data
1002 ndop = 0
1003 ndcp = 0
1004 neltp = 0
1005
1006 !======================================================================
1007 !
1008 ! S T E P : 1
1009 !
1010 !======================================================================
1011
1012 ! We build NDTA() which repesents the spin-orbitals used in this CSF.
1013 ! We start by initializing NDTA which is of length equal to the number of spin-orbitals in the system.
1014
1015 ndta(1:nsrb) = 0
1016
1017 ! Now loop over the reference determinant and for every spin-orbital within it, we mark that spin orbital
1018 ! to be populated in EVERY determinant of this CSF. Thus we set its value in NDTA to be equal to the number
1019 ! of determinants in this CSF.
1020
1021 ndta(ndtrf(1:nelt)) = nod
1022
1023 ! Loop over all determinants in this CSF and modify the count per spin-orb in ndta()
1024
1025 md = 1 ! index in nda, where information about current determinant starts
1026
1027 do i = 1, nod
1028 m = nda(md) ! number of replacements (w.r.t. reference det) defining this determinant
1029
1030 ! Loop over all replacement/replacing spin-orbitals
1031 !
1032 ! For each replaced spin-orb, we decrement its count in ndta() and for each replacing spin-orb, we increment
1033 ! its count in ndta.
1034
1035 do k = md + 1, md + m
1036 ndta( nda(k) ) = ndta( nda(k) ) - 1 ! decrement use of "replaced" spin-orbital
1037 ndta( nda(k+m) ) = ndta( nda(k+m) ) + 1 ! increment use of "replacing" spin-orbital
1038 end do
1039
1040 ! Update the pointer "md" to be at the start of the next determinant. That is the value which defines
1041 ! the number of replacements in that determinant.
1042
1043 md = md + 2*m + 1 ! move to the next packed determinant
1044 end do
1045
1046 if (zdebug) then
1047 write(nftw,'(/,25x,"Expanded determinant (NDTA) representation after")')
1048 write(nftw,'( 25x,"processing all (",I6,") dets within the ")') nod
1049 write(nftw,'( 25x,"present CSF. ",/)')
1050 write(nftw,'( 25x,"Spin Orb. Count ")')
1051 write(nftw,'( 25x,"--------- -------")')
1052 write(nftw,'( (25x,I9,2x,I7))') (i, ndta(i), i=1,nsrb)
1053 end if
1054
1055 !==========================================================================
1056 !
1057 ! S T E P : 2
1058 !
1059 !==========================================================================
1060
1061 ! We loop over all "orbitals" which are not lambda-degenerate
1062 !
1063 ! This means all sigma type orbitals when dealing with C_inf_v and ALL orbitals when dealing with D2h and sub-groups.
1064 !
1065 ! Given we have set the occupancy of an occupied spin-orbital to "nod" initially, then since each orbital is composed of
1066 ! TWO spin orbitals, we will know that the orbital is full if its occupancy is 2*nod. It may or may have been processed
1067 ! in the list of determinants. Remember that NDTA() is summed over ALL determinants in the CSF.
1068 !
1069 ! Following code:
1070 !
1071 ! 1. Examines each orbital
1072 ! 2. If an orbital is FULL, we store the constituent spin-orbs in MDC()
1073 ! 3. Otherwise we store them in MDO()
1074 !
1075 ! Note: this code works at the orbital level but produces output at the spin-orbital level
1076
1077 nod2 = nod + nod
1078
1079 ndo = 0
1080 ndc = 0
1081
1082 do i = 1, nsrbs, 2
1083 if (ndta(i) + ndta(i+1) == nod2) then
1084 mdc(ndc+1) = i ! Fully occupied
1085 mdc(ndc+2) = i + 1
1086 ndc = ndc + 2
1087 else
1088 if (ndta(i) /= 0) then ! Partially occupied
1089 ndo = ndo + 1
1090 mdo(ndo) = i
1091 end if
1092
1093 if (ndta(i+1) /= 0) then
1094 ndo = ndo + 1
1095 mdo(ndo) = i + 1
1096 end if
1097 end if
1098 end do
1099
1100 ! We do the same thing again but now for lambda-degenerate orbitals - if any exist.
1101 ! Of course the occupany is 4*nod.
1102
1103 nod2 = nod2 + nod2
1104
1105 do i = nsrbs + 1, nsrb, 4
1106 nd = ndta(i) + ndta(i+1) + ndta(i+2) + ndta(i+3)
1107
1108 if (nd == nod2) then
1109 do k = i, i + 3
1110 ndc = ndc + 1
1111 mdc(ndc) = k
1112 end do
1113 else
1114 do k = i, i + 3
1115 if (ndta(k) /= 0) then
1116 ndo = ndo + 1
1117 mdo(ndo) = k
1118 end if
1119 end do
1120 end if
1121 end do
1122
1123 if (zdebug) then
1124 write(nftw,'(/,25x,"After step 2 we have; ",/)')
1125 write(nftw,'( 25x," Number of closed orbtials (ndc) = ",I6)') ndc
1126 write(nftw,'( 25x," Number of open orbitals (ndo) = ",I6,/)') ndo
1127 write(nftw,'( 25x,"Closed orbitals: ",20(I4,1x),/,(20x,20(I4,1x)))') (mdc(i), i=1,ndc)
1128 write(nftw,'( 25x,"Open orbitals: ",20(I4,1x),/,(20x,20(I4,1x)))') (mdo(i), i=1,ndo)
1129 end if
1130
1131 !==========================================================================
1132 !
1133 ! S T E P : 3
1134 !
1135 !==========================================================================
1136
1137 ! ndta() is an array with one entry for each spin-orbitals
1138
1139 ! First we zeroize the array + mark any spin-orbital in the reference determinant as being occuiped in ndta()
1140 ndta(1:nsrb) = 0
1141 ndta(ndtrf(1:nelt)) = 1
1142
1143 if (ndc == 0) then
1144 mdop(1:nelt) = ndtrf(1:nelt)
1145 ndop = nelt
1146 ndcp = 0
1147 else
1148 do i = 1, ndc
1149 n = mdc(i)
1150 ndta(n) = ndta(n) + 1
1151 end do
1152
1153 ndop = 0
1154 do i = 1, nelt
1155 n = ndtrf(i)
1156 if (ndta(n) == 2) cycle
1157 ndop = ndop + 1
1158 mdop(ndop) = n
1159 end do
1160
1161 ndcp = 0
1162 do i = 1, ndc
1163 n = mdc(i)
1164 if (ndta(n) == 2) cycle
1165 ndcp = ndcp + 1
1166 mdcp(ndcp) = n
1167 end do
1168 end if
1169
1170 neltp = nelt - ndc
1171
1172 if (neltp /= 0) then
1173
1174 ! Yet another use of ndta(), now: let it contain spin-orbitals from reference determinant
1175 ! and all occupied spin-orbitals in open shells.
1176
1177 ndta(1:nsrb) = 0 ! clear the array
1178 ndta(ndtrf(1:nelt)) = 1 ! put 1 to every spin-orbital in reference determinant
1179
1180 do i = 1, ndo ! loop over all occupied spin-orbitals in open shells
1181 n = mdo(i) ! index of the occupied spin-orbital
1182 ndta(n) = ndta(n) + 1 ! increment use of that spin-orbital
1183 mdc(i) = ndta(n) ! backup the value of ndta(n)
1184 end do
1185
1186 ! Loop over all determinants in the CSF, populating the array "mop" with subset of the specification of the determinants:
1187 ! only spin-orbitals in open shells are used here, as the rest (spin-orbitals in closed shells) is not interesting for
1188 ! the projection algorithm.
1189
1190 no = 0
1191 md = 1 ! index in "mda" where the current determinant information starts
1192
1193 do i = 1, nod ! loop over all determinants
1194 m = nda(md) ! number of replacements (wrt reference det) defining the current det
1195 me = md + m ! index in "mda" where the to-be-replaced orbitals list ends
1196
1197 do k = 1, m ! loop over all replacements defining this determinant
1198 na = nda(md + k) ! index of spin-orbital to be replaced ...
1199 nb = nda(me + k) ! ... by this spin-orbital
1200 ndta(na) = ndta(na) - 1 ! decrease use of replaced spin-orbital
1201 ndta(nb) = ndta(nb) + 1 ! increase use of replacing spin-orbital
1202 end do
1203
1204 no0 = no ! remember size of "mop" before addition of spin-orbitals to it
1205
1206 do k = 1, ndo ! loop over all occupied spin-orbitals in partially occupied orbitals
1207 n = mdo(k) ! label of the occupied spin-orbital
1208
1209 if (ndta(n) == 2) then
1210
1211 ! So, either already the reference determinant already uses a spin-orbital from open shell (and the current
1212 ! determinant does not replace it), or the current determinat uses a spin-orbital from open shell as a replacement
1213 ! of something else. In any case, this determinant ends with using the open-shell spin-orbital.
1214
1215 no = no + 1 ! increment number of used open-shell spin-orbitals
1216
1217 if (no > mopmx) then ! too much data - limits too tight
1218 write(nftw,'(/,25x,"**** Error in; POPNWF() ",/)')
1219 write(nftw,'(/,25x,"Exceeded size of mop() ",/)')
1220 write(nftw,'( 25x," Determinant num (i) = ",I6)') i
1221 write(nftw,'( 25x," spin orbital (no) = ",I6)') no
1222 write(nftw,'( 25x," mopmx = ",I6,/)') mopmx
1223 stop 999
1224 end if
1225
1226 mop(no) = n ! store the open-shell spin-orbital label for further processing
1227 end if
1228
1229 ndta(n) = mdc(k) ! restore "reference + open shells" spin-orbital use count ndta(n) from backup
1230 end do
1231
1232 md = md + m + m + 1 ! move on to the beginning of the next packed determinant
1233
1234 ! sort the spin-orbitals in the open-shells-only subset of the determinant and store the corresponding permutation sign
1235 flip(i) = mod(qsort(no-no0, mop(no0+1:no)), 2) /= 0
1236 end do
1237
1238 ! verify that each determinant contributed the same number of spin-orbitals from open shells
1239 if (mod(no, nod) /= 0) then
1240 write(nftw,'(/,25x,"**** Error in; POPNWF() ",/)')
1241 stop 999
1242 end if
1243
1244 end if
1245
1246 ! Finalize
1247
1248 if (neltp == 0 .and. nod /= 1) then
1249
1250 nalm = 3
1251
1252 else
1253
1254 ! We reach this point if all has gone successfully.
1255 ! We copy the work variables into the return variables and then set a return code of success (nalm=0)
1256
1257 idop = ndop
1258 idcp = ndcp
1259 ieltp = neltp
1260
1261 nalm = 0
1262
1263 end if
1264
1265 ! Subroutine return point
1266
1267 if (zdebug) then
1268 write(nftw,'(/,25x,"Output data: ")')
1269 write(nftw,'( 25x," (idop) = ",I10)') idop
1270 write(nftw,'( 25x," (idcp) = ",I10)') idcp
1271 write(nftw,'( 25x," No. electrons in open shells (ieltp) = ",I10,/)') ieltp
1272
1273 write(nftw,'( 27x,"Spin orbitals in DR but not DC: ",/)')
1274 write(nftw,'( 27x,9(I4,1x))') (mdop(i), i=1,idop)
1275 write(nftw,'(/,27x,"Spin orbitals in DC but not DR: ",/)')
1276 write(nftw,'( 27x,9(I4,1x))') (mdcp(i), i=1,idcp)
1277
1278 write(nftw,'(/,25x,"Return code (nalm) = ",I10,/)') nalm
1279 write(nftw,'(/,25x,"**** Completed - POPNWF() ",/)')
1280 end if
1281
1282 end subroutine popnwf
1283
1284
1285 !> \brief Apply Lowdin projection operator
1286 !>
1287 !> This routine applies the Lowdin projection operator. More details
1288 !> can be found in the literature at for example:
1289 !> \verbatim
1290 !> Nelson F Beebe and Sten Lucil, J Phys B: At Mol Phys, Vol. 8, Issue 14, 1975, p2320
1291 !> \endverbatim
1292 !> This routine is called when a CSF is found to have two, or more electrons in open shells. Each pair of spin-orbitals in
1293 !> each determinant is examined and potentially used to create a new determinant. Thus the output expression for the CSF
1294 !> \verbatim
1295 !> nodo, cdo(), ndo()
1296 !> \endverbatim
1297 !> may be much larger than the input
1298 !> \verbatim
1299 !> nodi, cdi(), ndo()
1300 !> \endverbatim
1301 !> Note reuse of ndo() here. cdi() is used an an extendable buffer too and must have more than "nodi" elements.
1302 !>
1303 !> The generated list of determinants is examined for any with very small coefficients (thres) and these are removed. Thus the
1304 !> the list may grow and shrink in this routine.
1305 !>
1306 !> Of course the nature of the projection process is controlled by the quantum numbers input.
1307 !>
1308 !> The routine terminates with an error message if any error conditions are found.
1309 !>
1310 subroutine prjct (nelt, mxss, nodi, ndo, cdi, nodo, cdo, maxcdo, mgvn, iss, isd, thres, r, ndtr, mm, ms, maxndo, symtyp, nsrb)
1311
1312 use precisn, only : wp
1313 use congen_bstree, only : det_tree
1314
1315 real(kind=wp) :: fcta,fctb,fctc,fctr,tmp
1316 real(kind=wp), parameter :: zero = 0.0_wp
1317 real(kind=wp), parameter :: one = 1.0_wp
1318 real(kind=wp), parameter :: four = 4.0_wp
1319
1320 integer :: nelt ! # of electrons in open shells (i.e. per det)
1321 integer :: mxss ! max S for projecttion operator
1322 integer :: nodi ! Number of determinants in CSF on input
1323 integer :: nodo ! Number of determinants in CSF in output
1324 integer :: maxcdo ! Max size of cdo()
1325 integer :: maxndo ! Max size of ndo()
1326 integer :: mgvn ! Lambda or IRR for CSF
1327 integer :: iss ! Required S value
1328 integer :: isd ! Sz for determinants
1329
1330 real(kind=wp) :: r ! +1.0 for Sigma(+), -1.0 for Sigma(-)
1331 real(kind=wp) :: thres ! Determinants with coefficients < thres are deleted
1332 real(kind=wp) :: cdi(*) ! Expansion coeffs of each det on input - grows as the routine adds new determinants to the CSF
1333 real(kind=wp) :: cdo(maxcdo) ! On output holds the expansion coefficients for all determinants
1334
1335 integer :: symtyp ! Designates C-inf-v, D-inf-h or Abelian
1336 integer :: nsrb ! Number of spin-orbitals in system
1337
1338 integer, target :: ndo(maxndo) ! Input determinants - overwitten
1339 integer :: ndtr(nsrb) ! Workspace for building new determinants
1340 integer :: mm(nsrb) ! Lambda/IRR for each spin orbital
1341 integer :: ms(nsrb) ! Spin (Sz) of each spin prbital
1342
1343 integer :: i, ia, ib, id, idet, is, issp, istart, ma, mb, mga, mgb, nd, ninitial_dets
1344
1345 integer, pointer :: ndo_ptr(:)
1346 logical, parameter :: zdebug = .false.
1347 logical :: flip
1348
1349 type(det_tree) :: bst ! Binary search tree structure on top of the determinant storage with lexicographical compare
1350
1351 ! Banner header
1352 if (zdebug) then
1353 write(6,'(/,20x,"====> prjct() - project wavefunction <====",/)')
1354 write(6,'( 20x,"Input data: ")')
1355 write(6,'( 20x," # electrons open shell (nelt) = ",I7)') nelt
1356 write(6,'( 20x," Maximum S for projection (mxss) = ",I7)') mxss
1357 write(6,'( 20x," Lambda value for Wavefn (mgvn) = ",I7)') mgvn
1358 write(6,'( 20x," Required Spin value (iss) = ",I7)') iss
1359 write(6,'( 20x," Required Sz value (isd) = ",I7)') isd
1360 write(6,'( 20x," Threshold (thres) = ",D13.6)') thres
1361 write(6,'( 20x," Dimension of cdo() (maxcdo) = ",I7)') maxcdo
1362 write(6,'( 20x," Dimension of ndo() (maxndo) = ",I7)') maxndo
1363 write(6,'( 20x," Abelian/C-inf-v flag (symtyp) = ",I7)') symtyp
1364 write(6,'( 20x," Number of spin orbs (nsrb) = ",I7,/)') nsrb
1365 write(6,'( 20x,"No. of dets in this CSF (nodi) = ",I7)') nodi
1366
1367 do idet = 1, nodi
1368 istart = (idet - 1) * nelt
1369 write(6,'(/,20x,"Det No = ",I7," Coeff (cdi) = ",D13.6,/)') idet, cdi(idet)
1370 write(6,'( 20x," Sp. orbs in open shells (ndi) = ",20(I4,1x))') (ndo(istart+i), i=1,nelt)
1371 end do
1372 end if
1373
1374 ! Save the number of determinants in the CSF into a variable for use during diagnostic printing later (if used).
1375 ! The value of "nodi" may increase during execution of this routine.
1376 ninitial_dets = nodi
1377
1378 ! Compute the pre-multiplication factors which depend only on overal values - number of electrons and overal Spin.
1379 fcta = -nelt * (nelt - 4)
1380 fctb = iss * (iss + 2)
1381 issp = iss + 1
1382
1383 ! We initialize the number of output determinants to be the same as the number input.
1384 nodo = nodi
1385
1386 ! Copy CSF expansion coefficients from input array to output array before we launch into the loop over Sz components
1387 cdo(1:nodi) = cdi(1:nodi)
1388
1389 ! To speed up the searches, build a binary search tree on top of the determinant storage
1390 ndo_ptr => ndo(1:maxndo)
1391 call bst % init(ndo_ptr, nelt)
1392 do id = 1, nodi
1393 call bst % insert(id)
1394 if (zdebug) then
1395 write(6,'(/,20x,"Bstree after add det #",I0,": ")') id
1396 call bst % output(22)
1397 end if
1398 end do
1399
1400 ! Loop over Sz components of spin
1401 if (zdebug) then
1402 write(6,'(/,20x,"Entering loop over components of spin",/)')
1403 write(6,'( 20x," fcta = ",D13.6)') fcta
1404 write(6,'( 20x," fctb = ",D13.6)') fctb
1405 write(6,'( 20x," issp = ",I6,/)') issp
1406 end if
1407
1408 ! As shown in equation (6) of the Beebe and Stencil 1975 paper, referenced above, the spin ptojector is product over
1409 ! spin operators. This is instanciated here as the DO loop to line 180.
1410
1411 spin_loop: do is = isd + 1, mxss + 1, 2
1412
1413 ! As shown in equation (6) we omit the case k = S
1414 if (is == issp) cycle
1415
1416 ! Compute coefficient multiplication factors for this Sz
1417 fctc = (is - 1) * (is + 1)
1418 fctr = (fcta - fctc) / (fctb - fctc)
1419
1420 if (zdebug) then
1421 write(6,'(/,20x,"Working on Spin Iteration (is) = ",I5,/)') is
1422 write(6,'( 20x," Factor fctc = ",D13.6)') fctc
1423 write(6,'( 20x," Factor fctr = ",D13.6,/)') fctr
1424 end if
1425
1426 ! Copy all existing determinant coefficients for this CSF into cdo() and in doing so multiply by the factor
1427 ! pertaining to this Sz ("nodo" is the associated length of "cdo").
1428 cdo(1:nodi) = fctr * cdi(1:nodi)
1429 nodo = nodi
1430
1431 ! Descend into loop over all determinants currently in this CSF
1432 ! - This may include determinants that we have created in previous iterations of the loop to line 180 as well
1433 ! as those in the initial input list.
1434 ! - "nd" points at the location of the determinants in ndo() for each iteration
1435
1436 nd = 0
1437
1438 determinant_loop: do id = 1, nodi
1439
1440 fctr = four * cdi(id) / (fctb - fctc)
1441
1442 if (zdebug) then
1443 write(6,'(23x,"Working on determinant (id) = ",I5," of ",I5)') id, nodi
1444 write(6,'(23x,"Coefficient, cdi() = ",D13.6 )') cdi(id)
1445 write(6,'(23x,"Factor (fctr) = ",D13.6,/)') fctr
1446 write(6,'(23x,"Current op-shl det: ",20(I3,1x),/,(20x,20(I3,1x)) )') (ndo(nd+i), i=1,nelt)
1447 end if
1448
1449 ! Now descend into loop over all PAIRS of electrons
1450 ! - This is implemented as a double DO loop over electrons
1451
1452 first_electron_loop: do ia = 2, nelt
1453 second_electron_loop: do ib = 1, ia - 1
1454
1455 ! Copy the determinant from its location in NDO() to a temporary area in NDTR().
1456 ! - here, the determinant is composed of "nelt" electrons and is expressed as a list of occupied spin-orbitals
1457 ndtr(1:nelt) = ndo(nd+1:nd+nelt)
1458
1459 ! Consider the present pair of electrons and find their spin
1460 ! - The debug here is extremely useful but can generate massive amounts of output - uncomment if really needed.
1461
1462 ma = ndtr(ia)
1463 mb = ndtr(ib)
1464
1465 mga = ms(ma)
1466 mgb = ms(mb)
1467
1468 if (zdebug) then
1469 write(6,'(23x,"Evaluating electron pair: ")')
1470 write(6,'(23x," #1: idx(ia) = ",I3,"sporb(ma) = ",I3," Sz (mga) = ",I3 )') ia, ma, mga
1471 write(6,'(23x," #2: idx(ib) = ",I3,"sporb(mb) = ",I3," Sz (mgb) = ",I3,/)') ib, mb, mgb
1472 end if
1473
1474 ! Now look at the spins of this pair.
1475 !
1476 ! Remember that 0 means spin-up, 1 means spin-down.
1477 !
1478 ! Option # Electron a Electron b
1479 ! -------- ---------- ----------
1480 ! 1 0 0
1481 ! 2 1 0
1482 ! 3 0 1
1483 ! 4 1 1
1484 !
1485 ! When the spin-orbitals have the same value, that is
1486 ! options 1 and 4, we can't change them so all we do
1487 ! is augment the (output) coefficient of this determinant
1488 ! by the required factor - no more work to be done, so
1489 ! we can proceed to the next electron pair.
1490 !
1491 ! For options 2 and 3, we can create a new determinant
1492 ! by switching the electrons around. We preserve the Sz
1493 ! value by doing that. We rely in the following that the
1494 ! spin orbitals are created (see ms() mn() ...) in a
1495 ! particular order ( Orb N spin-up, Orb N spin down,
1496 ! ...)
1497 !
1498
1499 if (mga == mgb) then
1500 cdo(id) = cdo(id) + fctr
1501 cycle
1502 end if
1503
1504 if (mga == 0) then
1505 ma = ma + 1
1506 mb = mb - 1
1507 else
1508 ma = ma - 1
1509 mb = mb + 1
1510 end if
1511
1512 ndtr(ia) = ma
1513 ndtr(ib) = mb
1514
1515 ! sort the determinant, keeping an eye on the sign of the permutation
1516 flip = (mod(qsort(nelt, ndtr(1:nelt)), 2) /= 0)
1517
1518 if (zdebug) then
1519 write(6,'(23x,"New valid determinant produced by this pair",/)')
1520 write(6,'(23x,"New open shell det: ",20(I3,1x),/,(20x,20(I3,1x)) )') (ndtr(i), i=1,nelt)
1521 end if
1522
1523 ! We ee to screen to see that the spin-orbitals we have just added to the determinant (ma and mb) do not already
1524 ! occur elsewhere in it. if so, the new determinant created is not valid and must be rejected.
1525
1526 do i = 1, nelt
1527 if (ndtr(i) == ma .and. i /= ia) cycle
1528 if (ndtr(i) == mb .and. i /= ib) cycle
1529 end do
1530
1531 ! Given the "new" determinant just constructed in "ndtr" with associated coefficient "fctr",
1532 ! we examine the list of "nodo" determinants for this CSF, defined in ndo()/cdo(), and merge
1533 ! the "new" determinant into the list. This may mean adding it onto the end of cdo()/ndo() - see
1534 ! comments in the routine for explanation.
1535 !
1536 ! So, stmrg() needs to know the maximum dimensions of ndo()/cdo() to monitor the extension of these arrays.
1537 !
1538 ! "nodo" will be updated on return if we add ndtr() and fctr into the list.
1539
1540 call stmrg (nelt, maxcdo, maxndo, ndo, cdo, nodo, ndtr, merge(-fctr, fctr, flip), bst)
1541
1542 end do second_electron_loop
1543 end do first_electron_loop ! End of loop(s) over pairs of electrons
1544
1545 ! End of loop over determinants in this CSF, update the pointer "nd" to start at next CSF in NDO().
1546 ! Remember that a determinant consists of "nelt" consequtive spin orbitals in ndi()
1547
1548 nd = nd + nelt
1549
1550 end do determinant_loop ! End loop over "nodi" current dets in CSF
1551
1552 ! Remove any determinants whihch have an expansion coefficient less than "thres".
1553 ! Number of elements "nodo" in cdo() and ndo() may actually decrease here as elemenst are removed.
1554
1555 call cntrct (nelt, nodo, ndo, cdo, thres)
1556
1557 ! If we find that we have no determinants left in the CSF, we have an error condition.
1558
1559 if (nodo == 0) then
1560 write(6,'(/,10x,"**** Error in prjct() ",/)')
1561 write(6,'( 10x,"After removing all determinants with expansion ")')
1562 write(6,'( 10x,"coefficients less than (thres) = ",D13.6)') thres
1563 write(6,'( 10x,"there are no determinants left in this CSF",/)')
1564 stop 999
1565 end if
1566
1567 ! Ok, so now copy the full set of coefficients back to array cdi(). Note that originally cdi() was of length
1568 ! "nodi" but we have added to it. The variable "nodo" now holds the total number of determinants - so we need
1569 ! to reset "nodi" to that value.
1570 !
1571 ! We do this because the next iteration of the loop to line over spins starts by copying from cdi().
1572
1573 nodi = nodo
1574
1575 cdi(1:nodi) = cdo(1:nodi)
1576
1577 end do spin_loop
1578
1579 ! For Sigma wavefunctions in C-inf-v/D-inf-h we needed to consider the reflection symmetry.
1580 ! They can be Sigma(+) or Sigma(-)
1581
1582 if (symtyp <= 1 .and. mgvn == 0) then
1583 if (zdebug) write(6,'(/,20x,"Analysis of Reflection operator required",/)')
1584
1585 nodi = nodo
1586 cdi(1:nodi) = cdo(1:nodi)
1587
1588 call rfltn (nelt, nodi, ndo, cdi, r, maxcdo, maxndo, thres, nodo, cdo, ndtr, mm, bst)
1589
1590 if (nodo <= 0) then
1591 write(6,'(/,10x,"**** Error in prjct() ",/)')
1592 write(6,'( 10x,"After reflection analysis there are no ")')
1593 write(6,'( 10x,"no determinants left in the CSF",/)')
1594 stop 999
1595 end if
1596
1597 end if
1598
1599 ! Debug printout of the coefficients after spin projection
1600
1601 if (zdebug) then
1602 write(6,'(/,20x,"Coefficients after projection ")')
1603 write(6,'( 20x," (but not yet normalized) ",/)')
1604 write(6,'( 20x," No. of determinants (nodi) = ",I6,/)') nodi
1605 write(6,'(20x,I4,2x,D13.6)') (i, cdi(i), i=1,nodi)
1606 end if
1607
1608 ! Compute inverse sum of squared coefficients and normalize output
1609
1610 tmp = snrm2(nodo, cdo, 1)
1611 tmp = one / sqrt(tmp)
1612
1613 do i = 1, nodo
1614 cdo(i) = cdo(i) * tmp
1615 end do
1616
1617 ! Return point
1618
1619 continue
1620
1621 if (zdebug) then
1622 write(6,'(20x,"Final number of determinants in CSF (nodo) = ",I5,/)') nodo
1623
1624 if (nodo /= ninitial_dets) then
1625 ia = nodo - ninitial_dets
1626 write(6,'(20x,"The length of the CSF has changed: ")')
1627 write(6,'(20x," Initial number of dets = ",I6)') ninitial_dets
1628 write(6,'(20x," # of dets added = ",I6," by projection",/)') ia
1629 else
1630 write(6,'(20x,"# of dets in the CSF has NOT changed ",/)')
1631 end if
1632
1633 write(6,'(/,20x,"**** prjct() - completed",/)')
1634 end if
1635
1636 end subroutine prjct
1637
1638
1639 !> \brief Project the wave function
1640 !>
1641 !> The subroutine \c projec controls the projection of the wavefunctions
1642 !> and writes out the final wavefunctions plus header information for future use.
1643 !>
1644 !> \note MAL 06/05/11 PROJEC has been considerably modified to take advantage of dynamic memory allocation.
1645 !>
1646 subroutine projec (sname, megul, symtyp, mgvn, s, sz, r, pin, nocsf, byproj, idiag, npflg, thres, &
1647 nelt, nsym, nob, ndtrf, nftw, iposit, nob0, nob1, nob01, iscat, ntgsym, notgt, &
1648 nctgt, mcont, gucont, mrkorb, mdegen, mflag, nobe, nobp, nobv, maxtgsym)
1649
1650 use precisn, only : wp
1651 use global_utils, only : mprod
1652
1653 integer, intent(in) :: iscat, mflag
1654 integer, intent(inout) :: ntgsym
1655 integer :: byproj, idiag, iposit, megul, mgvn, nelt, nftw, nocsf, &
1656 nsym, symtyp, npflg(6), num_csfs_unproj, num_dets_unproj, &
1657 len_pkd_dets_unproj
1658 real(kind=wp) :: pin, r, s, sz, thres
1659 character(len=80) :: sname
1660 integer, dimension(ntgsym) :: gucont, mcont, mdegen, mrkorb, nctgt, notgt
1661 integer, dimension(nsym) :: nob, nob0, nob01, nobe, nobp, nobv
1662 integer, dimension(nelt) :: ndtrf
1663 integer, dimension(*) :: nob1
1664
1665 integer :: i,nalm,nb,nctarg,nd,nl,norb,junk, isd,iss,n,k,msum,isum,m,ierr, &
1666 num_dets,nreps,maxndi,maxcdi, maxndo,maxcdo,lenndo,lencdo, &
1667 leniphase,leniphase0,maxtgsym
1668
1669 !-----------------------------------------------------------------------
1670 ! Following are used to store the "unprojected" wavefunction
1671 !-----------------------------------------------------------------------
1672
1673 integer :: wfn_unproj_num_csfs, &
1674 wfn_unproj_num_dets, &
1675 wfn_unproj_len_pkd_dets
1676 integer, allocatable :: wfn_unproj_dets_per_csf(:), &
1677 wfn_unproj_packed_dets(:), &
1678 wfn_unproj_indx_1st_det_per_csf(:), &
1679 wfn_unproj_indx_1st_coeff_per_csf(:)
1680 real(kind=wp), allocatable :: wfn_unproj_coefficients_per_det(:)
1681
1682 !-----------------------------------------------------------------------
1683 ! Following are used to store the "projected" wavefunction
1684 !-----------------------------------------------------------------------
1685
1686 integer :: wfn_proj_num_csfs, &
1687 wfn_proj_num_dets, &
1688 wfn_proj_len_pkd_dets
1689 integer, allocatable :: wfn_proj_dets_per_csf(:), &
1690 wfn_proj_packed_dets(:), &
1691 wfn_proj_indx_1st_det_per_csf(:), &
1692 wfn_proj_indx_1st_coeff_per_csf(:)
1693 real(kind=wp), allocatable :: wfn_proj_coefficients_per_det(:)
1694
1695 !-----------------------------------------------------------------------
1696 ! Following are used to store the table of spin-orbitals
1697 !-----------------------------------------------------------------------
1698
1699 integer :: nsrb,noarg
1700 integer, allocatable :: itab_sporb_indx_in_sym(:), &
1701 itab_sporb_gu_value(:), &
1702 itab_sporb_sym(:), &
1703 itab_sporb_isz(:), &
1704 itab_sporb_mpos(:), &
1705 map_orbitals(:)
1706
1707 !------------------------------------------------------------------------
1708 ! Following are used during the phase analysis of the wavefunctio
1709 !------------------------------------------------------------------------
1710
1711 integer, allocatable :: nconf(:),iphase(:),iphase0(:)
1712
1713 !-------------------------------------------------------------------------
1714 ! Following logical flags are used to control the computation
1715 !
1716 ! They are provided to make the code easier to read than trying to
1717 ! remember that "byproj .eq. 0" means "bypass the projection of the
1718 ! wavefunction".
1719 !-------------------------------------------------------------------------
1720
1721 logical :: zbypass_wfn_projection, &
1722 zadjust_wfn_phase_for_scattering, &
1723 zpositrons,ztarget_state_calculation, &
1724 zscattering_calculation,zabelian
1725
1726 integer :: num_csfs_proj, num_dets_proj, len_pkd_dets_proj ! MAL 12/05/11 : None of these were declared in CG code. Why?
1727 ! They are not assigned values either, so most likely a problem here
1728
1729 if (symtyp >= 2) then
1730 write(nftw,'(" MOLECULE SYMMETRY CASE, symtyp =",I2)') symtyp
1731 junk = mprod(1, 1, npflg(6), nftw)
1732 end if
1733
1734 nalm = 0 ! JMC initialization
1735 iss = s + s
1736 isd = sz + sz
1737 if (iss < isd) then
1738 write(nftw, 40)
1739 write(nftw, 46)
1740 stop
1741 end if
1742
1743 !-------------------------------------------------------------------------
1744 ! The following logicals are created to improve code readability
1745 !-------------------------------------------------------------------------
1746
1747 zbypass_wfn_projection = byproj == 0
1748 zadjust_wfn_phase_for_scattering = iscat > 0
1749 zpositrons = iposit /= 0
1750 zabelian = symtyp == 2
1751
1752 !-------------------------------------------------------------------------
1753 ! Compute the table of spin-orbitals
1754 !-------------------------------------------------------------------------
1755
1756 nsrb = sum(nob(1:nsym))
1757 norb = nsrb
1758 ! JMC set but not used NORBB=(NORB*(NORB+1))/2
1759 nsrb = 2 * nsrb
1760
1761 !------------------------------------------------------------------------
1762 ! Memory allocation for table of spin-orbitals
1763 !------------------------------------------------------------------------
1764
1765 allocate(itab_sporb_indx_in_sym(nsrb), stat = ierr)
1766 if (ierr /= 0) then
1767 write(nftw,9900)
1768 write(nftw,9950) 'itab_sporb_indx_in_sym', ierr
1769 stop
1770 end if
1771
1772 allocate(itab_sporb_gu_value(nsrb),stat = ierr)
1773 if (ierr /= 0) then
1774 write(nftw,9900)
1775 write(nftw,9950) 'itab_sporb_gu_value', ierr
1776 stop
1777 end if
1778
1779 allocate(itab_sporb_sym(nsrb), stat = ierr)
1780 if (ierr /= 0) then
1781 write(nftw,9900)
1782 write(nftw,9950) 'itab_sporb_sym', ierr
1783 stop
1784 end if
1785
1786 allocate(itab_sporb_isz(nsrb), stat = ierr)
1787 if (ierr /= 0) then
1788 write(nftw,9900)
1789 write(nftw,9950) 'itab_sporb_isz', ierr
1790 stop
1791 end if
1792
1793 allocate(itab_sporb_mpos(nsrb), stat = ierr)
1794 if (ierr /= 0) then
1795 write(nftw,9900)
1796 write(nftw,9950) 'itab_sporb_mpos', ierr
1797 stop
1798 end if
1799
1800 allocate(map_orbitals(norb), stat = ierr)
1801 if (ierr /= 0) then
1802 write(nftw,9900)
1803 write(nftw,9950) 'mpos_orbitals', ierr
1804 stop
1805 end if
1806
1807 !-------------------------------------------------------------------------
1808 ! Compute the table of spin orbitals
1809 !-------------------------------------------------------------------------
1810
1811 !-------------------------------------------------------------------------
1812 ! For positrons in Abelian point groups there is a separate
1813 ! processing routine
1814 !-------------------------------------------------------------------------
1815
1816 if (zpositrons .and. zabelian) then
1817 call pmkorbs (nob, nobe, nsym, &
1818 itab_sporb_indx_in_sym, &
1819 itab_sporb_gu_value, &
1820 itab_sporb_sym, &
1821 itab_sporb_isz, &
1822 nsrb, norb, nsrb, &
1823 map_orbitals, &
1824 itab_sporb_mpos, &
1825 iposit, symtyp)
1826 else
1827 call mkorbs (nob, nsym, &
1828 itab_sporb_indx_in_sym, &
1829 itab_sporb_gu_value, &
1830 itab_sporb_sym, &
1831 itab_sporb_isz, &
1832 norb, nsrb, map_orbitals, &
1833 itab_sporb_mpos, &
1834 iposit, nob1, nob01, symtyp)
1835 end if
1836
1837 !-------------------------------------------------------------------------
1838 ! Validate the reference determinant
1839 !-------------------------------------------------------------------------
1840
1841 isum = 0
1842 if (.not. zabelian) then
1843 msum = 0
1844 do i = 1, nelt
1845 m = ndtrf(i)
1846 msum = msum + itab_sporb_sym(m)
1847 isum = isum + 1 - itab_sporb_isz(m) - itab_sporb_isz(m)
1848 end do
1849 else
1850 msum = 1
1851 do i = 1, nelt
1852 m = ndtrf(i)
1853 msum = mprod(msum, itab_sporb_sym(m) + 1, 0, nftw) !mal 12/05/11 nftw was missing in cg code. why?
1854 isum = isum + 1 - itab_sporb_isz(m) - itab_sporb_isz(m)
1855 end do
1856 msum = msum - 1
1857 end if
1858
1859 !-------------------------------------------------------------------------
1860 ! Cross check with input
1861 !-------------------------------------------------------------------------
1862
1863 if (abs(msum) /= mgvn) then
1864 write(nftw,9900)
1865 write(nftw,1190)
1866 stop
1867 end if
1868
1869 if (abs(isum) /= isd) then
1870 write(nftw,9900)
1871 write(nftw,1195) abs(isum), isd
1872 stop
1873 end if
1874
1875 !-------------------------------------------------------------------------
1876 ! Read the unprojected wavefunctions from unit megul
1877 !-------------------------------------------------------------------------
1878 !
1879 !-------------------------------------------------------------------------
1880 ! MAL 06/05/11 : Read the dimension information only, in order to see
1881 ! how many CSFs, how many determinants there are and also how long the
1882 ! determinant array is
1883 !-------------------------------------------------------------------------
1884
1885 call rdwf_getsize (megul, wfn_unproj_num_csfs, wfn_unproj_num_dets, wfn_unproj_len_pkd_dets)
1886
1887 !-------------------------------------------------------------------------
1888 ! Allocate the arrays dynamically for storage of the unprojected
1889 ! wavefunction
1890 !-------------------------------------------------------------------------
1891 !
1892 !-------------------------------------------------------------------------
1893 ! (1). Number of determinants per CSF
1894 !-------------------------------------------------------------------------
1895
1896 allocate(wfn_unproj_dets_per_csf(wfn_unproj_num_csfs), stat = ierr)
1897 if (ierr /= 0) then
1898 write(nftw,9900)
1899 write(nftw,9950) 'wfn_unproj_dets_per_csf', ierr
1900 stop
1901 end if
1902
1903 !-------------------------------------------------------------------------
1904 ! (2). The coefficient for each and every determinant
1905 !-------------------------------------------------------------------------
1906
1907 allocate(wfn_unproj_coefficients_per_det(wfn_unproj_num_dets), stat = ierr)
1908 if (ierr /= 0) then
1909 write(nftw,9900)
1910 write(nftw,9950) 'wfn_unproj_coefficients_per_det',ierr
1911 stop
1912 end if
1913
1914 !-------------------------------------------------------------------------
1915 ! (3). Each and every packed determinant
1916 !-------------------------------------------------------------------------
1917
1918 allocate(wfn_unproj_packed_dets(wfn_unproj_len_pkd_dets), stat = ierr)
1919 if (ierr /= 0) then
1920 write(nftw,9900)
1921 write(nftw,9950) 'wfn_unproj_packed_dets', ierr
1922 stop
1923 end if
1924
1925 !-------------------------------------------------------------------------
1926 ! (4). Index into the list of determinants to the location for the first
1927 ! determinant of each CSF
1928 ! Note how this has one extra entry.
1929 !-------------------------------------------------------------------------
1930
1931 allocate(wfn_unproj_indx_1st_det_per_csf(wfn_unproj_num_csfs+1), stat = ierr)
1932 if (ierr /= 0) then
1933 write(nftw,9900)
1934 write(nftw,9950) 'wfn_unproj_indx_1st_det_per_csf',ierr
1935 stop
1936 end if
1937
1938 !-------------------------------------------------------------------------
1939 ! (5). Index into the list of coefficients to the location for the first
1940 ! coefficient of each CSF
1941 ! Note how this has one extra entry
1942 !-------------------------------------------------------------------------
1943
1944 allocate(wfn_unproj_indx_1st_coeff_per_csf(wfn_unproj_num_csfs+1), stat = ierr)
1945 if (ierr /= 0) then
1946 write(nftw,9900)
1947 write(nftw,9950) 'wfn_unproj_indx_1st_coeff_per_csf', ierr
1948 stop
1949 end if
1950
1951 !-------------------------------------------------------------------------
1952 ! Now able to read the unprojected wavefunction from file
1953 ! Note that this does not include the indexing arrays
1954 ! These are computed next
1955 !-------------------------------------------------------------------------
1956
1957 call rdwf (megul, num_csfs_unproj, wfn_unproj_dets_per_csf, &
1958 num_dets_unproj, wfn_unproj_coefficients_per_det, &
1959 len_pkd_dets_unproj, wfn_unproj_packed_dets)
1960
1961 !-------------------------------------------------------------------------
1962 ! Check that the values read back match to those read earlier
1963 !-------------------------------------------------------------------------
1964
1965 if (num_csfs_unproj /= wfn_unproj_num_csfs) then
1966 write(nftw,*) ' Error 1 '
1967 stop 999
1968 end if
1969
1970 if (num_dets_unproj /= wfn_unproj_num_dets) then
1971 write(nftw,*) ' Error 2 '
1972 stop 999
1973 end if
1974
1975 if (len_pkd_dets_unproj /= wfn_unproj_len_pkd_dets) then
1976 write(nftw,*) ' Error 3 '
1977 stop 999
1978 end if
1979
1980 !-------------------------------------------------------------------------
1981 ! Given the input wavefunction, indexing vectors for it are built here
1982 !
1983 ! wnf_unproj_indx_1st_det_per_csf()
1984 ! points to the location of the first deteminant for each CSF
1985 ! within the array ndi() which holds all the packed determinants
1986 ! in the wavefunction.
1987 !
1988 ! wfn_unproj_indx_1st_coeff_per_csf()
1989 ! points to the location of the first coefficient for each CSF
1990 ! within the array cdi() which holds all the coefficients
1991 ! (one per determinant) in the wavefunction
1992 !
1993 !-------------------------------------------------------------------------
1994
1995 wfn_unproj_indx_1st_coeff_per_csf(1) = 1
1996
1997 do n = 2, num_csfs_unproj
1998 wfn_unproj_indx_1st_coeff_per_csf(n) = &
1999 wfn_unproj_indx_1st_coeff_per_csf(n-1) + &
2000 wfn_unproj_dets_per_csf(n-1)
2001 end do
2002
2003 wfn_unproj_indx_1st_coeff_per_csf(num_csfs_unproj+1) = &
2004 wfn_unproj_indx_1st_coeff_per_csf(num_csfs_unproj) + &
2005 wfn_unproj_dets_per_csf(num_csfs_unproj)
2006
2007 !-------------------------------------------------------------------------
2008 ! Index determinants now
2009 !-------------------------------------------------------------------------
2010
2011 wfn_unproj_indx_1st_det_per_csf(1) = 1
2012 k = 1
2013 do n = 1, num_csfs_unproj
2014 num_dets = wfn_unproj_dets_per_csf(n)
2015 do m = 1,num_dets
2016 nreps = wfn_unproj_packed_dets(k)
2017 k = k + (2*nreps + 1)
2018 end do
2019 if (n <= num_csfs_unproj) then
2020 wfn_unproj_indx_1st_det_per_csf(n+1) = k
2021 end if
2022 end do
2023
2024 !-------------------------------------------------------------------------
2025 ! If the user has requested it, then print the wavefunction
2026 !-------------------------------------------------------------------------
2027
2028 if (npflg(1) > 5) then
2029 write(nftw,1285) megul
2030 call ptpwf (nftw,num_csfs_unproj,nelt,ndtrf, &
2031 wfn_unproj_dets_per_csf, &
2032 wfn_unproj_indx_1st_det_per_csf, &
2033 wfn_unproj_indx_1st_coeff_per_csf, &
2034 wfn_unproj_packed_dets, &
2035 wfn_unproj_coefficients_per_det)
2036 end if
2037
2038 !-------------------------------------------------------------------------
2039 ! Allocate storage space for the projected wavefunction
2040 !-------------------------------------------------------------------------
2041 !
2042 !-------------------------------------------------------------------------
2043 ! The number of CSFs in the projected wavefunction will be no greater
2044 ! than the number in the unprojected wavefunction. It is possible to
2045 ! even delete a few due to the THRESHOLD criterion on coefficients.
2046 ! However, the number of determinants may grow due to the projection
2047 ! for open shell determinants (see prjct()).
2048 !
2049 ! A factor of 10 is allowed here as a guesstimate...this may need revision
2050 !
2051 !-------------------------------------------------------------------------
2052 ! If no projection is to be done, the data is just copied straight over
2053 ! which means the subsequent code does not need to be rewritten with
2054 ! different variable names
2055 !-------------------------------------------------------------------------
2056
2057 if (zbypass_wfn_projection) then
2058 wfn_proj_num_csfs = wfn_unproj_num_csfs
2059 wfn_proj_num_dets = wfn_unproj_num_dets
2060 wfn_proj_len_pkd_dets = wfn_unproj_len_pkd_dets
2061 else
2062 wfn_proj_num_csfs = wfn_unproj_num_csfs
2063 wfn_proj_num_dets = 10 * wfn_unproj_num_dets
2064 wfn_proj_len_pkd_dets = 10 * wfn_unproj_len_pkd_dets
2065 end if
2066
2067 !-------------------------------------------------------------------------
2068 ! Allocate space for the projected wavefunction
2069 !-------------------------------------------------------------------------
2070 !
2071 !-------------------------------------------------------------------------
2072 ! (1). Number of determinants per CSF
2073 !-------------------------------------------------------------------------
2074
2075 allocate(wfn_proj_dets_per_csf(wfn_proj_num_csfs), stat = ierr)
2076 if (ierr /= 0) then
2077 write(nftw,9900)
2078 write(nftw,9950) 'wfn_proj_dets_per_csf', ierr
2079 stop
2080 end if
2081
2082 !-------------------------------------------------------------------------
2083 ! (2). The coefficient for each and every determinant
2084 !-------------------------------------------------------------------------
2085
2086 allocate(wfn_proj_coefficients_per_det(wfn_proj_num_dets), stat = ierr)
2087 if (ierr /= 0) then
2088 write(nftw,9900)
2089 write(nftw,9950) 'wfn_proj_coefficients_per_det', ierr
2090 stop
2091 end if
2092
2093 !-------------------------------------------------------------------------
2094 ! (3). Each and every packed determinant
2095 !-------------------------------------------------------------------------
2096
2097 allocate(wfn_proj_packed_dets(wfn_proj_len_pkd_dets), stat=ierr)
2098 if (ierr /= 0) then
2099 write(nftw,9900)
2100 write(nftw,9950) 'wfn_proj_packed_dets', ierr
2101 stop
2102 end if
2103
2104 !-------------------------------------------------------------------------
2105 ! (4). Index into the list of determinants to the location for the first
2106 ! determinant of each CSF
2107 !
2108 ! This (and 5 below) have to have a "fake" N+1 CSF, so the size
2109 ! of the last Nth CSF can be known
2110 !-------------------------------------------------------------------------
2111
2112 allocate(wfn_proj_indx_1st_det_per_csf(wfn_proj_num_csfs+1), stat = ierr)
2113 if (ierr /= 0) then
2114 write(nftw,9900)
2115 write(nftw,9950) 'wfn_proj_indx_1st_det_per_csf', ierr
2116 stop
2117 end if
2118
2119 !-------------------------------------------------------------------------
2120 ! (5). Index into the list of coefficients to the location for the first
2121 ! coefficient of each CSF
2122 !-------------------------------------------------------------------------
2123
2124 allocate(wfn_proj_indx_1st_coeff_per_csf(wfn_proj_num_csfs+1), stat = ierr)
2125 if (ierr /= 0) then
2126 write(nftw,9900)
2127 write(nftw,9950) 'wfn_proj_indx_1st_coeff_per_csf', ierr
2128 stop
2129 end if
2130
2131 !-------------------------------------------------------------------------
2132 ! Project the wavefunction
2133 !-------------------------------------------------------------------------
2134 !
2135 !-------------------------------------------------------------------------
2136 ! There is a special case -- the wavefunctions read are already projected.
2137 ! In this case the input is just copied to the output
2138 !-------------------------------------------------------------------------
2139
2140 if (zbypass_wfn_projection) then
2141 wfn_proj_dets_per_csf = wfn_unproj_dets_per_csf
2142 wfn_proj_packed_dets = wfn_unproj_packed_dets
2143 wfn_proj_coefficients_per_det = wfn_unproj_coefficients_per_det
2144 wfn_proj_indx_1st_det_per_csf = wfn_unproj_indx_1st_det_per_csf
2145 wfn_proj_indx_1st_coeff_per_csf = wfn_unproj_indx_1st_det_per_csf
2146 else
2147
2148 maxndi = size(wfn_unproj_packed_dets)
2149 maxcdi = size(wfn_unproj_coefficients_per_det)
2150 maxndo = size(wfn_proj_packed_dets)
2151 maxcdo = size(wfn_proj_coefficients_per_det)
2152
2153 if (maxndi <= 0 .or. maxcdi <= 0) stop 901
2154 if (maxndo <= 0 .or. maxcdo <= 0) stop 902
2155
2156 call wfgntr (mgvn, iss, isd, thres, r, symtyp, nelt, &
2157 nsym, nob, nob1, nob01, nobe, norb, nsrb, &
2158 itab_sporb_indx_in_sym, &
2159 itab_sporb_gu_value, &
2160 itab_sporb_sym, &
2161 itab_sporb_isz, &
2162 iposit, map_orbitals, itab_sporb_mpos, &
2163 wfn_unproj_num_csfs, &
2164 ndtrf, &
2165 wfn_unproj_dets_per_csf, &
2166 wfn_unproj_packed_dets, &
2167 wfn_unproj_coefficients_per_det, &
2168 wfn_unproj_indx_1st_det_per_csf, &
2169 wfn_unproj_indx_1st_coeff_per_csf, &
2170 maxndi, maxcdi, &
2171 wfn_proj_dets_per_csf, &
2172 wfn_proj_packed_dets, &
2173 wfn_proj_coefficients_per_det, &
2174 wfn_proj_indx_1st_det_per_csf, &
2175 wfn_proj_indx_1st_coeff_per_csf, &
2176 maxndo, maxcdo, lenndo, lencdo, &
2177 npflg, byproj, nftw, nalm)
2178
2179 if (nalm /= 0) then
2180 write(nftw,9900)
2181 write(nftw,46)
2182 stop
2183 end if
2184
2185 end if ! end of bypass wavefunction projection switch
2186
2187 !-------------------------------------------------------------------------
2188 ! Print the projected CSFs
2189 !-------------------------------------------------------------------------
2190
2191 if (npflg(3) /= 0) then
2192 write(nftw,'("1 OUTPUT FUNCTIONS IN PACKED FORM")')
2193 call ptpwf (nftw, wfn_proj_num_csfs, nelt, ndtrf, &
2194 wfn_proj_dets_per_csf, &
2195 wfn_proj_indx_1st_det_per_csf, &
2196 wfn_proj_indx_1st_coeff_per_csf, &
2197 wfn_proj_packed_dets, &
2198 wfn_proj_coefficients_per_det)
2199 end if
2200
2201 !-------------------------------------------------------------------------
2202 ! Clean up dynamic storage that is no longer needed
2203 !-------------------------------------------------------------------------
2204 !
2205 !-------------------------------------------------------------------------
2206 ! Deallocate the arrays used to read the unprojected wavefunction
2207 !-------------------------------------------------------------------------
2208
2209 deallocate(wfn_unproj_dets_per_csf, stat = ierr)
2210 if (ierr /= 0) then
2211 write(nftw, 9900)
2212 write(nftw, 9960) 'wfn_unproj_dets_per_csf', ierr
2213 stop
2214 end if
2215
2216 deallocate(wfn_unproj_coefficients_per_det, stat = ierr)
2217 if (ierr /= 0) then
2218 write(nftw, 9900)
2219 write(nftw, 9960) 'wfn_unproj_coefficients_per_det', ierr
2220 stop
2221 end if
2222
2223 deallocate(wfn_unproj_packed_dets, stat = ierr)
2224 if (ierr /= 0) then
2225 write(nftw, 9900)
2226 write(nftw, 9960) 'wfn_unproj_packed_dets', ierr
2227 stop
2228 end if
2229
2230 deallocate(wfn_unproj_indx_1st_det_per_csf, stat = ierr)
2231 if (ierr /= 0) then
2232 write(nftw, 9900)
2233 write(nftw, 9960) 'wfn_unproj_indx_1st_det_per_csf', ierr
2234 stop
2235 end if
2236
2237 deallocate(wfn_unproj_indx_1st_coeff_per_csf, stat = ierr)
2238 if (ierr /= 0) then
2239 write(nftw, 9900)
2240 write(nftw, 9960) 'wfn_unproj_1st_coeff_per_csf', ierr
2241 stop
2242 end if
2243
2244 !-------------------------------------------------------------------------
2245 ! Calculate phase correction for SCATCI
2246 !-------------------------------------------------------------------------
2247 !-------------------------------------------------------------------------
2248 ! Figure out which calculation is being done
2249 !-------------------------------------------------------------------------
2250
2251 ztarget_state_calculation = iscat == 1
2252 zscattering_calculation = iscat > 1
2253
2254 !-------------------------------------------------------------------------
2255 ! Allocate workspace arrays needed in this step
2256 !
2257 ! Depends on type of calculation
2258 !
2259 ! Note that the phase array is needed for one of the write to file options
2260 !-------------------------------------------------------------------------
2261
2262 allocate(nconf(nelt), stat = ierr)
2263
2264 if (ierr /= 0) then
2265 write(nftw, 9900)
2266 write(nftw, 9950) 'nconf', ierr
2267 stop
2268 end if
2269
2270 !-------------------------------------------------------------------------
2271 ! iphase()
2272 !-------------------------------------------------------------------------
2273
2274 if (ztarget_state_calculation) then
2275 leniphase = nocsf
2276 else
2277 leniphase = sum(nctgt(1:ntgsym))
2278 end if
2279
2280 allocate(iphase(leniphase), stat = ierr)
2281 if (ierr /= 0) then
2282 write(nftw, 9900)
2283 write(nftw, 9950) 'iphase', ierr
2284 stop 999
2285 end if
2286
2287 leniphase = size(iphase)
2288
2289 !-------------------------------------------------------------------------
2290 ! iphase0()
2291 !-------------------------------------------------------------------------
2292
2293 allocate(iphase0(3*nocsf), stat = ierr)
2294
2295 if (ierr /= 0) then
2296 write(nftw, 9900)
2297 write(nftw, 9950) 'iphase0', ierr
2298 stop 999
2299 end if
2300
2301 !-------------------------------------------------------------------------
2302 ! Branch to appropriate phase handler -- watch for error condition
2303 ! (that is, iscat <= 0)
2304 !-------------------------------------------------------------------------
2305
2306 if (ztarget_state_calculation) then
2307
2308 write(nftw, 3000)
2309
2310 nctarg = nocsf
2311 ntgsym = -1
2312
2313 call dophz0 (nftw, nocsf, nelt, ndtrf, nconf, &
2314 wfn_proj_indx_1st_det_per_csf, &
2315 wfn_proj_packed_dets, &
2316 lenndo, &
2317 wfn_proj_indx_1st_coeff_per_csf, &
2318 wfn_proj_coefficients_per_det, &
2319 lencdo, &
2320 iphase, &
2321 npflg(5))
2322
2323 else if (zscattering_calculation) then
2324
2325 write(nftw, 3100)
2326 write(nftw, 3110) ntgsym,notgt
2327 write(nftw, 3120) nctgt
2328 write(nftw, 3130) mcont
2329
2330 if (symtyp == 1) write(nftw, 3140) gucont
2331 if (npflg(5) > 0) write(nftw, 3150) mrkorb
2332 if (symtyp <= 1 .and. mgvn > 0) write(nftw, 3160) mdegen
2333
2334 !-------------------------------------------------------------------------
2335 ! Count the number of continuum functions, that is a sum over all target
2336 ! states
2337 !-------------------------------------------------------------------------
2338
2339 if (iposit .NE. 0) then
2340 nctarg = sum(nctgt(1:maxtgsym))
2341 else
2342 nctarg = sum(nctgt(1:ntgsym))
2343 endif
2344
2345 !-------------------------------------------------------------------------
2346 ! Execute the phase alignment routine
2347 !-------------------------------------------------------------------------
2348
2349 call dophz (nftw, nocsf, nelt, ndtrf, nconf, &
2350 wfn_proj_indx_1st_det_per_csf, &
2351 wfn_proj_packed_dets, &
2352 lenndo, &
2353 wfn_proj_indx_1st_coeff_per_csf, &
2354 wfn_proj_coefficients_per_det, &
2355 lencdo, &
2356 iphase, &
2357 leniphase, &
2358 iphase0, &
2359 leniphase0, &
2360 nctarg, nctgt, notgt, mrkorb, &
2361 mdegen, ntgsym, mcont, &
2362 symtyp, npflg(5))
2363
2364 else
2365
2366 write(nftw,9900)
2367 write(nftw,*) 'neither a target state nor a scattering run'
2368 stop 999
2369
2370 end if
2371
2372 !------------------------------------------------------------------------
2373 ! Write the header and (projected) wavefunctions back to unit MEGUL
2374 !------------------------------------------------------------------------
2375 !
2376 !------------------------------------------------------------------------
2377 ! iscat > 0 => SCATCI, DENPROP format
2378 ! otherwise SPEEDY format
2379 !------------------------------------------------------------------------
2380
2381 if (iscat > 0) then
2382 write(nftw, 3167) megul
2383 call wrnfto (sname, mgvn, s, sz, r, pin, norb, nsrb, &
2384 nocsf, nelt, idiag, nsym, symtyp, &
2385 nob, ndtrf, wfn_proj_dets_per_csf, &
2386 nocsf + 1, &
2387 wfn_proj_indx_1st_coeff_per_csf, &
2388 wfn_proj_indx_1st_det_per_csf, &
2389 wfn_proj_packed_dets, &
2390 lenndo, &
2391 wfn_proj_coefficients_per_det, &
2392 lencdo, &
2393 megul, nob1, 2 * nsym, &
2394 npflg, thres, iposit, nob0, nob01, nctarg, &
2395 ntgsym, notgt, nctgt, mcont, gucont, iphase, &
2396 nobe, nobp, nobv, maxtgsym)
2397 write(nftw, 3170) megul
2398 else
2399 write(nftw, 3168) megul
2400 call wrwf (megul, &
2401 num_csfs_proj, & ! MAL 12/05/11 : Not declared in CG code
2402 wfn_proj_dets_per_csf, &
2403 num_dets_proj, & ! MAL 12/05/11 : Not declared in CG code
2404 wfn_proj_coefficients_per_det, &
2405 len_pkd_dets_proj, & ! MAL 12/05/11 : Not declared in CG code
2406 wfn_proj_packed_dets)
2407 end if
2408
2409 !-------------------------------------------------------------------------
2410 ! Deallocate workspace arrays used in dophz0()/dophz()
2411 !-------------------------------------------------------------------------
2412
2413 if (allocated(nconf)) then
2414 deallocate(nconf, stat = ierr)
2415 if (ierr /= 0) then
2416 write(nftw, 9900)
2417 write(nftw, 9960) 'nconf', ierr
2418 stop
2419 end if
2420 end if
2421
2422 if (allocated(iphase)) then
2423 deallocate(iphase, stat = ierr)
2424 if (ierr /= 0) then
2425 write(nftw, 9900)
2426 write(nftw, 9960) 'iphase', ierr
2427 stop
2428 end if
2429 end if
2430
2431 if (allocated(iphase0)) then
2432 deallocate(iphase0, stat = ierr)
2433 if (ierr /= 0) then
2434 write(nftw, 9900)
2435 write(nftw, 9960) 'iphase0', ierr
2436 stop
2437 end if
2438 end if
2439
2440 !-------------------------------------------------------------------------
2441 ! Subroutine common return point
2442 !-------------------------------------------------------------------------
2443 !
2444 !-------------------------------------------------------------------------
2445 ! Deallocate storage used for the table of spin-orbitals
2446 !-------------------------------------------------------------------------
2447
2448 deallocate(itab_sporb_indx_in_sym, stat = ierr)
2449 if (ierr /= 0) then
2450 write(nftw, 9900)
2451 write(nftw, 9960) 'itab_sporb_indx_in_sym', ierr
2452 stop
2453 end if
2454
2455 deallocate(itab_sporb_gu_value, stat = ierr)
2456 if (ierr /= 0) then
2457 write(nftw, 9900)
2458 write(nftw, 9960) 'itab_sporb_gu_value', ierr
2459 stop
2460 end if
2461
2462 deallocate(itab_sporb_sym, stat = ierr)
2463 if (ierr /= 0) then
2464 write(nftw, 9900)
2465 write(nftw, 9960) 'itab_sporb_sym', ierr
2466 stop
2467 end if
2468
2469 deallocate(itab_sporb_isz, stat = ierr)
2470 if (ierr /= 0) then
2471 write(nftw, 9900)
2472 write(nftw, 9960) 'itab_sporb_isz', ierr
2473 stop
2474 end if
2475
2476 deallocate(itab_sporb_mpos, stat = ierr)
2477 if (ierr /= 0) then
2478 write(nftw, 9900)
2479 write(nftw, 9960) 'itab_sporb_mpos', ierr
2480 stop
2481 end if
2482
2483 deallocate(map_orbitals, stat = ierr)
2484 if (ierr /= 0) then
2485 write(nftw, 9900)
2486 write(nftw, 9960) 'mpos_orbitals', ierr
2487 stop
2488 end if
2489
2490 write(nftw, 8000)
2491
2492 !------------------------------------------------------------------------
2493 ! Format statements
2494 !------------------------------------------------------------------------
2495
2496 40 format(.LT.' SSZ')
2497 1000 format(/,5x,'Projection and phase alignment of wavefunction ',/, &
2498 5x,'============================================== ',//,&
2499 5x,'Input data: ',/)
2500 1005 format(5x,' Sname = ',a,/, &
2501 5x,' Mgvn = ',i10,/, &
2502 5x,' S = ',f10.4,/, &
2503 5x,' Sz = ',f10.4,/, &
2504 5x,' R = ',f10.4,/, &
2505 5x,' Pin = ',f10.4,/, &
2506 5x,' Nocsf = ',i10,/, &
2507 5x,' Idiag = ',i10,//)
2508 1007 format(5x,' Number of electrons in system (nelt) = ',i5,//, &
2509 5x,' Reference determinant: ',//, &
2510 5x,' (refdet) = ',10(i5,1x),/, &
2511 (21x,10(i5,1x)))
2512
2513 1020 format(5x,' Point group (symmetry) of nuclear framework (symtyp) = ',i3,/)
2514 1021 format(5x,' This is the C-inf-v point group',/)
2515 1022 format(5x,' This is the D-inf-h point',/)
2516 1023 format(5x,' This is an Abelian point group ',/)
2517
2518 1030 format(5x,.eq.' Bypassing wavefunction projection (byproj 0)',/)
2519 1031 format(5x,.ne.' Wavefunction will be projected (byproj 0)',/)
2520
2521 1035 format(5x,.gt.' Adjusting phase of wavefunction for scattering (iscat 0)',/)
2522 1036 format(5x,.le.' Not adjusting phase of wavefunction for scattering (iscat 0)',/)
2523
2524 1038 format(/,5x,' Print flags (npflg) ',/,&
2525 5x,' ------------------- ',/,&
2526 5x,' 1. Unprojec and projec wavefunctions : ',i5,/,&
2527 5x,' 2. : ',i5,/,&
2528 5x,' 3. : ',i5,/,&
2529 5x,' 4. : ',i5,/,&
2530 5x,' 5. Target or scattering phase compute : ',i5,/,&
2531 5x,' 6. Abelian point grp multiplctn table : ',i5,/)
2532
2533 1099 format(/,5x,'**** End of the input data',/)
2534
2535 1110 format(/,5x,'Total number of orbitals (norb) = ',i8,/, &
2536 5x,'Triangulation of norb (norbb) = ',i8)
2537 1120 format(/,5x,'Total number of spin-orbs (nsrb) = ',i8,/)
2538 1130 format(5x,'Spin orbitals table of quantum numbers',//, &
2539 5x,' I N G M S MPOS ',/,&
2540 5x,'----- ----- ----- ----- ----- ----- ')
2541 1140 format((5x,6(i5,2x)))
2542 1145 format(/,5x,'**** End of table of spin-orbitals ',/)
2543
2544 1160 format(/,5x,'User defined quantum numbers of ref determinant :',//,&
2545 5x,' mgvn = ',i5,/, &
2546 5x,' S = ',f8.3,/, &
2547 5x,' Sz = ',f8.3,//, &
2548 5x,'and locally computed vars for spin from S,Sz: ',//,&
2549 5x,' iss = ',i5,/, &
2550 5x,' isd = ',i5)
2551 1170 format(/,5x,'For check, computed q-numbers of ref det:',//,&
2552 5x,' 2*Sz + 1 = ',i5)
2553 1180 format( 5x,' irreducible representation = ',i5,//,&
2554 5x,' (Note: totally symmetric representation = 0) ',/)
2555
2556 1185 format(5x,' Lambda value = ',i5,/)
2557 1190 format(5x,' Symmetry quantum number in refdet is not MGVN')
2558 1195 format(5x,' Sz in refdet (',i0,') is not = SZ (',i0,')')
2559
2560 1270 format(/,5x,'Starting to build indexes for the wavefunction',/)
2561 1280 format(/,5x,'Finished building indexes for the wavefunction',/)
2562 1285 format(/,5x,'Wavefunctions read from input file on unit ',i5,/)
2563
2564 2000 format(/,5x,'The wavefunction will be projected',//, &
2565 5x,'This means that the wavefunction on unit ',i5,' is an',/,&
2566 5x,'unprojected wavefunction.',/)
2567 2010 format(5x,'Data read from the wavefunction on unit: ',i5,//, &
2568 5x,' number of CSFs = ',i10,/, &
2569 5x,' number of determinants = ',i10,/, &
2570 5x,' length of packed determinants = ',i10,//, &
2571 5x,'This data will be used to allocate dynamic storage',/,&
2572 5x,'in which to hold the wavefunction.',/)
2573 2100 format(5x,'Projected CSFs in packed format:',/)
2574 3000 format(/,5x,'Computing phase for target state',/)
2575 3100 format(/,5x,'Performing phase correction for target',/,&
2576 5x,'states in a scattering run',/)
2577 46 format(' DUE TO ALARM CONDITION THIS RUN WAS TERMINATED')
2578 3110 format(/' CI target data for SCATCI:', &
2579 //' Number of target symmetries in expansion, NTGSYM =',&
2580 i5/' Number of continuum orbs for each state, NOTGT =',&
2581 20i5,/,(' ',20i5))
2582 3120 format(' Number of CI components for each state, NCTGT =',20i5,/,(' ',20i5))
2583 3130 format(' Continuum M projection for each state, MCONT =',20i5,/,(' ',20i5))
2584 3140 format(' Continuum G/U symmetry for each state, GUCONT =',20i5,/,(' ',20i5))
2585 3150 format(' Marked continuum orbital for each state, MRKORB =',20i5,/,(' ',20i5))
2586 3160 format(' Degenerate coupling case flag MDEGEN =',20i5,/,(' ',20i5))
2587
2588 3167 format(5x,'Writing projected CSFs to unit ',i5,' in format',/,&
2589 5x,'required by the SCATCI/DENPROP programs ',/)
2590 3168 format(5x,'Writing projected CSFs to unit ',i5,' in format',/,&
2591 5x, 'required by the SPEEDY program ',/)
2592 3170 format(5x,'Data on CSFs has been written to file (MEGUL) = ',i5/)
2593 8000 format(5x,'***** Wavefn projection (projec()) - completed',/)
2594 9900 format(/,5x,'***** Error in: projec() ',//)
2595 9950 format(5x,'Cannot allocate space for array ',a,//,&
2596 5x,'Return status from allocate() = ',i8,/)
2597 9960 format(5x,'Cannot de-allocate space for array ',a,//,&
2598 5x,'Return status from deallocate() = ',i8,/)
2599
2600 end subroutine projec
2601
2602
2603 !> \brief Print the CSFs.
2604 !>
2605 !> This provides a complete text dump of all CSFs in terms of their packed determinants.
2606 !>
2607 !> \param nftw File unit for text output of the program.
2608 !> \param nocsf Number of wave functions (CSFs).
2609 !> \param nelt Number of electrons (and size of \c ndtrf).
2610 !> \param ndtrf Reference determinant (spinorbitals per electron).
2611 !> \param nodi Array with number of determinants per CSF.
2612 !> \param indi Array with offsets in \c ndi per CSF.
2613 !> \param icdi Array with offsets in \c cdi per CSF.
2614 !> \param ndi Packed determinants.
2615 !> \param cdi Deteminant coefficients.
2616 !>
2617 subroutine ptpwf (nftw, nocsf, nelt, ndtrf, nodi, indi, icdi, ndi, cdi)
2618
2619 use precisn, only: wp
2620
2621 integer :: nelt, nftw, nocsf
2622 real(kind=wp), dimension(*) :: cdi
2623 integer, dimension(*) :: icdi, indi, ndi, ndtrf, nodi
2624 intent (in) cdi, icdi, indi, ndi, ndtrf, nelt, nftw, nocsf, nodi
2625
2626 integer :: i, k, ma, mb, mc, md, n
2627
2628 write(nftw,'(" REFERENCE DETERMINANT"//(1X,20I5))') (ndtrf(i), i=1,nelt)
2629 write(nftw,'(" CSF",9X,"COEFFICIENT",2X,"NSO"/)')
2630 do n = 1, nocsf
2631 ma = nodi(n)
2632 mb = indi(n)
2633 mc = icdi(n) - 1
2634 md = ndi(mb)
2635 write(nftw,'(1x,i4,d20.10,i5,2x,20i5/(32x,20i5))') n, cdi(mc+1), md, (ndi(mb+i), i=1,2*md)
2636 mb = mb + md + md + 1
2637 do k = 2, ma
2638 md = ndi(mb)
2639 write(nftw,'(5x,d20.10,i5,2x,20i5/(32x,20i5))') cdi(mc+k), md, (ndi(mb+i), i=1,2*md)
2640 mb = mb + md + md + 1
2641 end do
2642 end do
2643
2644 end subroutine ptpwf
2645
2646
2647 !> \brief Sort integer array.
2648 !> \authors J Benda
2649 !> \date 2018
2650 !>
2651 !> Sort array in-place in non-descending order. Currently implemented as a stable insertion sort.
2652 !> This algorithm is advantageous for short and *almost sorted* arrays, which is the case for augmented
2653 !> open-shell-only subsets of determinants in CONGEN, typically resulting in asymptotic complexity of O(n).
2654 !>
2655 !> \param n Length of the array to sort.
2656 !> \param a Integer array to sort.
2657 !>
2658 !> \return Number of swaps done. This is needed elsewhere to update determinant signs.
2659 !>
2660 integer function qsort (n, a) result (swaps)
2661
2662 integer, intent(in) :: n
2663 integer, dimension(n), intent(inout) :: a
2664
2665 integer :: b, i, j, k
2666
2667 swaps = 0
2668
2669 do i = 2, n ! process all positions except for the first
2670
2671 j = i - 1 ! previous position
2672 if (a(j) <= a(i)) cycle ! this is the correct order -> no change needed
2673 b = a(i) ! remember the current element a(i)
2674
2675 do while (j > 1) ! find the correct position for this element to the left of its current position
2676 if (b < a(j - 1)) then
2677 j = j - 1
2678 else
2679 exit
2680 end if
2681 end do
2682
2683 do k = i, j + 1, -1 ! shift all elements left of i and larger than a(i) one position to the right, vacating j
2684 a(k) = a(k - 1)
2685 end do
2686
2687 a(j) = b ! put the current element into the vacated space
2688 swaps = swaps + i - j ! update the number of swaps needed to achieve the new order
2689
2690 end do
2691
2692 end function qsort
2693
2694
2695 !> \brief Read CSF.
2696 !>
2697 !> Routine \ref congen_distribution::wfn stores the CSF data in buffers of fixed size.
2698 !>
2699 !> When the buffers are full, they are emptied to disk
2700 !> and reused. This is why we can have several sets to read here.
2701 !>
2702 subroutine rdwf (nft, k1, nodi, k2, cdi, k3, ndi)
2703
2704 use precisn, only : wp
2705
2706 integer :: k1, k2, k3, n1, n2, n3, i, nft, st
2707 integer, dimension(*) :: nodi, ndi
2708 real(kind=wp), dimension(*) :: cdi
2709
2710 rewind nft
2711
2712 k1 = 0
2713 k2 = 0
2714 k3 = 0
2715
2716 do
2717 read(nft, iostat = st) n1, (nodi(k1+i), i=1,n1)
2718 if (st /= 0) exit
2719 k1 = k1 + n1
2720
2721 read(nft, iostat = st) n2, (cdi(k2+i), i=1,n2)
2722 if (st /= 0) exit
2723 k2 = k2 + n2
2724
2725 read(nft, iostat = st) n3, (ndi(k3+i), i=1,n3)
2726 if (st /= 0) exit
2727 k3 = k3 + n3
2728 end do
2729
2730 rewind nft
2731
2732 end subroutine rdwf
2733
2734
2735 !> \brief Reads the size of the wavefunction
2736 !>
2737 !> Reads the information giving the size of the data used for the wavefunction, for example
2738 !> the number of determinants, but does not read the actual data, such as the determinants.
2739 !>
2740 !> This is really just a stripped down version of the routine \ref rdwf which reads the full data.
2741 !>
2742 !> \param iunit The logical unit on which the wavefucntion data is located.
2743 !> \param num_csfs On return, number of CSFs stored in the file.
2744 !> \param num_dets On return, number of determinants summed over all CSFs in the file.
2745 !> \param len_dets On return, total summed length of all arrays of packed determinants in the file.
2746 !>
2747 !> \note MAL 10/05/2011: This subroutine is new to congen and is included to bring congen into
2748 !> line with the changes that were made in \ref projec in order to utilize
2749 !> dynamic memory
2750 !>
2751 subroutine rdwf_getsize (iunit, num_csfs, num_dets, len_dets)
2752
2753 use precisn, only : wp
2754
2755 integer :: iunit, num_csfs, num_dets, len_dets
2756 integer :: ncsfs, ndets, ldets, ios, ntemp
2757
2758 rewind iunit
2759
2760 ncsfs = 0
2761 ndets = 0
2762 ldets = 0
2763
2764 ! The while loop reads records from the logical unit until the end of file, or some other error occurs.
2765 do
2766
2767 ! First record is a CSF counter (followed by array with determinant counts per CSF)
2768 read(iunit, iostat = ios) ntemp
2769 if (0 /= ios) exit
2770 ncsfs = ncsfs + ntemp
2771
2772 ! Second record is a counter for determinants (followed by coefficients per CSF per determinant)
2773 read(iunit, iostat = ios) ntemp
2774 if (0 /= ios) exit
2775 ndets = ndets + ntemp
2776
2777 ! Third record is the counter of integer data comprising determinants themselves (followed by packed determinants)
2778 read(iunit, iostat = ios) ntemp
2779 if (0 /= ios) exit
2780 ldets = ldets + ntemp
2781
2782 end do
2783
2784 rewind iunit
2785
2786 num_csfs = ncsfs
2787 num_dets = ndets
2788 len_dets = ldets
2789
2790 end subroutine rdwf_getsize
2791
2792
2793 !> \brief Add mirror-reflected spin-orbitals.
2794 !>
2795 !> Used only for C_infv and D_infh.
2796 !>
2797 subroutine rfltn (nelt, nodi, ndi, cdi, r, mxnd, ndmxp, thres, nodo, cdo, ndtr, mm, bst)
2798
2799 use precisn, only : wp
2800 use consts, only : half => xhalf
2801 use congen_bstree, only : det_tree
2802
2803 integer :: mxnd, ndmxp, nelt, nodi, nodo
2804 real(kind=wp) :: r, thres
2805 real(kind=wp), dimension(*) :: cdi, cdo
2806 integer, dimension(*) :: mm, ndi, ndtr
2807 type(det_tree) :: bst
2808 intent (in) cdi, mm, nodi, r
2809 intent (inout) nodo, bst
2810
2811 real(kind=wp) :: cfd
2812 integer :: i, j, ma, nd
2813
2814 cdo(1:nodi) = half * cdi(1:nodi)
2815
2816 nd = 0
2817 nodo = nodi
2818 do i = 1, nodi
2819 cfd = half * r * cdi(i)
2820 do j = 1, nelt
2821 ma = ndi(nd+j)
2822 if (mm(ma) /= 0) ma = ma + sign(2, mm(ma))
2823 ndtr(j) = ma
2824 end do
2825 if (mod(qsort(nelt, ndtr(1:nelt)), 2) /= 0) cfd = -cfd
2826 call stmrg (nelt, mxnd, ndmxp, ndi, cdo, nodo, ndtr, cfd, bst)
2827 if (nodo < 0) return
2828 nd = nd + nelt
2829 end do
2830
2831 call cntrct (nelt, nodo, ndi, cdo, thres)
2832
2833 end subroutine rfltn
2834
2835
2836 !> \brief Real strided vector norm.
2837 !>
2838 !> This is actually an in-house version of the BLAS level 1 routine of the same name, included here to avoid
2839 !> dependency on BLAS library.
2840 !>
2841 !> \param n Length of the vector
2842 !> \param array Vector of real numbers
2843 !> \param istep Stride
2844 !>
2845 !> \return Square of L2 norm of the vector.
2846 !>
2847 function snrm2 (n, array, istep)
2848
2849 use precisn, only : wp
2850 use consts, only : zero => xzero
2851
2852 integer :: istep, n
2853 real(kind=wp), dimension(*) :: array
2854 real(kind=wp) :: snrm2
2855 intent (in) array, istep, n
2856
2857 integer :: i, ii
2858
2859 snrm2 = zero
2860 if (n <= 0) return
2861
2862 ii = 1
2863 do i = 1, n
2864 snrm2 = snrm2 + array(ii)**2
2865 ii = ii + istep
2866 end do
2867
2868 end function snrm2
2869
2870
2871 !> \brief Add determinant to a list of determinants
2872 !>
2873 !> Given an existing list of determinants in cdo()/ndo() and a new single determinant cdi/ndi(), the new determinant
2874 !> is merged into the list and the list extended if necessary.
2875 !>
2876 !> This operation is used during spin-projection of a CSF.
2877 !>
2878 !> \note MAL 16/05/11 : Modified to bring the subroutine into line with the changes made to projec
2879 !>
2880 !> \param nelt Number of electrons in each det.
2881 !> \param maxcdo Dimension of cdo.
2882 !> \param maxndo Dimension of ndo.
2883 !> \param ndo List of determinants each with "nelt" spin-orbitals.
2884 !> \param cdo Coefficient for each det in ndo.
2885 !> \param nodo On input is the number of determinants in cdo/ndo. Will be updated for output if the data in cdi/ndi
2886 !> new entry.
2887 !> \param ndi A single det of "nelt" spin orbs which has to be merged into ndo.
2888 !> \param cdi Single coefficient going with the single determinant defined in ndi.
2889 !> \param bst Binary search tree used for fast localization of determinants.
2890 !>
2891 subroutine stmrg (nelt, maxcdo, maxndo, ndo, cdo, nodo, ndi, cdi, bst)
2892
2893 use precisn, only : wp
2894 use congen_bstree, only : det_tree
2895
2896 real(kind=wp), parameter :: one = 1.0_wp
2897
2898 type(det_tree) :: bst
2899
2900 integer :: nelt ! Number of electrons in each det.
2901 integer :: maxcdo ! Dimension of cdo
2902 integer :: maxndo ! Dimension of ndo
2903 integer :: ndo(maxndo) ! List of determinants each with "nelt" spin-orbs
2904 integer :: nodo ! On input is the number of dets in cdo()/ndo(). Will be updated
2905 ! for output if the data in cdi/ndi() is merged into cdo()/ndo() as a new entry.
2906 integer :: ndi(nelt) ! A single det of "nelt" spin orbs which has to be merged into ndo().
2907
2908 real(kind=wp) :: cdo(maxcdo) ! Coeff. for each det in ndo()
2909 real(kind=wp) :: cdi ! Single coeff. going with the single determinant defined in ndi()
2910
2911 integer i, ibase, idet, n
2912
2913 logical, parameter :: zdebug = .false.
2914
2915 ! Debug banner header
2916
2917 if (zdebug) then
2918 write(6,'(/,30x,"===> STMRG() <====",/)')
2919 write(6,'( 30x,"Input data: ")')
2920 write(6,'( 30x," nelt = ",I6)') nelt
2921 write(6,'( 30x," maxcdo = ",I6)') maxcdo
2922 write(6,'( 30x," maxndo = ",I6)') maxndo
2923 write(6,'( 30x," cdi = ",D13.6)') cdi
2924 write(6,'(/,30x,"# of dets in current (cdo,ndo) list (nodo) = ",I5,/)') nodo
2925
2926 ibase = 0
2927 do idet = 1, nodo
2928 write(6,'( 30x,I5,2x,D13.6,20(I4,1x))') idet, cdo(idet), (ndo(ibase+i), i=1,nelt)
2929 ibase = ibase + nelt
2930 end do
2931 end if
2932
2933 ! Try to find the input determinant in the list of determinants.
2934 ! - This should take around O(log2(nodo)) operations
2935
2936 n = bst % locate_det(ndi)
2937
2938 ! Now either update the coefficient (if det found), or insert new determinant.
2939
2940 if (n > 0) then
2941
2942 if (zdebug) then
2943 write(6,'(/,30x,"New determinant found in ""existing"" list:")')
2944 write(6,'( 30x," Found in exisiting list at n = ",I6)') n
2945 write(6,'( 30x," Coefficient cdo(n) = ",D13.6)') cdo(n)
2946 write(6,'( 30x," Augment coeff, cdi*sign = ",D13.6,/)') cdi
2947 end if
2948
2949 cdo(n) = cdo(n) + cdi
2950
2951 else
2952
2953 ! Ok, so we get here if we have to add the determinant onto the end of the exisitng list.
2954
2955 if (zdebug) then
2956 write(6,'(30x,"Adding new determinant to end of list",/)')
2957 end if
2958
2959 if (nodo + 1 > maxcdo .or. (nodo + 1) * nelt > maxndo) then
2960 write(6,'(/,10x,"**** Error in stmrg(): ",/)')
2961 write(6,'( 10x,"Insufficient space to add extra determinant onto")')
2962 write(6,'( 10x,"end of list.")')
2963 write(6,'( 10x," cdo() : required ",I10," available ",I10)') nodo + 1, maxcdo
2964 write(6,'( 10x," ndo() : required ",I10," available ",I10,/)') (nodo + 1) * nelt, maxndo
2965 stop 999
2966 end if
2967
2968 cdo(nodo + 1) = cdi
2969 ndo(nodo * nelt + 1 : nodo * nelt + nelt) = ndi(1:nelt)
2970 nodo = nodo + 1
2971
2972 call bst % insert(nodo)
2973
2974 if (zdebug) then
2975 write(6,'(30x,"Bstree after stmrg: ")')
2976 call bst % output(32)
2977 end if
2978
2979 end if
2980
2981 ! Return point
2982
2983 if (zdebug) then
2984 write(6,'(/,30x,"# of dets in current (cdo,ndo) list (nodo) = ",I5,/)') nodo
2985
2986 ibase = 0
2987 do idet = 1,nodo
2988 write(6,'( 30x,I5,2x,D13.6,20(I4,1x))') idet, cdo(idet), (ndo(ibase+i), i=1,nelt)
2989 ibase = ibase + nelt
2990 end do
2991
2992 write(6,'(/,30x,"***** STMRG() - completed ",/)')
2993 end if
2994
2995 end subroutine stmrg
2996
2997
2998 !> \brief Form spin eigenstates
2999 !>
3000 !> Takes the wavefunction generated by CSFGEN and transforms it to be
3001 !> fully in accord with the spin quantum numbers of the system.
3002 !>
3003 !> \note MAL 10/05/2011: The changes made to wfgntr have made so as to make the
3004 !> subroutine compatible with the changes made to its calling subroutine, \ref projec.
3005 !>
3006 subroutine wfgntr (mgvn, iss, isd, thres, r, symtyp, nelt, nsyml, nob, nobl, nob0l, nobe, norb, nsrb, &
3007 mn, mg, mm, ms, iposit, map, mpos, nocsf, ndtrf, nodi, ndi, cdi, indil, icdil, maxndi, maxcdi, &
3008 nodo, ndo, cdo, indo, icdo, maxndo, maxcdo, lenndo, lencdo, npflg, byproj, nftw, nalm)
3009
3010 use precisn, only : wp
3011 use global_utils, only : mprod
3012
3013 ! Local temporary storage
3014 ! - len_cdit has to be >= the maximum number of determinants in any one CSF
3015
3016 integer, parameter :: len_cdit = 5000
3017 real(kind=wp) :: cdit(len_cdit)
3018
3019 ! Fixed constants
3020
3021 real(kind=wp), parameter :: verysmall = 1.0d-30
3022
3023 ! Integer variables passed in the argument list
3024
3025 integer :: nftw ! logical unit for the printer
3026 integer :: symtyp, byproj
3027 integer :: lencdo ! final usage in cdo()
3028 integer :: lenndo ! final usage in ndo()
3029 integer :: maxcdo ! maximum available in cdo()
3030 integer :: maxndo ! maximum available in ndo()
3031 integer :: mgvn
3032 integer :: iss
3033 integer :: isd
3034 integer :: norb
3035 integer :: ndmx
3036 integer :: ncmx
3037 integer :: ndmxp
3038 integer :: nsyml
3039 integer :: nelt
3040 integer :: iposit
3041 integer :: nocsf,nsrb
3042 integer :: maxndi,maxcdi
3043 integer, dimension(nsyml) :: nob(nsyml),nobl(nsyml),nob0l(nsyml), nobe(nsyml)
3044 integer, dimension(nsrb) :: mn,mg,mm,ms,map,mpos
3045 integer, dimension(nelt) :: ndtrf
3046 integer :: npflg(6)
3047 real(kind=wp) :: r,thres
3048
3049 ! As elsewhere in the code, the wavefunction is represented as a
3050 ! set of data packed into arrays.
3051 !
3052 ! For the input wavefunction we have:
3053 !
3054 ! nodi() is the number of dets in each CSF
3055 ! ndi() holds the dets in packed format, that is as
3056 ! number of replacements + replaced + replacing
3057 ! cdi() is the coefficient for each determinant
3058 !
3059 ! We need two further indexing arrays, each of length,
3060 ! NOCSF+1 to handle the wavefunction data:
3061 !
3062 ! icdil(n) points at the first entry in the coefficients
3063 ! array, cdi(), for CSF "n".
3064 !
3065 ! indil(n) points at the first entry in the determinants
3066 ! array, ndi(), for CSF "n".
3067 !
3068 ! Remember these have to be one larger than the number of CSFs. We compute the storage size of CSF by looking at the location
3069 ! of the "following one" - hence need to add one on at the end.
3070
3071 integer, dimension(nocsf) :: nodi
3072 integer, dimension(maxndi) :: ndi
3073 integer, dimension(nocsf+1) :: indil, icdil
3074 real(kind=wp), dimension(maxcdi) :: cdi
3075
3076 ! Similar arrays exist for the output wavefunction and they are declared in the argument list too.
3077
3078 integer, dimension(nocsf) :: nodo
3079 integer, dimension(maxndi) :: ndo
3080 integer, dimension(nocsf+1) :: indo, icdo
3081 real(kind=wp), dimension(maxcdi) :: cdo
3082
3083 ! Local integer variables
3084 integer :: n, i, num_dets_input, ipos_dets_input, ipos_coeffs_out, ipos_coeffs_in, &
3085 ipos_dets_out, idet, isum, msum, nsrbs, needed, ierr, lenmop, nalm, &
3086 ipos_this_det, nreps, me, mf, idop, idcp, ieltp, num_dets_final, mxss
3087 integer, dimension(nelt) :: mdop, mdcp
3088 integer, dimension(nsrb) :: mdc, mdo, ndta
3089 logical, allocatable :: flip(:)
3090
3091 ! Local real variables
3092 real(kind=wp) :: mysum
3093
3094 integer, allocatable :: mop(:) ! Holds all expanded open shell per CSF (see allocation)
3095
3096 ! Following are used to analyze CSF dimensions on input
3097 integer :: icsf_with_max(1)
3098 integer :: max_num_dets_input
3099 integer :: max_num_dets_output
3100
3101 ! Local fixed logical values
3102 logical, parameter :: zdebug = .false.
3103
3104 ! Intrinsic Fortran functions used
3105 intrinsic :: sqrt, maxloc, minloc
3106
3107 ! Debug banner header
3108 if (zdebug) then
3109 write(nftw,1000)
3110 write(nftw,1010) mgvn,iss,isd,thres,r,nsyml,nelt,nocsf,nsrb
3111 write(nftw,1020) norb, ndmx, ncmx, ndmxp
3112 write(nftw,1030) maxcdo, maxndo
3113 write(nftw,1035)
3114 write(nftw,1036) (i,mn(i),mg(i),mm(i),ms(i),mpos(i),i=1,nsrb)
3115 write(nftw,1037)
3116 end if
3117
3118 ! We compute the number of spin-orbitals which are not
3119 ! degenerate. For C-inf-v and D-inf-h this means sigma
3120 ! type. For Abelian point groups it is all orbitals.
3121
3122 nsrbs = 0
3123 select case (symtyp)
3124 case (0) ; nsrbs = 2 * nob(1)
3125 case (1) ; nsrbs = 2 * (nob(1) + nob(2))
3126 case (2) ; nsrbs = 2 * sum(nob(1:nsyml))
3127 case default ; write(nftw, 9900) ; stop
3128 end select
3129
3130 if (zdebug) then
3131 write(nftw,1040) nsrbs
3132 end if
3133
3134 !=========================================================================
3135 !
3136 ! C O U N T M A X I M A F R O M C S F s
3137 !
3138 !=========================================================================
3139
3140 ! Looking at the number of determinants per CSF, we work out
3141 ! the CSF which has the maximum number of determinants.
3142
3143 max_num_dets_input = maxval(nodi)
3144 icsf_with_max = maxloc(nodi)
3145
3146 ! mop() needs to hold the expanded determinants when processing each CSF one at a time (see popnwf().
3147 ! Each det is then a list of "ieltp" spin orbs, where "ieltp" <= "nelt".
3148 !
3149 ! So we can compute lenmop and allocate the array. We over allocate by a factor (10 ?) here as the
3150 ! later processing requirements are not precisely known.
3151
3152 lenmop = 7 * nelt * max_num_dets_input
3153 allocate(mop(lenmop), stat = ierr)
3154 if (ierr /= 0) then
3155 write(nftw,9900)
3156 write(nftw,9925) lenmop
3157 stop 999
3158 end if
3159
3160 ! There will be one permutation sign per determinant.
3161
3162 allocate(flip(max_num_dets_input), stat = ierr)
3163 if (ierr /= 0) then
3164 write(nftw,9900)
3165 write(nftw,9926) max_num_dets_input
3166 stop 999
3167 end if
3168
3169 !=========================================================================
3170 !
3171 ! L O O P O V E R C S F s
3172 !
3173 !=========================================================================
3174
3175 if (zdebug) then
3176 write(nftw, 3000)
3177 end if
3178
3179 nalm = 0
3180 ipos_coeffs_out = 1
3181 ipos_dets_out = 1
3182
3183 do n = 1, nocsf
3184 num_dets_input = nodi(n)
3185 ipos_dets_input = indil(n)
3186 icdo(n) = ipos_coeffs_out
3187 indo(n) = ipos_dets_out
3188
3189 if (zdebug) then
3190 write(nftw,3010) n, nocsf, num_dets_input, ipos_dets_input, ipos_coeffs_out, ipos_dets_out
3191 end if
3192
3193 !-------------------------------------------------------------------------
3194 ! Step 1: Validate spatial and spin quantum numbers
3195 ! for all determinants in this CSF
3196 !-------------------------------------------------------------------------
3197
3198 ! Compute the overall change in spatial quantum number and in Sz component of spin for each determinant relative to the
3199 ! reference determinant. The overall change in spatial and in spin quantum numbers relative to the reference determinant
3200 ! should be zero. If not, then such a deterinant does not match the overall system quantum numbers and we have an error
3201 ! condition. Remember that we have already verified the quantum numbers of the reference determinant before calling this
3202 ! routine.
3203
3204 ipos_this_det = ipos_dets_input
3205
3206 do idet = 1, num_dets_input
3207 nreps = ndi(ipos_this_det)
3208
3209 if (zdebug) then
3210 write(nftw,3020) n, idet, num_dets_input, nreps
3211 end if
3212
3213 if (nreps /= 0) then ! If 0 would be reference det
3214 if (zdebug) then
3215 write(nftw,3030) (ndi(ipos_this_det+i), i=1,nreps)
3216 write(nftw,3035) (ndi(ipos_this_det+nreps+i), i=1,nreps)
3217 end if
3218
3219 isum = 0 ! Sum of Sz over spin-orbs
3220
3221 select case (symtyp)
3222
3223 !... C-inf-v and D-inf-h
3224 case (:1)
3225 msum = 0
3226 do i = 1, nreps
3227 me = ndi(ipos_this_det + i)
3228 mf = ndi(ipos_this_det + nreps + i)
3229 isum = isum + ms(me) - ms(mf)
3230 msum = msum + mm(me) - mm(mf)
3231 end do
3232
3233 !... Abelian point groups
3234 case (2)
3235 msum = 1
3236 do i = 1, nreps
3237 me = ndi(ipos_this_det + i)
3238 mf = ndi(ipos_this_det + nreps + i)
3239 isum = isum + ms(me) - ms(mf)
3240 msum = mprod(msum, mprod(mm(me)+1, mm(mf)+1, 0, nftw), 0, nftw)
3241 end do
3242 msum = msum - 1
3243
3244 !... Erroneous "symtyp" value
3245 case (3:)
3246 write(nftw,9900)
3247 stop
3248
3249 end select
3250
3251 if (msum /= 0) then
3252 write(nftw, 9900)
3253 write(nftw, 9214) idet, n
3254 stop 999
3255 end if
3256
3257 if (isum /= 0) then
3258 write(nftw,9900)
3259 write(nftw,9215) idet, n
3260 stop 999
3261 end if
3262
3263 end if ! End of if test on zero replacements
3264
3265 ! Align pointers for the next determinant. Remember, a determinant is stored as:
3266 ! - the number of replacements/replaced,
3267 ! - each replaced spin-orb,
3268 ! - each replacement spin-orb,
3269 ! therefore this determinant was of length 2*md+1
3270
3271 ipos_this_det = ipos_this_det + nreps + nreps + 1
3272
3273 end do
3274
3275 if (zdebug) then
3276 write(nftw, 3090)
3277 end if
3278
3279 !-------------------------------------------------------------------------
3280 ! Step 2: Find the number of electrons which are in orbitals that are not fully occupied.
3281 ! These are known as "open shells". Also find the list of the spin-orbitals corresponding to these.
3282 !-------------------------------------------------------------------------
3283
3284 ! popnwf() operates on the complete set of determinants defining this CSF. It is worth remembering that in Alchemy
3285 ! a CSF is defined firstly as an assignment of orbital occupation numbers. One, or more, CSFs can then be formed
3286 ! by distributing electrons to the spin-orbitals associated with this orbital assignment and
3287 ! then generating the required coupling coefficients.
3288 !
3289 ! On successful return, "ieltp" will hold the number of electrons in open shells. This may even be zero.
3290
3291 num_dets_input = nodi(n)
3292 ipos_dets_input = indil(n)
3293
3294 call popnwf (nsrb, nsrbs, nelt, ndtrf, lenmop, mdop, mdcp, mop, mdc, mdo, ndta, &
3295 num_dets_input, ndi(ipos_dets_input), idop, idcp, ieltp, flip, ierr)
3296
3297 ! Test for error condition and print details
3298 if (ierr == 0) then
3299 if (zdebug) then
3300 write(nftw,4010) ieltp
3301 end if
3302 else
3303 write(nftw,9900)
3304 select case (ierr)
3305 case (1) ; write(nftw,233) n
3306 case (2) ; write(nftw,235) n
3307 case (3:) ; write(nftw,237) n
3308 end select
3309 stop 999
3310 end if
3311
3312 !-------------------------------------------------------------------------
3313 ! Step 3: Normalize the expansion coefficients associated with the determinants in this CSF.
3314 ! These coefficients were obtained from products of the Clebsch-Gordan coupling coefficients.
3315 !-------------------------------------------------------------------------
3316
3317 ! The computation depends on how many electrons are in open shells.
3318 ! Normalized expansion coefficients are placed into the array "cdo()" during this process.
3319
3320 ipos_coeffs_in = icdil(n) - 1
3321
3322 ! update cdi with the sort permutation sign
3323 do i = 1, num_dets_input
3324 if (flip(i)) cdi(ipos_coeffs_in + i) = -cdi(ipos_coeffs_in + i)
3325 end do
3326
3327 !-------------------------------------------------------------------------
3328 ! 0 or 1 ELECTRONS in OPEN SHELLS
3329 !-------------------------------------------------------------------------
3330
3331 if (ieltp <= 1) then ! 0 or 1 electrons in open shells.
3332
3333 if (zdebug) then
3334 write (nftw,4510)
3335 write (nftw,4520)
3336 write (nftw,4522) ipos_coeffs_in, ipos_coeffs_out
3337 write (nftw,4525) (i, cdi(ipos_coeffs_in+1+i-1), i=1,num_dets_input)
3338 end if
3339
3340 mysum = snrm2(num_dets_input, cdi(ipos_coeffs_in+1), 1)
3341
3342 if (zdebug) write(nftw,4530) mysum
3343
3344 if (mysum < verysmall) then ! monitor for very small numbers
3345 write(nftw, 9900)
3346 write(nftw, 2222) mysum
3347 stop 999
3348 end if
3349
3350 mysum = 1.0_wp/sqrt(mysum)
3351
3352 do i = 1, num_dets_input
3353 cdo(ipos_coeffs_out+i-1) = mysum * cdi(ipos_coeffs_in+1+i-1)
3354 end do
3355
3356 num_dets_final = num_dets_input
3357
3358 if (zdebug) then
3359 write(nftw,4540)
3360 write(nftw,4525) (i, cdo(ipos_coeffs_out+i-1), i=1,num_dets_final)
3361 end if
3362
3363 !-------------------------------------------------------------------------
3364 ! >= 2 ELECTRONS in OPEN SHELLS
3365 !-------------------------------------------------------------------------
3366
3367 else ! >= 2 electrons in open shells - project wfn
3368
3369 if (zdebug) then
3370 write(nftw,4610)
3371 write(nftw,4520)
3372 write(nftw,4522) ipos_coeffs_in, ipos_coeffs_out
3373 write(nftw,4525) (i, cdi(ipos_coeffs_in+1+i-1), i=1,num_dets_input)
3374 end if
3375
3376 ! We need to copy the expansion coefficients to temporary local storage
3377 if (num_dets_input > len_cdit) then
3378 write(nftw,9900)
3379 write(nftw,9935) n, num_dets_input, len_cdit
3380 stop 999
3381 else
3382 do i = 1, num_dets_input
3383 cdit(i) = cdi(ipos_coeffs_in + i)
3384 end do
3385 end if
3386
3387 if (zdebug) then
3388 write(nftw,4625)
3389 write(nftw,4525) (i, cdit(i), i=1,num_dets_input)
3390 end if
3391
3392 ! Call prjct() to perform the spin projection
3393 !
3394 ! ieltp = number of electrons
3395 ! mxss = maximum Spin for projection
3396 ! ma = number of ddterminants
3397 ! mop = input determinants (overwritten on output)
3398 ! cdit = input coefficients with each determinant
3399 ! nod = Return code (>0 means number of dets in output)
3400 ! cdo() = Coefficients of determinants after projection. These are stored into cdo() beginning at
3401 ! location ipos_coeffs_out, which is updated for every CSF.
3402 ! lencdo = space reaining in cdo() array - monitored
3403
3404 mxss = ieltp
3405 lencdo = maxcdo - ipos_coeffs_out + 1
3406 lenmop = size(mop)
3407
3408 call prjct (ieltp, mxss, num_dets_input, mop, cdit, num_dets_final, cdo(ipos_coeffs_out), &
3409 lencdo, mgvn, iss, isd, thres, r, ndta, mm, ms, lenmop, symtyp, nsrb)
3410
3411 if (zdebug) then
3412 write(nftw,4540)
3413 write(nftw,4525) (i, cdo(ipos_coeffs_out+i-1), i=1,num_dets_final)
3414 end if
3415
3416 end if
3417
3418 !-------------------------------------------------------------------------
3419 ! Step 4: Now we can move the determinants for this
3420 ! CSF into place in the output array.
3421 !-------------------------------------------------------------------------
3422
3423 if (zdebug) then
3424 write(nftw, 4060)
3425 write(nftw, 4062) num_dets_final, ieltp, idop, idcp, ipos_dets_out, maxndo
3426 end if
3427
3428 call pkwf (num_dets_final, ieltp, cdo(ipos_coeffs_out), mop, idop, mdop, idcp, mdcp, &
3429 nftw, ipos_dets_out, ndo, maxndo, n)
3430
3431
3432 ! Record the number of dets for this CSF in nodo()
3433 ! Update pointer to next location in cdo().
3434
3435 nodo(n) = num_dets_final
3436 ipos_coeffs_out = ipos_coeffs_out + num_dets_final
3437
3438
3439 ! Screen for exhaustion of memory in ndo(), cdo()
3440 if (ipos_dets_out >= maxndo) then
3441 write(nftw,9900)
3442 write(nftw,9981) n, maxndo
3443 stop 999
3444 end if
3445
3446 if (ipos_coeffs_out >= maxcdo) then
3447 write(nftw,9900)
3448 write(nftw,9982) n, maxcdo
3449 stop 999
3450 end if
3451
3452 ! Finished with this CSF
3453 if (zdebug) then
3454 write (nftw,4690) n
3455 end if
3456
3457 end do
3458
3459 !=========================================================================
3460 !
3461 ! E N D L O O P O V E R C S F s
3462 !
3463 !=========================================================================
3464
3465 ! Finished with dynamic array mop()
3466 if (allocated(mop)) then
3467 deallocate(mop, stat = ierr)
3468 if (ierr /= 0) then
3469 write(nftw,9900)
3470 write(nftw,9927) lenmop
3471 stop 999
3472 end if
3473 end if
3474
3475 ! Finished with dynamic array flip()
3476 if (allocated(flip)) then
3477 deallocate(flip, stat = ierr)
3478 if (ierr /= 0) then
3479 write(nftw,9900)
3480 write(nftw,9928) max_num_dets_input
3481 stop 999
3482 end if
3483 end if
3484
3485 ! Need starting values for the "N+1" th CSF (which does not exist). These also serve as an upper bound for the "N"-th CSF
3486 ! and are used in loops in the subsequent code which evaluates symbolic energy expressions.
3487 indo(nocsf+1) = ipos_dets_out
3488 icdo(nocsf+1) = ipos_coeffs_out
3489
3490 ! High watermark in both arrays needs to be returned to caller.
3491 lenndo = ipos_dets_out - 1
3492 lencdo = ipos_coeffs_out - 1
3493
3494 ! Looking at the number of determinants per CSF, we work out the CSF which has the maximum number of determinants.
3495 max_num_dets_output = maxval( nodo )
3496 icsf_with_max = maxloc( nodo )
3497
3498 write(nftw,2992) icsf_with_max(1), max_num_dets_output
3499
3500 ! Subroutine return point
3501 write(nftw,7990) lenndo, maxndo, lencdo, maxcdo
3502 write(nftw,8000)
3503
3504 ! Format statements
3505 233 format(i6,' TH WF IN ERROR, (NO. OF OPEN SO NOT =)')
3506 237 format(i6,' TH WF IN ERROR,(NELTP=0,BUT NOD GT. 1)')
3507 235 format(' NEED MORE SPACE FOR MOP IN',i5,' TH WF',/, &
3508 ' Increase parameter LNDT in input')
3509 1000 format(/,10x,'====> WFGNTR() <====',/)
3510 1010 format( 10x,'Input data: ',/, &
3511 10x,' mgvn = ',i10,/, &
3512 10x,' iss = ',i10,/, &
3513 10x,' isd = ',i10,/, &
3514 10x,' thres = ',f12.5,/, &
3515 10x,' r = ',f12.5,/, &
3516 10x,' nsyml = ',i10,/, &
3517 10x,' nelt = ',i10,/, &
3518 10x,' nocsf = ',i10,/, &
3519 10x,' nsrb = ',i10)
3520 1020 format( 10x,' norb = ',i10,/, &
3521 10x,' ndmx = ',i10,/, &
3522 10x,' ncmx = ',i10,/, &
3523 10x,' ndmxp = ',i10,/)
3524 1030 format( 10x,' maxcdo = ',i10,/, &
3525 10x,' maxndo = ',i10,/)
3526 1035 format(5x,'Spin orbitals table of quantum numbers',//, &
3527 5x,' I N G M S MPOS ',/, &
3528 5x,'----- ----- ----- ----- ----- ----- ')
3529 1036 format((5x,6(i5,2x)))
3530 1037 format(/,5x,'**** End of table of spin-orbitals ',/)
3531 1040 format(10x,'No. non-degenerate spin orbitals (nsrbs) = ',i6,/)
3532 1055 format(10x,'Allocating ',i8,' integers for array mop() ',/)
3533 1500 format(/,10x,'Allocated ',i10,' integer units to array nr() ',/)
3534 2222 format(/,' Sum IN WFGNTR =',e20.12,//)
3535 2990 format(/,10x,'On input CSF ',i7,' has the largest ',/, &
3536 10x,'number of determinants = ',i7,/)
3537 2992 format(/,10x,'On output CSF ',i7,' has the largest ',/, &
3538 10x,'number of determinants = ',i7,/)
3539 3000 format(/,10x,'Entering loop over CSFs ',/)
3540 3010 format(/,10x,'>>>> Processing input CSF ',i10,' of ',i10,//, &
3541 10x,'Number of determinants (num_dets_input) = ',i7,/, &
3542 10x,'1st in pkd dets array (ipos_dets_input) = ',i7,//, &
3543 10x,'1st in Out coefs arry (ipos_coeffs_out) = ',i7,/, &
3544 10x,'1st in Output dets arry (ipos_dets_out) = ',i7)
3545 3020 format(/,15x,'CSF ',i7,' - Det. ',i6,' of ',i6,//, &
3546 20x,'Number of replacements (nreps) = ',i5,/)
3547 3030 format(20x,'Replaced spin orbs : ',20(i3,1x))
3548 3035 format(20x,'Replacments spin. orbs: ',20(i3,1x))
3549 3090 format(/,15x,'Quantum numbers for all determinants in this CSF',/, &
3550 15x,'have been validated.',/)
3551 4010 format(15x,'Number of electrons in open shells (ieltp) = ',i5,/)
3552 4050 format(15x,'The expansion coefficients for each determinant ',/ &
3553 15x,'have been normalized.',/)
3554 4060 format(/,15x,'This projected CSF will now be packed into',/ &
3555 15x,'into the array holding all output packed CSF',/)
3556 4062 format(15x,'Data sent into PKWF() follows: (old name/new name)',/, &
3557 15x,' nod (num_dets_final) = ',i10,/, &
3558 15x,' neltp (ieltp) = ',i10,/, &
3559 15x,' idop (idop) = ',i10,/, &
3560 15x,' idcp (idcp) = ',i10,/, &
3561 15x,' no (ipos_dets_out) = ',i10,/, &
3562 15x,' ndmx (maxndo) = ',i10,/)
3563 4510 format(15x,'Normalizing CSF expansion coefficients using ',/, &
3564 15x,'the SNRM2 function. Projection is not needed.'/)
3565 4520 format(/,15x,'CSF coefficients before normalization: ',/)
3566 4522 format(15x,'Storage locs for input and output coefficients: ',//, &
3567 15x,' For cdi(), ipos_coeffs_in = ',i7,//, &
3568 15x,' For cdo(), ipos_coeffs_out = ',i7,/)
3569 4525 format(15x,i6,'. ',2x,f13.7)
3570 4530 format(/,15x,'Sum - sqrs of coefficients (this CSF) = ',d13.6,/)
3571 4540 format(/,15x,'CSF coefficients after normalization: ',/)
3572 4610 format(15x,'Normalizing CSF expansion coefficients using ',/, &
3573 15x,'projection because it has >= 2 electrons in ',/, &
3574 15x,'open shells. '/)
3575 4625 format(/,15x,'Coefficients have been copied into CDIT(): ',/)
3576 4690 format(/,10x,'<<<< Completed processing of CSF number ',i6,/)
3577 7990 format(/,10x,'At end of wfgntr(), usage of memory in output',/, &
3578 10x,'arrays is as follows: ',//, &
3579 10x,' Array Used Max avail ',/, &
3580 10x,' ----- --------- --------- ',/, &
3581 10x,' ndo() ',i9,2x,i9,/, &
3582 10x,' cdo() ',i9,2x,i9,/)
3583 8000 format(/,10x,'**** WFGNTR() - completed ',/)
3584
3585 ! Error messages
3586 9214 format(5x,'Spatial symmetry for determinant ',i5,/, &
3587 5x,'in CSF ',i5,' does not match ref determinant',/)
3588 9215 format(5x,'Sz quantum number for determinant ',i5,/, &
3589 5x,'in CSF ',i5,' does not match ref determinant',/)
3590 9900 format(/,5x,'***** Error in: wfngtr() ',//)
3591 9925 format(5x,'Cannot allocate array mop() of length (lenmop) ',i8,/)
3592 9926 format(5x,'Cannot allocate array flip() of length (max_num_dets_input) ',i8,/)
3593 9927 format(5x,'Cannot de-alloc array mop() of length (lenmop) ',i8,/)
3594 9928 format(5x,'Cannot de-alloc array flip() of length (max_num_dets_input) ',i8,/)
3595 9935 format(5x,'Insufficient space in cdit() for projection ',/, &
3596 5x,'CSF ',i10,' has ',i10,' determinants ',/, &
3597 5x,'cdit() holds the expansion coefficient ',/, &
3598 5x,'for each determinant and len_cdit must be ',/, &
3599 5x,'at least as big as the number of determinants',/, &
3600 5x,'Currenttly it is fixed at ',i10,/)
3601 9955 format(5x,'WFNGTR() has received an error on return',/, &
3602 5x,'fromPOPNWF(). Code is terminating now.',/)
3603 9981 format(5x,'CSF ',i7,' has exhausted space available in ndo',/, &
3604 5x,'Available (maxndo) = ',i10)
3605 9982 format(5x,'CSF ',i7,' has exhausted space available in cdo',/, &
3606 5x,'Available (maxcdo) = ',i10)
3607
3608 end subroutine wfgntr
3609
3610
3611 !> \brief WRNFTO - WRite wavefunction data to unit NFTO
3612 !>
3613 !> \note MAL 10/05/2011 : This subroutine has been changed to bring it into
3614 !> line with the changes that have been made to 'projec' in order to
3615 !> utilize dynamic memory. 'wrnfto' has also been modified in order to
3616 !> comply to the F95 standard
3617 !>
3618 subroutine wrnfto (sname, mgvn, s, sz, r, pin, norb, nsrb, nocsf, nelt, idiag, nsym, symtyp, &
3619 nob, ndtrf, nodo, m, icdo, indo, ndo, lndi, cdo, lcdi, nfto, nobl, nx, &
3620 npflg, thres, iposit, nob0, nob0l, nctarg, ntgsym, notgt, nctgt, mcont, &
3621 gucont, iphz, nobe, nobp, nobv, maxtgsym)
3622
3623 use precisn, only : wp
3624
3625 integer :: symtyp, i, nfto, iposit, norb, nsrb, idiag, itg, maxtgsym, mgvn, &
3626 norbw, nsrbw, lcdi, lndi, nsym, nelt, m, nx, nctarg, ntgsym, nocsf
3627 integer, parameter :: iwrite = 6
3628 integer, dimension(nsym) :: nob, nob0, nobe, nobp, nobv
3629 integer, dimension(nelt) :: ndtrf
3630 integer, dimension(nocsf) :: nodo
3631 integer, dimension(m) :: icdo, indo
3632 integer, dimension(lndi) :: ndo
3633 integer, dimension(ntgsym) :: notgt, nctgt, mcont, gucont
3634 integer, dimension(nctarg) :: iphz
3635 integer, dimension(20) :: nobw
3636 integer, dimension(nx) :: nobl, nob0l
3637 integer, dimension(6) :: npflg
3638 real(kind=wp),dimension(lcdi) :: cdo
3639 real(kind=wp) :: s, sz, r, pin, thres
3640 character(120) :: name
3641 character(80) :: sname
3642
3643 !-------------------------------------------------------------------------
3644 ! Debug banner header
3645 !-------------------------------------------------------------------------
3646
3647 write(iwrite,'(/,5x,"Writing final results to disk (wrnfto) ")')
3648 write(iwrite,'( 5x,"-------------------------------------- ")')
3649 write(iwrite,'( 5x," Logical unit (nfto) = ",I8)') nfto
3650 write(iwrite,'( 5x," Positrons present (iposit) = ",I8)') iposit
3651 write(iwrite,'( 5x," Number of electrons (nelt) = ",I8)') nelt
3652 write(iwrite,'( 5x," Number of CSFs (nocsf) = ",I8)') nocsf
3653 write(iwrite,'( 5x," Number of symmetries (nsym) = ",I8)') nsym
3654 write(iwrite,'( 5x," Point group flag (symtyp) = ",I8)') symtyp
3655 write(iwrite,'( 5x," Orbitals per symm (nob) : ",(20(1x,I0)))') (nob(i), i=1,nsym)
3656 write(iwrite,'( 5x," Total # of orbitals (norb) = ",I8)') norb
3657 write(iwrite,'( 5x," Total # of spin orbs (nsrb) = ",I8)') nsrb
3658
3659 write(iwrite,'(/,5x," Length of index arrays - icdo,indo (m) = ",I8)') m
3660 write(iwrite,'( 5x," Length of coeff. array - cdo (lcdi) = ",I8)') lcdi
3661 write(iwrite,'( 5x," (equals # dets in wfn)")')
3662 write(iwrite,'( 5x," Length of packed dets array - ndo (lndi) = ",I8)') lndi
3663
3664 write(iwrite,'(/,5x," Spin quantum number (s) = ",F8.2)') s
3665 write(iwrite,'( 5x," Z-projection of spin (sz) = ",F8.2)') sz
3666 write(iwrite,'( 5x," Reflection quant. # (r) = ",F8.2)') r
3667 write(iwrite,'( 5x," Pin (pin) = ",F8.2)') pin
3668 write(iwrite,'( 5x," (idiag) = ",I8,/)') idiag
3669
3670 name = ' '
3671 name = sname
3672
3673 norbw = norb
3674 nsrbw = nsrb
3675
3676 nobw(1:nsym) = nob(1:nsym)
3677
3678 !--------------------------------------------------------------------------
3679 ! Rewind the unit before writing on it
3680 !--------------------------------------------------------------------------
3681
3682 rewind nfto
3683
3684 !--------------------------------------------------------------------------
3685 ! Slightly different formats if positrons are involved
3686 !--------------------------------------------------------------------------
3687
3688 if (iposit == 0) then
3689 write(nfto) name, mgvn, s, sz, r, pin, norbw, nsrbw, nocsf, nelt, lcdi, idiag, &
3690 nsym, symtyp, lndi, npflg, thres, nctarg, ntgsym
3691 if (ntgsym > 0) write(nfto) iphz, nctgt, notgt, mcont, gucont
3692 if (ntgsym <= 0) write(nfto) iphz
3693 write(nfto) (nobw(i), i=1,nsym), ndtrf, nodo, iposit, nob0, nobl, nob0l
3694 else
3695 write(nfto) name, mgvn, s, sz, r, pin, norbw, nsrbw, nocsf, nelt, lcdi, idiag, &
3696 nsym, symtyp, lndi, npflg, thres, nctarg, maxtgsym
3697 if (maxtgsym > 0) then
3698 write(nfto) iphz
3699 write(nfto) (nctgt(itg), itg=1,maxtgsym)
3700 write(nfto) (notgt(itg), itg=1,maxtgsym)
3701 write(nfto) (mcont(itg), itg=1,maxtgsym)
3702 write(nfto) (gucont(itg), itg=1,maxtgsym)
3703 end if
3704 if (maxtgsym <= 0) write(nfto) iphz
3705 write(nfto) (nobw(i), i=1,nsym), ndtrf, nodo, iposit, nob0, nobl, nob0l
3706 write(nfto) (nobe(i), i=1,nsym)
3707 write(nfto) (nobp(i), i=1,nsym)
3708 write(nfto) (nobv(i), i=1,nsym)
3709 end if
3710
3711 !-------------------------------------------------------------------------
3712 ! Now come the determinants per CSF
3713 !-------------------------------------------------------------------------
3714
3715 write(nfto) icdo, indo
3716 write(nfto) ndo
3717 write(nfto) cdo
3718
3719 end subroutine wrnfto
3720
3721
3722 !> \brief Write wave functions using SPEEDY format
3723 !>
3724 !> This subroutine writes all determinants in the current CSF to a binary file that has the following format:
3725 !> \verbatim
3726 !> [WP] n1, [INTEGER] nodo(1:n1)
3727 !> [WP] n2, [WP] cdo(1:n2)
3728 !> [WP] n3, [INTEGER] ndo(1:n3)
3729 !> \endverbatim
3730 !>
3731 !> On entry, the file will be rewindws to its beginning.
3732 !> On return, the output file is rewinded to its beginning, again.
3733 !>
3734 !> \param nft An open binary file for output.
3735 !> \param n1 Length of \c nodo (number of determinants).
3736 !> \param nodo Determinant sizes.
3737 !> \param n2 Length of \c cdo (number of determinants).
3738 !> \param cdo Determinant factors within the CSF.
3739 !> \param n3 Length of \c ndo (number of integers defining the determinants).
3740 !> \param ndo Packed determinants.
3741 !>
3742 subroutine wrwf (nft, n1, nodo, n2, cdo, n3, ndo)
3743
3744 use precisn, only : wp
3745
3746 integer :: n1, n2, n3, nft
3747 real(kind=wp), dimension(n2) :: cdo
3748 integer, dimension(n3) :: ndo
3749 integer, dimension(n1) :: nodo
3750 intent (in) cdo, n1, n2, n3, ndo, nft, nodo
3751
3752 rewind nft
3753
3754 write(nft) n1, nodo
3755 write(nft) n2, cdo
3756 write(nft) n3, ndo
3757
3758 rewind nft
3759
3760 end subroutine wrwf
3761
3762end module congen_projection
Determinant binary search tree.
Module containing parameters / data required throughout the CONGEN program.
integer nsym
Number of symmetries given in input file (right-trimmed of those with zero orbitals).
integer nftw
Unit number for printing; may be changed via the STATE namelist so not a parameter.
integer symtyp
Symmetry type, 0 = C_infv, 1 = D_infh, 2 = {D_2h, C_2v, C_s, E}.
Projection on spin states.
subroutine, private popnwf(nsrb, nsrbs, nelt, ndtrf, mopmx, mdop, mdcp, mop, mdc, mdo, ndta, nod, nda, idop, idcp, ieltp, flip, nalm)
Get open-shell part of determinants.
subroutine, private wfgntr(mgvn, iss, isd, thres, r, symtyp, nelt, nsyml, nob, nobl, nob0l, nobe, norb, nsrb, mn, mg, mm, ms, iposit, map, mpos, nocsf, ndtrf, nodi, ndi, cdi, indil, icdil, maxndi, maxcdi, nodo, ndo, cdo, indo, icdo, maxndo, maxcdo, lenndo, lencdo, npflg, byproj, nftw, nalm)
Form spin eigenstates.
subroutine, private dophz0(nftw, nocsf, nelt, ndtrf, nconf, indo, ndo, lenndo, icdo, cdo, lencdo, iphz, npflg)
Phase factor.
subroutine, private rfltn(nelt, nodi, ndi, cdi, r, mxnd, ndmxp, thres, nodo, cdo, ndtr, mm, bst)
Add mirror-reflected spin-orbitals.
subroutine, private wrwf(nft, n1, nodo, n2, cdo, n3, ndo)
Write wave functions using SPEEDY format.
subroutine, public projec(sname, megul, symtyp, mgvn, s, sz, r, pin, nocsf, byproj, idiag, npflg, thres, nelt, nsym, nob, ndtrf, nftw, iposit, nob0, nob1, nob01, iscat, ntgsym, notgt, nctgt, mcont, gucont, mrkorb, mdegen, mflag, nobe, nobp, nobv, maxtgsym)
Project the wave function.
subroutine, private stmrg(nelt, maxcdo, maxndo, ndo, cdo, nodo, ndi, cdi, bst)
Add determinant to a list of determinants.
subroutine, private prjct(nelt, mxss, nodi, ndo, cdi, nodo, cdo, maxcdo, mgvn, iss, isd, thres, r, ndtr, mm, ms, maxndo, symtyp, nsrb)
Apply Lowdin projection operator.
subroutine, private rdwf_getsize(iunit, num_csfs, num_dets, len_dets)
Reads the size of the wavefunction.
integer function, private qsort(n, a)
Sort integer array.
real(kind=wp) function, private snrm2(n, array, istep)
Real strided vector norm.
subroutine, private dophz(nftw, nocsf, nelt, ndtrf, nconf, indo, ndo, lenndo, icdo, cdo, lencdo, iphz, leniphz, iphz0, leniphz0, nctarg, nctgt, notgt, mrkorb, mdegen, ntgsym, mcont, symtyp, npflg)
Phase factor.
subroutine, private mkorbs(nob, nsym, mn, mg, mm, ms, norb, nsrb_in, map, mpos, iposit, nobl, nob0l, symtyp)
Compute the orbital table.
subroutine, private wrnfto(sname, mgvn, s, sz, r, pin, norb, nsrb, nocsf, nelt, idiag, nsym, symtyp, nob, ndtrf, nodo, m, icdo, indo, ndo, lndi, cdo, lcdi, nfto, nobl, nx, npflg, thres, iposit, nob0, nob0l, nctarg, ntgsym, notgt, nctgt, mcont, gucont, iphz, nobe, nobp, nobv, maxtgsym)
WRNFTO - WRite wavefunction data to unit NFTO.
subroutine, private cntrct(nelt, no, ndo, cdo, thres)
Throw away determinants with negligible contribution.
integer function, private iphase(nconf, nelt)
Sequence phase factor.
subroutine, private pkwf(nod, ieltp, cdo, mdo, idopl, mdop, idcpl, mdcp, nftw, ndo, ndto, len_ndto, ithis_csf)
Pack wave function.
subroutine, private ptpwf(nftw, nocsf, nelt, ndtrf, nodi, indi, icdi, ndi, cdi)
Print the CSFs.
subroutine, private rdwf(nft, k1, nodi, k2, cdi, k3, ndi)
Read CSF.
subroutine, private pmkorbs(nob, nobe, nsym, mn, mg, mm, ms, nsrb, norb, nsrbd, map, mpos, iposit, symtyp)
?
Determinant binary search tree.