~ubuntu-branches/ubuntu/karmic/psicode/karmic

« back to all changes in this revision

Viewing changes to src/bin/detci/ints.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Banck, Michael Banck, Daniel Leidert
  • Date: 2009-02-23 00:12:02 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090223001202-rutldoy3dimfpesc
Tags: 3.4.0-1
* New upstream release.

[ Michael Banck ]
* debian/patches/01_DESTDIR.dpatch: Refreshed.
* debian/patches/02_FHS.dpatch: Removed, applied upstream.
* debian/patches/03_debian_docdir: Likewise.
* debian/patches/04_man.dpatch: Likewise.
* debian/patches/06_466828_fix_gcc_43_ftbfs.dpatch: Likewise.
* debian/patches/07_464867_move_executables: Fixed and refreshed.
* debian/patches/00list: Adjusted.
* debian/control: Improved description.
* debian/patches-held: Removed.
* debian/rules (install/psi3): Do not ship the ruby bindings for now.

[ Daniel Leidert ]
* debian/rules: Fix txtdir via DEB_MAKE_INSTALL_TARGET.
* debian/patches/01_DESTDIR.dpatch: Refreshed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
** INTS.C
3
 
**
4
 
** Return values of one and two-electron integrals
5
 
**
6
 
** C. David Sherrill
7
 
** Center for Computational Quantum Chemistry
8
 
** University of Georgia
9
 
**
10
 
** Updated 3/18/95 to exclude frozen virtual orbitals.
11
 
** Updated 3/28/95 to exclude frozen core orbitals.
12
 
*/
13
 
 
14
 
#include <stdio.h>
15
 
#include <stdlib.h>
16
 
#include <libiwl/iwl.h>
17
 
#include <libciomr/libciomr.h>
18
 
#include <libqt/qt.h>
19
 
#include <psifiles.h>
20
 
#include "structs.h"
21
 
#define EXTERN
22
 
#include "globals.h"
23
 
 
24
 
#define MIN0(a,b) (((a)<(b)) ? (a) : (b))
25
 
#define MAX0(a,b) (((a)>(b)) ? (a) : (b))
26
 
 
27
 
 
28
 
void read_integrals()
29
 
