~ubuntu-branches/ubuntu/vivid/psicode/vivid

« back to all changes in this revision

Viewing changes to src/bin/cscf/diis.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
 
/* $Log$
2
 
 * Revision 1.2  2004/05/03 04:32:40  crawdad
3
 
 * Major mods based on merge with stable psi-3-2-1 release.  Note that this
4
 
 * version has not been fully tested and some scf-optn test cases do not run
5
 
 * correctly beccause of changes in mid-March 2004 to optking.
6
 
 * -TDC
7
 
 *
8
 
/* Revision 1.1.1.1.12.2  2004/04/21 15:45:07  evaleev
9
 
/* Modified DIIS algorithm for RHF and ROHF to work in OSO basis rather than in
10
 
/* AO basis, to avoid difficulties of transforming between MO and AO bases
11
 
/* when linear dependencies are present.
12
 
/*
13
 
/* Revision 1.1.1.1.12.1  2004/04/06 21:29:05  crawdad
14
 
/* Corrections to the RHF/ROHF DIIS algorithm, which was simply incorrect.
15
 
/* The backtransformation of the DIIS error vectors to the AO basis was not
16
 
/* mathematically right.
17
 
/* -TDC and EFV
18
 
/*
19
 
/* Revision 1.1.1.1  2000/02/04 22:52:29  evaleev
20
 
/* Started PSI 3 repository
21
 
/*
22
 
/* Revision 1.3  1999/11/02 23:55:55  localpsi
23
 
/* Shawn Brown - (11/2/99) Modified to the code in a few major ways.
24
 
/*
25
 
/* 1.  Added the capability to do UHF.  All of the features available with the
26
 
/* other refrences have been added for UHF.
27
 
/*
28
 
/* 2.  For UHF, I had to alter the structure of file30. (See cleanup.c for a
29
 
/* map)  This entailed adding a pointer array right after the header in the SCF
30
 
/* section of file30 that pointed to all of the data for the SCF caclulation.
31
 
/* Functions were added to libfile30 to account for this and they are
32
 
/* incorporated in this code.
33
 
/*
34
 
/* 3.  Updated and fixed all of the problems associated with my previous
35
 
/* guessing code.  The code no longer uses OPENTYPE to specify the type of
36
 
/* occupation.  The keword REFERENCE and MULTP can now be used to indicate any
37
 
/* type of calculation.  (e.g. ROHF with MULTP of 1 is an open shell singlet
38
 
/* ROHF calculation)  This code was moved to occ_fun.c.  The code can also
39
 
/* guess at any multplicity in a highspin case, provided enough electrons.
40
 
/*
41
 
/* Revision 1.2  1999/08/17 19:04:13  evaleev
42
 
/* Changed the default symmetric orthogonalization to the canonical
43
 
/* orthogonalization. Now, if near-linear dependencies in the basis are found,
44
 
/* eigenvectors of the overlap matrix with eigenvalues less than 1E-6 will be
45
 
/* left out. This will lead to num_mo != num_so, i.e. SCF eigenvector is no
46
 
/* longer a square matrix. Had to rework some routines in libfile30, and add some.
47
 
/* The progrem prints out a warning if near-linear dependencies are found. TRANSQT
48
 
/* and a whole bunch of other codes has to be fixed to work with such basis sets.
49
 
/*
50
 
/* Revision 1.1.1.1  1999/04/12 16:59:25  evaleev
51
 
/* Added a version of CSCF that can work with CINTS.
52
 
/* -Ed
53
 
 * */
54
 
 
55
 
static char *rcsid = "$Id: diis.c 2455 2004-05-03 04:32:41Z crawdad $";
56
 
 
57
 
#define EXTERN
58
 
#include "includes.h"
59
 
#include "common.h"
60
 
 
61
 
extern double delta;
62
 
 
63
 
static double *btemp, **bold, **bmat;
64
 
static struct diis_mats {
65
 
  double ***fock_c;       /* Closed-shell Fock matrix in AO basis */
66
 
  double ***fock_o;       /* Open-shell Fock matrix in AO basis */
67
 
  double ***error;        /* Error matrix in AO basis */
68
 
  } *diism,dtemp;
69
 
 
70
 
void diis(scr1,scr2,scr3,c1,c2,cim,newci)
71
 
   double cim;
72
 
   double **scr1, **scr2, **scr3,*c1,*c2;
73
 
   int newci;
74
 
