~ubuntu-branches/ubuntu/karmic/psicode/karmic

« back to all changes in this revision

Viewing changes to src/lib/libiwl/sortbuf.cc

  • 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
/*!
 
2
  \file
 
3
  \ingroup IWL
 
4
*/
 
5
#include <cstdio>
 
6
#include <cmath>
 
7
#include <libciomr/libciomr.h>
 
8
#include "iwl.h"
 
9
#include "iwl.hpp"
 
10
 
 
11
#define MIN0(a,b) (((a)<(b)) ? (a) : (b))
 
12
#define MAX0(a,b) (((a)>(b)) ? (a) : (b))
 
13
 
 
14
#define BIGNUM 40000
 
15
 
 
16
using namespace psi;
 
17
 
 
18
void IWL::sort_buffer(IWL *Inbuf, IWL *Outbuf,
 
19
    double *ints, int fpq, int lpq, int *ioff, int *ioff2, 
 
20
    int nbfso, int elbert, int intermediate, int no_pq_perm, 
 
21
    int qdim, int add, int printflg, FILE *outfile)
 
22
{
 
23
    int i;
 
24
    Value *valptr;              /* array of integral values */
 
25
    Label *lblptr;              /* array of integral labels */
 
26
    int idx;                    /* index for curr integral (0..ints_per_buf) */
 
27
    int lastbuf;                /* last buffer flag */
 
28
    int p, q, qmax, qmin, r, rmin, rmax, s, smin, smax, pq, rs;
 
29
    long int pqrs, offset;
 
30
    int first_p, first_q, first_pq, last_p, last_q;
 
31
    int nbstri;
 
32
 
 
33
    if (printflg) {
 
34
        fprintf(outfile, "\nsortbuf for pq=%d to %d\n", fpq, lpq);
 
35
    }
 
36
 
 
37
    if (no_pq_perm && !intermediate) {
 
38
        fprintf(outfile,"(sortbuf): illegal parameter combination.\n");
 
39
        fprintf(stderr, "(sortbuf): illegal parameter combination.\n");
 
40
    }
 
41
 
 
42
    nbstri = nbfso * (nbfso + 1) / 2;
 
43
 
 
44
    /* figure out ranges on things */
 
45
    /* I believe this section works fine, even with different ioff arrays */
 
46
    i = 0;
 
47
    while (fpq >= ioff[i] && i < BIGNUM) i++;
 
48
    if (i == BIGNUM) {
 
49
        fprintf(outfile, "(sortbuf): parameter error\n") ;
 
50
        return;
 
51
    }
 
52
    first_p = i-1 ; first_q = fpq - ioff[i-1];
 
53
    first_pq = ioff[first_p] + first_q;
 
54
    if (first_pq != fpq) {
 
55
        fprintf(outfile, "(sortbuf): fpq != first_pq.\n");
 
56
        fprintf(stderr,  "(sortbuf): fpq != first_pq.\n");
 
57
    }
 
58
 
 
59
    if (!intermediate) {
 
60
        if (elbert) offset = ioff2[first_pq] + first_pq ;
 
61
        else offset = ioff[first_pq] ;
 
62
    }
 
63
    else offset = 0;
 
64
 
 
65
    i=0; 
 
66
    while (lpq >= ioff[i] && i < BIGNUM) i++ ;
 
67
    if (i == BIGNUM) {
 
68
        fprintf(outfile, "(sortbuf): parameter error\n") ;
 
69
        return ;
 
70
    }
 
71
    last_p = i-1 ; last_q = lpq - ioff[i-1] ;
 
72
 
 
73
 
 
74
    lblptr = Inbuf->labels_;
 
75
    valptr = Inbuf->values_;
 
76
 
 
77
    /* read a buffer at a time until we're done */
 
78
 
 
79
    do {
 
80
        Inbuf->fetch();
 
81
        lastbuf = Inbuf->lastbuf_;
 
82
        for (idx=4*Inbuf->idx_; Inbuf->idx_<Inbuf->inbuf_; Inbuf->idx_++) {
 
83
            p = (int) lblptr[idx++];
 
84
            q = (int) lblptr[idx++];
 
85
            r = (int) lblptr[idx++];
 
86
            s = (int) lblptr[idx++];
 
87
 
 
88
            /* if (no_pq_perm) ioff is the appropriate offset array for the left
 
89
               indices (ioff[p] = nvirt * p for MP2); ioff2 is then the usual
 
90
               ioff offset array, used for the right indices */
 
91
            if (no_pq_perm) {
 
92
                pq = ioff[p] + q;
 
93
                rs = ioff2[MAX0(r,s)] + MIN0(r,s);
 
94
            }
 
95
            else {
 
96
                pq = ioff[MAX0(p,q)] + MIN0(p,q);
 
97
                rs = ioff[MAX0(r,s)] + MIN0(r,s);
 
98
            }
 
99
 
 
100
            if (!intermediate) {
 
101
                if (elbert)
 
102
                    pqrs = ioff2[pq] + rs;
 
103
                else {
 
104
                    pqrs = ioff[MAX0(pq,rs)];
 
105
                    pqrs += MIN0(pq,rs);
 
106
                }
 
107
            }
 
108
            else {
 
109
                pqrs = (pq - first_pq);
 
110
                pqrs *= nbstri;
 
111
                pqrs += rs;
 
112
            }
 
113
 
 
114
            if (printflg && ints[pqrs-offset] != 0.0) 
 
115
                fprintf(outfile, "Adding %10.6f to el %d %d %d %d = %10.6lf\n", 
 
116
                valptr[Inbuf->idx_], p, q, r, s, ints[pqrs-offset]);
 
117
 
 
118
            if (add) ints[pqrs-offset] += valptr[Inbuf->idx_];
 
119
            else ints[pqrs-offset] += valptr[Inbuf->idx_];
 
120
 
 
121
            if (printflg) 
 
122
                fprintf(outfile, "<%d %d %d %d | %d %d [%ld] = %10.6f\n",
 
123
                p, q, r, s, pq, rs, pqrs, ints[pqrs-offset]) ;
 
124
        }
 
125
    } while (!lastbuf);
 
126
 
 
127
    /* now write them out again, in order */
 
128
    lblptr = Outbuf->labels_;
 
129
    valptr = Outbuf->values_;
 
130
 
 
131
    idx = 0;
 
132
 
 
133
    for (p=first_p; p<=last_p; p++) {
 
134
        qmax = (p==last_p) ? last_q : p ;
 
135
        qmin = (p==first_p) ? first_q : 0 ;
 
136
        if(no_pq_perm) {
 
137
            qmax = (p==last_p) ? last_q : (qdim-1);
 
138
            qmin = (p==first_p) ? first_q: 0;
 
139
        }
 
140
        for (q=qmin; q<=qmax; q++) {
 
141
            pq = ioff[p] + q ; /* This should be fine even with MP2 */
 
142
 
 
143
            if (!intermediate) {
 
144
                rmin = (elbert) ? p : 0 ; 
 
145
                rmax = (elbert) ? nbfso : p+1 ;
 
146
            }
 
147
            else {  /* This should be fine with MP2, also */
 
148
                rmin = 0;
 
149
                rmax = nbfso;
 
150
            }
 
151
 
 
152
            for (r=rmin; r<rmax; r++) {
 
153
 
 
154
                if (!intermediate) {
 
155
                    if (elbert) {
 
156
                        smax = r+1 ;
 
157
                        smin = (p==r) ? q : 0 ;
 
158
                    }
 
159
                    else {
 
160
                        smax = (p==r) ? (q+1) : (r+1) ;
 
161
                        smin = 0 ;
 
162
                    }
 
163
                }
 
164
                else { /* This should be fine with MP2, also */
 
165
                    smax = r + 1;
 
166
                    smin = 0;
 
167
                }
 
168
 
 
169
                for (s=smin; s < smax; s++) {
 
170
                    if(no_pq_perm) rs = ioff2[r] + s;
 
171
                    else rs = ioff[r] + s;
 
172
 
 
173
                    /* Again, this should be fine with MP2 */
 
174
                    if (elbert) pqrs = ioff2[pq] + rs ;
 
175
                    else if (intermediate) {
 
176
                        pqrs = (pq - first_pq);
 
177
                        pqrs *= nbstri;
 
178
                        pqrs += rs;
 
179
                    }
 
180
                    else pqrs = ioff[pq] + rs ;
 
181
 
 
182
                    if (fabs(ints[pqrs-offset]) > Outbuf->cutoff_) {
 
183
                        idx = 4*Outbuf->idx_;
 
184
                        lblptr[idx++] = p;
 
185
                        lblptr[idx++] = q;
 
186
                        lblptr[idx++] = r;
 
187
                        lblptr[idx++] = s;
 
188
                        valptr[Outbuf->idx_] = ints[pqrs-offset];
 
189
                        if (printflg) 
 
190
                            fprintf(outfile, ">%d %d %d %d | %d %d [%ld] = %10.6f\n",
 
191
                            p, q, r, s, pq, rs, pqrs, ints[pqrs-offset]) ;
 
192
 
 
193
                        Outbuf->idx_++;
 
194
                        if (Outbuf->idx_ == Outbuf->ints_per_buf_) {
 
195
                            Outbuf->lastbuf_ = 0;
 
196
                            Outbuf->inbuf_ = Outbuf->idx_;
 
197
                            Outbuf->put();
 
198
                            Outbuf->idx_ = 0;
 
199
                        } 
 
200
                    }
 
201
                }
 
202
            }
 
203
        }
 
204
    }
 
205
}
 