{
30
 
   int i, j, ij, k, l, kl, ijkl, ijij;
31
 
   int nmotri, nmotri_full;
32
 
   double value;
33
 
   extern void check_energy(double *H, double *twoel_ints, int *docc, 
34
 
      int *frozen_docc, int fzc_flag, double escf, double enuc, double efzc, 
35
 
      int nirreps, int *reorder, int *opi, FILE *outfile);
36
 
   int junk;
37
 
   double *tmp_onel_ints;
38
 
 
39
 
   /* allocate memory for one and two electron integrals */
40
 
   nmotri_full = (CalcInfo.nmo * (CalcInfo.nmo + 1)) / 2;
41
 
   nmotri = (CalcInfo.num_ci_orbs * (CalcInfo.num_ci_orbs + 1)) / 2 ;
42
 
   CalcInfo.onel_ints = (double *) init_array(nmotri) ;
43
 
   CalcInfo.twoel_ints = (double *) init_array(nmotri * (nmotri + 1) / 2);
44
 
   CalcInfo.maxK = (double *) init_array(CalcInfo.num_ci_orbs);  
45
 
 
46
 
   /* replace old iwl_rdone call with the new one which filters 
47
 
    * note we must always filter the one-elec ints in the new scheme, 
48
 
    * although the two-elec ints only need filtering for first derivs
49
 
    * or for MCSCF 
50
 
    */
51
 
 
52
 
   /* iwl_rdone(Parameters.oei_file, nmotri, CalcInfo.onel_ints, 
53
 
                &(CalcInfo.efzc), Parameters.oei_erase); */
54
 
 
55
 
   tmp_onel_ints = init_array(nmotri_full);
56
 
   iwl_rdone(Parameters.oei_file, PSIF_MO_FZC, tmp_onel_ints, nmotri_full,
57
 
             Parameters.oei_erase, (Parameters.print_lvl>4), outfile);
58
 
   filter(tmp_onel_ints, CalcInfo.onel_ints, ioff, CalcInfo.nmo, 
59
 
          CalcInfo.num_fzc_orbs, CalcInfo.num_fzv_orbs);
60
 
   free(tmp_onel_ints);
61
 
 
62
 
   iwl_rdtwo(Parameters.tei_file, CalcInfo.twoel_ints, ioff, CalcInfo.nmo, 
63
 
             Parameters.filter_ints ? CalcInfo.num_fzc_orbs : 0, 
64
 
             Parameters.filter_ints ? CalcInfo.num_fzv_orbs : 0, 
65
 
             (Parameters.print_lvl>4), outfile);
66
 
 
67
 
   /* Determine maximum K integral for use in averaging the diagonal */
68
 
   /* Hamiltonian matrix elements over spin-coupling set */
69
 
   if (Parameters.hd_ave) {
70
 
     for(i=0; i<CalcInfo.num_ci_orbs; i++) 
71
 
        for(j=0; j<CalcInfo.num_ci_orbs; j++) {
72
 
           /* if (i==j) continue; */
73
 
           ij = ioff[MAX0(i,j)] + MIN0(i,j);
74
 
           ijij = ioff[ij] + ij;
75
 
           value = CalcInfo.twoel_ints[ijij];
76
 
           if(value > CalcInfo.maxK[i]) CalcInfo.maxK[i] = value;
77
 
           }
78
 
      for(i=0; i<CalcInfo.num_ci_orbs; i++) {
79
 
        if(CalcInfo.maxK[i] > CalcInfo.maxKlist)
80
 
          CalcInfo.maxKlist = CalcInfo.maxK[i];
81
 
        if (Parameters.print_lvl > 4)
82
 
          fprintf(outfile,"maxK[%d] = %lf\n",i, CalcInfo.maxK[i]);
83
 
        } 
84
 
      }
85
 
 
86
 
   if (Parameters.print_lvl > 4) {
87
 
      fprintf(outfile, "\nOne-electron integrals\n") ;
88
 
      for (i=0, ij=0; i<CalcInfo.num_ci_orbs; i++) {
89
 
         for (j=0; j<=i; j++, ij++) {
90
 
            fprintf(outfile, "h(%d)(%d) = %11.7lf\n", i, j, 
91
 
               CalcInfo.onel_ints[ij]) ;
92
 
            }
93
 
         }
94
 
      fprintf(outfile, "\n") ;
95
 
      }
96
 
 
97
 
   if (Parameters.print_lvl > 4) {
98
 
      fprintf(outfile, "\nmaxKlist = %lf\n",CalcInfo.maxKlist);
99
 
      fprintf(outfile, "\nTwo-electron integrals\n");
100
 
      for (i=0; i<CalcInfo.num_ci_orbs; i++) {
101
 
         for (j=0; j<=i; j++) {
102
 
            ij = ioff[MAX0(i,j)] + MIN0(i,j) ;
103
 
            for (k=0; k<=i; k++) {
104
 
               for (l=0; l<=k; l++) {
105
 
                  kl = ioff[MAX0(k,l)] + MIN0(k,l) ;
106
 
                  ijkl = ioff[MAX0(ij,kl)] + MIN0(ij,kl) ;
107
 
                  fprintf(outfile, "%2d %2d %2d %2d (%4d) = %10.6lf\n",
108
 
                     i, j, k, l, ijkl, CalcInfo.twoel_ints[ijkl]);
109
 
                  } 
110
 
               }
111
 
            }
112
 
         }
113
 
      }
114
 
 
115
 
   if (Parameters.print_lvl) {
116
 
      check_energy(CalcInfo.onel_ints, CalcInfo.twoel_ints, CalcInfo.docc, 
117
 
         CalcInfo.frozen_docc, Parameters.fzc, CalcInfo.escf, CalcInfo.enuc, 
118
 
         CalcInfo.efzc, CalcInfo.nirreps, CalcInfo.reorder, 
119
 
         CalcInfo.orbs_per_irr, outfile);
120
 
      }
121
 
 
122
 
123
 
 
124
 
 
125
 
 
126
 
double get_onel(int i, int j)
127
 
{
128
 
   int ij ;
129
 
   double value ;
130
 
 
131
 
   if (i > j) {
132
 
      ij = ioff[i] + j;
133
 
      value = CalcInfo.onel_ints[ij] ;
134
 
      return(value) ;
135
 
      }
136
 
   else {
137
 
      ij = ioff[j] + i ;
138
 
      value = CalcInfo.onel_ints[ij] ;
139
 
      return(value) ;
140
 
      }
141
 
   return(CalcInfo.onel_ints[ij]) ;
142
 
}
143
 
 
144
 
 
145
 
double get_twoel(int i, int j, int k, int l)
146
 
{
147
 
   int ij, kl, ijkl ;
148
 
 
149
 
   ij = ioff[MAX0(i,j)] ;
150
 
   ij += MIN0(i,j) ;
151
 
   kl = ioff[MAX0(k,l)] ;
152
 
   kl += MIN0(k,l) ;
153
 
   ijkl = ioff[MAX0(ij,kl)] ;
154
 
   ijkl += MIN0(ij,kl) ;
155
 
 
156
 
 
157
 
   return(CalcInfo.twoel_ints[ijkl]) ;
158
 
}
159
 
 
160
 
 
161
 
 
162
 
/*
163
 
** tf_onel_ints(): Function lumps together one-electron contributions
164
 
**    so that h'_{ij} = h_{ij} - 1/2 SUM_k (ik|kj)
165
 
**    The term h' arises in the calculation of sigma1 and sigma2 via
166
 
**    equation (20) of Olsen, Roos, et. al. JCP 1988
167
 
**
168
 
*/
169
 
void tf_onel_ints(int printflag, FILE *outfile)
170
 
{
171
 
   int i, j, k, ij, ik, kj, ikkj ;
172
 
   int nbf ;
173
 
   double *tei, *teptr ;
174
 
   double tval ;
175
 
   int ntri;
176
 
 
177
 
   /* set up some shorthand notation (speed up access) */
178
 
   nbf = CalcInfo.num_ci_orbs ;
179
 
   tei = CalcInfo.twoel_ints ;
180
 
   ntri = (nbf * (nbf + 1)) / 2;
181
 
 
182
 
   /* ok, new special thing for CASSCF...if there are *no* excitations
183
 
      into restricted orbitals, and if Parameters.fci=TRUE, then we
184
 
      do *not* want to sum over the restricted virts in h' or else
185
 
      we would need to account for RAS-out-of-space contributions
186
 
      (requiring fci=false).
187
 
    */
188
 
   if (Parameters.fci && (nbf > Parameters.ras3_lvl) && 
189
 
       Parameters.ras34_max == 0)
190
 
      nbf = Parameters.ras3_lvl;
191
 
 
192
 
   /* allocate space for the new array */
193
 
   CalcInfo.tf_onel_ints = init_array(ntri) ;
194
 
 
195
 
   /* fill up the new array */
196
 
   for (i=0,ij=0; i<nbf; i++)
197
 
      for (j=0; j<=i; j++) {
198
 
         tval = CalcInfo.onel_ints[ij] ;
199
 
 
200
 
         for (k=0; k<nbf; k++) {
201
 
            ik = ioff[MAX0(i,k)] + MIN0(i,k) ;
202
 
            kj = ioff[MAX0(k,j)] + MIN0(k,j) ;
203
 
            ikkj = ioff[ik] + kj ;
204
 
            teptr = tei + ikkj ;
205
 
            tval -= 0.5 * (*teptr) ;
206
 
            } 
207
 
 
208
 
         CalcInfo.tf_onel_ints[ij++] = tval ;
209
 
         }
210
 
   /* print if necessary */
211
 
   if (printflag) {
212
 
      fprintf(outfile, "\nh' matrix\n") ;
213
 
      print_array(CalcInfo.tf_onel_ints, nbf, outfile) ;
214
 
      fprintf(outfile, "\n") ;
215
 
      }
216
 
}
217
 
 
218
 
 
219
 
 
220
 
/*
221
 
** form_gmat(): Form the g matrix necessary for restriction to the RAS
222
 
**    subspaces (i.e. to eliminate contributions of out-of-space terms).
223
 
**    See equations (28-29) in Olsen, Roos, et. al. JCP 1988
224
 
**
225
 
*/
226
 
void form_gmat(int printflag, FILE *outfile)
227
 
{
228
 
   int nbf ;
229
 
   double *tei, *oei ;
230
 
   double tval ;
231
 
   int i, j, k, ij, ii, ik, kj, ikkj, iiij ;
232
 
 
233
 
 
234
 
   /* set up some shorthand notation (speed up access) */
235
 
   nbf = CalcInfo.num_ci_orbs ;
236
 
   oei = CalcInfo.onel_ints ;
237
 
   tei = CalcInfo.twoel_ints ;
238
 
 
239
 
   /* allocate space for the new array */
240
 
   /* CalcInfo.gmat = init_matrix(nbf, nbf) ; */
241
 
   /* why not use init_blockmatix here? */
242
 
   CalcInfo.gmat = (double **) malloc (nbf * sizeof(double *));
243
 
   CalcInfo.gmat[0] = (double *) malloc (nbf * nbf * sizeof(double));
244
 
   for (i=1; i<nbf; i++) {
245
 
      CalcInfo.gmat[i] = CalcInfo.gmat[i-1] + nbf;
246
 
      }
247
 
 
248
 
   /* fill up the new array */
249
 
   for (i=0; i<nbf; i++) {
250
 
      for (j=i+1; j<nbf; j++) {
251
 
         ij = ioff[j] + i ;
252
 
         tval = oei[ij] ;
253
 
         for (k=0; k<i; k++) {
254
 
            ik = ioff[i] + k ;
255
 
            kj = ioff[j] + k ;
256
 
            ikkj = ioff[kj] + ik ;
257
 
            tval -= tei[ikkj] ;
258
 
            }
259
 
         CalcInfo.gmat[i][j] = tval ;
260
 
         }
261
 
      } 
262
 
 
263
 
   for (i=0, ij=0; i<nbf; i++) {
264
 
      for (j=0; j<=i; j++,ij++) {
265
 
         tval = oei[ij] ;
266
 
         for (k=0; k<i; k++) {
267
 
            ik = ioff[i] + k ;
268
 
            kj = ioff[MAX0(k,j)] + MIN0(k,j) ;
269
 
            ikkj = ioff[ik] + kj ;
270
 
            tval -= tei[ikkj] ;
271
 
            }
272
 
         ii = ioff[i] + i ;
273
 
         iiij = ioff[ii] + ij ;
274
 
         if (i==j) tval -= 0.5 * tei[iiij] ;
275
 
         else tval -= tei[iiij] ;
276
 
         CalcInfo.gmat[i][j] = tval ;
277
 
         }
278
 
      }
279
 
 
280
 
   if (printflag) {
281
 
      fprintf(outfile, "\ng matrix\n") ;
282
 
      print_mat(CalcInfo.gmat, nbf, nbf, outfile) ;
283
 
      fprintf(outfile, "\n") ;
284
 
      }
285
 
}
286