~ubuntu-branches/ubuntu/quantal/psicode/quantal

« back to all changes in this revision

Viewing changes to src/bin/mvo/mvo.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Banck
  • Date: 2006-09-10 14:01:33 UTC
  • Revision ID: james.westby@ubuntu.com-20060910140133-ib2j86trekykfsfv
Tags: upstream-3.2.3
ImportĀ upstreamĀ versionĀ 3.2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
** MVO
 
3
**
 
4
** This program reads the frozen core operator from TRANSQT 
 
5
** output ** and diagonalizes the virtual-virtual block to make 
 
6
** Modified Virtual Orbitals (MVO's) as described in 
 
7
** C. W. Bauschlicher, J. Chem. Phys. 72, 880 (1980)
 
8
**
 
9
** C. David Sherrill
 
10
** Georgia Institute of Technology
 
11
** March 9, 2001
 
12
*/
 
13
 
 
14
#include <stdio.h>
 
15
#include <stdlib.h>
 
16
#include <math.h>
 
17
#include <string.h>
 
18
#include <libipv1/ip_lib.h>
 
19
#include <libpsio/psio.h>
 
20
#include <libciomr/libciomr.h>
 
21
#include <libchkpt/chkpt.h>
 
22
#include <libqt/qt.h>
 
23
#include <psifiles.h>
 
24
#include <libiwl/iwl.h>
 
25
#include "MOInfo.h"
 
26
#include "params.h"
 
27
#include "globals.h"
 
28
 
 
29
 
 
30
/* First definitions of globals */
 
31
FILE *infile, *outfile;
 
32
char *psi_file_prefix;
 
33
int *ioff;
 
34
struct MOInfo moinfo;
 
35
struct Params params;
 
36
 
 
37
/* Max length of ioff array */
 
38
#define IOFF_MAX 32641
 
39
 
 
40
 
 
41
#define MIN0(a,b) (((a)<(b)) ? (a) : (b))
 
42
#define MAX0(a,b) (((a)>(b)) ? (a) : (b))
 
43
#define INDEX(i,j) ((i>j) ? (ioff[(i)]+(j)) : (ioff[(j)]+(i)))
 
44
 
 
45
 
 
46
/* Function prototypes */
 
47
void init_io(int argc, char *argv[]);
 
48
void title();
 
49
void init_ioff();
 
50
void get_parameters();
 
51
void print_parameters();
 
52
void get_moinfo();
 
53
void cleanup();
 
54
void exit_io();
 
55
void get_reorder_array(void);
 
56
void get_fzc_operator(void);
 
57
void get_mvos(void);
 
58
void get_canonical(void);
 
59
void get_mp2nos(void);
 
60
 
 
61
main(int argc, char *argv[])
 
62
{
 
63
  params.print_lvl = 1;
 
64
  init_io(argc, argv);
 
65
  title();
 
66
  get_parameters();
 
67
  get_moinfo();
 
68
  print_parameters();
 
69
  get_reorder_array();
 
70
  init_ioff();
 
71
  if (params.mp2nos) {
 
72
    get_mp2nos();
 
73
  }
 
74
  else if (params.canonical) {
 
75
    get_canonical();
 
76
  }
 
77
  else {
 
78
    get_fzc_operator();
 
79
    get_mvos();
 
80
  }
 
81
  cleanup();
 
82
  exit_io();
 
83
  exit(0);
 
84
}
 
85
 
 
86
void init_io(int argc, char *argv[])
 
87
{
 
88
  int i;
 
89
  int num_extra_args = 0;
 
90
  char **extra_args;
 
91
 
 
92
  extra_args = (char **) malloc(argc*sizeof(char *));
 
93
 
 
94
   for (i=1; i<argc; i++) {
 
95
     if (strcmp(argv[i], "--quiet") == 0) {
 
96
       params.print_lvl = 0;
 
97
     }
 
98
     else {
 
99
       extra_args[num_extra_args++] = argv[i];
 
100
     }
 
101
   }
 
102
 
 
103
  psi_start(num_extra_args,extra_args,0); 
 
104
  if (params.print_lvl) tstart(outfile);
 
105
  ip_cwk_add(":MVO");
 
106
 
 
107
  psio_init();
 
108
  free(extra_args);
 
109
}
 
110
 
 
111
 
 
112
void title(void)
 
113
{
 
114
  if (params.print_lvl) {
 
115
    fprintf(outfile, "\n");
 
116
    fprintf(outfile,"\t**************************************************\n");
 
117
    fprintf(outfile,"\t*     MVO: Obtain Modified Virtual Orbitals      *\n");
 
118
    fprintf(outfile,"\t*                                                *\n");
 
119
    fprintf(outfile,"\t*               C. David Sherrill                *\n");
 
120
    fprintf(outfile,"\t*                  March  2001                   *\n");
 
121
    fprintf(outfile,"\t**************************************************\n");
 
122
    fprintf(outfile, "\n");
 
123
    }
 
124
}
 
125
 
 
126
void init_ioff(void)
 
127
{
 
128
  int i;
 
129
  ioff = (int *) malloc(IOFF_MAX * sizeof(int));
 
130
  if(ioff == NULL) {
 
131
      fprintf(stderr, "(transqt): error malloc'ing ioff array\n");
 
132
      exit(0);
 
133
          }
 
134
  ioff[0] = 0;
 
135
  for(i=1; i < IOFF_MAX; i++) {
 
136
      ioff[i] = ioff[i-1] + i;
 
137
    }
 
138
}
 
139
 
 
140
void exit_io(void)
 
141
{
 
142
  psio_done();
 
143
  if (params.print_lvl) tstop(outfile);
 
144
  psi_stop();
 
145
}
 
146
 
 
147
 
 
148
void get_parameters(void)
 
149
{
 
150
  int errcod;
 
151
 
 
152
  errcod = ip_string("WFN", &(params.wfn),0);
 
153
  if(errcod == IPE_KEY_NOT_FOUND) {
 
154
    params.wfn = (char *) malloc(sizeof(char)*5);
 
155
    strcpy(params.wfn, "CCSD");
 
156
  }
 
157
 
 
158
  params.h_fzc_file = PSIF_OEI;
 
159
  errcod = ip_data("FZC_FILE","%d",&(params.h_fzc_file),0);
 
160
 
 
161
  params.print_mos = 0;
 
162
  errcod = ip_boolean("PRINT_MOS", &(params.print_mos),0);
 
163
 
 
164
  params.print_lvl = 1;
 
165
  errcod = ip_data("PRINT", "%d", &(params.print_lvl),0);
 
166
 
 
167
  params.oei_erase = 0;
 
168
  errcod = ip_boolean("OEI_ERASE",&(params.oei_erase),0); 
 
169
 
 
170
  params.fzc = 1;
 
171
  errcod = ip_boolean("FZC",&(params.fzc),0);
 
172
 
 
173
  params.mp2nos = 0;
 
174
  errcod = ip_boolean("MP2NOS",&(params.mp2nos),0);
 
175
 
 
176
  if (strcmp(params.wfn, "CI")==0 || strcmp(params.wfn, "DETCAS")==0 ||
 
177
      strcmp(params.wfn, "DETCI")==0) {
 
178
    params.ras_type = 1;
 
179
    }
 
180
  else {
 
181
    params.ras_type = 0;
 
182
    }
 
183
 
 
184
  params.fzc_fock_coeff = 1.0;
 
185
  errcod = ip_data("FZC_FOCK_COEFF", "%lf", &(params.fzc_fock_coeff),0);
 
186
 
 
187
  params.fock_coeff = 0.0;
 
188
  errcod = ip_data("FOCK_COEFF", "%lf", &(params.fock_coeff),0);
 
189
 
 
190
  params.ivo = 0;
 
191
  errcod = ip_boolean("IVO", &(params.ivo), 0);
 
192
 
 
193
  params.canonical = 0;
 
194
  errcod = ip_boolean("CANONICAL", &(params.canonical), 0);
 
195
  return;
 
196
 
 
197
}
 
198
 
 
199
 
 
200
void print_parameters(void)
 
201
{
 
202
 
 
203
  if (params.print_lvl) {
 
204
      fprintf(outfile,"\tInput Parameters:\n");
 
205
      fprintf(outfile,"\t-----------------\n");
 
206
      fprintf(outfile,"\tWavefunction           =  %s\n", params.wfn);
 
207
      fprintf(outfile,"\tPrint MOs              =  %s\n", 
 
208
                                  (params.print_mos ? "Yes": "No"));
 
209
      fprintf(outfile,"\tErase OEI file         =  %s\n", 
 
210
                                  (params.oei_erase ? "Yes": "No"));
 
211
      fprintf(outfile,"\tFrozen core            =  %s\n", 
 
212
                                  (params.fzc ? "Yes": "No"));
 
213
      fprintf(outfile,"\tIVO                    =  %s\n", 
 
214
                                  (params.ivo ? "Yes": "No"));
 
215
      fprintf(outfile,"\tCanonical              =  %s\n",
 
216
                                  (params.canonical ? "Yes": "No"));
 
217
      fprintf(outfile,"\tFrozen Core OEI file   =  %d\n", 
 
218
                                  params.h_fzc_file);
 
219
      fprintf(outfile,"\tfzc_fock_coeff         =  %lf\n", 
 
220
                                  params.fzc_fock_coeff);
 
221
      fprintf(outfile,"\tfock_coeff             =  %lf\n", 
 
222
                                  params.fock_coeff);
 
223
      fprintf(outfile,"\tPrint Level            =  %d\n", params.print_lvl);
 
224
      fflush(outfile);
 
225
    }
 
226
  
 
227
  return;
 
228
}
 
229
 
 
230
void get_fzc_operator(void)
 
231
{
 
232
 
 
233
  moinfo.fzc_operator = (double *) init_array(moinfo.fzc_op_size);
 
234
  /*
 
235
  iwl_rdone(params.h_fzc_file, moinfo.fzc_operator, &(moinfo.efzc),
 
236
            ioff, moinfo.nmo, 0, 0, params.oei_erase,
 
237
            (params.print_lvl>4), outfile);
 
238
  */
 
239
  iwl_rdone(params.h_fzc_file, PSIF_MO_FZC, moinfo.fzc_operator, 
 
240
            moinfo.fzc_op_size, params.oei_erase,
 
241
            (params.print_lvl>4), outfile);
 
242
  
 
243
}
 
244
 
 
245
 
 
246
 
 
247
void get_moinfo(void)
 
248
{
 
249
  int i,j,k,h,errcod,size,row,col,p,q,offset,first_offset,last_offset,warned;
 
250
  int *tmpi, nopen;
 
251
  double **tmpmat, **so2ao;
 
252
  double N; /* number of valence electrons */
 
253
 
 
254
  chkpt_init(PSIO_OPEN_OLD);
 
255
  moinfo.nmo = chkpt_rd_nmo();
 
256
  moinfo.nso = chkpt_rd_nso();
 
257
  moinfo.nao = chkpt_rd_nao();
 
258
  moinfo.nirreps = chkpt_rd_nirreps();
 
259
  moinfo.iopen = chkpt_rd_iopen();
 
260
  moinfo.labels = chkpt_rd_irr_labs();
 
261
  moinfo.sopi   = chkpt_rd_sopi();
 
262
  moinfo.orbspi = chkpt_rd_orbspi();
 
263
  moinfo.clsdpi = chkpt_rd_clsdpi();
 
264
  moinfo.openpi = chkpt_rd_openpi();
 
265
 
 
266
  moinfo.fzc_op_size = (moinfo.nmo * (moinfo.nmo + 1)) / 2;
 
267
 
 
268
  moinfo.sosym = init_int_array(moinfo.nso);
 
269
  for (i=0,k=0; i<moinfo.nirreps; i++) {
 
270
      for (j=0; j<moinfo.sopi[i]; j++,k++) {
 
271
          moinfo.sosym[k] = i;
 
272
        }
 
273
    }
 
274
  
 
275
  moinfo.orbsym = init_int_array(moinfo.nmo);
 
276
  for (i=0,k=0; i<moinfo.nirreps; i++) {
 
277
      for (j=0; j<moinfo.orbspi[i]; j++,k++) {
 
278
          moinfo.orbsym[k] = i;
 
279
        }
 
280
    }
 
281
 
 
282
  moinfo.frdocc = init_int_array(moinfo.nirreps);
 
283
  moinfo.fruocc = init_int_array(moinfo.nirreps);
 
284
  errcod = ip_int_array("FROZEN_DOCC", moinfo.frdocc, moinfo.nirreps);
 
285
  errcod = ip_int_array("FROZEN_UOCC", moinfo.fruocc, moinfo.nirreps);
 
286
 
 
287
  if (!params.fzc) {
 
288
      for (i=0; i<moinfo.nirreps; i++) {
 
289
          moinfo.frdocc[i] = 0;
 
290
        }
 
291
    }
 
292
 
 
293
  moinfo.nfzc = 0;
 
294
  moinfo.nfzv = 0;
 
295
  for (i=0; i<moinfo.nirreps; i++) {
 
296
      moinfo.nfzc += moinfo.frdocc[i];
 
297
      moinfo.nfzv += moinfo.fruocc[i];
 
298
    }
 
299
 
 
300
  moinfo.ndocc = 0;
 
301
  tmpi = init_int_array(moinfo.nirreps);
 
302
  errcod = ip_int_array("DOCC", tmpi, moinfo.nirreps);
 
303
  if (errcod == IPE_OK) {
 
304
      for (i=0,warned=0; i<moinfo.nirreps; i++) {
 
305
          if (tmpi[i] != moinfo.clsdpi[i] && !warned) {
 
306
              fprintf(outfile, "\tWarning: DOCC doesn't match PSIF_CHKPT\n");
 
307
              warned = 1;
 
308
            }
 
309
          moinfo.clsdpi[i] = tmpi[i];
 
310
          moinfo.ndocc += tmpi[i];
 
311
        }
 
312
    }
 
313
  else {
 
314
    for (i=0; i<moinfo.nirreps; i++) {
 
315
      moinfo.ndocc += moinfo.clsdpi[i];
 
316
    }
 
317
  }
 
318
 
 
319
  moinfo.nsocc = 0;
 
320
  errcod = ip_int_array("SOCC", tmpi, moinfo.nirreps);
 
321
  if (errcod == IPE_OK) {
 
322
      for (i=0,warned=0; i<moinfo.nirreps; i++) {
 
323
          if (tmpi[i] != moinfo.openpi[i] && !warned) {
 
324
              fprintf(outfile, "\tWarning: SOCC doesn't match PSIF_CHKPT\n");
 
325
              warned = 1;
 
326
            }
 
327
          moinfo.openpi[i] = tmpi[i];
 
328
          moinfo.nsocc += tmpi[i];
 
329
        }
 
330
    }
 
331
 
 
332
  moinfo.virtpi = init_int_array(moinfo.nirreps);
 
333
  for(i=0; i < moinfo.nirreps; i++) {
 
334
      moinfo.virtpi[i] = moinfo.orbspi[i]-moinfo.clsdpi[i]-moinfo.openpi[i];
 
335
    }
 
336
 
 
337
  if (params.print_lvl) {
 
338
      fprintf(outfile,"\n\tCheckpoint file parameters:\n");
 
339
      fprintf(outfile,"\t------------------\n");
 
340
      fprintf(outfile,"\tNumber of irreps = %d\n",moinfo.nirreps);
 
341
      fprintf(outfile,"\tNumber of SOs    = %d\n",moinfo.nso);
 
342
      fprintf(outfile,"\tNumber of MOs    = %d\n\n",moinfo.nmo);
 
343
      fprintf(outfile,
 
344
          "\tLabel\t# SOs\t# MOs\t# FZDC\t# DOCC\t# SOCC\t# VIRT\t# FZVR\n");
 
345
      fprintf(outfile,
 
346
          "\t-----\t-----\t-----\t------\t------\t------\t------\t------\n");
 
347
      for(i=0; i < moinfo.nirreps; i++) {
 
348
          fprintf(outfile,
 
349
             "\t %s\t   %d\t   %d\t    %d\t    %d\t    %d\t    %d\t    %d\n",
 
350
             moinfo.labels[i],moinfo.sopi[i],moinfo.orbspi[i],moinfo.frdocc[i],
 
351
             moinfo.clsdpi[i],moinfo.openpi[i],moinfo.virtpi[i],
 
352
             moinfo.fruocc[i]);
 
353
        }
 
354
      fflush(outfile);
 
355
    }
 
356
 
 
357
 
 
358
  /*
 
359
     Construct first and last index arrays for SOs: this defines the first
 
360
     absolute orbital index and last absolute orbital
 
361
     index for each irrep.  When there are no orbitals for an irrep, the
 
362
     value is -1 for first[] and -2 for last[].  Note that there must be
 
363
     basis functions in the first irrep (i.e. totally symmetric) for this to 
 
364
     work.
 
365
  */
 
366
  moinfo.first_so = init_int_array(moinfo.nirreps);
 
367
  moinfo.last_so = init_int_array(moinfo.nirreps);
 
368
  for(h=0; h < moinfo.nirreps; h++) {
 
369
      moinfo.first_so[h] = -1;
 
370
      moinfo.last_so[h] = -2;
 
371
    }
 
372
  first_offset = 0;
 
373
  last_offset = moinfo.sopi[0] - 1; 
 
374
  moinfo.first_so[0] = first_offset;
 
375
  moinfo.last_so[0] = last_offset;
 
376
  for(h=1; h < moinfo.nirreps; h++) {
 
377
      first_offset += moinfo.sopi[h-1];
 
378
      last_offset += moinfo.sopi[h];
 
379
      if(moinfo.sopi[h]) {
 
380
          moinfo.first_so[h] = first_offset;
 
381
          moinfo.last_so[h] = last_offset;
 
382
        }
 
383
    }
 
384
  
 
385
  /*
 
386
     Construct first and last index arrays: this defines the first
 
387
     absolute orbital index (Pitzer ordering) and last absolute orbital
 
388
     index for each irrep.  When there are no orbitals for an irrep, the
 
389
     value is -1 for first[] and -2 for last[].  Note that there must be
 
390
     orbitals in the first irrep (i.e. totally symmetric) for this to work.
 
391
  */
 
392
  moinfo.first = init_int_array(moinfo.nirreps);
 
393
  moinfo.last = init_int_array(moinfo.nirreps);
 
394
  for(h=0; h < moinfo.nirreps; h++) {
 
395
      moinfo.first[h] = -1;
 
396
      moinfo.last[h] = -2;
 
397
    }
 
398
  first_offset = 0;
 
399
  last_offset = moinfo.orbspi[0] - 1; 
 
400
  moinfo.first[0] = first_offset;
 
401
  moinfo.last[0] = last_offset;
 
402
  for(h=1; h < moinfo.nirreps; h++) {
 
403
      first_offset += moinfo.orbspi[h-1];
 
404
      last_offset += moinfo.orbspi[h];
 
405
      if(moinfo.orbspi[h]) {
 
406
          moinfo.first[h] = first_offset;
 
407
          moinfo.last[h] = last_offset;
 
408
        }
 
409
    }
 
410
  /*
 
411
     Construct first and last active index arrays: this defines the first
 
412
     absolute orbital index (Pitzer ordering) and last absolute orbital
 
413
     index for each irrep, excluding frozen orbitals.  When there are no
 
414
     orbitals for an irrep, the value is -1 for first[] and -2 for last[].
 
415
     Note that there must be orbitals in the first irrep (i.e. totally
 
416
     symmetric) for this to work.  
 
417
  */
 
418
  moinfo.fstact = init_int_array(moinfo.nirreps);
 
419
  moinfo.lstact = init_int_array(moinfo.nirreps);
 
420
  for(h=0; h < moinfo.nirreps; h++) {
 
421
      moinfo.fstact[h] = -1;
 
422
      moinfo.lstact[h] = -2;
 
423
    }
 
424
  first_offset = moinfo.frdocc[0];
 
425
  last_offset = moinfo.orbspi[0] - moinfo.fruocc[0] - 1; 
 
426
  moinfo.fstact[0] = first_offset;
 
427
  moinfo.lstact[0] = last_offset;
 
428
  for(h=1; h < moinfo.nirreps; h++) {
 
429
      first_offset += moinfo.orbspi[h-1]+moinfo.frdocc[h]-moinfo.frdocc[h-1];
 
430
      last_offset += moinfo.orbspi[h] - moinfo.fruocc[h] + moinfo.fruocc[h-1];
 
431
      if(moinfo.orbspi[h]) {
 
432
          moinfo.fstact[h] = first_offset;
 
433
          moinfo.lstact[h] = last_offset;
 
434
        }
 
435
    }
 
436
 
 
437
  /* Now define active[] such that frozen orbitals are taken into account */
 
438
  moinfo.active = init_int_array(moinfo.nirreps);
 
439
  for(h=0; h < moinfo.nirreps; h++) {
 
440
      moinfo.active[h] = moinfo.orbspi[h]-moinfo.frdocc[h]-moinfo.fruocc[h];
 
441
    }
 
442
 
 
443
  chkpt_close();
 
444
 
 
445
  /* in case IVO's have been asked for */
 
446
  if (params.ivo) {
 
447
 
 
448
    /* count the number of valence electrons */
 
449
    for (h=0; h < moinfo.nirreps; h++) {
 
450
      N += 2.0 * (double) (moinfo.clsdpi[h] - moinfo.frdocc[h]);
 
451
      N += (double) moinfo.openpi[h];
 
452
    }  
 
453
 
 
454
    /* use the number of valence electrons to compute the mixing ratio */
 
455
    params.fock_coeff = (N-1)/N;
 
456
 
 
457
    /*
 
458
    fprintf(outfile, "inside IVO routine now, N=%f, fock=%f\n", N,
 
459
      params.fock_coeff);
 
460
    */
 
461
 
 
462
    if (params.fock_coeff < 0.0) params.fock_coeff = 0.0;
 
463
    params.fzc_fock_coeff = 1.0 - params.fock_coeff;
 
464
  }
 
465
 
 
466
}
 
467
 
 
468
 
 
469
 
 
470
 
 
471
void get_reorder_array(void)
 
472
{
 
473
  int i, errcod;
 
474
  int j, k, l, fzv_offset;
 
475
 
 
476
  moinfo.order = init_int_array(moinfo.nmo);
 
477
 
 
478
  /* the following will only be set nonzero if it is a CI related WFN */
 
479
  moinfo.ras_opi = init_int_matrix(4,moinfo.nirreps);
 
480
 
 
481
  if (strcmp(params.wfn, "CI") == 0 || strcmp(params.wfn, "DETCI") == 0
 
482
       || strcmp(params.wfn, "QDPT") == 0 
 
483
       || strcmp(params.wfn, "OOCCD") == 0 
 
484
       || strcmp(params.wfn, "DETCAS") == 0) {
 
485
    
 
486
    moinfo.ras_opi = init_int_matrix(4,moinfo.nirreps); 
 
487
    
 
488
    if (!ras_set(moinfo.nirreps, moinfo.nmo, params.fzc, moinfo.orbspi,
 
489
                 moinfo.clsdpi, moinfo.openpi, moinfo.frdocc, moinfo.fruocc, 
 
490
                 moinfo.ras_opi, moinfo.order, params.ras_type)) {
 
491
      fprintf(outfile, "Error in ras_set().  Aborting.\n");
 
492
      exit(1);
 
493
    }
 
494
  } 
 
495
  
 
496
  else { /* default (CC, MP2, other) */
 
497
    reorder_qt(moinfo.clsdpi, moinfo.openpi, moinfo.frdocc, moinfo.fruocc,
 
498
               moinfo.order, moinfo.orbspi, moinfo.nirreps);
 
499
  }
 
500
  
 
501
   /* construct an array to map the other direction, i.e., from correlated */
 
502
   /* to Pitzer order */
 
503
   moinfo.corr2pitz = init_int_array(moinfo.nmo);
 
504
   for (i=0; i<moinfo.nmo; i++) {
 
505
     j = moinfo.order[i];
 
506
     moinfo.corr2pitz[j] = i;
 
507
   }
 
508
 
 
509
}
 
510
 
 
511
 
 
512
void cleanup(void)
 
513
{
 
514
  free(moinfo.fzc_operator);
 
515
  free_int_matrix(moinfo.ras_opi, 4);
 
516
}
 
517
 
 
518
void get_mvos(void)
 
519
{
 
520
 
 
521
  int h, nirreps, nvir, ntri, offset, row, col;
 
522
  int i, j, ij, iabs, jabs, icorr, jcorr, ijcorr, nocc;
 
523
  int ndv, ndoccv, *ndvph, k, colv;
 
524
  int errcod;
 
525
  double *FCvv, *FC, **evecs, *evals, **Cvv, **Cvvp, **Cnew;
 
526
  double *eig_unsrt, **scf_vector;
 
527
 
 
528
  FC = moinfo.fzc_operator;
 
529
  nirreps = moinfo.nirreps;
 
530
 
 
531
  chkpt_init(PSIO_OPEN_OLD);
 
532
  scf_vector = chkpt_rd_scf();
 
533
  eig_unsrt = chkpt_rd_evals();
 
534
  chkpt_close();
 
535
 
 
536
  /* read in which of the doccs are to be treated as virtuals */
 
537
  ndv = 0;
 
538
 
 
539
  if (ip_exist("DOCC_VIRT",0)) {
 
540
     errcod = ip_count("DOCC_VIRT",&ndv,0);
 
541
     params.docc_virt = init_int_array(ndv);
 
542
     for(k=0; k < ndv; k++) {
 
543
       params.docc_virt[k] = 0;
 
544
       errcod = ip_data("DOCC_VIRT","%d",(&(params.docc_virt[k])),1,k);
 
545
     }
 
546
  }
 
547
 
 
548
  /* finished reading in which doccs are to be treated as virtuals */
 
549
 
 
550
  /* form the vv block of FC for each irrep h */
 
551
  for (h=0,offset=0; h < nirreps; h++) {
 
552
 
 
553
  /* find out which doccs are to be treated as virtuals */
 
554
    ndoccv = 0;
 
555
    ndvph = init_int_array(moinfo.clsdpi[h]);
 
556
    for (k=0;k<moinfo.clsdpi[h];k++) {
 
557
      ndvph[k] = 0;
 
558
      }
 
559
    if (ip_exist("DOCC_VIRT",0)) {
 
560
      for (k=0;k<(ndv-1);k=(k+2)) {
 
561
        if ( (params.docc_virt[k]) == (h+1)) {
 
562
          ndoccv++;
 
563
          ndvph[(params.docc_virt[k+1])-1] = ndoccv;
 
564
        }
 
565
      }
 
566
    }
 
567
  /* ndoccv is the number of doccs to be treated as virts for irrep h */
 
568
  /* ndvph is a 1-d array of length "number of doccs for irrep h".    */
 
569
  /* it is a string of integers, 0 meaning "leave this docc alone",   */
 
570
  /* 1 at position j means that docc number j is the first docc-virt, */
 
571
  /* 2 at position j means that docc number j is the second docc-virt */
 
572
  /* etc.                                                             */
 
573
 
 
574
    nvir = moinfo.virtpi[h] + ndoccv;
 
575
    nocc = moinfo.clsdpi[h] + moinfo.openpi[h] - ndoccv;
 
576
 
 
577
    if (nvir < 1) break;
 
578
 
 
579
    if (params.print_lvl) {
 
580
      fprintf(outfile, "Working on irrep %d (%d vir, %d occ)\n", 
 
581
              h, nvir, nocc);
 
582
    }
 
583
 
 
584
    ntri = (nvir * (nvir+1))/2;
 
585
    FCvv = init_array(ntri);
 
586
    evals = init_array(ntri);
 
587
    evecs = block_matrix(nvir,nvir);
 
588
    Cvv = block_matrix(moinfo.sopi[h],nvir);
 
589
    Cvvp = block_matrix(moinfo.sopi[h],nvir);
 
590
    Cnew = block_matrix(moinfo.sopi[h],moinfo.orbspi[h]);
 
591
 
 
592
    for (i=0,ij=0; i<nvir; i++) {
 
593
      /* convert this MO index into a Correlated MO index */
 
594
      if (i>=ndoccv) {
 
595
        iabs = i + nocc + offset;
 
596
      }
 
597
      else {
 
598
        for (k=0; k<(nocc + ndoccv); k++) {
 
599
          if ( (i+1) == ndvph[k] )
 
600
             iabs = k + offset;
 
601
        }
 
602
      }
 
603
      icorr = moinfo.order[iabs];
 
604
      for (j=0; j<=i; j++,ij++) {
 
605
        if (j>=ndoccv) {
 
606
          jabs = j + nocc + offset;
 
607
        }
 
608
        else {
 
609
          for (k=0; k<(nocc + ndoccv); k++) {
 
610
            if ( (j+1) == ndvph[k] )
 
611
               jabs = k + offset; 
 
612
          }
 
613
        }
 
614
        jcorr = moinfo.order[jabs];  
 
615
        ijcorr = INDEX(icorr,jcorr);
 
616
        FCvv[ij] = params.fzc_fock_coeff * FC[ijcorr] ;
 
617
        if (i==j) FCvv[ij] += params.fock_coeff * eig_unsrt[iabs];
 
618
      }
 
619
    }
 
620
 
 
621
    if (params.print_lvl) {
 
622
      fprintf(outfile, "Old FCvv matrix for irrep %d\n", h);
 
623
      print_array(FCvv, nvir, outfile);
 
624
    }
 
625
 
 
626
    /* diagonalize the vv block of FC */
 
627
    rsp(nvir, nvir, ntri, FCvv, evals, 1, evecs, 1E-12);
 
628
 
 
629
    if (params.print_lvl) {
 
630
      fprintf(outfile, "\nDiagonalization matrix for FCvv irrep %d\n", h);
 
631
      print_mat(evecs, nvir, nvir, outfile);
 
632
 
 
633
      fprintf(outfile, "\nEigenvalues of FCvv for irrep %d\n", h);
 
634
      for (i=0; i<nvir; i++) {
 
635
        fprintf(outfile, "%lf ", evals[i]);
 
636
      }
 
637
      fprintf(outfile, "\n");
 
638
    }
 
639
 
 
640
    /* load up the vv part of SCF matrix C */
 
641
    for (i=moinfo.first_so[h],row=0; i<= moinfo.last_so[h]; i++,row++) {
 
642
      colv = 0;
 
643
      for (j=moinfo.first_so[h],k=0; j < (moinfo.first_so[h]+nocc+ndoccv); j++,k++) {
 
644
        if (ndvph[k] != 0) {
 
645
           Cvv[row][colv] = scf_vector[i][j];
 
646
           colv += 1;
 
647
        }
 
648
      }
 
649
      for (j=moinfo.first_so[h]+nocc+ndoccv,col=ndoccv; j<=moinfo.last_so[h]; j++,col++) {
 
650
        Cvv[row][col] = scf_vector[i][j];
 
651
      }
 
652
    } 
 
653
 
 
654
    if (params.print_lvl) {
 
655
      fprintf(outfile, "Old Cvv matrix for irrep %d\n", h);
 
656
      print_mat(Cvv, moinfo.sopi[h], nvir, outfile);
 
657
    }
 
658
     
 
659
    /* multiply the FCvv eigenvectors by Cvv to get new Cvv */
 
660
    mmult(Cvv, 0, evecs, 0, Cvvp, 0, moinfo.sopi[h], nvir, nvir, 0);
 
661
 
 
662
    if (params.print_lvl) {
 
663
      fprintf(outfile, "New Cvv matrix for irrep %d\n", h);
 
664
      print_mat(Cvvp, moinfo.sopi[h], nvir, outfile);
 
665
    }
 
666
 
 
667
    /* Load up the new C matrix and write it out */
 
668
 
 
669
    /* load up the occupied orbitals */
 
670
    for (i=moinfo.first_so[h],row=0; i<= moinfo.last_so[h]; i++,row++) {
 
671
      for (j=moinfo.first_so[h],col=0; j< moinfo.first_so[h]+nocc+ndoccv; j++,col++) {
 
672
        if (ndvph[col] != 0) {
 
673
          Cnew[row][col] = Cvvp[row][(ndvph[col]-1)];
 
674
        }
 
675
        else {
 
676
          Cnew[row][col] = scf_vector[i][j];
 
677
        }
 
678
      }
 
679
    }
 
680
 
 
681
    /* load up the new virtuals */
 
682
    for (i=0; i<moinfo.sopi[h]; i++) {
 
683
      for (j=ndoccv; j<nvir; j++) {
 
684
        Cnew[i][j+nocc] = Cvvp[i][j];
 
685
      }
 
686
    }
 
687
 
 
688
    if (params.print_lvl) {
 
689
      fprintf(outfile, "New C matrix for irrep %d\n", h);
 
690
      print_mat(Cnew, moinfo.sopi[h], moinfo.orbspi[h], outfile);
 
691
    }
 
692
 
 
693
    chkpt_init(PSIO_OPEN_OLD);
 
694
    chkpt_wt_scf_irrep(Cnew, h);
 
695
    chkpt_close();
 
696
 
 
697
    offset += moinfo.orbspi[h];
 
698
    free(FCvv);
 
699
    free(evals);
 
700
    free_block(evecs);
 
701
  }
 
702
 
 
703
  free(eig_unsrt);
 
704
  free_block(scf_vector);
 
705
}
 
706