4
** This file contains code for the General CI (GENCI) module
7
** Center for Computational Quantum Chemistry, UGA
18
#include <libciomr/libciomr.h>
23
namespace psi { namespace detci {
26
#define NORM_TOL 1.0E-5
27
#define INDEX(i,j) ( (i>j) ? (ioff[(i)] + (j)): (ioff[(j)] + (i)) )
28
#define MIN0(a,b) (((a)<(b)) ? (a) : (b))
29
#define MAX0(a,b) (((a)>(b)) ? (a) : (b))
32
** SCHMIDT_ADDOC(): Assume A is a orthogonal matrix.
33
** This function Gram-Schmidt
34
** orthogonalizes a new vector v and adds it to matrix A. A must contain
35
** a free row pointer for a new row. Don't add orthogonalized v' if
36
** norm(v') < NORM_TOL.
38
** David Sherrill, Feb 1994
39
** Matt Leininger, June 1996 Rewrote for out-of-core
42
** buffer4 = buffer to store d or f vectors
43
** buffer5 = buffer to store b vectors
44
** buf_size = size of buffers
45
** extra_buf = size of the last extra buffer of a vector
46
** num_buf = number of buffers of size buf_size in a vector length N
48
** N = dimension (length) of b, d, or f vectors
50
** Returns: 1 if a vector is added to A, 0 otherwise
53
int schmidt_addoc(double *buffer4, double *buffer5, int buf_size, int extra_buf,
54
int num_buf, PSI_FPTR d_index, int N, int L,
55
int b_file, int d_file)
57
double *dotval, normval = 0.0, tval;
59
PSI_FPTR b_index = 0, jnk = 0, f_index;
61
/* determine array of dot products b.f */
63
dotval = init_array(L);
64
for (i=0; i<num_buf; i++) { /* loop over num_buf's in b and f */
65
wreadw(d_file, (char *) buffer4, sizeof(double)*buf_size,
67
b_index = i*buf_size*sizeof(double);
68
for (j=0; j<L; j++) { /* loop over b vectors */
69
wreadw(b_file, (char *) buffer5, sizeof(double)*buf_size,
71
dot_arr(buffer4, buffer5, buf_size, &tval);
73
b_index += N*sizeof(double);
77
b_index = num_buf*buf_size*sizeof(double);
78
wreadw(d_file, (char *) buffer4, sizeof(double)*extra_buf,
81
wreadw(b_file, (char *) buffer5, sizeof(double)*extra_buf,
83
dot_arr(buffer4, buffer5, extra_buf, &tval);
85
b_index += N*sizeof(double);
89
/* schmidt orthronormalize f to the set of b vectors */
90
d_index -= N*sizeof(double);
91
for (i=0; i<num_buf; i++) {
92
wreadw(d_file, (char *) buffer4, sizeof(double)*buf_size,
94
b_index = i*buf_size*sizeof(double);
95
for (j=0; j<L; j++) { /* loop over b vectors */
96
wreadw(b_file, (char *) buffer5, sizeof(double)*buf_size,
98
b_index += N*sizeof(double);
99
for (I=0; I<buf_size; I++)
100
buffer4[I] -= dotval[j]*buffer5[I];
102
dot_arr(buffer4, buffer4, buf_size, &tval);
104
wwritw(d_file, (char *) buffer4, sizeof(double)*buf_size,
107
if (extra_buf != 0) {
108
b_index = num_buf*buf_size*sizeof(double);
109
wreadw(d_file, (char *) buffer4, sizeof(double)*extra_buf,
111
for (i=0; i<L; i++) {
112
wreadw(b_file, (char *) buffer5, sizeof(double)*extra_buf,
114
b_index += N*sizeof(double);
115
for (I=0; I<extra_buf; I++)
116
buffer4[I] -= dotval[i]*buffer5[I];
118
dot_arr(buffer4, buffer4, extra_buf, &tval);
120
wwritw(d_file, (char *) buffer4, sizeof(double)*extra_buf,
122
} /* end extra_buf */
123
normval = sqrt(normval);
124
/* fprintf(outfile,"\n normval = %15.10f\n", normval); */
126
/* test norm of new b vector */
128
if (normval < NORM_TOL)
131
f_index -= N*sizeof(double);
132
b_index = N*L*sizeof(double);
133
for (i=0; i<num_buf; i++) {
134
wreadw(d_file, (char *) buffer4, sizeof(double)*buf_size,
136
for (I=0; I<buf_size; I++)
137
buffer4[I] /= normval;
138
wwritw(b_file, (char *) buffer4, sizeof(double)*buf_size,
141
if (extra_buf != 0) {
142
wreadw(d_file, (char *) buffer4, sizeof(double)*extra_buf,
144
for (I=0; I<extra_buf; I++)
145
buffer4[I] /= normval;
146
wwritw(b_file, (char *) buffer4, sizeof(double)*extra_buf,
148
} /* end extra_buf */
157
** NORMALIZE.C : Normalize a set of vectors
159
** Assume we're normalizing the ROWS
161
** David Sherrill, Feb 1994
162
** Matt Leininger, June 1996 modified for out-of-core vectors
164
void v_normalize(double *A, PSI_FPTR index, int buf_size,
165
int extra_buf, int num_buf, int d_file)
167
double normval = 0.0, tval;
169
PSI_FPTR jnk = 0, index2;
173
/* divide each row by the square root of its norm */
174
for (i=0; i<num_buf; i++) {
175
wreadw(d_file, (char *) A, sizeof(double)*buf_size, index, &index);
176
dot_arr(A, A, buf_size, &tval);
179
if (extra_buf != 0) {
180
wreadw(d_file, (char *) A, sizeof(double)*extra_buf, index, &index);
181
dot_arr(A, A, extra_buf, &tval);
183
} /* end extra_buf */
184
normval = sqrt(normval);
187
for (i=0; i<num_buf; i++) {
188
wreadw(d_file, (char *) A, sizeof(double)*buf_size, index, &index);
189
for (I=0; I<buf_size; I++)
191
wwritw(d_file, (char *) A, sizeof(double)*buf_size, index2, &index2);
193
if (extra_buf != 0) {
194
wreadw(d_file, (char *) A, sizeof(double)*extra_buf, index, &index);
195
for (I=0; I<extra_buf; I++)
197
wwritw(d_file, (char *) A, sizeof(double)*extra_buf, index2, &index2);
198
} /* end extra_buf */
203
** V_SCHMIDT(): Assume A is a orthogonal matrix. This function Gram-Schmidt
204
** orthogonalizes a set of given vectors.
205
** David Sherrill, Feb 1994
206
** Matt Leininger, June 1996 Rewrote for out-of-core
209
** buffer4 = buffer to store b vectors
210
** buffer5 = buffer to store b vectors
211
** buf_size = size of buffers
212
** extra_buf = size of the last extra buffer of a vector
213
** num_buf = number of buffers of size buf_size in a vector length N
214
** N = dimension (length) of b vectors
217
double *v_schmidt(double *buffer4, double *buffer5, int buf_size, int extra_buf,
218
int num_buf, int N, int L, int b_file)
220
double normval, tval, *dotval;
221
int i, j, k, I, tridim;
222
PSI_FPTR x_index = 0, jnk = 0, y_index, xwrit_index;
224
/* determine array of dot products b.f */
225
x_index = N*sizeof(double);
226
xwrit_index = x_index;
227
tridim = (L*(L+1))/2;
228
dotval = init_array(tridim);
229
for (k=1; k<L; k++) { /* loop over b vectors */
230
for (i=0; i<num_buf; i++) { /* loop over num_buf's in b vectors */
231
wreadw(b_file, (char *) buffer4, sizeof(double)*buf_size,
233
y_index = i*buf_size*sizeof(double);
234
for (j=0; j<=k; j++) { /* loop over b vectors */
235
wreadw(b_file, (char *) buffer5, sizeof(double)*buf_size,
237
dot_arr(buffer4, buffer5, buf_size, &tval);
238
dotval[INDEX(k,j)] += tval;
239
y_index += N*sizeof(double);
242
if (extra_buf != 0) {
243
y_index = num_buf*buf_size*sizeof(double);
244
wreadw(b_file, (char *) buffer4, sizeof(double)*extra_buf,
246
for (i=0; i<=k; i++) {
247
wreadw(b_file, (char *) buffer5, sizeof(double)*extra_buf,
249
dot_arr(buffer4, buffer5, extra_buf, &tval);
250
dotval[INDEX(i,k)] += tval;
251
y_index += N*sizeof(double);
253
} /* end extra_buf */
255
/* schmidt orthronormalize the set of b vectors */
256
x_index -= N*sizeof(double);
258
for (i=0; i<num_buf; i++) {
259
wreadw(b_file, (char *) buffer4, sizeof(double)*buf_size,
261
y_index = i*buf_size*sizeof(double);
262
for (j=0; j<k; j++) { /* loop over b vectors */
263
wreadw(b_file, (char *) buffer5, sizeof(double)*buf_size,
265
y_index += N*sizeof(double);
266
for (I=0; I<buf_size; I++)
267
buffer4[I] -= dotval[INDEX(j,k)]*buffer5[I];
269
dot_arr(buffer4, buffer4, buf_size, &tval);
271
wwritw(b_file, (char *) buffer4, sizeof(double)*buf_size,
272
xwrit_index, &xwrit_index);
274
if (extra_buf != 0) {
275
y_index = num_buf*buf_size*sizeof(double);
276
wreadw(b_file, (char *) buffer4, sizeof(double)*extra_buf,
278
for (i=0; i<k; i++) {
279
wreadw(b_file, (char *) buffer5, sizeof(double)*extra_buf,
281
y_index += N*sizeof(double);
282
for (I=0; I<extra_buf; I++)
283
buffer4[I] -= dotval[INDEX(i,k)]*buffer5[I];
285
dot_arr(buffer4, buffer4, extra_buf, &tval);
287
wwritw(b_file, (char *) buffer4, sizeof(double)*extra_buf,
288
xwrit_index, &xwrit_index);
289
} /* end extra_buf */
291
/* Normalize vector */
292
normval = sqrt(normval);
293
x_index -= N*sizeof(double);
294
for (i=0; i<num_buf; i++) {
295
wreadw(b_file, (char *) buffer4, sizeof(double)*buf_size,
297
for (I=0; I<buf_size; I++)
298
buffer4[I] /= normval;
299
wwritw(b_file, (char *) buffer4, sizeof(double)*buf_size,
302
if (extra_buf != 0) {
303
wreadw(b_file, (char *) buffer4, sizeof(double)*extra_buf,
305
for (I=0; I<extra_buf; I++)
306
buffer4[I] /= normval;
307
wwritw(b_file, (char *) buffer4, sizeof(double)*extra_buf,
309
} /* end extra_buf */
314
void det2strings(BIGINT det, int *alp_code, int *alp_idx,
315
int *bet_code, int *bet_idx)
319
/* determine the CI block we're in */
320
for (i=0; i<CIblks.num_blocks-1; i++) {
321
if (CIblks.offset[i+1] > det) break;
323
*alp_code = CIblks.Ia_code[i];
324
*bet_code = CIblks.Ib_code[i];
326
*alp_idx = (det - CIblks.offset[i]) / CIblks.Ib_size[i];
327
*bet_idx = (det - CIblks.offset[i]) % CIblks.Ib_size[i];
331
BIGINT strings2det(int alp_code, int alp_idx, int bet_code, int bet_idx)
336
blknum = CIblks.decode[alp_code][bet_code];
338
fprintf(outfile, "CIvect::strings2det failed --- invalid block\n");
342
addr = CIblks.offset[blknum];
343
addr += alp_idx * CIblks.Ib_size[blknum] + bet_idx;
350
** unit_guess - uses a unit guess for the first b vector in the
351
** davidson-liu algorithm
355
void unit_guess(int alp_code, int alp_idx, int bet_code, int bet_idx,
356
int switch_buf3, double *buffer, int buf_size,
357
int num_buf, int extra_buf, PSI_FPTR b_file,
358
PSI_FPTR b_writ, int M, int N)
364
/* Form initial guess b vector */
365
i = strings2det(CalcInfo.ref_alp_list, CalcInfo.ref_alp_rel,
366
CalcInfo.ref_bet_list, CalcInfo.ref_bet_rel);
369
wwritw(b_file, (char *) buffer, sizeof(double)*buf_size,
372
v_normalize(buffer, (b_writ-M*N*sizeof(double)), buf_size, 0,
375
else if (switch_buf3) {
376
for (j=0; j<num_buf; j++) {
377
if ((i >= (j*buf_size)) && (i < ((j+1)*buf_size)))
378
buffer[i-j*buf_size] = 1.0;
379
wwritw(b_file, (char *) buffer, sizeof(double)*buf_size,
381
if ((i >= (j*buf_size)) && (i < ((j+1)*buf_size)))
382
buffer[i-j*buf_size] = 0.0;
384
if (extra_buf != 0) {
385
if ((i >= num_buf*buf_size) && (i < (extra_buf+num_buf*buf_size)))
386
buffer[i-num_buf*buf_size] = 1.0;
387
wwritw(b_file, (char *) buffer, sizeof(double)*extra_buf,
389
if ((i > num_buf*buf_size) && (i < (extra_buf+num_buf*buf_size)))
390
buffer[i-num_buf*buf_size] = 0.0;
392
v_normalize(buffer, (b_writ-M*N*sizeof(double)), buf_size, extra_buf,
396
/* b_writ -= N*sizeof(double);
397
wreadw(b_file, (char *) buffer, sizeof(double)*buf_size,
399
for (I=0; I<buf_size; I++)
400
if (buffer[I] != 0.0) fprintf(outfile,"b[0][%d] = %lf\n\n",
402
printf("Done reading in b trial vector for check.\n"); */
408
** max_element - determines the maximum value in a list of diagonal
410
** buffer - array of matrix elements
411
** num_elements - number of elements in array buffer
412
** max - pointer to max value
413
** max_num - the element number to the maximum value
415
void max_element(double *buffer, int num_elements, double *max, int *max_num)
421
for (i=1; i<num_elements; i++) {
422
if (buffer[i] > (*max)) {
432
** min_element - determines the minimum value in a list of diagonal
434
** buffer - array of matrix elements
435
** num_elements - number of elements in array buffer
436
** min - pointer to max value
437
** min_num - the element number to the minimum value
439
void min_element(double *buffer, int num_elements, double *min, int *min_num)
445
for (i=1; i<num_elements; i++) {
446
if (buffer[i] < (*min)) {
456
** read_c() - reads in the CI vector for a restart of the calculation
459
void read_c(int switch_buf3, double *buffer, int buf_size, int num_buf,
460
int extra_buf, int b_file, PSI_FPTR b_writ, int c_file,
466
wreadw(c_file, (char *) buffer, sizeof(double)*buf_size,
468
wwritw(b_file, (char *) buffer, sizeof(double)*buf_size,
471
else if (switch_buf3) {
472
for (i=0; i<num_buf; i++) {
473
wreadw(c_file, (char *) buffer, sizeof(double)*buf_size,
475
wwritw(b_file, (char *) buffer, sizeof(double)*buf_size,
478
if (extra_buf != 0) {
479
wreadw(c_file, (char *) buffer, sizeof(double)*extra_buf,
481
wwritw(b_file, (char *) buffer, sizeof(double)*extra_buf,
488
}} // namespace psi::detci