206
 
 
207
extern "C" {
 
208
        
 
209
/*!
 
210
** sortbuf()
 
211
**
 
212
** Function reads a file of two-electron integrals into
 
213
** core and writes them back out again in canonical order.  Used in
 
214
** Yoshimine sorts where we have a file containing all rs for a few
 
215
** values of pq, but the ints are not in canonical order.  At the 
 
216
** very least, we need to sort to make sure that all (pq|rs) for a
 
217
** given pq are grouped together, since the transformation program
 
218
** wants to work with all rs for a single pq value at one time.
 
219
** We may or may not use the restriction pq >= rs (not used if 
 
220
** intermediate = 1, which is how this routine is always called
 
221
** right now).
 
222
**
 
223
** One interesting issue here is that the intermediate array ('ints')
 
224
** must be big enough to hold the integrals in the current buffer, but
 
225
** we don't generally want it to be much larger than necessary!  Thus
 
226
** we calculate an 'offset' which is the canonical index of the first
 
227
** integral in the buffer, and we use this so that the first integral
 
228
** in the buffer is stored in ints[0].  What's different for the
 
229
** Elbert ordering is that we have all rs for a given pq but rs >= pq!
 
230
** If we want our canonical indices to be consecutive WITHIN THE
 
231
** CURRENT BUFFER, we MUST use upper triangle ordering rather than 
 
232
** lower triangle!  That's what ioff2 is used for.  Obviously the
 
233
** offset must also be calculated with ioff2 for the Elbert order.
 
234
** Formula for ioff2: ioff2[0] = 0; ioff2[i] = ioff2[i-1] + n - i;
 
235
** Note that this is not the case when this routine is used for MP2
 
236
** sorts.  The definitions of the ioff arrays can be confusing, so
 
237
** care should be taken when using this routine.
 
238
**
 
239
**    \param Inbuf       = IWL buffer for input
 
240
**    \param Outbuf      = IWL buffer for output
 
241
**    \param ints        = array to hold integrals in
 
242
**    \param fpq         = first pq for this tape
 
243
**    \param lpq         = last pq for this tape 
 
244
**    \param ioff        = offset array for the left indices
 
245
**    \param ioff2       = offset array for Elbert sorts or for the right 
 
246
**                  indices when no_pq_perm=1 
 
247
**    \param nbfso       = number of basis functions in SO's
 
248
**    \param lastsort    = 1 if this is the last intape, 0 otherwise
 
249
**    \param elbert      = integrals obey rs >= pq.  Use ioff2 to get offset.
 
250
**    \param intermediate= 1 if sorting a intermediate in the transformation
 
251
**                  which is indexed as X[ij][kl] where ij runs from
 
252
**                  fpq to lpq and kl runs from 0 to nbstri
 
253
**    \param no_pq_perm  = don't use permutational symmetry to swap p and q
 
254
**                  (appropriate for MP2 where one is occ and one is virt)
 
255
**    \param qdim        = dimensions for the q index...nvirt for MP2
 
256
**    \param add         = add contributions to the same integral during sort
 
257
**    \param printflg    = 1 for printing, 0 otherwise
 
258
**    \param outfile     = output file pointer
 
259
**
 
260
** Returns: none
 
261
**
 
262
** Revised 6/27/96 by CDS for new IWL format
 
263
** N.B. Now need to iwl_flush the output buffer...not done in here!!
 
264
** \ingroup IWL
 
265
*/
 
266
void sortbuf(struct iwlbuf *Inbuf, struct iwlbuf *Outbuf,
 
267
      double *ints, int fpq, int lpq, int *ioff, int *ioff2, 
 
268
      int nbfso, int elbert, int intermediate, int no_pq_perm, 
 
269
      int qdim, int add, int printflg, FILE *outfile) 
 
270
{
 
271
   int i;
 
272
   Value *valptr;              /* array of integral values */
 
273
   Label *lblptr;              /* array of integral labels */
 
274
   int idx;                    /* index for curr integral (0..ints_per_buf) */
 
275
   int lastbuf;                /* last buffer flag */
 
276
   int p, q, qmax, qmin, r, rmin, rmax, s, smin, smax, pq, rs;
 
277
   long int pqrs, offset;
 
278
   int first_p, first_q, first_pq, last_p, last_q;
 
279
   int nbstri;
 
280
 
 
281
   if (printflg) {
 
282
     fprintf(outfile, "\nsortbuf for pq=%d to %d\n", fpq, lpq);
 
283
   }
 
284
 
 
285
   if (no_pq_perm && !intermediate) {
 
286
     fprintf(outfile,"(sortbuf): illegal parameter combination.\n");
 
287
     fprintf(stderr, "(sortbuf): illegal parameter combination.\n");
 
288
   }
 
289
   
 
290
   nbstri = nbfso * (nbfso + 1) / 2;
 
291
   
 
292
   /* figure out ranges on things */
 
293
   /* I believe this section works fine, even with different ioff arrays */
 
294
   i = 0;
 
295
   while (fpq >= ioff[i] && i < BIGNUM) i++;
 
296
   if (i == BIGNUM) {
 
297
     fprintf(outfile, "(sortbuf): parameter error\n") ;
 
298
     return;
 
299
   }
 
300
   first_p = i-1 ; first_q = fpq - ioff[i-1];
 
301
   first_pq = ioff[first_p] + first_q;
 
302
   if (first_pq != fpq) {
 
303
     fprintf(outfile, "(sortbuf): fpq != first_pq.\n");
 
304
     fprintf(stderr,  "(sortbuf): fpq != first_pq.\n");
 
305
   }
 
306
   
 
307
   if (!intermediate) {
 
308
     if (elbert) offset = ioff2[first_pq] + first_pq ;
 
309
     else offset = ioff[first_pq] ;
 
310
   }
 
311
   else offset = 0;
 
312
 
 
313
   i=0; 
 
314
   while (lpq >= ioff[i] && i < BIGNUM) i++ ;
 
315
   if (i == BIGNUM) {
 
316
     fprintf(outfile, "(sortbuf): parameter error\n") ;
 
317
     return ;
 
318
   }
 
319
   last_p = i-1 ; last_q = lpq - ioff[i-1] ;
 
320
   
 
321
   
 
322
   lblptr = Inbuf->labels;
 
323
   valptr = Inbuf->values;
 
324
 
 
325
   /* read a buffer at a time until we're done */
 
326
 
 
327
   do {
 
328
      iwl_buf_fetch(Inbuf);
 
329
      lastbuf = Inbuf->lastbuf;
 
330
      for (idx=4*Inbuf->idx; Inbuf->idx<Inbuf->inbuf; Inbuf->idx++) {
 
331
        p = (int) lblptr[idx++];
 
332
        q = (int) lblptr[idx++];
 
333
        r = (int) lblptr[idx++];
 
334
        s = (int) lblptr[idx++];
 
335
 
 
336
        /* if (no_pq_perm) ioff is the appropriate offset array for the left
 
337
           indices (ioff[p] = nvirt * p for MP2); ioff2 is then the usual
 
338
           ioff offset array, used for the right indices */
 
339
        if (no_pq_perm) {
 
340
          pq = ioff[p] + q;
 
341
          rs = ioff2[MAX0(r,s)] + MIN0(r,s);
 
342
        }
 
343
        else {
 
344
          pq = ioff[MAX0(p,q)] + MIN0(p,q);
 
345
          rs = ioff[MAX0(r,s)] + MIN0(r,s);
 
346
        }
 
347
        
 
348
        if (!intermediate) {
 
349
          if (elbert)
 
350
            pqrs = ioff2[pq] + rs;
 
351
          else {
 
352
            pqrs = ioff[MAX0(pq,rs)];
 
353
            pqrs += MIN0(pq,rs);
 
354
          }
 
355
        }
 
356
        else {
 
357
          pqrs = (pq - first_pq);
 
358
          pqrs *= nbstri;
 
359
          pqrs += rs;
 
360
        }
 
361
        
 
362
        if (printflg && ints[pqrs-offset] != 0.0) 
 
363
           fprintf(outfile, "Adding %10.6lf to el %d %d %d %d = %10.6lf\n", 
 
364
                   valptr[Inbuf->idx], p, q, r, s, ints[pqrs-offset]);
 
365
 
 
366
        if (add) ints[pqrs-offset] += valptr[Inbuf->idx];
 
367
        else ints[pqrs-offset] += valptr[Inbuf->idx];
 
368
 
 
369
        if (printflg) 
 
370
          fprintf(outfile, "<%d %d %d %d | %d %d [%ld] = %10.6lf\n",
 
371
                  p, q, r, s, pq, rs, pqrs, ints[pqrs-offset]) ;
 
372
      }
 
373
   } while (!lastbuf);
 
374
   
 
375
   /* now write them out again, in order */
 
376
   lblptr = Outbuf->labels;
 
377
   valptr = Outbuf->values;
 
378
 
 
379
   idx = 0;
 
380
 
 
381
   for (p=first_p; p<=last_p; p++) {
 
382
     qmax = (p==last_p) ? last_q : p ;
 
383
     qmin = (p==first_p) ? first_q : 0 ;
 
384
     if(no_pq_perm) {
 
385
       qmax = (p==last_p) ? last_q : (qdim-1);
 
386
       qmin = (p==first_p) ? first_q: 0;
 
387
     }
 
388
     for (q=qmin; q<=qmax; q++) {
 
389
       pq = ioff[p] + q ; /* This should be fine even with MP2 */
 
390
       
 
391
       if (!intermediate) {
 
392
         rmin = (elbert) ? p : 0 ; 
 
393
         rmax = (elbert) ? nbfso : p+1 ;
 
394
       }
 
395
       else {  /* This should be fine with MP2, also */
 
396
         rmin = 0;
 
397
         rmax = nbfso;
 
398
       }
 
399
       
 
400
       for (r=rmin; r<rmax; r++) {
 
401
         
 
402
         if (!intermediate) {
 
403
           if (elbert) {
 
404
             smax = r+1 ;
 
405
             smin = (p==r) ? q : 0 ;
 
406
           }
 
407
           else {
 
408
             smax = (p==r) ? (q+1) : (r+1) ;
 
409
             smin = 0 ;
 
410
           }
 
411
         }
 
412
         else { /* This should be fine with MP2, also */
 
413
           smax = r + 1;
 
414
           smin = 0;
 
415
         }
 
416
         
 
417
         for (s=smin; s < smax; s++) {
 
418
           if(no_pq_perm) rs = ioff2[r] + s;
 
419
           else rs = ioff[r] + s;
 
420
           
 
421
           /* Again, this should be fine with MP2 */
 
422
           if (elbert) pqrs = ioff2[pq] + rs ;
 
423
           else if (intermediate) {
 
424
             pqrs = (pq - first_pq);
 
425
             pqrs *= nbstri;
 
426
             pqrs += rs;
 
427
           }
 
428
           else pqrs = ioff[pq] + rs ;
 
429
           
 
430
           if (fabs(ints[pqrs-offset]) > Outbuf->cutoff) {
 
431
             idx = 4*Outbuf->idx;
 
432
             lblptr[idx++] = p;
 
433
             lblptr[idx++] = q;
 
434
             lblptr[idx++] = r;
 
435
             lblptr[idx++] = s;
 
436
             valptr[Outbuf->idx] = ints[pqrs-offset];
 
437
             if (printflg) 
 
438
               fprintf(outfile, ">%d %d %d %d | %d %d [%ld] = %10.6lf\n",
 
439
                       p, q, r, s, pq, rs, pqrs, ints[pqrs-offset]) ;
 
440
             
 
441
             Outbuf->idx++;
 
442
             if (Outbuf->idx == Outbuf->ints_per_buf) {
 
443
               Outbuf->lastbuf = 0;
 
444
               Outbuf->inbuf = Outbuf->idx;
 
445
               iwl_buf_put(Outbuf);
 
446
               Outbuf->idx = 0;
 
447
             } 
 
448
           }
 
449
         }
 
450
       }
 
451
     }
 
452
   }
 
453
   
 
454
}
 
455
 
 
456
 
 
457
} /* extern "C" */
 
 
b'\\ No newline at end of file'