5
** This file contains the C code for the General CI (GENCI) module
8
** Center for Computational Quantum Chemistry, UGA
15
#define NORM_TOL 1.0E-5
16
#define INDEX(i,j) ( (i>j) ? (ioff[(i)] + (j)): (ioff[(j)] + (i)) )
17
#define MIN0(a,b) (((a)<(b)) ? (a) : (b))
18
#define MAX0(a,b) (((a)>(b)) ? (a) : (b))
24
#include <libciomr/libciomr.h>
30
** SCHMIDT_ADDOC(): Assume A is a orthogonal matrix.
31
** This function Gram-Schmidt
32
** orthogonalizes a new vector v and adds it to matrix A. A must contain
33
** a free row pointer for a new row. Don't add orthogonalized v' if
34
** norm(v') < NORM_TOL.
36
** David Sherrill, Feb 1994
37
** Matt Leininger, June 1996 Rewrote for out-of-core
40
** buffer4 = buffer to store d or f vectors
41
** buffer5 = buffer to store b vectors
42
** buf_size = size of buffers
43
** extra_buf = size of the last extra buffer of a vector
44
** num_buf = number of buffers of size buf_size in a vector length N
46
** N = dimension (length) of b, d, or f vectors
48
** Returns: 1 if a vector is added to A, 0 otherwise
51
int schmidt_addoc(double *buffer4, double *buffer5, int buf_size, int extra_buf,
52
int num_buf, PSI_FPTR d_index, int N, int L,
53
int b_file, int d_file)
55
double *dotval, normval = 0.0, tval;
57
PSI_FPTR b_index = 0, jnk = 0, f_index;
59
/* determine array of dot products b.f */
61
dotval = init_array(L);
62
for (i=0; i<num_buf; i++) { /* loop over num_buf's in b and f */
63
wreadw(d_file, (char *) buffer4, sizeof(double)*buf_size,
65
b_index = i*buf_size*sizeof(double);
66
for (j=0; j<L; j++) { /* loop over b vectors */
67
wreadw(b_file, (char *) buffer5, sizeof(double)*buf_size,
69
dot_arr(buffer4, buffer5, buf_size, &tval);
71
b_index += N*sizeof(double);
75
b_index = num_buf*buf_size*sizeof(double);
76
wreadw(d_file, (char *) buffer4, sizeof(double)*extra_buf,
79
wreadw(b_file, (char *) buffer5, sizeof(double)*extra_buf,
81
dot_arr(buffer4, buffer5, extra_buf, &tval);
83
b_index += N*sizeof(double);
87
/* schmidt orthronormalize f to the set of b vectors */
88
d_index -= N*sizeof(double);
89
for (i=0; i<num_buf; i++) {
90
wreadw(d_file, (char *) buffer4, sizeof(double)*buf_size,
92
b_index = i*buf_size*sizeof(double);
93
for (j=0; j<L; j++) { /* loop over b vectors */
94
wreadw(b_file, (char *) buffer5, sizeof(double)*buf_size,
96
b_index += N*sizeof(double);
97
for (I=0; I<buf_size; I++)
98
buffer4[I] -= dotval[j]*buffer5[I];
100
dot_arr(buffer4, buffer4, buf_size, &tval);
102
wwritw(d_file, (char *) buffer4, sizeof(double)*buf_size,
105
if (extra_buf != 0) {
106
b_index = num_buf*buf_size*sizeof(double);
107
wreadw(d_file, (char *) buffer4, sizeof(double)*extra_buf,
109
for (i=0; i<L; i++) {
110
wreadw(b_file, (char *) buffer5, sizeof(double)*extra_buf,
112
b_index += N*sizeof(double);
113
for (I=0; I<extra_buf; I++)
114
buffer4[I] -= dotval[i]*buffer5[I];
116
dot_arr(buffer4, buffer4, extra_buf, &tval);
118
wwritw(d_file, (char *) buffer4, sizeof(double)*extra_buf,
120
} /* end extra_buf */
121
normval = sqrt(normval);
122
/* fprintf(outfile,"\n normval = %15.10f\n", normval); */
124
/* test norm of new b vector */
126
if (normval < NORM_TOL)
129
f_index -= N*sizeof(double);
130
b_index = N*L*sizeof(double);
131
for (i=0; i<num_buf; i++) {
132
wreadw(d_file, (char *) buffer4, sizeof(double)*buf_size,
134
for (I=0; I<buf_size; I++)
135
buffer4[I] /= normval;
136
wwritw(b_file, (char *) buffer4, sizeof(double)*buf_size,
139
if (extra_buf != 0) {
140
wreadw(d_file, (char *) buffer4, sizeof(double)*extra_buf,
142
for (I=0; I<extra_buf; I++)
143
buffer4[I] /= normval;
144
wwritw(b_file, (char *) buffer4, sizeof(double)*extra_buf,
146
} /* end extra_buf */
155
** NORMALIZE.C : Normalize a set of vectors
157
** Assume we're normalizing the ROWS
159
** David Sherrill, Feb 1994
160
** Matt Leininger, June 1996 modified for out-of-core vectors
162
void v_normalize(double *A, PSI_FPTR index, int buf_size,
163
int extra_buf, int num_buf, int d_file)
165
double normval = 0.0, tval;
167
PSI_FPTR jnk = 0, index2;
171
/* divide each row by the square root of its norm */
172
for (i=0; i<num_buf; i++) {
173
wreadw(d_file, (char *) A, sizeof(double)*buf_size, index, &index);
174
dot_arr(A, A, buf_size, &tval);
177
if (extra_buf != 0) {
178
wreadw(d_file, (char *) A, sizeof(double)*extra_buf, index, &index);
179
dot_arr(A, A, extra_buf, &tval);
181
} /* end extra_buf */
182
normval = sqrt(normval);
185
for (i=0; i<num_buf; i++) {
186
wreadw(d_file, (char *) A, sizeof(double)*buf_size, index, &index);
187
for (I=0; I<buf_size; I++)
189
wwritw(d_file, (char *) A, sizeof(double)*buf_size, index2, &index2);
191
if (extra_buf != 0) {
192
wreadw(d_file, (char *) A, sizeof(double)*extra_buf, index, &index);
193
for (I=0; I<extra_buf; I++)
195
wwritw(d_file, (char *) A, sizeof(double)*extra_buf, index2, &index2);
196
} /* end extra_buf */
201
** V_SCHMIDT(): Assume A is a orthogonal matrix. This function Gram-Schmidt
202
** orthogonalizes a set of given vectors.
203
** David Sherrill, Feb 1994
204
** Matt Leininger, June 1996 Rewrote for out-of-core
207
** buffer4 = buffer to store b vectors
208
** buffer5 = buffer to store b vectors
209
** buf_size = size of buffers
210
** extra_buf = size of the last extra buffer of a vector
211
** num_buf = number of buffers of size buf_size in a vector length N
212
** N = dimension (length) of b vectors
215
double *v_schmidt(double *buffer4, double *buffer5, int buf_size, int extra_buf,
216
int num_buf, int N, int L, int b_file)
218
double normval, tval, *dotval;
219
int i, j, k, I, tridim;
220
PSI_FPTR x_index = 0, jnk = 0, y_index, xwrit_index;
222
/* determine array of dot products b.f */
223
x_index = N*sizeof(double);
224
xwrit_index = x_index;
225
tridim = (L*(L+1))/2;
226
dotval = init_array(tridim);
227
for (k=1; k<L; k++) { /* loop over b vectors */
228
for (i=0; i<num_buf; i++) { /* loop over num_buf's in b vectors */
229
wreadw(b_file, (char *) buffer4, sizeof(double)*buf_size,
231
y_index = i*buf_size*sizeof(double);
232
for (j=0; j<=k; j++) { /* loop over b vectors */
233
wreadw(b_file, (char *) buffer5, sizeof(double)*buf_size,
235
dot_arr(buffer4, buffer5, buf_size, &tval);
236
dotval[INDEX(k,j)] += tval;
237
y_index += N*sizeof(double);
240
if (extra_buf != 0) {
241
y_index = num_buf*buf_size*sizeof(double);
242
wreadw(b_file, (char *) buffer4, sizeof(double)*extra_buf,
244
for (i=0; i<=k; i++) {
245
wreadw(b_file, (char *) buffer5, sizeof(double)*extra_buf,
247
dot_arr(buffer4, buffer5, extra_buf, &tval);
248
dotval[INDEX(i,k)] += tval;
249
y_index += N*sizeof(double);
251
} /* end extra_buf */
253
/* schmidt orthronormalize the set of b vectors */
254
x_index -= N*sizeof(double);
256
for (i=0; i<num_buf; i++) {
257
wreadw(b_file, (char *) buffer4, sizeof(double)*buf_size,
259
y_index = i*buf_size*sizeof(double);
260
for (j=0; j<k; j++) { /* loop over b vectors */
261
wreadw(b_file, (char *) buffer5, sizeof(double)*buf_size,
263
y_index += N*sizeof(double);
264
for (I=0; I<buf_size; I++)
265
buffer4[I] -= dotval[INDEX(j,k)]*buffer5[I];
267
dot_arr(buffer4, buffer4, buf_size, &tval);
269
wwritw(b_file, (char *) buffer4, sizeof(double)*buf_size,
270
xwrit_index, &xwrit_index);
272
if (extra_buf != 0) {
273
y_index = num_buf*buf_size*sizeof(double);
274
wreadw(b_file, (char *) buffer4, sizeof(double)*extra_buf,
276
for (i=0; i<k; i++) {
277
wreadw(b_file, (char *) buffer5, sizeof(double)*extra_buf,
279
y_index += N*sizeof(double);
280
for (I=0; I<extra_buf; I++)
281
buffer4[I] -= dotval[INDEX(i,k)]*buffer5[I];
283
dot_arr(buffer4, buffer4, extra_buf, &tval);
285
wwritw(b_file, (char *) buffer4, sizeof(double)*extra_buf,
286
xwrit_index, &xwrit_index);
287
} /* end extra_buf */
289
/* Normalize vector */
290
normval = sqrt(normval);
291
x_index -= N*sizeof(double);
292
for (i=0; i<num_buf; i++) {
293
wreadw(b_file, (char *) buffer4, sizeof(double)*buf_size,
295
for (I=0; I<buf_size; I++)
296
buffer4[I] /= normval;
297
wwritw(b_file, (char *) buffer4, sizeof(double)*buf_size,
300
if (extra_buf != 0) {
301
wreadw(b_file, (char *) buffer4, sizeof(double)*extra_buf,
303
for (I=0; I<extra_buf; I++)
304
buffer4[I] /= normval;
305
wwritw(b_file, (char *) buffer4, sizeof(double)*extra_buf,
307
} /* end extra_buf */
312
void det2strings(BIGINT det, int *alp_code, int *alp_idx,
313
int *bet_code, int *bet_idx)
317
/* determine the CI block we're in */
318
for (i=0; i<CIblks.num_blocks-1; i++) {
319
if (CIblks.offset[i+1] > det) break;
321
*alp_code = CIblks.Ia_code[i];
322
*bet_code = CIblks.Ib_code[i];
324
*alp_idx = (det - CIblks.offset[i]) / CIblks.Ib_size[i];
325
*bet_idx = (det - CIblks.offset[i]) % CIblks.Ib_size[i];
329
BIGINT strings2det(int alp_code, int alp_idx, int bet_code, int bet_idx)
334
blknum = CIblks.decode[alp_code][bet_code];
335
addr = CIblks.offset[blknum];
336
addr += alp_idx * CIblks.Ib_size[blknum] + bet_idx;
343
** unit_guess - uses a unit guess for the first b vector in the
344
** davidson-liu algorithm
348
void unit_guess(int alp_code, int alp_idx, int bet_code, int bet_idx,
349
int switch_buf3, double *buffer, int buf_size,
350
int num_buf, int extra_buf, PSI_FPTR b_file,
351
PSI_FPTR b_writ, int M, int N)
357
/* Form initial guess b vector */
358
i = strings2det(CalcInfo.ref_alp_list, CalcInfo.ref_alp_rel,
359
CalcInfo.ref_bet_list, CalcInfo.ref_bet_rel);
362
wwritw(b_file, (char *) buffer, sizeof(double)*buf_size,
365
v_normalize(buffer, (b_writ-M*N*sizeof(double)), buf_size, 0,
368
else if (switch_buf3) {
369
for (j=0; j<num_buf; j++) {
370
if ((i >= (j*buf_size)) && (i < ((j+1)*buf_size)))
371
buffer[i-j*buf_size] = 1.0;
372
wwritw(b_file, (char *) buffer, sizeof(double)*buf_size,
374
if ((i >= (j*buf_size)) && (i < ((j+1)*buf_size)))
375
buffer[i-j*buf_size] = 0.0;
377
if (extra_buf != 0) {
378
if ((i >= num_buf*buf_size) && (i < (extra_buf+num_buf*buf_size)))
379
buffer[i-num_buf*buf_size] = 1.0;
380
wwritw(b_file, (char *) buffer, sizeof(double)*extra_buf,
382
if ((i > num_buf*buf_size) && (i < (extra_buf+num_buf*buf_size)))
383
buffer[i-num_buf*buf_size] = 0.0;
385
v_normalize(buffer, (b_writ-M*N*sizeof(double)), buf_size, extra_buf,
389
/* b_writ -= N*sizeof(double);
390
wreadw(b_file, (char *) buffer, sizeof(double)*buf_size,
392
for (I=0; I<buf_size; I++)
393
if (buffer[I] != 0.0) fprintf(outfile,"b[0][%d] = %lf\n\n",
395
printf("Done reading in b trial vector for check.\n"); */
401
** max_element - determines the maximum value in a list of diagonal
403
** buffer - array of matrix elements
404
** num_elements - number of elements in array buffer
405
** max - pointer to max value
406
** max_num - the element number to the maximum value
408
void max_element(double *buffer, int num_elements, double *max, int *max_num)
414
for (i=1; i<num_elements; i++) {
415
if (buffer[i] > (*max)) {
425
** min_element - determines the minimum value in a list of diagonal
427
** buffer - array of matrix elements
428
** num_elements - number of elements in array buffer
429
** min - pointer to max value
430
** min_num - the element number to the minimum value
432
void min_element(double *buffer, int num_elements, double *min, int *min_num)
438
for (i=1; i<num_elements; i++) {
439
if (buffer[i] < (*min)) {
449
** read_c() - reads in the CI vector for a restart of the calculation
452
void read_c(int switch_buf3, double *buffer, int buf_size, int num_buf,
453
int extra_buf, int b_file, PSI_FPTR b_writ, int c_file,
459
wreadw(c_file, (char *) buffer, sizeof(double)*buf_size,
461
wwritw(b_file, (char *) buffer, sizeof(double)*buf_size,
464
else if (switch_buf3) {
465
for (i=0; i<num_buf; i++) {
466
wreadw(c_file, (char *) buffer, sizeof(double)*buf_size,
468
wwritw(b_file, (char *) buffer, sizeof(double)*buf_size,
471
if (extra_buf != 0) {
472
wreadw(c_file, (char *) buffer, sizeof(double)*extra_buf,
474
wwritw(b_file, (char *) buffer, sizeof(double)*extra_buf,