5
#include <libiwl/iwl.h>
6
#include <libciomr/libciomr.h>
7
#include <libmoinfo/libmoinfo.h>
10
#include "memory_manager.h"
12
#define MAX(i,j) ((i>j) ? i : j)
13
#define MIN(i,j) ((i>j) ? j : i)
14
#define INDEX(i,j) ((i>j) ? (ioff[(i)]+(j)) : (ioff[(j)]+(i)))
18
namespace psi{ namespace mcscf{
20
void SCF::read_so_tei()
24
total_symmetric_block_size = INDEX(pairpi[0]-1,pairpi[0]-1)+1;
26
size_t free_memory = mem->get_FreeMemory();
28
// Determine the number of matrix elements of the PK (and K) matrix to hold in core
30
nin_core = min(free_memory / sizeof(double),total_symmetric_block_size);
32
nin_core = min(free_memory / (2 * sizeof(double)),total_symmetric_block_size);
34
if(nin_core != total_symmetric_block_size)
37
size_t total_symmetric_pairs = pairpi[0];
39
// Determine how to split the two-electron operators
42
size_t pqrs_index = 0;
46
batch_index_min[0]= 0;
47
batch_index_max[0]= 0;
49
for(size_t pq = 0; pq < total_symmetric_pairs; ++pq){
51
if(pq_incore + pq + 1 > nin_core){
52
// The batch is full. Save info.
53
batch_pq_max[nbatch] = pq;
54
batch_pq_min[nbatch + 1] = pq;
55
batch_index_max[nbatch] = pqrs_index;
56
batch_index_min[nbatch + 1] = pqrs_index;
63
if(batch_pq_max[nbatch] != total_symmetric_pairs){
64
batch_pq_max[nbatch] = total_symmetric_pairs;
65
batch_index_max[nbatch] = total_symmetric_block_size;
69
for(int batch = 0; batch < nbatch; ++batch){
70
batch_size[batch] = batch_index_max[ batch] - batch_index_min[batch];
71
fprintf(outfile,"\n batch %3d pq = [%8ld,%8ld] index = [%16ld,%16ld]",
73
batch_pq_min[batch],batch_pq_max[batch],
74
batch_index_min[batch],batch_index_max[batch]);
78
// Allocate the PK matrix
79
allocate1(double,PK,nin_core);
80
for(size_t i=0; i < nin_core; i++)
82
fprintf(outfile,"\n\n Allocated the PK matrix (%d elements) ",nin_core);
86
// Allocate the K matrix
87
allocate1(double,K,nin_core);
88
for(size_t i=0; i < nin_core; i++)
90
fprintf(outfile,"\n Allocated the K matrix (%d elements) ",nin_core);
95
read_so_tei_form_PK();
97
read_so_tei_form_PK_and_K();
100
void SCF::read_so_tei_form_PK()
102
fprintf(outfile,"\n Reading the two-electron integrals to form PK ... ");
105
for(int batch = 0; batch < nbatch; ++batch){
106
fprintf(outfile,"\n batch %3d ... ",batch);
108
// Compute the minimum and maximum indices
109
size_t min_index = batch_index_min[batch];
110
size_t max_index = batch_index_max[batch];
111
size_t buffer_size = max_index - min_index;
113
for(size_t pqrs = 0; pqrs < buffer_size; ++pqrs)
117
size_t p,q,r,s,four_index;
118
int ilsti,nbuf,fi,index;
120
iwl_buf_init(&ERIIN,PSIF_SO_TEI,0.0,1,1);
122
ilsti = ERIIN.lastbuf;
125
for(index=0;index<nbuf;index++){
126
// Compute the [pq] index for this pqrs combination
127
p = (short int)abs((float)ERIIN.labels[fi]);
128
q = ERIIN.labels[fi+1];
129
r = ERIIN.labels[fi+2];
130
s = ERIIN.labels[fi+3];
131
value = ERIIN.values[index];
133
if(pair_sym[p][q] == 0)
135
four_index = INDEX(pair[p][q],pair[r][s]);
136
if((four_index >= min_index) && (four_index < max_index)){
137
PK[four_index - min_index] += value;
140
if(pair_sym[p][r] == 0)
142
four_index = INDEX(pair[p][r],pair[q][s]);
143
if((four_index >= min_index) && (four_index < max_index)){
144
if((p == r) || (q == s))
145
PK[four_index - min_index] -= 0.5 * value;
147
PK[four_index - min_index] -= 0.25 * value;
150
if(pair_sym[p][s] == 0){
151
four_index = INDEX(pair[p][s],pair[q][r]);
152
if((four_index >= min_index) && (four_index < max_index)){
153
if((p != q) && (r != s)){
154
if((p == s) || (q == r))
155
PK[four_index - min_index] -= 0.5 * value;
157
PK[four_index - min_index] -= 0.25 * value;
164
iwl_buf_fetch(&ERIIN);
166
iwl_buf_close(&ERIIN,1);
168
// Half the diagonal elements held in core
169
for(int pq = batch_pq_min[batch]; pq < batch_pq_max[batch]; ++pq){
170
PK[INDEX(pq,pq) - min_index] *= 0.5;
173
// Write the PK matrix to disk
174
write_Raffanetti("PK",PK,batch);
176
fprintf(outfile,"done.");
179
fprintf(outfile,"\n");
183
void SCF::read_so_tei_form_PK_and_K()
185
fprintf(outfile,"\n Reading the two-electron integrals to form PK and K ... ");
188
for(int batch = 0; batch < nbatch; ++batch){
189
fprintf(outfile,"\n batch %3d ... ",batch);
191
// Compute the minimum and maximum indices
192
size_t min_index = batch_index_min[batch];
193
size_t max_index = batch_index_max[batch];
194
size_t buffer_size = max_index - min_index;
196
for(size_t pqrs = 0; pqrs < buffer_size; ++pqrs){
197
PK[pqrs] = 0.0; K[pqrs] = 0.0;
201
size_t p,q,r,s,four_index;
202
int ilsti,nbuf,fi,index;
205
iwl_buf_init(&ERIIN,PSIF_SO_TEI,0.0,1,1);
207
ilsti = ERIIN.lastbuf;
210
for(index=0;index<nbuf;index++){
211
// Compute the [pq] index for this pqrs combination
212
p = (short int)abs((float)ERIIN.labels[fi]);
213
q = ERIIN.labels[fi+1];
214
r = ERIIN.labels[fi+2];
215
s = ERIIN.labels[fi+3];
216
value = ERIIN.values[index];
218
if(pair_sym[p][q] == 0)
220
four_index = INDEX(pair[p][q],pair[r][s]);
221
if((four_index >= min_index) && (four_index < max_index)){
222
PK[four_index - min_index] += value;
225
if(pair_sym[p][r] == 0)
227
four_index = INDEX(pair[p][r],pair[q][s]);
228
if((four_index >= min_index) && (four_index < max_index)){
229
if((p == r) || (q == s)){
230
PK[four_index - min_index] -= 0.5 * value;
231
K[four_index - min_index] -= 0.5 * value;
233
PK[four_index - min_index] -= 0.25 * value;
234
K[four_index - min_index] -= 0.25 * value;
238
if(pair_sym[p][s] == 0){
239
four_index = INDEX(pair[p][s],pair[q][r]);
240
if((four_index >= min_index) && (four_index < max_index)){
241
if((p != q) && (r != s)){
242
if((p == s) || (q == r)){
243
PK[four_index - min_index] -= 0.5 * value;
244
K[four_index - min_index] -= 0.5 * value;
246
PK[four_index - min_index] -= 0.25 * value;
247
K[four_index - min_index] -= 0.25 * value;
255
iwl_buf_fetch(&ERIIN);
257
iwl_buf_close(&ERIIN,1);
259
// Half the diagonal elements held in core
260
for(int pq = batch_pq_min[batch]; pq < batch_pq_max[batch]; ++pq){
261
PK[INDEX(pq,pq) - min_index] *= 0.5;
262
K[INDEX(pq,pq) - min_index] *= 0.5;
265
// Write the PK matrix to disk
266
write_Raffanetti("PK",PK,batch);
267
write_Raffanetti("K",K,batch);
269
fprintf(outfile,"done.");
272
fprintf(outfile,"\n");
276
}} /* End Namespaces */