{
75
 
  int i,j,k,ij;
76
 
  int errcod;
77
 
  int m,nn,num_mo;
78
 
  double occi, occj;
79
 
  int try = 0;
80
 
  int last = iter-1;
81
 
  int col = iter+1;
82
 
  double etemp, dotp, norm, determ, etempo;
83
 
  double scale;
84
 
  struct symm *s;
85
 
  struct diis_mats *d;
86
 
  int diis_print=0;
87
 
  double **C;  /* AO->MO transform = P^-1 * C */
88
 
  double **X, **S; /* scratch matrix */
89
 
  double **tmp1;
90
 
 
91
 
  if(diism == NULL) {
92
 
    bmat = (double **) block_matrix(ndiis+1,ndiis+1);
93
 
    bold = (double **) block_matrix(ndiis,ndiis);
94
 
    btemp = (double *) init_array(ndiis+1);
95
 
 
96
 
    diism = (struct diis_mats *) malloc(sizeof(struct diis_mats)*ndiis);
97
 
 
98
 
    for(i=0; i < ndiis ; i++) {
99
 
      diism[i].fock_c = (double ***) malloc(sizeof(double **)*num_ir);
100
 
      if(iopen) 
101
 
        diism[i].fock_o = (double ***) malloc(sizeof(double **)*num_ir);
102
 
      diism[i].error = (double ***) malloc(sizeof(double **)*num_ir);
103
 
      for(j=0; j < num_ir ; j++) {
104
 
        if(nn=scf_info[j].num_so) {
105
 
          num_mo = scf_info[j].num_mo;
106
 
          diism[i].fock_c[j] = (double **) block_matrix(nn,nn);
107
 
          if(iopen) diism[i].fock_o[j] = (double **) block_matrix(nn,nn);
108
 
          diism[i].error[j] = (double **) block_matrix(num_mo,num_mo);
109
 
        }
110
 
      }
111
 
    }
112
 
  }
113
 
 
114
 
  scale = 1.0 + dampsv;
115
 
 
116
 
  if (iter > ndiis) {
117
 
    last = ndiis-1;
118
 
    col = ndiis+1;
119
 
    dtemp = diism[0];
120
 
    for (i=0; i < last ; i++) {
121
 
      diism[i] = diism[i+1];
122
 
    }
123
 
    diism[last] = dtemp;
124
 
  }
125
 
      
126
 
  /* Debugging stuff */
127
 
   
128
 
  errcod = ip_boolean("DIIS_PRINT",&diis_print,0);
129
 
  if(iter == 1 && diis_print)
130
 
    ffile(&diis_out,"diis_out.dat",0);
131
 
   
132
 
  /* save ao fock matrices in fock_save */
133
 
   
134
 
  d = &diism[last];
135
 
  for (m=0; m < num_ir ; m++) {
136
 
    s = &scf_info[m];
137
 
    if(nn=s->num_so) {
138
 
      num_mo = s->num_mo;
139
 
      tri_to_sq(s->fock_pac,d->fock_c[m],nn);
140
 
      if(iopen) tri_to_sq(s->fock_open,d->fock_o[m],nn);
141
 
 
142
 
      /* form error matrix in mo basis */
143
 
      mmult(s->cmat,1,d->fock_c[m],0,scr1,0,num_mo,nn,nn,0);
144
 
      mmult(scr1,0,s->cmat,0,scr2,0,num_mo,nn,num_mo,0);
145
 
      if(iopen) {
146
 
        mmult(s->cmat,1,d->fock_o[m],0,scr1,0,num_mo,nn,nn,0);
147
 
        mmult(scr1,0,s->cmat,0,scr3,0,num_mo,nn,num_mo,0);
148
 
      }
149
 
 
150
 
      for (i=0; i < num_mo; i++) {
151
 
        occi = s->occ_num[i];
152
 
        for (j=0; j <= i ; j++ ) {
153
 
          occj = s->occ_num[j];
154
 
          if (!iopen) {
155
 
            if (occi == 0.0 && occj != 0.0 ) {
156
 
              scr1[i][j]= scr2[i][j];
157
 
              scr1[j][i]= scr2[i][j];
158
 
            }
159
 
            else {
160
 
              scr1[i][j]=scr1[j][i]=0.0;
161
 
            }
162
 
          }
163
 
          else if(!twocon) {
164
 
            if ((occi == 1.0 || occi == 0.5) && occj == 2.0 )
165
 
              etemp = scr2[i][j]-0.5*scr3[i][j];
166
 
            else if(occi == 0.0) {
167
 
              if (occj == 2.0) etemp = scr2[i][j];
168
 
              else if (occj != 0.0) etemp = 0.5*scr3[i][j];
169
 
              else etemp = 0.0;
170
 
            }
171
 
            else etemp = 0.0;
172
 
            scr1[i][j] = scr1[j][i] = etemp;
173
 
          }
174
 
          else {
175
 
            if (occi != 2.0 && occi != 0.0 && occj == 2.0 )
176
 
              etemp = cim*(c1[m]*scr2[i][j]-c2[m]*scr3[i][j]);
177
 
            else if(occi == 0.0) {
178
 
              if (occj == 2.0) etemp = scr2[i][j];
179
 
              else if (occj != 0.0) etemp = cim*scr3[i][j];
180
 
              else etemp = 0.0;
181
 
            }
182
 
            else etemp = 0.0;
183
 
            scr1[i][j] = scr1[j][i] = etemp;
184
 
          }
185
 
        }
186
 
      }
187
 
 
188
 
      /* transform the error matrix into the OSO basis */
189
 
      X = block_matrix(num_mo, num_mo);
190
 
      C_DGEMM('n', 'n', num_mo, num_mo, num_mo, 1.0, s->ucmat[0], num_mo, scr1[0], nsfmax, 0.0, X[0], num_mo);
191
 
      C_DGEMM('n', 't', num_mo, num_mo, num_mo, 1.0, X[0], num_mo, s->ucmat[0], num_mo, 0.0, d->error[m][0], num_mo);
192
 
      free_block(X);
193
 
 
194
 
      for(i=0; i < num_mo ; i++) {
195
 
        for(j=0; j <= i ; j++) {
196
 
          etemp=fabs(scr1[i][j]);
197
 
          diiser = MAX0(diiser,etemp);
198
 
        }
199
 
      }
200
 
    }
201
 
  }
202
 
               
203
 
  /* then set up b matrix */
204
 
 
205
 
  if (iter > ndiis) {
206
 
    for (i=0; i < last ; i++) {
207
 
      for (j=0; j <= i ; j++) {
208
 
        bold[i][j]=bold[j][i]=bold[i+1][j+1];
209
 
      }
210
 
    }
211
 
  }
212
 
  for (i=0; i <= last ; i++) {
213
 
    etemp=0.0;
214
 
    for (m=0; m < num_ir ; m++) {
215
 
      s = &scf_info[m];
216
 
      if(nn=s->num_so) {
217
 
        num_mo = s->num_mo;
218
 
        sdot(diism[i].error[m],diism[last].error[m],num_mo,&dotp);
219
 
        etemp += dotp;
220
 
      }
221
 
    }
222
 
    bold[i][last]=bold[last][i] = etemp;
223
 
  }
224
 
 
225
 
  bmat[0][0] = 0.0;
226
 
  btemp[0] = -1.0;
227
 
  norm = 1.0/bold[0][0];
228
 
  for (i=1; i <= last+1 ; i++) {
229
 
    bmat[i][0]=bmat[0][i] = -1.0;
230
 
    btemp[i] = 0.0;
231
 
    for (j=1; j <= i ; j++) {
232
 
      bmat[i][j]=bmat[j][i] = bold[i-1][j-1]*norm;
233
 
      if(i==j) bmat[i][j] *= scale;
234
 
    }
235
 
  }
236
 
   
237
 
  if(diis_print){
238
 
    fprintf(diis_out,"\nBMAT for iter %d",iter);
239
 
    print_mat(bmat,col,col,diis_out);
240
 
  }
241
 
        
242
 
  if (iter-1) {
243
 
    flin(bmat,btemp,col,1,&determ);
244
 
 
245
 
    /* test for poorly conditioned equations */
246
 
    while (fabs(determ) < 1.0e-19 && try < last) {
247
 
 
248
 
      try++;
249
 
      col--;
250
 
 
251
 
      bmat[0][0] = 0.0;
252
 
      btemp[0] = -1.0;
253
 
      norm=1.0/bold[try][try];
254
 
      for (i=1; i <= ndiis-try ; i++) {
255
 
        bmat[i][0]=bmat[0][i] = -1.0;
256
 
        for (j=1; j <= i ; j++) {
257
 
          bmat[i][j]=bmat[j][i]=bold[i+try-1][j+try-1]*norm;
258
 
          if(i==j) bmat[i][j] *= scale;
259
 
        }
260
 
        btemp[i] = 0.0;
261
 
      }
262
 
         
263
 
      if(diis_print){
264
 
        fprintf(diis_out,"\nCorrected BMAT for iter %d",iter);
265
 
        print_mat(bmat,col,col,diis_out);
266
 
      }
267
 
         
268
 
      flin(bmat,btemp,col,1,&determ);
269
 
    }
270
 
      
271
 
    if(fabs(determ) < 10.0e-20) {
272
 
      printf(" try %d no good\n",try);
273
 
      return;
274
 
    }
275
 
      
276
 
    if(iter >= it_diis) {
277
 
      for (m=0; m < num_ir ; m++) {
278
 
        s = &scf_info[m];
279
 
        if(nn=s->num_so) {
280
 
          for (i=ij=0; i < nn ; i++) {
281
 
            for (j=0; j <= i ; j++,ij++) {
282
 
              int kk=1;
283
 
              etemp=0.0;
284
 
              etempo=0.0;
285
 
              for (k=try; k < last+1 ; k++) {
286
 
                if(iopen) etempo += btemp[kk]*diism[k].fock_o[m][i][j];
287
 
                etemp += btemp[kk]*diism[k].fock_c[m][i][j];
288
 
                kk++;
289
 
              }
290
 
              if(iopen) s->fock_open[ij] = etempo;
291
 
              s->fock_pac[ij] = etemp;
292
 
            }
293
 
          }
294
 
        }
295
 
      }
296
 
    }
297
 
  }
298
 
}
299
 
 
300