CONGEN  5.0
Configuration generation for SCATCI
congen_driver.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/>.
24 
25  implicit none
26 
27  ! module entry point
28  public csfgen
29 
30  ! internal support routines
31  private csfout
32  private getcon
33  private getcup
34  private getref
35  private icgcf
36  private stwrit
37  private subdel
38  private wfnin
39  private wfnin0
40  private wrnmlt
41  private wvwrit
42 
43 contains
44 
49  subroutine csfgen
50 
51  use precisn, only : wp
52  use consts, only : zero => xzero, two => xtwo
53  use congen_data, only : mxtarg, nx => nu, ny, nz, jx, jy, jz, ky, kz, ntcon, test, nrcon, nobt, &
54  nsym, nobi, ift, next, navail => nx, icdi, iexcon, indi, inodi, iqnstr, &
56  ncall, ncsf, confpf, occst => occshl, pqnst, mshlst => mshl, gushst => gushl, &
57  cupst => cup, sshlst, shlmx1, nqntot => qntot, nqntar => qntar, ngutot => gutot, &
58  nnndel => nndel, nnlecg, nisz, nsmtyp => symtyp, nftw, nftr, exdet, exref
59 
60  use iso_c_binding, only : c_loc, c_f_pointer
61  use congen_distribution, only : distrb
62  use congen_pagecontrol, only : addl, newpg, space
63  use congen_projection, only : projec
64 
65  real(wp), allocatable, dimension(:), target :: bmx
66  real(wp), pointer :: bmx_ptr
67  integer, dimension(:), pointer :: int_ptr, ndel_ptr, ndel1_ptr, ndel2_ptr, irfcon_ptr
68  integer :: byproj, cdimn, conmes, d, defltc, guold, gutot, i, idiag, iposit, is, iscat, iso, isz, itu, j, lc, lcdi, &
69  lcdo, lcdt, ln, lndi, lndo, lndt, lpp, lsquare, ltri, maxtgsym, megu, mflag, mold, mt, n, nadel, nbmx, &
70  nconmx, ncsf0, ncupp, ndimn, ndpmax, ndpp, ndprod, negmax, negr, nelecg, nelect, nelp, nelr, nemax, nerfg, &
71  nerfs, nextk, nfto, nndel, nobep, nodimn, npcupf, npmult, nrefo, nrefog, nrefop, nrerun, nrfgmx, nrfgoe, &
72  nrfoe, nrfomx, ns, nshgmx, nshlp0, nshlpt, nspf, nspi, nsymmx, nsymp, ntconp, err
73  integer, dimension(3,jx) :: cup, pqn
74  logical :: ene, ener, enob, enrefo, epsno, eqnt, erefd, error, errorg, espace, esymt, qmoln
75  logical, dimension(11) :: erfg
76  logical, dimension(9) :: erfs
77  character(len=80) :: gname, sname
78  integer, dimension(mxtarg) :: gucont, mcont, mdegen, mrkorb, nctgt, notgt
79  integer, dimension(jx) :: gushl, ksss, loopf, mshl, occshl, shlmx, sshl
80  integer, dimension(jy) :: kdssv, nelecp, nshlp, nslsv
81  integer, dimension(nx) :: nob, nob0, nob0l, nobl
82  integer, dimension(nx) :: nobe, nobp, nobv
83  integer, dimension(6) :: npflg
84  integer, dimension(jz) :: nshcon
85  integer :: ntgsmx, ntgsym, nwfngp, pqn2, symtyp
86  real(kind=wp) :: pin, r, s, sz, thres
87  integer, dimension(3) :: qntar, qntar1, qntot
88  integer, dimension(nz) :: refdet ! Reference determinant (assignment of electrons to spin-orbitals).
89  integer, dimension(kz) :: refdtg ! Wfngrp reference determinant (assignment of electrons to spin-orbitals).
90  integer, dimension(ny) :: refgu ! Gerade/ungerade quantum numbers for the reference determinant (per quintet).
91  integer, dimension(ky) :: refgug ! Gerade/ungerade quantum numbers for the wfngrp reference determinant (per quintet).
92  integer, dimension(5,ny) :: reforb ! Reference determinant setup (quintets from &state).
93  integer, dimension(5,ky) :: reforg ! Movable electrons setup (quintets from &wfngrp).
94  integer, dimension(3,jx,jz) :: tcon ! Constraints. ???
95 
96  equivalence(reforg(1,1), reforb(1,1))
97  equivalence(refgu(1), refgug(1))
98 
99  ! named error flags
100  equivalence(erfs(1), esymt)
101  equivalence(erfs(2), enob)
102  equivalence(erfs(3), epsno)
103  equivalence(erfs(4), ene)
104  equivalence(erfs(5), enrefo)
105  equivalence(erfs(6), ener)
106  equivalence(erfs(7), erefd)
107  equivalence(erfs(8), eqnt)
108  equivalence(erfs(9), espace)
109 
110  ! input namelists
111  namelist /state / megul, nrerun, lcdt, lndt, nfto, ltri, idiag, thres, megu, npflg, nodimx, ndimx, cdimx, &
112  byproj, lcdo, lndo, nftw, iscat, ntgsym, sname, lpp, confpf, symtyp, qntot, gutot, isz, &
113  npmult, nob, reforb, refgu, nrefo, nelect, nndel, qmoln, &
114  iposit, nob0, nbmx, nobe, nobp, nobv ! this last row: positron control data
115 
116  namelist /wfngrp/ nelecg, ndprod, nelecp, nshlp, gname, reforg, refgug, nrefog, mshl, gushl, pqn, cup, defltc, &
117  npcupf, test, nrcon, nshcon, tcon, ntcon, qntar, lsquare
118 
119  !
120  ! Hardcoded limits
121  !
122 
123  conmes = 400 ! Quantenmol-specific output file unit with time estimate.
124  nrfoe = 30 ! initial value for "nrefop" (see below).
125  nrfgoe = 10 ! ... ?? ... Used in GETCON.
126  nerfs = 9 ! Number of error condition flags in erfs.
127  nerfg = 11 ! Number of error condition flags in erfg.
128  nsymmx = nx ! Maximal number of symmetries.
129  nrfomx = ny ! Maximal number of reference orbital quintets.
130  nemax = nz ! Maximal number of electrons.
131  nrfgmx = ky ! Maximal number of quintets used in single wave function group.
132  negmax = kz ! Maximal number of movable electrons.
133  nshgmx = jx ! Maximal number of pqn triplets per wave function group.
134  ndpmax = jy ! Maximal number of sets of orbitals per wave function group.
135  nconmx = jz ! Maximal number of constraints.
136 
137  nobl(:) = 0
138  nob0l(:) = 0
139  mdegen(:) = 0
140 
141  !
142  ! Default input data
143  !
144 
145  qmoln = .false. ! Indicates CONGEN running from Quantenmol.
146  iscat = 0 ! Output format: 0 = SPEEDY, 1 = SCATCI, 2 = SCATCI + information for phase correcting target CI wavefunctions.
147  ntgsym = mxtarg ! Number of distinct target states ???
148  nndel = 0 ! Whether to read CSFs from input stream.
149  megul = 13 ! Congen output file with generated configurations.
150  nrerun = 0 ! Restart flag for SPEEDY (not used in SCATCI).
151  lcdt = 500 ! Not used.
152  lndt = 5000 ! Not used.
153  lcdo = 500 ! Limit on number of determinants.
154  lndo = 5000 ! Limit on number of integers used in determinant description.
155  nfto = 15 ! Fortran data set number for output unit of SPEEDY.
156  ltri = 300 ! Not used.
157  idiag = -1 ! Matrix element evaluation flag passed to SPEEDY or SCATCI.
158  nbmx = 2000000 ! Workspace: Number of real numbers.
159  byproj = 1 ! Project wave functions in 1 = CONGEN, 0 = SPEEDY, -1 = nowhere (should be avoided).
160  megu = 14 ! Output data set with the namelist input to be passed to SPEEDY.
161  thres = 1.e-10_wp ! Threshold for storing coefficients of matrix elements that contribute to Hij.
162 
163  nobe(:) = 0 ! Number of electronic orbitals.
164  nobp(:) = 0 ! Number of positronic orbitals.
165  nobv(:) = 0 ! Not used, set to number of target (non-continuum) orbitals.
166 
167  npflg(1:6) = 0 ! Print flags for SPEEDY / SCATCI.
168 
169  cdimx = 400 ! Workspace size for determinant (real) multiplication factors.
170  ndimx = 4000 ! Workspace size for packed determinant (integer) descriptions.
171  nodimx = 100 ! Workspace size for number of packed determinants per CSF.
172  cdimn = 100 ! Default value for user namelist override of cdimx.
173  ndimn = 1000 ! Default value for user namelist override of ndimx.
174  nodimn = 25 ! Default value for user namelist override of nodimx.
175 
176  isz = 0 ! 2*Sz + 1
177  lpp = 0 ! Length of line printer page. Used to determine where to put page banner.
178  confpf = 1 ! Print flag for the amount of print given of configurations and prototypes.
179  symtyp = -1 ! Symmetry type, 0 = C_infv, 1 = D_infh, 2 = {D_2h, C_2v, C_s, E}.
180  gutot = 0 ! Inversion symmetry, used for D_infh only (+1 = gerade, -1 = ungerade).
181  npmult = 0 ! Print flag for the D2h multiplication table (0 = no, 1 = yes).
182  nelect = 0 ! Number of electrons.
183  iposit = 0 ! Exotic particle flag: 0 = electrons only, +/-1 = positive non-electron, +/-2 = negative non-electron.
184 
185  qntot(1:3) = -2 ! Total quantum numbers (spin multiplicity, irreducible representation, inversion symmetry).
186 
187  nob(1:nsymmx) = 0 ! Number of orbitals for configuration generation per symmetry, including continuum orbitals.
188  nob0(1:nsymmx) = 0 ! As above, excluding continuum orbitals.
189  nsoi(1:nsymmx) = 0 ! For each symmetry, index of the first spin-orbital (index runs across all symmetries).
190  nobi(1:nsymmx) = 0 ! For each symmetry, index of the first orbital (index runs across all symmetries).
191 
192  nrefo = 0 ! How many quintets are needed to define the reference determinant.
193 
194  refdet(1:nemax) = 0 ! Reference determinant (assignment of electrons to spin-orbitals).
195  refgu(1:nrfomx) = -2 ! Gerade (= +1) or underage (= -1) symmetry for the M value of each reference quintet.
196  reforb(1:5,1:nrfomx) = -2 ! Reference determinant setup (quintets).
197  erfs(1:nerfs) = .false. ! Error condition indicators.
198 
199  nsym = nsymmx ! Number of symmetries: initialized to maximal number of symmetries.
200  nsymp = nsymmx ! Number of symmetries, whose info to print in stwrit.
201  nrefop = nrfoe !
202  nelp = 0 ! Auxiliary variable typically holding the (calculated) number of electrons.
203 
204  ! read the input namelist
205  read(nftr, state, iostat = i)
206 
207  ! abort if namelist read failed
208  if (i /= 0) then
209  write(nftw,'("1***** NO INPUT DATA FOR NAMELIST &STATE")')
210  return
211  end if
212 
213  ! choose default value for idiag if not set by input
214  if (idiag < 0) then
215  if (iscat <= 0) idiag = 0 ! SPEEDY format
216  if (iscat > 0) idiag = 1 ! SCATCI format
217  end if
218 
219  ! Check the NOB-values
220  !
221  ! NOBE(i) number of electronic orbitals, default nobe(i)=nob(i)
222  ! NOBP(i) number of positronic orbitals, default nobp(i)=0
223  ! NOBV(i) at the moment not used, but printed on output, default nobv(i)=nob0(i)
224 
225  do i = 1, nsym
226  if (nobp(i) == 0) then
227  nobe(i) = nob(i)
228  end if
229  nobep = nobe(i) + nobp(i)
230  if (nobep /= nob(i)) then
231  write(nftw,*) 'ERROR on input:'
232  write(nftw,*) 'not: NOB(i)=NOBE(i)+NOBP(i)'
233  write(nftw,*) 'i=', i
234  write(nftw,*) 'NOB(i)=', nob(i)
235  write(nftw,*) 'NOBE(i)=', nobe(i)
236  write(nftw,*) 'NOBP(i)=', nobp(i)
237  end if
238  if (nobv(i) == 0) then
239  nobv(i) = nob0(i)
240  end if
241  if (nob0(i) > nob(i)) then
242  write(nftw,*) 'ERROR on input:'
243  write(nftw,*) 'NOB0(i) > NOB(i)'
244  write(nftw,*) 'i=', i
245  write(nftw,*) 'NOB(i)=', nob(i)
246  write(nftw,*) 'NOB0(i)=', nob0(i)
247  end if
248  end do
249 
250  ! get index (-> nsym) of last symmetry with at least one orbital
251  nsym = 0
252  do i = 1, nsymmx
253  if (nob(i) /= 0) nsym = i
254  end do
255  nsymp = nsym
256 
257  ! set limit on shell occupancy
258  ! symtyp = 0 (C_infv) : 2,4,4,4,...
259  ! symtyp = 1 (D_infh) : 2,2,4,4,...
260  ! symtyp other : 2,2,2,2,...
261  shlmx1(1:nsymmx) = 2
262  if (symtyp == 0) shlmx1(2:nsymmx) = 4
263  if (symtyp == 1) shlmx1(3:nsymmx) = 4
264 
265  ! prepare global indices of orbitals and spin-orbitals across symmetries
266  nobt = 0
267  ntso = 0
268  do i = 1, nsym
269  nsoi(i) = ntso + 1 ! 1-based index of spin-orbital across symmetries
270  nobi(i) = nobt ! 0-based index of orbital across symmetries
271  nob(i) = abs(nob(i))
272  nobt = nobt + nob(i)
273  ntso = ntso + shlmx1(i) * nob(i)
274  end do
275 
276  allocate(exdet(ntso), exref(ntso), stat = err)
277 
278  ! set up error flags
279  enob = (nsym == 0)
280  epsno = (err /= 0)
281  ene = (nelect <= 0 .or. nelect > nemax)
282  esymt = (symtyp < 0)
283 
284  ! continue only if no error condition is raised
285  if (.not. any(erfs)) then
286 
287  ! assemble reference list of spin-orbitals (target "reference determinant")
288  call getref (reforb, refgu, nrefo, nelect, refdet, nelr, nsoi, nob, shlmx1, nsym, symtyp, nrfomx, enrefo, ener, erefd)
289 
290  ! more initializations
291  nelp = nelect
292  if (.not. enrefo) nrefop = nrefo
293  confpf = max(confpf, 1)
294  if (isz == 0) isz = qntot(1)
295 
296  ! check validity of total quantum numbers
297  eqnt = (qntot(1) <= 0 .or. qntot(2) < 0) &
298  .or. (qntot(2) == 0 .and. symtyp <= 1 .and. abs(qntot(3)) /= 1) &
299  .or. (abs(isz - 1) > qntot(1) - 1) &
300  .or. (symtyp == 1 .and. abs(gutot) /= 1)
301 
302  ! update array bounds based on namelist input
303  cdimx = max(cdimn, cdimx)
304  ndimx = max(ndimn, ndimx)
305  nodimx = max(nodimn, nodimx)
306 
307  ! allocate the wp-real (!) workspace
308  allocate(bmx(nbmx))
309 
310  ! calculate positions of data in the workspace
311  icdi = 1
312  indi = icdi + cdimx
313  inodi = indi + ndimx
314  ndel = inodi + nodimx
315  ndel1 = ndel + nndel
316  ndel2 = ndel1 + nndel
317  next = ndel2 + nndel
318  navail = nbmx - next + 1
319  nextk = next / 1024
320 
321  ! Workspace is composed of the following consecutive chunks of real numbers
322  ! icdi : icdi + cdimx ... determinant coefficients (real number per determinant)
323  ! indi : indi + ndimx ... packed determinants (size + replacements per determinant)
324  ! inodi : inodi + nodimx ... states ()
325  ! ndel : ndel + nndel ... space for configurations read from input (unit nftr)
326  ! ndel1 : ndel1 + nndel ... workspace for reading configurations from input (unit nftr)
327  ! ndel2 : ndel2 + nndel ... workspace for reading configurations from input (unit nftr)
328  !
329  ! + further chunks per every wave function group:
330  ! irfcon : irfcon + nobt * ntcon ... orbital constraints
331  ! iexcon : iexcon + nobt ... more orbital contrains?
332  ! iqnstr : ? ... only temporarily, overwritten by next wave function group
333 
334  write(nftw,'(" NBMX =",I9," WORDS")') nbmx
335  write(nftw,'(" ***** REGION USED FOR INPUT DATA ",I7," WORDS ",I5," K")') next, nextk
336  write(nftw,'(" ***** LEFT ",I9," WORDS")') navail
337 
338  ! are we out of space already?
339  espace = (navail <= 0)
340 
341  end if
342 
343  ! print current setup information
344  call stwrit (nelect, confpf, qntot, cdimx, icdi, ntso, symtyp, ndimx, indi, nrefo, nodimx, inodi, nsym, gutot, nbmx, &
345  isz, navail, idiag, megu, thres, lcdt, megul, lndt, nfto, nrerun, ltri, npflg, nndel, nob, nsoi, nsymp, &
346  refdet, nerfs, erfs, nrefop, reforb, refgu, nelp, lpp, sname, error, byproj, lndo, lcdo, iposit, nob0, &
347  npmult, ntgsym, mxtarg, nobe, nobp, nobv)
348 
349  ! if requested, read CSFs directly from input stream
350  if (nndel /= 0) then
351  bmx_ptr => bmx(ndel) ; call c_f_pointer (c_loc(bmx_ptr), ndel_ptr, (/1/))
352  bmx_ptr => bmx(ndel1) ; call c_f_pointer (c_loc(bmx_ptr), ndel1_ptr, (/1/))
353  bmx_ptr => bmx(ndel2) ; call c_f_pointer (c_loc(bmx_ptr), ndel2_ptr, (/1/))
354  call subdel (ndel_ptr, ndel1_ptr, ndel2_ptr, nndel)
355  end if
356 
357  ! general default for wfngrp arrays
358  call wfnin (nwfngp, nadel, nncsf, ncsf, lcdi, lndi, nelecg, ndprod, nrefog, npcupf, negmax, refdtg, nrfgmx, refgug, &
359  ntcon, reforg, nshgmx, nsymmx, mshl, gushl, pqn, cup, ndpmax, nshlp, nconmx, test, nrcon, nshcon, tcon, errorg)
360 
361  ncsf0 = 0 !
362  ntgsmx = ntgsym !
363  ntgsym = 0 !
364  maxtgsym = 0 !
365  mold = -1 ! symmetry (M-value) of a shell (pqn triplet)
366  guold = 0 !
367  qntar1(1) = -1 !
368  pqn2 = 0 !
369  lsquare = 0 !
370 
371  ! loop over wfngrp input sets
372  wfngrp_loop: do while (nndel == 0 .or. nadel < nndel)
373 
374  ! set default values to some parameters (others are carried over from the previous namelist, if any)
375  call wfnin0 (nelecp, defltc, nerfg, erfg, gname, qntar, errorg, ndpmax)
376 
377  ! read the user settings from the next &wfngrp namelist
378  read(nftr, wfngrp, iostat = i)
379 
380  ! check success
381  if (i /= 0) then
382  call space (2)
383  call addl (1)
384  if (nwfngp == 0) then
385  write(nftw,'(" ***** NO WFNGRP INPUT FOUND")')
386  return
387  end if
388  write(nftw,'(" ***** END OF FILE ON INPUT")')
389  exit wfngrp_loop
390  end if
391 
392  write(*,*) 'lsquare =', lsquare
393 
394  ! total number of pqn triplets for this &wfngrp
395  nshlpt = sum(abs(nshlp(1:ndprod)))
396 
397  ! assemble information for phase correction data
398  if (iscat < 2 .or. mold < -1) then
399 
400  ! no phase correction data required (or all that was needed is already done, do nothing)
401 
402  else if (mold == mshl(nshlpt) .and. (symtyp /= 1 .or. guold == gushl(nshlpt)) .and. &
403  all(qntar(1:3) == qntar1(1:3)) .and. pqn2 == pqn(2,nshlpt) .and. lsquare /= 1) then
404 
405  ! the same target state? - check continuum orbitals consistent!
406  if (notgt(ntgsym) /= pqn(3,nshlpt) - pqn(2,nshlpt) + 1) then
407  write(nftw,'(//," Attempt to perform CI target calculation with different length continua for same target:")')
408  write(nftw,'( " Number of continua, last WFNGRP",I4)') notgt(ntgsym)
409  write(nftw,'( " Number of continua, this WFNGRP",I4)') pqn(3,nshlpt) - pqn(2,nshlpt) + 1
410  write(nftw,'( " STOP")')
411  stop
412  end if
413 
414  else
415 
416  ! new target state detected: first save data about old one
417  if (ntgsym >= 1) then
418  nctgt(ntgsym) = (ncsf - ncsf0) / notgt(ntgsym)
419  mrkorb(ntgsym) = nspi
420  end if
421 
422  if (qntar(1) <= 0 .or. ntgsym == ntgsmx) then
423 
424  ! all target states are finished
425  mold = -2
426 
427  else
428 
429  ncsf0 = ncsf
430  ntgsym = ntgsym + 1
431  if (lsquare == 0) maxtgsym = maxtgsym + 1
432  write(nftw,'(/," Target state number",I3) ') ntgsym
433  write(nftw,'(" TARGET MULTIPLICITY =",I5,5X,"TARGET SYMMETRY =",I5,5X,"TARGET INVERSION SYMMETRY =",I5)') qntar
434  write(nftw,'(" Coupling to continuum with M =",I3)') mshl(nshlpt)
435  if (symtyp == 1) write(nftw,'(27x,"GU =",I3)') gushl(nshlpt)
436 
437  ! save continuum electron data for future use
438  notgt(ntgsym) = pqn(3,nshlpt) - pqn(2,nshlpt) + 1
439  mcont(ntgsym) = mshl(nshlpt)
440  if (symtyp == 1) gucont(ntgsym) = gushl(nshlpt)
441  pqn2 = pqn(2,nshlpt)
442 
443  ! for degenerate symmetries/degenerate target states, need extra
444  ! information to sort out coupling of possible second continuum
445  if (symtyp <= 1 .and. qntot(2) > 0 .and. qntar(2) > 0) then
446  mdegen(ntgsym) = max(qntot(2), qntar(2)) - mcont(ntgsym)
447  end if
448 
449  qntar1(1:3) = qntar(1:3)
450  mold = mshl(nshlpt)
451  if (symtyp == 1) guold = gushl(nshlpt)
452 
453  end if
454 
455  end if
456 
457  ndpp = ndpmax
458  nelp = 0
459  ncupp = 0
460  ntconp = 0
461  nwfngp = nwfngp + 1
462  erfg(1) = .true.
463  if (nelecg <= 0 .or. nelecg > negmax) go to 150
464  erfg(1) = .false.
465  ndprod = max(1, ndprod)
466  erfg(2) = .true.
467  if (ndprod > ndpmax) go to 150
468  erfg(2) = .false.
469  ndpp = ndprod
470  nshlpt = 0
471 
472  nelecp(1:ndprod) = abs(nelecp(1:ndprod))
473  nshlp(1:ndprod) = abs(nshlp(1:ndprod))
474  negr = sum(nelecp(1:ndprod))
475  nshlpt = sum(nshlp(1:ndprod))
476 
477  erfg(3) = (any(nshlp(1:ndprod) == 0))
478 
479  nshlp0 = nshlpt - nshlp(ndprod)
480  if (nshlpt > nshgmx) erfg(3) = .true.
481  if (negr /= nelecg) erfg(4) = .true.
482  if (erfg(3) .or. erfg(4)) go to 150
483 
484  ! reference determinant (refdtg) for the wave function group
485  call getref (reforg, refgug, nrefog, nelecg, refdtg, nelr, nsoi, nob, shlmx1, &
486  nsym, symtyp, nshgmx, erfg(5), erfg(6), erfg(7))
487 
488  if (.not. erfg(5)) nrefop = nrefog
489  if (.not. erfg(6)) nelp = nelecg
490  if (erfg(5) .or. erfg(6) .or. erfg(7)) go to 150
491 
492  ! Set "exref" to contain only the non-movable subset of the global reference determinant.
493  exref(1:ntso) = 0 ! start with unpopulated spin-orbitals
494  exref(refdet(1:nelect)) = 1 ! populate spin-orbitals according to the reference determinant
495  if (any(exref(refdtg(1:nelecg)) == 0)) erfg(7) = .true. ! non-movable spin-orbitals must be a subset of all reference spin-orbitals
496  exref(refdtg(1:nelecg)) = 0 ! un-populate spin-orbitals with movable electrons
497  if (erfg(7)) go to 150
498 
499  ! check shell data...
500  erfg(8) = .true.
501  if (iposit /= 0 .and. nelecp(ndprod) /= 1) go to 150 ! ... but skip the check if for non-electrons ...?
502  do i = 1, nshlpt ! scan all sets of orbitals
503  mshl(i) = abs(mshl(i)) ! use absolute value of the M-value (symmetry)
504  mt = mshl(i) + 1 ! change M-value from 0-based index to 1-based index
505  if (symtyp == 1) then ! special section for degenerate point groups
506  if (abs(gushl(i)) /= 1) go to 150 ! gerage (+1) or ungerade (-1) only possible
507  itu = 1 ! let's call this a kind of parity,...
508  if (mod(mt,2) == 0) itu = -1 ! ...as it changes its sign across the symmetry eigenspaces
509  mt = mt + mt - abs((gushl(i) + itu) / 2) ! expanded symmetry index combining the orig symmetry and g/u
510  end if
511  sshl(i) = mt ! 1-based index of symmetry (expanded, in case of degenerate groups)
512  if (mt > nsym) go to 150 ! out of bounds symmetry index!
513  if (pqn(1,i) /= 0) then ! transform pqn=x00 to xxx for unified processing later
514  pqn(2,i) = pqn(1,i)
515  pqn(3,i) = pqn(2,i)
516  end if
517  d = pqn(3,i) - pqn(2,i) ! distance between orbitals (= orbital count - 1)
518  if (d < 0) go to 150 ! wrong order of orbitals in triplet!
519  shlmx(i) = shlmx1(mt) * (d + 1) ! maximal occupation of i-th set of orbitals
520  nspi = nsoi(mt) + (pqn(2,i) - 1) * shlmx1(mt) ! index of the first spin-orbital in the current set orbitals
521  nspf = nspi + shlmx(i) - 1 ! index of the last spin-orbital in the current set of orbitals
522  if (iposit /= 0 .and. i >= nshlp0) cycle ! ... some extra for non-electrons ...?
523  if (any(exref(nspi:nspf) /= 0)) go to 150 ! the set of orbitals mustn't contain non-movable ones
524  if (pqn(3,i) > nob(mt)) then ! out of bounds orbital index!
525  write(nftw,'(//," Error: PQN number",i3," accesses orbital number",i3)') i, pqn(3,i)
526  write(nftw,'( " symmetry",i2," only contains",i3," orbitals")') mt, nob(mt)
527  go to 150
528  end if
529  end do
530  erfg(8) = .false.
531 
532  ! ???
533  ncupp = nshlpt - 1
534  call getcup (nshlpt, defltc, ndprod, nshlp, cup(1,1), erfg(9))
535  if (erfg(9)) npcupf = 1
536  ntcon = min(abs(ntcon), nconmx)
537 
538  ! calculate positions of new data in the workspace
539  irfcon = next
540  if (ntcon == 0) go to 150
541  iexcon = irfcon + nobt * ntcon
542  next = iexcon + nobt
543  navail = nbmx - next + 1
544  nextk = next / 1024
545  write(nftw,'(" ***** REGION USED FOR DETERMINANTS ",I7," WORDS ",I5," K")') next, nextk
546  write(nftw,'(" **** LEFT ",I7," WORDS")') navail
547  if (navail <= 0) erfg(11) = .true.
548 
549  ! set up constraints
550  bmx_ptr => bmx(irfcon) ; call c_f_pointer (c_loc(bmx_ptr), irfcon_ptr, (/1/))
551  call getcon (ntcon, nshcon, nrcon, nshgmx, nrfgoe, ntconp, nelecg, nsym, &
552  nobt, nob, nobi, nsoi, shlmx1, exref, tcon, irfcon_ptr, &
553  erfg(10))
554 
555  ! position of "qnstr"(?) data in the workspace
556  150 iqnstr = next
557 
558  ! write information about wave function group to output...
559  bmx_ptr => bmx(irfcon) ; call c_f_pointer (c_loc(bmx_ptr), irfcon_ptr, (/1/))
560  call wvwrit (nwfngp, gname, nelecg, defltc, irfcon, ndprod, symtyp, ntcon, &
561  navail, nrefog, nelecp, nshlp, qntar, nshlpt, nshgmx, mshl, &
562  gushl, pqn, cup, ncupp, npcupf, refdtg, nelp, ntconp, nshcon, &
563  nobt, reforb, refgu, test, nrcon, tcon, irfcon_ptr, nerfg, &
564  erfg, ndpp, nrefop, errorg)
565 
566  ! ... and do nothing more if there are errors
567  if (errorg) return
568 
569  ! push data to global arrays
570  nqntot(1:3) = qntot(1:3)
571  nqntar(1:3) = qntar(1:3)
572  nisz = isz
573  ngutot = gutot
574  nnlecg = nelecg
575  nsmtyp = symtyp
576  nnndel = nndel
577 
578  exref(1:ntso) = 0 ! start with un-populated spin-orbitals
579  exref(refdtg(1:nelecg)) = 1 ! populate spin-orbitals with movable electrons only
580 
581  ncall = 1 ! this will make "wfn" routine initialize some arrays
582  ift = 1 ! this will make "assign" routine initialize some arrays
583 
584  call icgcf ! precompute needed binomial coefficients
585 
586  call distrb (nelecp, nshlp, shlmx, occshl, nslsv, kdssv, loopf, ksss, pqn, &
587  occst, shlmx1, pqnst, mshl, mshlst, gushl, gushst, cup, cupst, &
588  ndprod, symtyp, confpf, sshl, sshlst, ncsf, nncsf, nadel, &
589  nndel, bmx, nftw)
590 
591  ! write constructed (non-yet-projected) CSFs to output file
592  bmx_ptr => bmx(1) ; call c_f_pointer (c_loc(bmx_ptr), int_ptr, (/1/))
593  call csfout (lc, ln, megul, nndel, bmx, int_ptr)
594 
595  ! update total number of stored coefficients and integers forming packed determinants
596  lcdi = lcdi + lc
597  lndi = lndi + ln
598 
599  end do wfngrp_loop
600 
601  ! check that data for final target state has been saved
602  mflag = 0
603  if (ntgsym >= 1) then
604  if (mold > -2) then
605  nctgt(ntgsym) = (ncsf - ncsf0) / notgt(ntgsym)
606  mrkorb(ntgsym) = nspi
607  end if
608 
609  ! for degenerate symmetries/degenerate target states, need extra
610  ! information to sort out coupling of possible second continuum
611  ! check this for errors and missed couplings
612  if (symtyp <= 1 .and. qntot(2) > 0) then
613  if (mdegen(ntgsym) > 0) mdegen(ntgsym) = 0
614  do n = 2, ntgsym
615  if (mdegen(n) > 0) then
616  if (mdegen(n-1) <= 0) then
617  write(nftw,'(/," WARNING: for target state number",I3)') ntgsym
618  write(nftw,'( " Coupling to upper continuum only detected")')
619  write(nftw,'( " Calculation may give target phase problems")')
620  mdegen(n) = 0
621  else if (nctgt(n) /= nctgt(n-1)) then
622  write(nftw,'(/," Target states",I3," and",I3)') n - 1, n
623  write(nftw,'( " analysed for degenerate coupling to the continuum")')
624  write(nftw,'( " But number of CSFs differ:",I6," and",I6," respectively: STOP")') nctgt(n-1), nctgt(n)
625  stop
626  end if
627  else if (mdegen(n) > 0) then
628  if (mdegen(n-1) > 0) mdegen(n-1) = 0
629  end if
630  if (mdegen(n) /= 0) mflag = max(mflag, nctgt(n))
631  end do
632  end if
633  end if
634 
635  call space (2)
636  call addl (1)
637 
638  write(nftw,'(" ********** TOTAL NUMBER OF CSF''S GENERATED IS ",I9)') ncsf
639 
640  !
641  ! Quantenmol: open a file fort.400 to inform the user about estimated time of the run
642  !
643 
644  if (qmoln .and. iscat < 2 .and. megul == 70) then
645 
646  open(unit = conmes, status = 'unknown')
647  write(conmes,'(/," *** TOTAL NUMBER OF GENERATED CSF''S FOR THE GROUND STATE IS ",I6)') ncsf
648 
649  if (ncsf <= 600) then
650  write(conmes,'("*** This target calculation should not take long !",/)')
651  else if (ncsf > 600 .and. ncsf < 12000) then
652  write(conmes,'("*** This target calculation will take a few hours !")')
653  write(conmes,'("*** You can have a cup of tea and come back later.",/)')
654  else if (ncsf > 12000 .and. ncsf <= 22000) then
655  write(conmes,'("*** Oops, This target calculation is very big !")')
656  write(conmes,'("*** You can come back tomorrow.",/)')
657  else if (ncsf > 22000 .and. ncsf <= 80000) then
658  write(conmes,'("*** Oops, This target calculation is very big ")')
659  write(conmes,'("*** and can take several days to run !",/)')
660  else if (ncsf > 80000) then
661  write(conmes,'("*** Oops, This target calculation is too big ")')
662  write(conmes,'("*** to be computationally possible !")')
663  write(conmes,'("*** Rerun with a smaller basis or contact ")')
664  write(conmes,'("*** technical support: support@quantemol.com")')
665  end if
666 
667  close(conmes)
668 
669  end if
670 
671  s = real(qntot(1) - 1,kind = wp) / two
672  sz = real(isz - 1, kind = wp) / two
673  r = zero
674  if (qntot(2) == 0 .and. symtyp <= 1) r = real(qntot(3), kind = wp)
675  pin = zero
676 
677  ! save contents of nob and nob0 prior to any symmetry conversion
678  nobl(1:nsym) = nob(1:nsym)
679  nob0l(1:nsym) = nob0(1:nsym)
680  if (symtyp == 1) then
681  pin = real(gutot, kind = wp)
682  j = 0
683  do i = 1, nsym, 2
684  j = j + 1
685  nob(j) = nob(i) + nob(i+1)
686  nob0(j) = nob0(i) + nob0(i+1)
687  end do
688  nsym = j
689  end if
690 
691  if (allocated(bmx)) deallocate(bmx)
692 
693  call newpg
694 
695  ! stage 2: read CSFs back and project
696  rewind megul
697 
698  ! SCATCI data output
699  if (byproj > 0 .or. iscat > 0) then
700  call projec (sname, megul, symtyp, qntot(2), s, sz, r, pin, ncsf, byproj, idiag, npflg, thres, nelect, nsym, &
701  nob, refdet, nftw, iposit, nob0, nobl, nob0l, iscat, ntgsym, notgt, nctgt, mcont, gucont, mrkorb, &
702  mdegen, mflag, nobe, nobp, nobv, maxtgsym)
703  end if
704 
705  ! SPEEDY data output
706  if (iscat <= 0) then
707  call wrnmlt (megu, sname, nrerun, megul, symtyp, qntot(2), s, sz, r, pin, ncsf, byproj, lcdi, lndi, lcdo, lndo, &
708  lcdt, lndt, nfto, ltri, idiag, npflg, thres, nelect, nsym, nob, refdet, nftw, iposit, nob0, nobl, &
709  nob0l, nx, nobe, nobp, nobv)
710  rewind megu
711  end if
712 
713  ! final text information output
714  if (confpf >= 1) then
715  call wrnmlt (nftw, sname, nrerun, megul, symtyp, qntot(2), s, sz, r, pin, ncsf, byproj, lcdi, lndi, lcdo, lndo, &
716  lcdt, lndt, nfto, ltri, idiag, npflg, thres, nelect, nsym, nob, refdet, nftw, iposit, nob0, nobl, &
717  nob0l, nx, nobe, nobp, nobv)
718  end if
719 
720  end subroutine csfgen
721 
722 
752  subroutine csfout (ia, ib, megul, nndel, cr, nr)
753 
754  use precisn, only : wp
755  use congen_data, only : lratio, iidis2, lcdi, lndi, ni, nid, noi, icdi, indi, inodi
756 
757  integer :: ia, ib, megul, nndel
758  real(kind=wp), dimension(*) :: cr
759  integer, dimension(*) :: nr
760  intent (in) cr, megul, nndel, nr
761  intent (out) ia, ib
762 
763  integer :: i
764 
765  if (noi /= 0 .or. ni /= 0 .or. nid /= 0) then
766 
767  if (nndel == 0 .or. iidis2 /= 0) then
768  write(megul) noi, (nr(i+(inodi-1)*lratio), i=1,noi)
769  write(megul) nid, (cr(i+icdi-1), i=1,nid)
770  write(megul) ni, (nr(i+(indi-1)*lratio), i=1,ni)
771  lcdi = lcdi + nid
772  lndi = lndi + ni
773  end if
774 
775  noi = 0
776  nid = 0
777  ni = 0
778 
779  end if
780 
781  ia = lcdi
782  ib = lndi
783 
784  end subroutine csfout
785 
786 
789  subroutine getcon (ntcon, nshcon, nrcon, nshgmx, npmax, nc, nelecg, nsym, nobt, nob, nobi, nsoi, shlmx1, exref, tcon, &
790  refcon, error)
791 
792  logical :: error
793  integer :: nc, nelecg, nobt, npmax, nshgmx, nsym, ntcon
794  integer, dimension(*) :: exref, nob, nobi, nrcon, nshcon, nsoi, shlmx1
795  integer, dimension(nobt,*) :: refcon
796  integer, dimension(3,nshgmx,*) :: tcon ! JMC the dimensions could be changed to (3,JX,JZ) if desired.
797  intent (in) exref, nelecg, nob, nobi, nobt, npmax, nrcon, nshgmx, nsoi, nsym, ntcon, shlmx1, tcon
798  intent (out) error
799  intent (inout) nc, nshcon, refcon
800 
801  integer :: ic, j, k, nel, nesym, net, netc, noc, ns, nshcr, nspf, nspi, pqnt, pqntm, symt
802 
803  error = .false.
804  nc = 0
805  if (ntcon == 0) return
806  error = .true.
807  do ic = 1, ntcon
808  nc = nc + 1
809  do j = 1, nobt
810  refcon(j,ic) = 0
811  end do
812  nshcr = nshcon(ic)
813  if (nshcr <= nshgmx) then
814  else
815  nshcon(ic) = npmax
816  return
817  end if
818  if (nrcon(ic) < 0 .or. nrcon(ic) > nelecg) return
819  netc = 0
820  do j = 1, nshcr
821  symt = tcon(1,j,ic) + 1
822  pqnt = tcon(2,j,ic)
823  net = tcon(3,j,ic)
824  if (symt <= 0 .or. symt > nsym) return
825  if (net <= 0) return
826  netc = netc + net
827  nesym = shlmx1(symt)
828  pqntm = pqnt + (net - 1) / nesym
829  if (pqnt <= 0 .or. pqntm > nob(symt)) return
830  nspi = nsoi(symt) + (pqnt - 1) * nesym
831  nspf = nspi + ((net + 1) / nesym) * nesym - 1
832  do ns = nspi, nspf
833  if (exref(ns) /= 0) return
834  end do
835  noc = nobi(symt) + pqnt - 1
836  nel = net
837  do k = 1, nel, nesym
838  noc = noc + 1
839  if (refcon(noc,ic) /= 0) return
840  refcon(noc,ic) = min(nesym, net)
841  net = net - nesym
842  end do
843  end do
844  if (netc /= nelecg) return
845  end do
846  error = .false.
847 
848  end subroutine getcon
849 
850 
853  subroutine getcup (nshlt, def, nd, nshlp, cup, error)
854 
855  integer :: def, nd, nshlt
856  logical :: error
857  integer, dimension(3,nshlt) :: cup
858  integer, dimension(nd) :: nshlp
859  intent (in) def, nd, nshlp, nshlt
860  intent (out) error
861  intent (inout) cup
862 
863  integer :: i, i1cup, i2cup, ifc, ifcup, ii, iicup, itest, j, nc, ncup, ncup2, ndm1, ns1, ns2, nsc1, nsc2
864 
865  error = .false.
866  if (nshlt == 1) return
867 
868  if (def == 0) then
869 
870  ifcup = nshlt
871  ifc = 0
872  i1cup = 1
873  do i = 1, nd
874  iicup = nshlp(i) - 1
875  if (iicup /= 0) then
876  i2cup = i1cup
877  do ii = 1, iicup
878  ifc = ifc + 1
879  ifcup = ifcup + 1
880  i2cup = i2cup + 1
881  cup(1,ifc) = i1cup
882  cup(2,ifc) = i2cup
883  cup(3,ifc) = ifcup
884  i1cup = ifcup
885  end do
886  i1cup = i2cup
887  end if
888  i1cup = i1cup + 1
889  end do
890  ndm1 = nd - 1
891 
892  ! complete shell to shell couplings
893  ns1 = 1
894  nsc1 = nshlp(1) - 1
895  do i = 1, ndm1
896  ns2 = ns1 + nshlp(i)
897  nsc2 = nsc1 + (nshlp(i + 1) - 1)
898  ifc = ifc + 1
899  ifcup = ifcup + 1
900  i1cup = ns1
901  i2cup = ns2
902  if (nshlp(i) /= 1) i1cup = cup(3,nsc1)
903  if (nshlp(i+1) /= 1) i2cup = cup(3,nsc2)
904  if (i > 1) i1cup = cup(3,ifc-1)
905  cup(1,ifc) = i1cup
906  cup(2,ifc) = i2cup
907  cup(3,ifc) = ifcup
908  ns1 = ns2
909  nsc1 = nsc2
910  end do
911 
912  end if
913 
914  ! check cup array for allowed values
915  error = .true.
916  ncup = nshlt - 1
917  itest = nshlt
918  do i = 1, ncup
919  itest = itest + 1
920  if (cup(3,i) /= itest) return
921  if (cup(1,i) >= itest .or. cup(2,i) >= itest) return
922  end do
923 
924  ncup2 = ncup + ncup
925  do i = 1, ncup2
926  nc = 0
927  do j = 1, ncup
928  if (cup(1,j) == i) nc = nc + 1
929  if (cup(2,j) == i) nc = nc + 1
930  end do
931  if (nc /= 1) return
932  end do
933  error = .false.
934 
935  end subroutine getcup
936 
937 
967  subroutine getref (reforb, refgu, nrefo, nelec, refdet, nelr, nsoi, nob, shlmx, nsym, symtyp, nrfomx, e1, e2, e3)
968 
969  logical :: e1, e2, e3
970  integer :: nelec, nelr, nrefo, nrfomx, nsym, symtyp
971  integer, dimension(*) :: nob, nsoi, refdet, shlmx
972  integer, dimension(*) :: refgu
973  integer, dimension(5,*) :: reforb
974  intent (in) nelec, nob, nrefo, nrfomx, nsoi, nsym, refgu, reforb, shlmx, symtyp
975  intent (out) e1, e2, e3
976  intent (inout) nelr, refdet
977 
978  integer :: i, isot, j, jj, ne, neb, nelrm1, neo, ner, nesr, pqnr, pqnrm, symr, t1, tgu
979 
980  ! so far no errors
981  e1 = .false.
982  e2 = .false.
983  e3 = .false.
984 
985  ! make sure that 'nrefo' is in interval 1 .. 'nrfomx'
986  if (nrefo <= 0 .or. nrefo > nrfomx) then
987  e1 = .true.
988  return
989  end if
990 
991  ! make sure that there are really 'nelec' electrons used in quintets
992  nelr = sum(abs(reforb(3,1:nrefo)))
993  if (nelr /= nelec) then
994  e2 = .true.
995  return
996  end if
997 
998  ! loop over all quintets
999  nelr = 0
1000  do i = 1, nrefo
1001 
1002  ! unpack quintet data
1003  symr = reforb(1,i) + 1
1004  pqnr = reforb(2,i)
1005  ne = reforb(3,i)
1006 
1007  ! D_infh-specific code
1008  if (symtyp == 1) then
1009  ! check if the mirror symmetry q-number is valid
1010  tgu = refgu(i)
1011  if (abs(tgu) /= 1) then
1012  e3 = .true.
1013  return
1014  end if
1015 
1016  ! remap symr according to this table:
1017  !
1018  ! | original symr
1019  ! tgu | 1 2 3 4 5 ...
1020  ! ----|-----------------------
1021  ! +1 | 1 4 5 8 9 ...
1022  ! -1 | 2 3 6 7 10 ...
1023  !
1024  if (mod(symr,2) /= 0) tgu = -tgu
1025  symr = 2 * symr - (1 - tgu) / 2
1026  end if
1027 
1028  ! abort on reference to non-existent symmetry
1029  if (symr <= 0 .or. symr > nsym .or. ne <= 0) then
1030  e3 = .true.
1031  return
1032  end if
1033 
1034  ! make sure that electrons in this quintet actually fit in provided orbitals
1035  nesr = shlmx(symr)
1036  pqnrm = pqnr + (ne - 1) / nesr
1037  if (pqnr <= 0 .or. pqnrm > nob(symr)) then
1038  e3 = .true.
1039  return
1040  end if
1041 
1042  ! spin-orbital indices
1043  isot = nsoi(symr) + (pqnr - 1) * nesr - 1 ! global index of the spin-orbital just before the starting one for this quintet
1044  neo = mod(ne, nesr) ! number of electrons in this quintet that are in open shell
1045  ner = nelr + ne - neo ! number of all electrons in closed shells so far
1046  neb = min(neo, nesr - neo) ! number of electrons or holes in the shell, whichever is smaller
1047 
1048  ! label electrons in this quintet by the next free spin-orbitals
1049  do j = 1, ne
1050  nelr = nelr + 1
1051  isot = isot + 1
1052  refdet(nelr) = isot
1053  end do
1054 
1055  ! And that's all for closed shell!
1056  ! ... also cycle if there are no data for treatment of open shells
1057  if (neo == 0) cycle
1058  if (all(reforb(3+1:3+neb,i) == -1)) cycle
1059 
1060  ! revisit the first electron that is not in closed shell
1061  isot = isot - neo + 1
1062 
1063  ! if the shell is not filled over half...
1064  if (neo == neb) then
1065  do j = 1, neb
1066  if (reforb(3+j,i) < 0 .or. reforb(3+j,i) > nesr) then
1067  e3 = .true.
1068  return
1069  end if
1070  ner = ner + 1
1071  ! ... just correct the electron spin-orbital indices by offset ("spin") value given by the user from reforb(4:,i)
1072  refdet(ner) = isot + reforb(3+j,i)
1073  end do
1074  cycle
1075  end if
1076 
1077  ! when the shell is filled over half ...
1078  nesr_loop: do j = 1, nesr
1079  do jj = 1, neb
1080  if (reforb(3+jj,i) < 0 .or. reforb(3+jj,i) > nesr) then
1081  e3 = .true.
1082  return
1083  end if
1084  if (reforb(3+jj,i) < j - 1) cycle nesr_loop
1085  end do
1086  ner = ner + 1
1087  ! ... do some other magic ???
1088  refdet(ner) = isot + j - 1
1089  end do nesr_loop
1090 
1091  end do
1092 
1093  ! order spin-orbital numbers in refdet (if more than one electron)
1094  nelrm1 = nelr - 1
1095  if (nelrm1 > 0) then
1096  do i = 1, nelrm1
1097  t1 = refdet(i)
1098  j = i + 1
1099  do jj = 1, ner
1100  if (t1 == refdet(jj)) return
1101  if (t1 <= refdet(jj)) cycle
1102  t1 = refdet(jj)
1103  refdet(jj) = refdet(i)
1104  refdet(i) = t1
1105  end do
1106  end do
1107  end if
1108 
1109  end subroutine getref
1110 
1111 
1123  subroutine icgcf
1124 
1125  use precisn, only : wp
1126  use consts, only : one => xone
1127  use congen_data, only : binom, ind, jsmax
1128 
1129  integer :: i, jj, js, lb, lb1
1130 
1131  ind(1) = 1
1132  ind(2) = 1
1133  binom(1) = one
1134  binom(2) = one
1135  lb = 3
1136  lb1 = 1
1137  js = jsmax + 1
1138  do i = 2, js
1139  do jj = 2, i
1140  binom(lb) = binom(lb1) + binom(lb1 + 1)
1141  lb = lb + 1
1142  lb1 = lb1 + 1
1143  end do
1144  ind(i + 1) = lb1
1145  binom(lb) = one
1146  lb = lb + 1
1147  end do
1148 
1149  end subroutine icgcf
1150 
1151 
1161  subroutine stwrit (nelect, confpf, qntot, cdimx, icdi, ntso, symtyp, ndimx, indi, nrefo, nodimx, inodi, nsym, gutot, nbmx, &
1162  isz, navail, idiag, megu, thres, lcdt, megul, lndt, nfto, nrerun, ltri, npflg, nndel, nob, nsoi, nsymp, &
1163  refdet, nerfs, erfs, nrefop, reforb, refgu, nelp, lpp, sname, error, byproj, lndo, lcdo, iposit, nob0, &
1164  npmult, ntgsym, mxtarg, nobe, nobp, nobv)
1165 
1166  use precisn, only : wp
1167  use global_utils, only : mprod
1168  use congen_data, only : nftw, nu, rhead
1169  use congen_pagecontrol, only : addl, ctlpg1, newpg, space
1170 
1171  integer :: byproj, cdimx, confpf, gutot, icdi, idiag, indi, inodi, &
1172  iposit, isz, lcdo, lcdt, lndo, lndt, lpp, ltri, megu, &
1173  megul, mxtarg, navail, nbmx, ndimx, nelect, nelp, &
1174  nerfs, nfto, nndel, nodimx, npmult, nrefo, nrefop, &
1175  nrerun, nsym, nsymp, ntgsym, ntso, symtyp
1176  logical :: error
1177  character(len=80) :: sname
1178  real(kind=wp) :: thres
1179  logical, dimension(9) :: erfs
1180  integer, dimension(nu) :: nob, nob0, nobe, nobp, nobv, nsoi ! JMC changing the dimension from 10
1181  integer, dimension(6) :: npflg
1182  integer, dimension(3) :: qntot
1183  integer, dimension(*) :: refdet, refgu
1184  integer, dimension(5,*) :: reforb
1185  intent (in) byproj, cdimx, confpf, erfs, gutot, icdi, idiag, indi, &
1186  inodi, iposit, isz, lcdo, lcdt, lndo, lndt, ltri, &
1187  megu, megul, mxtarg, navail, nbmx, ndimx, nelect, &
1188  nelp, nerfs, nfto, nndel, nob, nob0, nobe, nobp, nobv, &
1189  nodimx, npflg, nrefo, nrefop, nrerun, nsoi, nsym, &
1190  nsymp, ntgsym, ntso, qntot, refdet, refgu, reforb, &
1191  symtyp, thres
1192  intent (inout) error
1193 
1194  character(len=32), dimension(9) :: ersnts
1195  character(len=30) :: head = 'CONGEN 1.0 IBM SAN JOSE '
1196  integer :: i, ii, imax, ip, it, junk, lsn = 64, nitem = 30
1197 
1198  data ersnts/'SYMMETRY TYPE OUT OF RANGE ', &
1199  'NO ORBITALS GIVEN ', &
1200  'EXDET, EXREF ALLOCATION FAILED ', &
1201  'NELECT OUT OF RANGE ', &
1202  'NREFO OUT OF RANGE ', &
1203  'SUM NELEC IN REF ORBS NE NELECT ', &
1204  'ERROR IN REFORB DATA ', &
1205  'ERROR IN TOTAL QN DATA ', &
1206  'NO CORE FOR CDI, NDI, AND NODI '/
1207 
1208  call ctlpg1 (lpp, head, len(head), sname, lsn)
1209  call newpg
1210  call addl (15)
1211 
1212  write(nftw,'(T2,"NELECT",T8,I4,T15,"CONFPF",I3,T27,"MULT ",I2,T38,"CDIMX ",I5,T52,"ICDI ",I6)') &
1213  nelect, confpf, qntot(1), cdimx, icdi
1214  write(nftw,'(" NTSO ",I4,T15,"SYMTYP",I3,T27,"MVAL ",I2,T38,"NIDMX ",I5,T52,"INDI ",I6)') &
1215  ntso, symtyp, qntot(2), ndimx, indi
1216  write(nftw,'(" NREFO ",I4,T27,"REFLC",I3,T38,"NODIMX",I5,T52,"INODI",I6)') nrefo, qntot(3), nodimx, inodi
1217  write(nftw,'(" NSYM ",I4,T27,"GUTOT",I3,T38,"NCORE",I10)') nsym, gutot, nbmx
1218  write(nftw,'(T27,"ISZ ",I3,T38,"NAV ",I10)') isz, navail
1219 
1220  write(nftw,'(//,T14," DATA FOR SPEEDY INPUT")')
1221  write(nftw,'(/, T14,"IDIAG ",I4,T27,"MEGU ",I3,T38,"THRES ",1PE12.4)') idiag, megu, thres
1222  write(nftw,'(T14,"LCDT ",I4,T27,"MEGUL",I3)') lcdt, megul
1223  write(nftw,'(T14,"LNDT ",I4,T27,"NFTO ",I3)') lndt, nfto
1224  write(nftw,'(T14,"NRERUN",I4,T27,"LTRI ",I3)') nrerun, ltri
1225  write(nftw,'(/,T14,"NPFLG =",6I3,2X,"NNDEL = ",I5)') npflg, nndel
1226 
1227  call addl (1)
1228 
1229  write(nftw,'(T14,"BYPROJ",I2,3x,"LNDO",I10,3x,"LCDO",I10)') byproj, lndo, lcdo
1230 
1231  if (ntgsym < mxtarg) then
1232  call addl (1)
1233  write(nftw,'(" ntgsym",I4)') ntgsym
1234  end if
1235 
1236  call space (2)
1237  call addl (3)
1238 
1239  write(nftw,'(" NSYM",30I5)') (ip, ip=1,nsymp)
1240  write(nftw,'(" NOB ",30I5)') (nob(ip), ip=1,nsymp)
1241  if (iposit /= 0) then
1242  call addl (4) ! JMC adding this line
1243  write(nftw,'(" NOB0",30I5)') (nob0(ip), ip=1,nsymp)
1244  write(nftw,'(" NOBE",30I5)') (nobe(ip), ip=1,nsymp)
1245  write(nftw,'(" NOBP",30I5)') (nobp(ip), ip=1,nsymp)
1246  write(nftw,'(" NOBV",30I5)') (nobv(ip), ip=1,nsymp)
1247  end if
1248  write(nftw, '(" NSOI",30I5)') (nsoi(ip), ip=1,nsymp)
1249  call space (1)
1250  if (iposit /= 0) then
1251  call addl (1) ! JMC adding this line
1252  write(nftw,'(5X,"POSITRON SCATTERING CASE: IPOSIT =",I3)') iposit
1253  call space (1)
1254  end if
1255 
1256  it = 1
1257  if (symtyp == 1) it = 2
1258  do i = 1, nrefop, nitem
1259  imax = min(i + nitem - 1, nrefop)
1260  call addl (6) ! JMC the argument will be too small in some cases (i=1 and symtyp=1)???
1261  if (i == 1) then
1262  write(nftw,'(" REFERENCE DETERMINANT INPUT DATA")')
1263  it = it - 1
1264  end if
1265  write(nftw,'(1X,A4,I5,29I4)') rhead(1), (ip,ip=i,imax)
1266  do ii = 1, 5
1267  write(nftw, '(1X,A4,I5,29I4)') rhead(ii+1), (reforb(ii,ip), ip=i,imax)
1268  end do
1269  if (symtyp == 1) write(nftw, '(1X,A4,I5,29I4)') rhead(7), (refgu(ip), ip=i,imax)
1270  call space (1)
1271  end do
1272  call space (1)
1273  it = (nelp + nitem - 1) / nitem
1274  if (mod(nelp,nitem) == 0) it = it + 1
1275 
1276  if (nelp /= 0) then
1277  call addl (it)
1278  write(nftw,'(" REFDET =",30(I3,",")/(9X,30(I3,",")))') (refdet(ip), ip=1,nelp)
1279  end if
1280 
1281  ! print D_2h multiplication table
1282  if (symtyp >= 2 .and. npmult /= 0) then
1283  call addl (25)
1284  junk = mprod(1, 1, npmult, nftw)
1285  end if
1286 
1287  ! process &state errors
1288  error = .false.
1289  do i = 1, nerfs
1290  if (erfs(i)) then
1291  if (.not. error) then
1292  call space (2)
1293  call addl (2)
1294  write(nftw,'(" **** ERROR DATA FOR &STATE FOLLOWS (&WFNGRP NOT PROCESSED)"/12X,A32)') ersnts(i)
1295  error = .true.
1296  else
1297  call addl (1)
1298  write(nftw,'(12X,A32)') ersnts(i)
1299  end if
1300  end if
1301  end do
1302 
1303  end subroutine stwrit
1304 
1305 
1308  subroutine subdel (ndel, ndel1, ndel2, nndel)
1309 
1310  use congen_data, only : nftw, nftr
1311 
1312  integer :: nndel
1313  integer, dimension(*) :: ndel, ndel1, ndel2 ! JMC changing dimension from 2.
1314  intent (inout) ndel, ndel1, ndel2, nndel
1315 
1316  integer :: i, j, k, m, nndel1
1317 
1318  read(nftr,'(16I5)') nndel
1319  read(nftr,'(16I5)') (ndel(i), i=1,nndel)
1320 
1321  read(nftr,'(16I5)') nndel1
1322 
1323  do while (nndel1 /= 0)
1324 
1325  read(nftr,'(16I5)') (ndel1(j), j=1,nndel1)
1326 
1327  i = 1
1328  j = 1
1329  k = 0
1330 
1331  read_loop: do
1332 
1333  if (ndel(i) <= ndel1(j)) then
1334  k = k + 1
1335  if (ndel(i) == ndel1(j)) j = j + 1
1336  ndel2(k) = ndel(i)
1337  i = i + 1
1338  if (i > nndel) then
1339  ndel(1:k) = ndel2(1:k)
1340  do m = j, nndel1
1341  k = k + 1
1342  ndel(k) = ndel1(m)
1343  end do
1344  exit read_loop
1345  end if
1346  else
1347  k = k + 1
1348  ndel2(k) = ndel1(j)
1349  j = j + 1
1350  end if
1351 
1352  if (j > nndel1) then
1353  do m = i, nndel
1354  k = k + 1
1355  ndel2(k) = ndel(m)
1356  end do
1357  ndel(1:k) = ndel2(1:k)
1358  exit read_loop
1359  end if
1360 
1361  end do read_loop
1362 
1363  nndel = k
1364  read(nftr,'(16I5)') nndel1
1365 
1366  end do
1367 
1368  write(nftw,'(" ***** NUMBER OF CHOSEN CONFIGURATIONS ***",I10)') nndel
1369  write(nftw,'(/,24I5)')(ndel(i),i=1,nndel)
1370  write(7,'(16I5)') (ndel(i), i=1,nndel) ! JMC writing to unit 7 (hardwired)???
1371 
1372  end subroutine subdel
1373 
1374 
1377  subroutine wfnin (nwfngp, nadel, nncsf, ncsf, lcdi, lndi, nelecg, ndprod, nrefog, npcupf, negmax, refdtg, nrfgmx, refgug, &
1378  ntcon, reforg, nshgmx, nsymmx, mshl, gushl, pqn, cup, ndpmax, nshlp, nconmx, test, nrcon, nshcon, tcon, &
1379  errorg)
1380 
1381  logical :: errorg
1382  integer :: lcdi, lndi, nadel, nconmx, ncsf, ndpmax, ndprod, negmax, nelecg, nncsf, npcupf, nrefog, nrfgmx, nshgmx, &
1383  nsymmx, ntcon, nwfngp
1384  integer, dimension(3,*) :: cup, pqn
1385  integer, dimension(*) :: gushl, mshl, nrcon, nshcon, nshlp, refdtg, refgug, test
1386  integer, dimension(5,*) :: reforg
1387  integer, dimension(3,nshgmx,*) :: tcon ! JMC the dimensions could be changed to (3,JX,JZ) if desired.
1388  intent (in) nconmx, ndpmax, negmax, nrfgmx, nshgmx, nsymmx
1389  intent (out) cup, errorg, gushl, lcdi, lndi, mshl, nadel, ncsf, ndprod, nelecg, nncsf, npcupf, nrcon, nrefog, nshcon, &
1390  nshlp, ntcon, nwfngp, pqn, refdtg, refgug, reforg, tcon, test
1391 
1392  integer :: i, j, k
1393 
1394  ! general default for wfngrp arrays
1395 
1396  nwfngp = 0
1397  nadel = 1
1398  nncsf = 0
1399  ncsf = 0
1400  lcdi = 0
1401  lndi = 0
1402  ntcon = 0
1403 
1404  nelecg = 0
1405  ndprod = 0
1406  nrefog = 0
1407  npcupf = 0
1408 
1409  refdtg(1:negmax) = 0
1410  refgug(1:nrfgmx) = -2
1411  reforg(1:5,1:nrfgmx) = -2
1412 
1413  mshl(1:nshgmx) = nsymmx + 1
1414  gushl(1:nshgmx) = -2
1415 
1416  pqn(1:3,1:nshgmx) = -1
1417  cup(1:3,1:nshgmx) = -1
1418 
1419  errorg = .false.
1420 
1421  nshlp(1:ndpmax) = 0
1422  test(1:nconmx) = 1
1423  nrcon(1:nconmx) = -1
1424  nshcon(1:nconmx) = 0
1425 
1426  tcon(1,1:nshgmx,1:nconmx) = -1
1427  tcon(2,1:nshgmx,1:nconmx) = 0
1428  tcon(3,1:nshgmx,1:nconmx) = 0
1429 
1430  end subroutine wfnin
1431 
1432 
1447  subroutine wfnin0 (nelecp, defltc, nerfg, erfg, gname, qntar, errorg, ndpmax)
1448 
1449  integer :: defltc, ndpmax, nerfg
1450  logical :: errorg
1451  character(len=80) :: gname
1452  logical, dimension(*) :: erfg
1453  integer, dimension(*) :: nelecp
1454  integer, dimension(3) :: qntar
1455  intent (in) ndpmax, nerfg
1456  intent (out) defltc, erfg, gname, nelecp, qntar
1457 
1458  nelecp(1:ndpmax) = -1
1459  erfg(1:nerfg) = .false.
1460 
1461  gname = ' '
1462  defltc = 0
1463 
1464  qntar(1) = -1
1465  qntar(2) = 0
1466  qntar(3) = 0
1467 
1468  end subroutine wfnin0
1469 
1470 
1473  subroutine wrnmlt (k, sname, nrerun, megul, symtyp, mgvn, s, sz, r, pin, ncsf, byproj, lcdi, lndi, lcdo, lndo, lcdt, lndt, &
1474  nfto, ltri, idiag, npflg, thres, nelect, nsym, nob, refdet, nftw, iposit, nob0, nobl, nob0l, nx, nobe, &
1475  nobp, nobv)
1476 
1477  use precisn, only : wp
1478 
1479  integer :: byproj, idiag, iposit, k, lcdi, lcdo, lcdt, lndi, lndo, lndt, ltri, megul, mgvn, ncsf, nelect, nfto, nftw, &
1480  nrerun, nsym, nx, symtyp
1481  real(kind=wp) :: pin, r, s, sz, thres
1482  character(len=80) :: sname
1483  integer, dimension(*) :: nob, nob0, refdet
1484  integer, dimension(nx) :: nob0l, nobl
1485  integer, dimension(nx) :: nobe, nobp, nobv
1486  integer, dimension(6) :: npflg
1487  intent (in) byproj, idiag, iposit, k, lcdi, lcdo, lcdt, lndi, lndo, lndt, ltri, megul, mgvn, ncsf, nelect, nfto, &
1488  nob, nob0, nob0l, nobe, nobl, nobp, nobv, npflg, nrerun, nsym, nx, pin, r, refdet, s, sname, symtyp, &
1489  sz, thres
1490 
1491  character(len=4) :: blank1 = ' '
1492  integer :: j
1493 
1494  write(k,'(" &INPUT")')
1495  write(k,'(" NAME=''",A80,"'',")') sname
1496  write(k,'(" NRERUN=",I3,", MEGUL=",I3,", SYMTYP=",I3,",")') nrerun, megul, symtyp
1497  write(k,'(" MGVN=",I3,", S=",F6.1,",SZ=",F6.1,", R=",F6.1,", PIN=",F6.1,", NOCSF=",I6,",")') mgvn, s, sz, r, pin, ncsf
1498  write(k,'(" BYPROJ=",I2,",")') byproj
1499  write(k,'(" LCDI=",I15,", LNDI=",I15,", LCDO=",I7,", LNDO=",I15,","," LCDT=",I7,", LNDT=",I7,",")') &
1500  lcdi, lndi, lcdo, lndo, lcdt, lndt
1501  write(k,'(" NFTO=",I3,", LTRI=",I5,", IDIAG=",I3,", NPFLG=",5(I2,",")," NPMSPD =",I2,",")') nfto, ltri, idiag, npflg
1502  write(k,'(" THRES=",1PD9.2,",")') thres
1503  write(k,'(" NELT=",I4,", NSYM=",I3,", NOB=",10(I3,","))') nelect, nsym, (nob(j), j=1,nsym)
1504  write(k,'(" NDTRF=",A1,12(I3,",",A1)/(8X,12(I3,",",A1)))') (blank1, refdet(j), j=1,nelect)
1505  write(k,'(" NOBL=",10(I3,","))') nobl
1506  write(k,'(" NOB0L=",10(I3,","))') nob0l
1507 
1508  if (iposit /= 0) then
1509  write(k,'(" IPOSIT=",I3)') iposit
1510  write(k,'(" NOB0=",10(I3,","))') (nob0(j), j=1,nsym)
1511  write(k,'(" NOBE=",10(I3,","))') (nobe(j), j=1,nsym)
1512  write(k,'(" NOBP=",10(I3,","))') (nobp(j), j=1,nsym)
1513  write(k,'(" NOBV=",10(I3,","))') (nobv(j), j=1,nsym)
1514  end if
1515  write(k,'(" /")')
1516 
1517  end subroutine wrnmlt
1518 
1519 
1522  subroutine wvwrit (nwfngp, gname, nelecg, defltc, irfcon, ndprod, symtyp, ntcon, navail, nrefog, nelecp, nshlp, qntar, &
1523  nshlpt, nshgmx, mshl, gushl, pqn, cup, ncupp, npcupf, refdtg, nelp, ntconp, nshcon, nobt, reforb, &
1524  refgu, test, nrcon, tcon, refcon, nerfg, erfg, ndpp, nrefop, errorg)
1525 
1526  use congen_data, only : nftw, rhead
1527  use congen_pagecontrol, only : addl, newpg, space
1528 
1529  integer :: defltc, irfcon, navail, ncupp, ndpp, ndprod, nelecg, nelp, nerfg, nobt, npcupf, nrefog, nrefop, &
1530  nshgmx, nshlpt, ntcon, ntconp, nwfngp, symtyp
1531  logical :: errorg
1532  character(len=80) :: gname
1533  integer, dimension(3,*) :: cup, pqn
1534  logical, dimension(11) :: erfg
1535  integer, dimension(*) :: gushl, mshl, nelecp, nrcon, nshcon, nshlp, refcon, refdtg, refgu, test
1536  ! change refcon from integer to couble for consistency
1537  ! double precision refcon(*) ! jmc the correponding actual arg is d.p. ???
1538  integer, dimension(3) :: qntar
1539  integer, dimension(5,*) :: reforb
1540  integer, dimension(3,nshgmx,*) :: tcon ! jmc changing the 2nd dimension from LG to NSHGMX for consistency with elsewhere.
1541  ! The dimensions could also be changed to (3,JX,JZ) if desired.
1542  intent (in) cup, defltc, erfg, gname, gushl, irfcon, mshl, navail, ncupp, ndpp, ndprod, nelecg, nelecp, nelp, &
1543  nerfg, nobt, npcupf, nrcon, nrefog, nrefop, nshcon, nshgmx, nshlp, nshlpt, ntcon, ntconp, nwfngp, pqn, &
1544  qntar, refcon, refdtg, refgu, reforb, symtyp, tcon
1545  intent (inout) errorg, test
1546 
1547  character(len=32), dimension(11) :: ersntg
1548  character(len=4) :: hcup = 'CUP ', htcon = 'TCON', lpc = ' ( '
1549  integer :: i, i1, i2, ic, ii, iimax, imax, ip, ishp, it, jj, jnshl, nshcr, nit1 = 10, nit2 = 30
1550 
1551  data ersntg/'NELECG OUT OF RANGE ', &
1552  'NDPROD TOO LARGE ', &
1553  'NSHLP OUT OF RANGE ', &
1554  'NELECG NE SUM OF NELEP ', &
1555  'NREF OUT OF RANGE ', &
1556  'NELECG NE SUM OVER NELEC IN REFO', &
1557  'ERROR IN REF ORB DATA ', &
1558  'ERROR IN SHELL DATA ', &
1559  'ERROR IN COUPLING DATA ', &
1560  'ERROR IN CONFIG CONSTRAINT DATA ', &
1561  'NO SPACE FOR REFCON ARRAY '/
1562 
1563  ! print wfngrp input data
1564  call newpg
1565  call addl (9)
1566  write(nftw,'(" WFN GROUP",I4,4X,A80)') nwfngp, gname
1567  write(nftw,'(" NELECG",I4,T15,"DEFLTC",I3,T27,"IRFCON",I6)') nelecg, defltc, irfcon
1568  write(nftw,'(" NDPROD",I4,T15,"NTCON ",I3,T27,"NAV ",I10)') ndprod, ntcon, navail
1569  write(nftw,'(" NREFOG",I4,/)') nrefog
1570  write(nftw,'(9X,9I3)') (i, i=1,ndpp)
1571  write(nftw,'(" NELECP =",9I3)') (nelecp(i), i=1,ndpp)
1572  write(nftw,'(" NSHLP =",9I3)') (nshlp(i), i=1,ndpp)
1573 
1574  if (qntar(1) /= -1) then
1575  call addl (1)
1576  write(nftw,'(5X,"TARGET MULTIPLICITY =",I5,5X,"TARGET SYMMETRY =",I5,5X,"TARGET INVERSION SYMMETRY =",I5)') &
1577  (qntar(i), i=1,3)
1578  end if
1579 
1580  call space (1)
1581 
1582  if (ndprod /= 0 .and. nshlpt <= nshgmx) then
1583 
1584  it = merge(1, 0, symtyp == 1)
1585  ishp = 0
1586 
1587  do ip = 1, ndprod
1588  jnshl = nshlp(ip)
1589  if (jnshl == 0) then
1590  call addl (1)
1591  write(nftw,'(I4," ORBITALS IN GROUP",I2)') jnshl, ip
1592  call space (2)
1593  end if
1594  do i = 1, jnshl, nit1
1595  imax = min(i + nit1 - 1, jnshl)
1596  if (i == 1) then
1597  call addl (4 + it)
1598  write(nftw,'(I4," ORBITALS IN GROUP",I2)') jnshl, ip
1599  else
1600  call addl (3 + it)
1601  end if
1602  write(nftw,'(1X,A4,I8,9I12)') rhead(1), (ii, ii=i,imax)
1603  write(nftw, '(1X,A4,I8,9I12)') rhead(2), (mshl(ishp+ii), ii=i,imax)
1604  if (symtyp == 1) write(nftw,'(1X,A4,I8,9I12)') rhead(7), (gushl(ishp+ii), ii=i,imax)
1605  write(nftw,'(1X,A4,10(A3,I2,",",I2,",",I2,")"))') rhead(3), (lpc,(pqn(jj,ishp+ii), jj=1,3), ii=i,imax)
1606  call space (1)
1607  end do
1608  ishp = ishp + jnshl
1609  end do
1610 
1611  call space (1)
1612 
1613  if (ncupp * npcupf /= 0) then
1614  do i = 1, ncupp, nit1
1615  imax = min(i + nit1 - 1, ncupp)
1616  i1 = i + nshlpt
1617  i2 = imax + nshlpt
1618  if (i == 1) then
1619  call addl (3)
1620  write(nftw,'(" COUPLING DATA")')
1621  else
1622  call addl (2)
1623  end if
1624  write(nftw,'(1X,A4,I8,9I12)') rhead(1), (ii, ii=i1,i2)
1625  write(nftw, '(1X,A4,10(A3,I2,",",I2,",",I2,")"))') hcup, (lpc,(cup(jj,ii), jj=1,3), ii=i,imax)
1626  call space (1)
1627  end do
1628  end if
1629 
1630  it = merge(2, 1, symtyp == 1)
1631 
1632  do i = 1, nrefop, nit2
1633  imax = min(i + nit2 - 1, nrefop)
1634  call addl (6 + it)
1635  if (i == 1) then
1636  write(nftw,'(" REFERENCE DETERMINANT INPUT DATA")')
1637  it = it - 1
1638  end if
1639  write(nftw, '(1X,A4,I5,29I4)') rhead(1), (ip, ip=i,imax)
1640  do ii = 1, 5
1641  write(nftw, '(1X,A4,I5,29I4)') rhead(ii+1), (reforb(ii,ip), ip=i,imax)
1642  end do
1643  if (symtyp == 1) write(nftw, '(1X,A4,I5,29I4)') rhead(7), (refgu(ip), ip=i,imax)
1644  call space (1)
1645  end do
1646 
1647  call space (1)
1648 
1649  it = (nelp + nit2 - 1) / nit2
1650  if (mod(nelp, nit2) == 0) it = it + 1
1651  if (nelp /= 0) then
1652  call addl (it)
1653  write(nftw,'(" REFDET =",30(I3,","),/,(9X,30(I3,",")))') (refdtg(ip), ip=1,nelp)
1654  end if
1655 
1656  call space (1)
1657 
1658  do ic = 1, ntconp
1659  nshcr = nshcon(ic)
1660  it = 1 + 2 * ((nshcr + nit1 - 1) / nit1) + 1 + (nobt + nit2 - 1) / nit2 ! jmc one too many here???
1661  if (mod(nobt, nit2) == 0) it = it + 1
1662  if (ic == 1) then
1663  call addl (2 + it)
1664  write(nftw,'(" EXITATION CONSTRAINTS / TCON(SYM,PQN,NE",/)')
1665  else
1666  call addl(it)
1667  end if
1668  if (test(ic) /= 1) then
1669  write(nftw,'(I3,10X,"GT",I3," REPLACEMENTS ALLOWED(INTERSECTION)")') ic, nrcon(ic)
1670  test(ic) = 0
1671  else
1672  write(nftw,'(I3,10X,"LE",I3," REPLACEMENTS ALLOWED(UNION)")') ic, nrcon(ic)
1673  end if
1674  if (nshcr /= 0) then
1675  do ii = 1, nshcr, nit1
1676  iimax = min(ii + nit1 - 1, nshcr)
1677  write(nftw,'(1X,A4,I8,9I12)') rhead(1), (ip, ip=ii,iimax)
1678  write(nftw,'(1X,A4,10(A3,I2,",",I2,",",I2,")"))') htcon, (lpc,(tcon(jj,ip,ic), jj=1,3), ip=ii,iimax)
1679  end do
1680  call space (1)
1681  write(nftw,'(" REFCON =",30(I3,",")/(9X,30(I3,",")))') (refcon(ip), ip=1,nobt)
1682  end if
1683  call space (1)
1684  end do
1685 
1686  end if
1687 
1688  ! print wfngrp error messages
1689 
1690  do i = 1, nerfg
1691  if (.not. erfg(i)) cycle
1692  if (.not. errorg) then
1693  call space (2)
1694  call addl (2)
1695  write(nftw,'(" **** ERROR DATA FOR &WFNGRP FOLLOWS",/,12X,A32)') ersntg(i)
1696  errorg = .true.
1697  cycle
1698  end if
1699  call addl (1)
1700  write(nftw,'(12X,A32)') ersntg(i)
1701  end do
1702 
1703  end subroutine wvwrit
1704 
1705 end module congen_driver
congen_pagecontrol::ctlpg1
subroutine, public ctlpg1(lpp, h1, nh1, h2, nh2)
Controls page layout and counting.
Definition: congen_pagecontrol.f90:73
congen_driver::stwrit
subroutine, private stwrit(nelect, confpf, qntot, cdimx, icdi, ntso, symtyp, ndimx, indi, nrefo, nodimx, inodi, nsym, gutot, nbmx, isz, navail, idiag, megu, thres, lcdt, megul, lndt, nfto, nrerun, ltri, npflg, nndel, nob, nsoi, nsymp, refdet, nerfs, erfs, nrefop, reforb, refgu, nelp, lpp, sname, error, byproj, lndo, lcdo, iposit, nob0, npmult, ntgsym, mxtarg, nobe, nobp, nobv)
Write information obtained from &state.
Definition: congen_driver.f90:1165
congen_data::nz
integer, parameter nz
Used to dimension REFDET in congen_driver::csfgen; maximum number of electrons.
Definition: congen_data.f90:42
congen_data::jx
integer, parameter jx
Used to dimension many arrays in congen_driver::csfgen; limit on the sum of elements in the NSHLP arr...
Definition: congen_data.f90:43
congen_data::mshl
integer, dimension(lg) mshl
Symmetry number from zero to n-1 (mvalue).
Definition: congen_data.f90:93
congen_data::noi
integer noi
Number of determinants per CSF.
Definition: congen_data.f90:146
congen_data::lratio
integer lratio
Ratio of real size to integer size. Used to manage workspace data.
Definition: congen_data.f90:74
congen_data::nid
integer nid
Length of the integer array containing all packed determinants.
Definition: congen_data.f90:145
congen_data::jz
integer, parameter jz
Maximum number of constraints upon CSFs accepted (limit on input variable NTCON).
Definition: congen_data.f90:46
congen_data::megul
integer megul
File unit for binary output of generated configurations.
Definition: congen_data.f90:128
congen_data::nisz
integer nisz
Total S_z, set by CSFGEN, defaults to first element of qntot.
Definition: congen_data.f90:85
congen_data::ny
integer, parameter ny
Used to dimension REFGU and REFORB in csfgen. Limit on input variable NREFO.
Definition: congen_data.f90:41
congen_driver::subdel
subroutine, private subdel(ndel, ndel1, ndel2, nndel)
Read CSFs from input stream.
Definition: congen_driver.f90:1309
congen_data::ndel2
integer ndel2
Workspace position used for reading CSFs from the input.
Definition: congen_data.f90:83
congen_data::rhead
character(len=4), dimension(7), parameter rhead
Definition: congen_data.f90:63
congen_data::cup
integer, dimension(3, lg) cup
Coupling scheme data. ???
Definition: congen_data.f90:90
congen_pagecontrol
Page control.
Definition: congen_pagecontrol.f90:26
congen_data::ntcon
integer ntcon
Definition: congen_data.f90:111
congen_driver::icgcf
subroutine, private icgcf
Precomputes needed binomial coefficients.
Definition: congen_driver.f90:1124
congen_data::icdi
integer icdi
Position in workspace where the determinant coefficients start (one coeff per one determinant).
Definition: congen_data.f90:75
congen_driver::csfout
subroutine, private csfout(ia, ib, megul, nndel, cr, nr)
Store the wave function to file and reset arrays.
Definition: congen_driver.f90:753
congen_driver::wfnin0
subroutine, private wfnin0(nelecp, defltc, nerfg, erfg, gname, qntar, errorg, ndpmax)
Defaults to be reset before every wfngrp.
Definition: congen_driver.f90:1448
congen_data::nu
integer, parameter nu
Maximal number of irreducible representation (= max dimension of NOB etc.).
Definition: congen_data.f90:40
congen_data::indi
integer indi
Position in workspace where packed determinants start (each as size + replacements).
Definition: congen_data.f90:77
congen_data::inodi
integer inodi
Position in workspace where CSFs start (as number of determinants per CSF).
Definition: congen_data.f90:78
congen_data::qntar
integer, dimension(3) qntar
Coupling control for current wfn group. ???
Definition: congen_data.f90:101
congen_data::symtyp
integer symtyp
Symmetry type, 0 = C_infv, 1 = D_infh, 2 = {D_2h, C_2v, C_s, E}.
Definition: congen_data.f90:88
congen_data::ind
integer, dimension(jsmax+2) ind
Pascal triangle row pointers into congen_data::binom.
Definition: congen_data.f90:107
congen_driver::csfgen
subroutine, public csfgen
Central CONGEN subroutine.
Definition: congen_driver.f90:50
congen_data::confpf
integer confpf
Print flag for the amount of print given of configurations and prototypes.
Definition: congen_data.f90:120
congen_data::ni
integer ni
Number of determinants currently in memory.
Definition: congen_data.f90:144
congen_data::occshl
integer, dimension(lg) occshl
Compressed shell occupations, all zeros deleted and pseudo shells expanded.
Definition: congen_data.f90:94
congen_driver::getcon
subroutine, private getcon(ntcon, nshcon, nrcon, nshgmx, npmax, nc, nelecg, nsym, nobt, nob, nobi, nsoi, shlmx1, exref, tcon, refcon, error)
Check tcon data and form refcon array.
Definition: congen_driver.f90:791
congen_data::ncsf
integer ncsf
Total number of CSFs generated.
Definition: congen_data.f90:121
congen_data::next
integer next
Position in the workspace indicating the first unused element.
Definition: congen_data.f90:147
congen_data::nobt
integer nobt
Total number of all orbitals considered in the calculation, essentially equal to sum(nob).
Definition: congen_data.f90:110
congen_data::sshlst
integer, dimension(lg) sshlst
Definition: congen_data.f90:97
congen_data::nftr
integer, parameter nftr
Unit number for reading standard input.
Definition: congen_data.f90:56
congen_driver::wfnin
subroutine, private wfnin(nwfngp, nadel, nncsf, ncsf, lcdi, lndi, nelecg, ndprod, nrefog, npcupf, negmax, refdtg, nrfgmx, refgug, ntcon, reforg, nshgmx, nsymmx, mshl, gushl, pqn, cup, ndpmax, nshlp, nconmx, test, nrcon, nshcon, tcon, errorg)
Set defaults for wave function group parameters.
Definition: congen_driver.f90:1380
congen_data::qntot
integer, dimension(3) qntot
Total quantum numbers.
Definition: congen_data.f90:102
congen_driver::getref
subroutine, private getref(reforb, refgu, nrefo, nelec, refdet, nelr, nsoi, nob, shlmx, nsym, symtyp, nrfomx, e1, e2, e3)
Form reference list of spin-orbital numbers.
Definition: congen_driver.f90:968
congen_data::nftw
integer nftw
Unit number for printing; may be changed via the STATE namelist so not a parameter.
Definition: congen_data.f90:57
congen_data::nsym
integer nsym
Number of symmetries given in input file (right-trimmed of those with zero orbitals).
Definition: congen_data.f90:112
congen_data::iqnstr
integer iqnstr
Starting position in workspace for per-shell quantum numbers (e.g. congen_distribution::cplem).
Definition: congen_data.f90:79
congen_pagecontrol::space
subroutine, public space(lines)
Add blank lines to output.
Definition: congen_pagecontrol.f90:144
congen_data::ky
integer, parameter ky
Used to dimension REFGUG and REFORG in congen_driver::csfgen. Limit on input variable NREFOG?
Definition: congen_data.f90:47
congen_driver::getcup
subroutine, private getcup(nshlt, def, nd, nshlp, cup, error)
Set up coupling scheme.
Definition: congen_driver.f90:854
congen_data::ncall
integer ncall
Used to signal to "wfn" to initialize some variables.
Definition: congen_data.f90:129
congen_data::irfcon
integer irfcon
Definition: congen_data.f90:80
congen_data::gushl
integer, dimension(lg) gushl
Gerade/ungerade per shell.
Definition: congen_data.f90:92
congen_data::mxtarg
integer, parameter mxtarg
Maximum number of target state symmetries.
Definition: congen_data.f90:49
congen_data::exdet
integer, dimension(:), allocatable exdet
Definition: congen_data.f90:135
congen_driver::wrnmlt
subroutine, private wrnmlt(k, sname, nrerun, megul, symtyp, mgvn, s, sz, r, pin, ncsf, byproj, lcdi, lndi, lcdo, lndo, lcdt, lndt, nfto, ltri, idiag, npflg, thres, nelect, nsym, nob, refdet, nftw, iposit, nob0, nobl, nob0l, nx, nobe, nobp, nobv)
Final text information output.
Definition: congen_driver.f90:1476
congen_data::lndi
integer lndi
Total number of integers forming packed determinants.
Definition: congen_data.f90:143
congen_data::shlmx1
integer, dimension(nu) shlmx1
Maximal occupancy of orbitals per symmetry.
Definition: congen_data.f90:103
congen_data::ndel
integer ndel
Workspace position used for the CSFs read from input.
Definition: congen_data.f90:81
congen_data::ift
integer ift
Used to signal to congen_distribution::assign to initialize some variables.
Definition: congen_data.f90:109
congen_data::ntso
integer ntso
Total number of spin-orbitals, given the orbitals and their maximal occupacy (from group properties).
Definition: congen_data.f90:133
congen_data::iidis2
integer iidis2
Definition: congen_data.f90:141
congen_data::nnlecg
integer nnlecg
The total number of electrons which are movable within the current wfn group.
Definition: congen_data.f90:87
congen_data
Module containing parameters / data required throughout the CONGEN program.
Definition: congen_data.f90:32
congen_data::iexcon
integer iexcon
Position in workspace where EX constraints start.
Definition: congen_data.f90:76
congen_projection
Projection on spin states.
Definition: congen_projection.f90:30
congen_data::gutot
integer gutot
Total gerade (= +1) / ungerade (= -1) quantum number.
Definition: congen_data.f90:84
congen_data::nobi
integer, dimension(nu) nobi
Running index of the first orbital in each symmetry.
Definition: congen_data.f90:114
congen_pagecontrol::newpg
subroutine, public newpg
Start new page of output.
Definition: congen_pagecontrol.f90:121
congen_data::nncsf
integer nncsf
Number of CSFs generated by congen_distribution::wfn (total).
Definition: congen_data.f90:131
congen_driver
Main CONGEN subroutines.
Definition: congen_driver.f90:23
congen_data::kz
integer, parameter kz
Used to dimension REFDTG in csfgen; limit on input variable NELECG?
Definition: congen_data.f90:48
congen_data::pqnst
integer, dimension(3, lg) pqnst
Definition: congen_data.f90:91
congen_driver::wvwrit
subroutine, private wvwrit(nwfngp, gname, nelecg, defltc, irfcon, ndprod, symtyp, ntcon, navail, nrefog, nelecp, nshlp, qntar, nshlpt, nshgmx, mshl, gushl, pqn, cup, ncupp, npcupf, refdtg, nelp, ntconp, nshcon, nobt, reforb, refgu, test, nrcon, tcon, refcon, nerfg, erfg, ndpp, nrefop, errorg)
Display information about the wave function group.
Definition: congen_driver.f90:1525
congen_data::exref
integer, dimension(:), allocatable exref
Population of spin-orbitals (0 = not populated, 1 = populated).
Definition: congen_data.f90:136
congen_distribution::distrb
subroutine, public distrb(nelecp, nshlp, shlmx, occshl, nslsv, kdssv, loopf, ksss, pqn, occst, shlmx1, pqnst, mshl, mshlst, gushl, gushst, cup, cupst, ndprod, symtyp, confpf, sshl, sshlst, ncsf, nncsf, nadel, nndel, x, nftw)
Distribute electrons to spin-orbitals.
Definition: congen_distribution.f90:996
congen_data::lcdi
integer lcdi
Total number of determinants (including those already flushed to disk).
Definition: congen_data.f90:142
congen_data::binom
real(kind=wp), dimension((jsmax *jsmax+3 *jsmax+4)/2) binom
Table of precomputed Pascal triangle.
Definition: congen_data.f90:106
congen_distribution
Distribute electrons to available orbitals.
Definition: congen_distribution.f90:23
congen_data::test
integer, dimension(jz) test
Determines which of the two types of constraints will be used.
Definition: congen_data.f90:117
congen_data::jsmax
integer, parameter jsmax
Maximal order of precomputed binomial coefficients.
Definition: congen_data.f90:105
congen_projection::projec
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.
Definition: congen_projection.f90:1649
congen_data::nx
integer nx
Full or remaining workspace size (depending on context).
Definition: congen_data.f90:148
congen_data::nodimx
integer nodimx
Maximal number of workspace elements usable for CSF information.
Definition: congen_data.f90:132
congen_pagecontrol::addl
subroutine, public addl(lines)
Add blank lines to output.
Definition: congen_pagecontrol.f90:50
congen_data::ndimx
integer ndimx
Maximal number of workspace elements usable for packed determinant data.
Definition: congen_data.f90:130
congen_data::ndel1
integer ndel1
Workspace position used for reading CSFs from the input.
Definition: congen_data.f90:82
congen_data::jy
integer, parameter jy
Used to dimension various arrays in csfgen including NELECP and NSHLP. Limit on input variable NDPROD...
Definition: congen_data.f90:44
congen_data::cdimx
integer cdimx
Maximal number of determinants.
Definition: congen_data.f90:125
congen_data::nrcon
integer, dimension(jz) nrcon
Definition: congen_data.f90:116
congen_data::nndel
integer nndel
Number of workspace elements used for reservation of space needed when reading CSFs from input.
Definition: congen_data.f90:86
congen_data::nsoi
integer, dimension(nu) nsoi
Running index of the first spin-orbital within given total symmetry.
Definition: congen_data.f90:139