1 /*------------------------------------------------------------------------------
2
3 icm.cpp
4 computes the Coulomb integral within an image-charge model
5 written by Georgy Samsonidze (January 2010)
6
7 Based on surface.cpp for generating an isosurface of the scalar field.
8 Objects used by ICM refactored out into Common/wfn_utils.cpp by DAS
9
10 The following common objects are used from Common/wfn_utils.cpp
11 macros: MAX
12 structures: CARTESIAN, ELEMENT
13 constants: MAXCHAR, EPS9, INF9, BOHR, vertex, periodic_table
14 functions: lowercase, erasechar, parse, cub_read, xsf_read, cell_set,
15 normal_make, box_check, scalar_clone, inversion, isovalue_scale
16
17 The Coulomb integral is from J. B. Neaton, M. S. Hybertsen, and S. G. Louie,
18 Renormalization of Molecular Electronic Levels at Metal-Molecule Interfaces,
19 Phys. Rev. Lett. 97, 216405 (2006).
20
21 If the wavefunction overlaps with the image plane, 1 / | r - r' | is averaged
22 over r' in the grid cell by Monte Carlo algorithm. Make sure two of the
23 lattice vectors lie in the image plane and the third one is normal to it,
24 otherwise the number of (r,r') pairs to be averaged increases significantly
25 and the code will refuse to run.
26
27 Exactly one of the two blocks in brackets below should appear. Supply the
28 mirror plane lines to do the image-charge model; supply a second filename
29 to compute the Coulomb integral of two different wavefunctions or densities.
30
31 --------------------------------------------------------------------------------
32
33 Input is read from file icm.inp | example (HOMO of benzene)
34
35 inputfilename file | inputfilename C6H6.b_15.cube
36 inputfileformat cube|xsf | inputfileformat cube
37 threshold (0.0,1.0] | threshold 0.99
38 threshold_power 0|1|2 | threshold_power 1
39 coulomb_power 1|2 | coulomb_power 1
40 [
41 mirrorplaneorigin | mirrorplaneorigin
42 <mpox> <mpoy> <mpoz> | 0.0 0.0 -2.0
43 mirrorplanenormal | mirrorplanenormal
44 <mpnx> <mpny> <mpnz> | 0.0 0.0 1.0
45 mirrorplaneunit bohr|angstrom | mirrorplaneunit angstrom
46 ][
47 inputfilename2 file | inputfilename2 C6H6.b_15.cube
48 inputfileformat2 cube|xsf | inputfileformat2 cube
49 ]
50 uc T|F | uc F
51 uco | uco
52 <ucox> <ucoy> <ucoz> | 0.0 0.0 0.0
53 ucv | ucv
54 <ucv1x> <ucv1y> <ucv1z> | 1.0 0.0 0.0
55 <ucv2x> <ucv2y> <ucv2z> | 0.0 1.0 0.0
56 <ucv3x> <ucv3y> <ucv3z> | 0.0 0.0 1.0
57 ucu bohr|angstrom|latvec | ucu latvec
58 sc T|F | sc T
59 sco | sco
60 <scox> <scoy> <scoz> | -0.5 -0.5 -0.5
61 scv | scv
62 <scv1x> <scv1y> <scv1z> | 1.0 0.0 0.0
63 <scv2x> <scv2y> <scv2z> | 0.0 1.0 0.0
64 <scv3x> <scv3y> <scv3z> | 0.0 0.0 1.0
65 scu bohr|angstrom|latvec | scu latvec
66 renormalize | F
67
68 --------------------------------------------------------------------------------
69
70 In the above example, the HOMO wavefunction of benzene is read from a
71 Gaussian Cube file. The wavefunction is placed in the center of the
72 supercell (see the meaning of uc, uco, ucv, ucu, sc, sco, scv, scu
73 parameters in Visual/surface.cpp). The parts of the wavefunction
74 outside an isosurface that contains 99% of the charge density are
75 dropped (parameters threshold and threshold_power have the same
76 meaning as isovalue and power in Visual/surface.cpp). Parameter
77 coulomb_power tells the code whether the wavefunction in the Coulomb
78 integral needs to be squared. Set both powers to 1 if the wavefunction
79 file contains the squared amplitude as produced by ESPRESSO, and to 2
80 for the linear amplitude as in PARATEC or SIESTA. The mirror plane
81 is defined by parameters mirrorplaneorigin and mirrorplanenormal;
82 in the above example it is parallel to the xy plane crossing the
83 z axis at -2 Angstrom.
84
85 ------------------------------------------------------------------------------*/
86
87 #include <stdio.h>
88 #include <stdlib.h>
89 #include <string.h>
90 #include <math.h>
91 #include <limits.h>
92 //#include <time.h>
93 #include "wfn_utils.h"
94
95 #ifdef PARA
96 #include "mpi.h"
97 #endif
98
99 const int NCELL = 2;
100 const int NRAND = 2500000;
101 const double HARTREE = 27.21138505;
102
103 // wtf, these are global variables!!
104 double ravg[2*NCELL+1][2*NCELL+1][2*NCELL+1];
105
106 struct cell_info
107 {
108 bool uc, sc;
109 int ucf, scf;
110 CARTESIAN sfv[3], uco, ucv[3], sco, scv[3];
111 bool renorm;
112 };
113
volume(const CARTESIAN * vec)114 double volume(const CARTESIAN *vec)
115 {
116 return fabs(vec[0].xx * (vec[1].yy * vec[2].zz - vec[2].yy * vec[1].zz) -
117 vec[0].yy * (vec[1].xx * vec[2].zz - vec[2].xx * vec[1].zz) +
118 vec[0].zz * (vec[1].xx * vec[2].yy - vec[2].xx * vec[1].yy));
119 }
120
par_read(const char * pfn,char * ifn,char * iff,char * ifn2,char * iff2,double * threshold,int * threshold_power,int * coulomb_power,CARTESIAN * mpo,CARTESIAN * mpn)121 int par_read(const char *pfn, char *ifn, char *iff, char *ifn2, char *iff2, double *threshold, int *threshold_power, int *coulomb_power, CARTESIAN *mpo, CARTESIAN *mpn)
122 {
123 int ierr, icount = 0, icheck = 0, icount2 = 0, icount_mirror = 0;
124 char s1[MAXCHAR], s2[MAXCHAR], s3[MAXCHAR];
125 char* trash;
126 FILE *hh;
127 bool is_bohr;
128
129 ifn2[0] = '\0';
130 iff2[0] = '\0';
131
132 hh = fopen(pfn, "r");
133 if (hh == NULL)
134 return -1;
135
136 while (!feof(hh))
137 {
138 strncpy(s1, "\0", 1);
139 trash = fgets(s1, MAXCHAR, hh);
140 parse(s1, s2, s3);
141 lowercase(s2);
142 if (strcmp(s2, "inputfilename") == 0)
143 {
144 icount++;
145 erasechar(s3, ' ');
146 erasechar(s3, '\t');
147 strncpy(ifn, s3, MAXCHAR);
148 ifn[MAXCHAR - 1] = '\0';
149 }
150 else if (strcmp(s2, "inputfileformat") == 0)
151 {
152 icount++;
153 erasechar(s3, ' ');
154 erasechar(s3, '\t');
155 strncpy(iff, s3, MAXCHAR);
156 iff[MAXCHAR - 1] = '\0';
157 }
158 if (strcmp(s2, "inputfilename2") == 0)
159 {
160 icount2++;
161 erasechar(s3, ' ');
162 erasechar(s3, '\t');
163 strncpy(ifn2, s3, MAXCHAR);
164 ifn2[MAXCHAR - 1] = '\0';
165 }
166 else if (strcmp(s2, "inputfileformat2") == 0)
167 {
168 icount2++;
169 erasechar(s3, ' ');
170 erasechar(s3, '\t');
171 strncpy(iff2, s3, MAXCHAR);
172 iff2[MAXCHAR - 1] = '\0';
173 }
174 else if (strcmp(s2, "threshold") == 0)
175 {
176 icount++;
177 *threshold = atof(s3);
178 if (*threshold < EPS9 || *threshold > 1.0 + EPS9)
179 {
180 fprintf(stderr, "Value for 'threshold' is not legal.\n");
181 icheck--;
182 }
183 }
184 else if (strcmp(s2, "threshold_power") == 0)
185 {
186 icount++;
187 *threshold_power = atoi(s3);
188 if (*threshold_power < 0 || *threshold_power > 2)
189 {
190 fprintf(stderr, "Value for 'threshold_power' is not legal.\n");
191 icheck--;
192 }
193 }
194 else if (strcmp(s2, "coulomb_power") == 0)
195 {
196 icount++;
197 *coulomb_power = atoi(s3);
198 if (*coulomb_power < 1 || *coulomb_power > 2)
199 {
200 fprintf(stderr, "Value for 'coulomb_power' is not legal.\n");
201 icheck--;
202 }
203 }
204 else if (strcmp(s2, "mirrorplaneorigin") == 0)
205 {
206 icount_mirror++;
207 ierr = fscanf(hh, "%le%le%le\n", &mpo->xx, &mpo->yy, &mpo->zz);
208 }
209 else if (strcmp(s2, "mirrorplanenormal") == 0)
210 {
211 icount_mirror++;
212 ierr = fscanf(hh, "%le%le%le\n", &mpn->xx, &mpn->yy, &mpn->zz);
213 }
214 else if (strcmp(s2, "mirrorplaneunit") == 0)
215 {
216 icount_mirror++;
217 erasechar(s3, ' ');
218 erasechar(s3, '\t');
219 lowercase(s3);
220 if (strcmp(s3, "bohr") == 0)
221 is_bohr = true;
222 else if (strcmp(s3, "angstrom") == 0)
223 is_bohr = false;
224 else
225 {
226 fprintf(stderr, "Value for 'mirrorplaneunit' is not legal.\n");
227 icheck--;
228 }
229 }
230 }
231
232 if(icount2 > 0 && icount_mirror > 0) {
233 fprintf(stderr, "Set parameters about only one of second filename or mirror plane.\n");
234 return -1;
235 }
236
237 if(icount2 <= 0 && icount_mirror <= 0) {
238 fprintf(stderr, "Must set parameters about one of second filename or mirror plane.\n");
239 return -1;
240 }
241
242 if (icount_mirror > 0 && !is_bohr)
243 {
244 mpo->xx /= BOHR;
245 mpo->yy /= BOHR;
246 mpo->zz /= BOHR;
247 }
248
249 ierr = fclose(hh);
250 if (ierr != 0)
251 return -1;
252
253 if (icount != 5)
254 {
255 fprintf(stderr, "Not all non-cell parameters were set.\n");
256 return -1;
257 }
258
259 if (icount2 > 0 && icount2 != 2)
260 {
261 fprintf(stderr, "Not all parameters about second filename were set.\n");
262 return -1;
263 }
264
265 if (icount_mirror > 0 && icount_mirror != 3)
266 {
267 fprintf(stderr, "Not all parameters about mirror plane were set.\n");
268 return -1;
269 }
270
271 if (icheck < 0)
272 return -1;
273
274 return 0;
275 }
276
par_read_cell(const char * pfn,cell_info & ci,char suffix)277 int par_read_cell(const char *pfn, cell_info & ci, char suffix)
278 {
279 int ii, ierr, icount = 0, icheck = 0;
280 char s1[MAXCHAR], s2[MAXCHAR], s3[MAXCHAR];
281 char* trash;
282 FILE *hh;
283
284 hh = fopen(pfn, "r");
285 if (hh == NULL)
286 return -1;
287
288 while (!feof(hh))
289 {
290 strncpy(s1, "\0", 1);
291 trash = fgets(s1, MAXCHAR, hh);
292 parse(s1, s2, s3);
293 lowercase(s2);
294
295 if(suffix != '\0')
296 {
297 if(s2[strlen(s2)-1] == suffix)
298 {
299 // remove suffix
300 s2[strlen(s2)-1] = '\0';
301 }
302 else
303 {
304 continue;
305 }
306 }
307
308 if (strcmp(s2, "uc") == 0)
309 {
310 icount++;
311 erasechar(s3, ' ');
312 erasechar(s3, '\t');
313 lowercase(s3);
314 if (strcmp(s3, "f") == 0 || strcmp(s3, "false") == 0 || strcmp(s3, "n") == 0 || strcmp(s3, "no") == 0)
315 ci.uc = false;
316 else if (strcmp(s3, "t") == 0 || strcmp(s3, "true") == 0 || strcmp(s3, "y") == 0 || strcmp(s3, "yes") == 0)
317 ci.uc = true;
318 else
319 {
320 fprintf(stderr, "Value for 'uc' is not legal.\n");
321 icheck--;
322 }
323 }
324 else if (strcmp(s2, "uco") == 0)
325 {
326 icount++;
327 ierr = fscanf(hh, "%le%le%le\n", &ci.uco.xx, &ci.uco.yy, &ci.uco.zz);
328 }
329 else if (strcmp(s2, "ucv") == 0)
330 {
331 icount++;
332 for (ii = 0; ii < 3; ii++)
333 ierr = fscanf(hh, "%le%le%le\n", &ci.ucv[ii].xx, &ci.ucv[ii].yy, &ci.ucv[ii].zz);
334 }
335 else if (strcmp(s2, "ucu") == 0)
336 {
337 icount++;
338 erasechar(s3, ' ');
339 erasechar(s3, '\t');
340 lowercase(s3);
341 if (strcmp(s3, "bohr") == 0)
342 ci.ucf = 0;
343 else if (strcmp(s3, "angstrom") == 0)
344 ci.ucf = 1;
345 else if (strcmp(s3, "latvec") == 0)
346 ci.ucf = 2;
347 else
348 {
349 fprintf(stderr, "Value for 'ucu' is not legal.\n");
350 icheck--;
351 }
352 }
353 else if (strcmp(s2, "sc") == 0)
354 {
355 icount++;
356 erasechar(s3, ' ');
357 erasechar(s3, '\t');
358 lowercase(s3);
359 if (strcmp(s3, "f") == 0 || strcmp(s3, "false") == 0 || strcmp(s3, "n") == 0 || strcmp(s3, "no") == 0)
360 ci.sc = false;
361 else if (strcmp(s3, "t") == 0 || strcmp(s3, "true") == 0 || strcmp(s3, "y") == 0 || strcmp(s3, "yes") == 0)
362 ci.sc = true;
363 else
364 {
365 fprintf(stderr, "Value for 'sc' is not legal.\n");
366 icheck--;
367 }
368 }
369 else if (strcmp(s2, "sco") == 0)
370 {
371 icount++;
372 ierr = fscanf(hh, "%le%le%le\n", &ci.sco.xx, &ci.sco.yy, &ci.sco.zz);
373 }
374 else if (strcmp(s2, "scv") == 0)
375 {
376 icount++;
377 for (ii = 0; ii < 3; ii++)
378 ierr = fscanf(hh, "%le%le%le\n", &ci.scv[ii].xx, &ci.scv[ii].yy, &ci.scv[ii].zz);
379 }
380 else if (strcmp(s2, "scu") == 0)
381 {
382 icount++;
383 erasechar(s3, ' ');
384 erasechar(s3, '\t');
385 lowercase(s3);
386 if (strcmp(s3, "bohr") == 0)
387 ci.scf = 0;
388 else if (strcmp(s3, "angstrom") == 0)
389 ci.scf = 1;
390 else if (strcmp(s3, "latvec") == 0)
391 ci.scf = 2;
392 else
393 {
394 fprintf(stderr, "Value for 'scu' is not legal.\n");
395 icheck--;
396 }
397 }
398 else if (strcmp(s2, "renormalize") == 0)
399 {
400 icount++;
401 erasechar(s3, ' ');
402 erasechar(s3, '\t');
403 lowercase(s3);
404 if (strcmp(s3, "f") == 0 || strcmp(s3, "false") == 0 || strcmp(s3, "n") == 0 || strcmp(s3, "no") == 0)
405 ci.renorm = false;
406 else if (strcmp(s3, "t") == 0 || strcmp(s3, "true") == 0 || strcmp(s3, "y") == 0 || strcmp(s3, "yes") == 0)
407 ci.renorm = true;
408 else
409 {
410 fprintf(stderr, "Value for 'renorm' is not legal.\n");
411 icheck--;
412 }
413 }
414 }
415
416 ierr = fclose(hh);
417 if (ierr != 0)
418 return -1;
419
420 if (icount != 9)
421 {
422 if(suffix == '\0')
423 {
424 fprintf(stderr, "Not all cell parameters were set.\n");
425 }
426 else
427 {
428 fprintf(stderr, "Not all cell parameters were set, with suffix %c.\n", suffix);
429 }
430 }
431
432 if (icount != 9 || icheck < 0)
433 return -1;
434
435 return 0;
436 }
437
scalar_trunc(double threshold,scalar_field & sf)438 int scalar_trunc(double threshold, scalar_field & sf)
439 {
440 int ii, jj, kk, imin, imax, jmin, jmax, kmin, kmax, ni0, nj0, nk0, ni1, nj1, nk1;
441 double ***scalar0 = NULL;
442
443 ni0 = sf.ni;
444 nj0 = sf.nj;
445 nk0 = sf.nk;
446
447 imin = ni0;
448 imax = -1;
449 jmin = nj0;
450 jmax = -1;
451 kmin = nk0;
452 kmax = -1;
453
454 for (ii = 0; ii < ni0; ii++)
455 for (jj = 0; jj < nj0; jj++)
456 for (kk = 0; kk < nk0; kk++)
457 if (fabs(sf.scalar[ii][jj][kk]) > threshold)
458 {
459 if (ii < imin)
460 imin = ii;
461 if (ii > imax)
462 imax = ii;
463 if (jj < jmin)
464 jmin = jj;
465 if (jj > jmax)
466 jmax = jj;
467 if (kk < kmin)
468 kmin = kk;
469 if (kk > kmax)
470 kmax = kk;
471 }
472
473 ni1 = imax - imin + 1;
474 nj1 = jmax - jmin + 1;
475 nk1 = kmax - kmin + 1;
476
477 if (ni1 < 1 || nj1 < 1 || nk1 < 1)
478 return -1;
479
480 if (ni1 != ni0 || nj1 != nj0 || nk1 != nk0)
481 {
482 sf.ni = ni1;
483 sf.nj = nj1;
484 sf.nk = nk1;
485
486 scalar0 = sf.scalar;
487
488 sf.scalar = allocate_scalar(ni1, nj1, nk1);
489
490 for (ii = 0; ii < ni1; ii++)
491 for (jj = 0; jj < nj1; jj++)
492 for (kk = 0; kk < nk1; kk++)
493 sf.scalar[ii][jj][kk] = scalar0[ii + imin][jj + jmin][kk + kmin];
494
495 deallocate_scalar(scalar0, ni0, nj0);
496
497 sf.origin.xx += sf.stepv[0].xx * double(imin) + sf.stepv[1].xx * double(jmin) + sf.stepv[2].xx * double(kmin);
498 sf.origin.yy += sf.stepv[0].yy * double(imin) + sf.stepv[1].yy * double(jmin) + sf.stepv[2].yy * double(kmin);
499 sf.origin.zz += sf.stepv[0].zz * double(imin) + sf.stepv[1].zz * double(jmin) + sf.stepv[2].zz * double(kmin);
500 }
501
502 if (ni1 == ni0 || nj1 == nj0 || nk1 == nk0)
503 {
504 fprintf(stderr, "WARNING: The selected isovalue overlaps with the edge of the cell.\n");
505 fprintf(stderr, "Beware, the Coulomb integral does not use periodic boundary conditions.\n");
506 }
507
508 return 0;
509 }
510
scalar_norm(int coulomb_power,double * wfnorm,scalar_field & sf,bool renorm)511 int scalar_norm(int coulomb_power, double *wfnorm, scalar_field & sf, bool renorm)
512 {
513 int ii, jj, kk, ierr = 0;
514 double vv, ww = 0.0;
515
516 for (ii = 0; ii < sf.ni; ii++)
517 for (jj = 0; jj < sf.nj; jj++)
518 for (kk = 0; kk < sf.nk; kk++)
519 if (coulomb_power == 1)
520 sf.scalar[ii][jj][kk] = fabs(sf.scalar[ii][jj][kk]);
521 else
522 sf.scalar[ii][jj][kk] = sf.scalar[ii][jj][kk] * sf.scalar[ii][jj][kk];
523
524 vv = volume(sf.stepv) / (BOHR * BOHR * BOHR);
525
526 if (vv < EPS9)
527 ierr = -1;
528
529 for (ii = 0; ii < sf.ni; ii++)
530 for (jj = 0; jj < sf.nj; jj++)
531 for (kk = 0; kk < sf.nk; kk++)
532 ww += sf.scalar[ii][jj][kk];
533
534 if (ww < EPS9)
535 ierr = -1;
536
537 ww *= vv;
538 *wfnorm = ww;
539
540 if(renorm)
541 {
542 for (ii = 0; ii < sf.ni; ii++)
543 for (jj = 0; jj < sf.nj; jj++)
544 for (kk = 0; kk < sf.nk; kk++)
545 sf.scalar[ii][jj][kk] /= *wfnorm;
546 }
547
548 return ierr;
549 }
550
mirror_transform(const CARTESIAN * in,const CARTESIAN * mpn)551 CARTESIAN mirror_transform(const CARTESIAN *in, const CARTESIAN *mpn)
552 {
553 double pp;
554 CARTESIAN dd;
555
556 pp = in->xx * mpn->xx + in->yy * mpn->yy + in->zz * mpn->zz;
557 dd.xx = in->xx - 2 * pp * mpn->xx;
558 dd.yy = in->yy - 2 * pp * mpn->yy;
559 dd.zz = in->zz - 2 * pp * mpn->zz;
560
561 return dd;
562 }
563
564 // convert origin and step vectors from Angstrom to Bohr
convert_to_bohr(scalar_field & sf1)565 void convert_to_bohr(scalar_field & sf1)
566 {
567 int ii;
568
569 sf1.origin.xx /= BOHR;
570 sf1.origin.yy /= BOHR;
571 sf1.origin.zz /= BOHR;
572
573 for (ii = 0; ii < 3; ii++)
574 {
575 sf1.stepv[ii].xx /= BOHR;
576 sf1.stepv[ii].yy /= BOHR;
577 sf1.stepv[ii].zz /= BOHR;
578 }
579 }
580
mirror_plane(CARTESIAN * mpo,CARTESIAN * mpn,scalar_field & sf1,scalar_field & sf2)581 int mirror_plane(CARTESIAN *mpo, CARTESIAN *mpn, scalar_field & sf1, scalar_field & sf2)
582 {
583 int ii;
584 double pp;
585 CARTESIAN aa, dd;
586
587 pp = mpn->xx * mpn->xx + mpn->yy * mpn->yy + mpn->zz * mpn->zz;
588 if (pp < EPS9)
589 return -1;
590 pp = sqrt(pp);
591 if (fabs(1.0 - pp) > EPS9)
592 {
593 mpn->xx /= pp;
594 mpn->yy /= pp;
595 mpn->zz /= pp;
596 }
597
598 for (ii = 0; ii < 4; ii++)
599 {
600 if (ii == 0)
601 {
602 aa.xx = sf1.origin.xx - mpo->xx;
603 aa.yy = sf1.origin.yy - mpo->yy;
604 aa.zz = sf1.origin.zz - mpo->zz;
605 }
606 else
607 {
608 aa.xx = sf1.stepv[ii - 1].xx;
609 aa.yy = sf1.stepv[ii - 1].yy;
610 aa.zz = sf1.stepv[ii - 1].zz;
611 }
612
613 dd = mirror_transform(&aa, mpn);
614
615 if (ii == 0)
616 {
617 sf2.origin.xx = mpo->xx + dd.xx;
618 sf2.origin.yy = mpo->yy + dd.yy;
619 sf2.origin.zz = mpo->zz + dd.zz;
620 }
621 else
622 {
623 sf2.stepv[ii - 1].xx = dd.xx;
624 sf2.stepv[ii - 1].yy = dd.yy;
625 sf2.stepv[ii - 1].zz = dd.zz;
626 }
627 }
628
629 return 0;
630 }
631
632 // shortest step vector of v1 or v2, times NCELL. possibly it doesn't need to be v2 also?
set_cutoff(const CARTESIAN * v1,const CARTESIAN * v2,double * rcutoff,double * r2cutoff)633 void set_cutoff(const CARTESIAN *v1, const CARTESIAN *v2, double *rcutoff, double *r2cutoff)
634 {
635 int ii;
636 double l2, l2min = INF9;
637
638 for (ii = 0; ii < 3; ii++)
639 {
640 l2 = v1[ii].xx * v1[ii].xx + v1[ii].yy * v1[ii].yy + v1[ii].zz * v1[ii].zz;
641 if (l2min > l2)
642 l2min = l2;
643
644 l2 = v2[ii].xx * v2[ii].xx + v2[ii].yy * v2[ii].yy + v2[ii].zz * v2[ii].zz;
645 if (l2min > l2)
646 l2min = l2;
647 }
648 *r2cutoff = l2min * double(NCELL * NCELL);
649 *rcutoff = sqrt(*r2cutoff);
650 }
651
652 // Do the two scalar fields overlap?
check_overlap(int rank,const scalar_field & sf1,const scalar_field & sf2,double rcutoff)653 bool check_overlap(int rank, const scalar_field & sf1, const scalar_field & sf2, double rcutoff)
654 {
655 bool flag_overlap = false;
656 int ii, nplus = 0, nminus = 0, iminus, ngrid1, ngrid2, dplus = 0, dminus = 0;
657 double vl1[3], vl2[3], vdotv, vcosv, vdotr, pp[4], dd[4];
658 CARTESIAN rr[4];
659
660 for (ii = 0; ii < 3; ii++)
661 {
662 vl1[ii] = sqrt(sf1.stepv[ii].xx * sf1.stepv[ii].xx + sf1.stepv[ii].yy * sf1.stepv[ii].yy + sf1.stepv[ii].zz * sf1.stepv[ii].zz);
663 vl2[ii] = sqrt(sf2.stepv[ii].xx * sf2.stepv[ii].xx + sf2.stepv[ii].yy * sf2.stepv[ii].yy + sf2.stepv[ii].zz * sf2.stepv[ii].zz);
664 vdotv = sf1.stepv[ii].xx * sf2.stepv[ii].xx + sf1.stepv[ii].yy * sf2.stepv[ii].yy + sf1.stepv[ii].zz * sf2.stepv[ii].zz;
665 vcosv = vdotv / (vl1[ii] * vl2[ii]);
666 if (fabs(vcosv - 1.0) < EPS9)
667 nplus++;
668 if (fabs(vcosv + 1.0) < EPS9)
669 {
670 nminus++;
671 iminus = ii;
672 }
673 }
674
675 if (nplus == 2 && nminus == 1)
676 {
677 switch (iminus)
678 {
679 case 0:
680 ngrid1 = sf1.ni;
681 ngrid2 = sf2.ni;
682 case 1:
683 ngrid1 = sf1.nj;
684 ngrid2 = sf2.nj;
685 case 2:
686 ngrid1 = sf1.nk;
687 ngrid2 = sf2.nk;
688 }
689
690 rr[0].xx = sf1.origin.xx;
691 rr[0].yy = sf1.origin.yy;
692 rr[0].zz = sf1.origin.zz;
693 rr[1].xx = sf1.origin.xx + sf1.stepv[iminus].xx * double(ngrid1 - 1);
694 rr[1].yy = sf1.origin.yy + sf1.stepv[iminus].yy * double(ngrid1 - 1);
695 rr[1].zz = sf1.origin.zz + sf1.stepv[iminus].zz * double(ngrid1 - 1);
696 rr[2].xx = sf2.origin.xx;
697 rr[2].yy = sf2.origin.yy;
698 rr[2].zz = sf2.origin.zz;
699 rr[3].xx = sf2.origin.xx + sf2.stepv[iminus].xx * double(ngrid2 - 1);
700 rr[3].yy = sf2.origin.yy + sf2.stepv[iminus].yy * double(ngrid2 - 1);
701 rr[3].zz = sf2.origin.zz + sf2.stepv[iminus].zz * double(ngrid2 - 1);
702
703 for (ii = 0; ii < 4; ii++)
704 {
705 vdotr = sf1.stepv[iminus].xx * rr[ii].xx + sf1.stepv[iminus].yy * rr[ii].yy + sf1.stepv[iminus].zz * rr[ii].zz;
706 pp[ii] = vdotr / vl1[iminus];
707 }
708
709 dd[0] = pp[0] - pp[2];
710 dd[1] = pp[0] - pp[3];
711 dd[2] = pp[1] - pp[2];
712 dd[3] = pp[1] - pp[3];
713
714 for (ii = 0; ii < 4; ii++)
715 if (dd[ii] > 0.0)
716 dplus++;
717 else
718 dminus++;
719
720 if (dplus == 4 || dminus == 4)
721 {
722 for (ii = 0; ii < 4; ii++)
723 if (fabs(dd[ii]) < rcutoff)
724 flag_overlap = true;
725 }
726 else
727 flag_overlap = true;
728 }
729 else
730 {
731 if (rank == 0)
732 {
733 fprintf(stderr, " The image plane is not parallel/perpendicular to the lattice vectors.\n");
734 fprintf(stderr, " Skipping wavefunction overlap check and Monte Carlo averaging.\n");
735 fprintf(stderr, " Your job may fail if the wavefunction overlaps with its image.\n\n");
736 }
737 }
738
739 return flag_overlap;
740 }
741
grid_offset(const scalar_field & sf1,const scalar_field & sf2)742 CARTESIAN grid_offset(const scalar_field & sf1, const scalar_field & sf2)
743 {
744 int ii, nn;
745 double lv2, vdotd;
746 CARTESIAN dd;
747
748 dd.xx = sf1.origin.xx - sf2.origin.xx;
749 dd.yy = sf1.origin.yy - sf2.origin.yy;
750 dd.zz = sf1.origin.zz - sf2.origin.zz;
751
752 for (ii = 0; ii < 3; ii++)
753 {
754 lv2 = sf1.stepv[ii].xx * sf1.stepv[ii].xx + sf1.stepv[ii].yy * sf1.stepv[ii].yy + sf1.stepv[ii].zz * sf1.stepv[ii].zz;
755 vdotd = sf1.stepv[ii].xx * dd.xx + sf1.stepv[ii].yy * dd.yy + sf1.stepv[ii].zz * dd.zz;
756 nn = double_to_int(vdotd / lv2);
757
758 dd.xx = dd.xx - sf1.stepv[ii].xx * double(nn);
759 dd.yy = dd.yy - sf1.stepv[ii].yy * double(nn);
760 dd.zz = dd.zz - sf1.stepv[ii].zz * double(nn);
761 }
762
763 return dd;
764 }
765
rand_init()766 void rand_init()
767 {
768 int seed;
769 //time_t seconds;
770
771 // seconds = time(NULL);
772 // seed = (int)seconds;
773 seed = 5000;
774 srand(seed);
775 }
776
mc_average(int rank,int size,const CARTESIAN * offset,const CARTESIAN * v1,const CARTESIAN * v2)777 void mc_average(int rank, int size, const CARTESIAN *offset, const CARTESIAN *v1, const CARTESIAN *v2)
778 {
779 int ii, jj, kk, ll, mm, lmin, lmax, navg;
780 int nlocal[2*NCELL+1][2*NCELL+1][2*NCELL+1];
781 #ifdef PARA
782 int ndummy[2*NCELL+1][2*NCELL+1][2*NCELL+1];
783 #endif
784 double rinv, r2, rr[3];
785 double rlocal[2*NCELL+1][2*NCELL+1][2*NCELL+1];
786 #ifdef PARA
787 double rdummy[2*NCELL+1][2*NCELL+1][2*NCELL+1];
788 #endif
789 CARTESIAN dd, crand;
790
791 #ifdef VERBOSE
792 if (rank == 0)
793 printf(" averaging 1 / | r - r' | over r' in the grid cell\n\n");
794 #endif
795
796 lmin = double_to_int(double(NRAND) * double(rank) / double(size));
797 lmax = double_to_int(double(NRAND) * double(rank + 1) / double(size));
798
799 for (ii = -NCELL; ii <= NCELL; ii++)
800 for (jj = -NCELL; jj <= NCELL; jj++)
801 for (kk = -NCELL; kk <= NCELL; kk++)
802 {
803 nlocal[ii+NCELL][jj+NCELL][kk+NCELL] = lmax - lmin;
804 rlocal[ii+NCELL][jj+NCELL][kk+NCELL] = 0.0;
805 }
806
807 for (ll = lmin; ll < lmax; ll++)
808 {
809 for (mm = 0; mm < 3; mm++)
810 rr[mm] = double(rand()) / double(RAND_MAX) - 0.5;
811
812 crand.xx = v2[0].xx * rr[0] + v2[1].xx * rr[1] + v2[2].xx * rr[2];
813 crand.yy = v2[0].yy * rr[0] + v2[1].yy * rr[1] + v2[2].yy * rr[2];
814 crand.zz = v2[0].zz * rr[0] + v2[1].zz * rr[1] + v2[2].zz * rr[2];
815
816 for (ii = -NCELL; ii <= NCELL; ii++)
817 for (jj = -NCELL; jj <= NCELL; jj++)
818 for (kk = -NCELL; kk <= NCELL; kk++)
819 {
820 dd.xx = offset->xx + v1[0].xx * double(ii) + v1[1].xx * double(jj) + v1[2].xx * double(kk);
821 dd.yy = offset->yy + v1[0].yy * double(ii) + v1[1].yy * double(jj) + v1[2].yy * double(kk);
822 dd.zz = offset->zz + v1[0].zz * double(ii) + v1[1].zz * double(jj) + v1[2].zz * double(kk);
823
824 r2 = (dd.xx - crand.xx) * (dd.xx - crand.xx) + (dd.yy - crand.yy) * (dd.yy - crand.yy) + (dd.zz - crand.zz) * (dd.zz - crand.zz);
825 if (r2 > EPS9)
826 rlocal[ii+NCELL][jj+NCELL][kk+NCELL] += 1.0 / sqrt(r2);
827 else
828 nlocal[ii+NCELL][jj+NCELL][kk+NCELL]--;
829 }
830 }
831
832 #ifdef PARA
833 MPI_Allreduce(nlocal, ndummy, pow(2*NCELL+1, 3), MPI_INTEGER, MPI_SUM, MPI_COMM_WORLD);
834
835 for (ii = -NCELL; ii <= NCELL; ii++)
836 for (jj = -NCELL; jj <= NCELL; jj++)
837 for (kk = -NCELL; kk <= NCELL; kk++)
838 nlocal[ii+NCELL][jj+NCELL][kk+NCELL] = ndummy[ii+NCELL][jj+NCELL][kk+NCELL];
839
840 MPI_Allreduce(rlocal, rdummy, pow(2*NCELL+1, 3), MPI_DOUBLE_PRECISION, MPI_SUM, MPI_COMM_WORLD);
841
842 for (ii = -NCELL; ii <= NCELL; ii++)
843 for (jj = -NCELL; jj <= NCELL; jj++)
844 for (kk = -NCELL; kk <= NCELL; kk++)
845 rlocal[ii+NCELL][jj+NCELL][kk+NCELL] = rdummy[ii+NCELL][jj+NCELL][kk+NCELL];
846 #endif
847
848 for (ii = -NCELL; ii <= NCELL; ii++)
849 for (jj = -NCELL; jj <= NCELL; jj++)
850 for (kk = -NCELL; kk <= NCELL; kk++)
851 ravg[ii+NCELL][jj+NCELL][kk+NCELL] = rlocal[ii+NCELL][jj+NCELL][kk+NCELL] / double(nlocal[ii+NCELL][jj+NCELL][kk+NCELL]);
852 }
853
tab_average(const CARTESIAN * v1,const CARTESIAN * p1,const CARTESIAN * p2,const CARTESIAN * offset)854 double tab_average(const CARTESIAN *v1, const CARTESIAN *p1, const CARTESIAN *p2, const CARTESIAN *offset)
855 {
856 bool f_offset, f_range;
857 int ii, nn[3];
858 double lv2, vdotd, rinv;
859 CARTESIAN dd;
860
861 dd.xx = p1->xx - p2->xx - offset->xx;
862 dd.yy = p1->yy - p2->yy - offset->yy;
863 dd.zz = p1->zz - p2->zz - offset->zz;
864
865 for (ii = 0; ii < 3; ii++)
866 {
867 lv2 = v1[ii].xx * v1[ii].xx + v1[ii].yy * v1[ii].yy + v1[ii].zz * v1[ii].zz;
868 vdotd = v1[ii].xx * dd.xx + v1[ii].yy * dd.yy + v1[ii].zz * dd.zz;
869 nn[ii] = double_to_int(vdotd / lv2);
870
871 dd.xx = dd.xx - v1[ii].xx * double(nn[ii]);
872 dd.yy = dd.yy - v1[ii].yy * double(nn[ii]);
873 dd.zz = dd.zz - v1[ii].zz * double(nn[ii]);
874 }
875
876 f_offset = fabs(dd.xx) < EPS9 && fabs(dd.yy) < EPS9 && fabs(dd.zz) < EPS9;
877 f_range = abs(nn[0]) <= NCELL && abs(nn[1]) <= NCELL && abs(nn[2]) <= NCELL;
878 if (f_offset && f_range)
879 rinv = ravg[nn[0]+NCELL][nn[1]+NCELL][nn[2]+NCELL];
880 else
881 {
882 if(~f_offset) fprintf(stderr, "\nError: f_offset failed in tab_average.\n");
883 if(~f_range) fprintf(stderr, "\nError: f_range failed in tab_average.\n");
884 rinv = -1.0;
885 }
886
887 return rinv;
888 }
889
coulomb_integral(int rank,int size,const CARTESIAN * offset,double r2cutoff,double * energy,const scalar_field & sf1,const scalar_field & sf2)890 int coulomb_integral(int rank, int size, const CARTESIAN *offset, double r2cutoff, double *energy,
891 const scalar_field & sf1, const scalar_field & sf2)
892 {
893 int i1, j1, k1, i2, j2, k2;
894 #ifdef VERBOSE
895 int pnew, pold = -1;
896 #endif
897 double r2, rinv, vol1, vol2, ww = 0.0;
898 #ifdef PARA
899 double rdummy;
900 #endif
901 CARTESIAN p1, p2;
902
903 vol1 = volume(sf1.stepv);
904 if (vol1 < EPS9)
905 {
906 fprintf(stderr, "\nError: cell volume 1 = 0 in coulomb_integral\n\n");
907 return -1;
908 }
909
910 vol2 = volume(sf2.stepv);
911 if (vol2 < EPS9)
912 {
913 fprintf(stderr, "\nError: cell volume 2 = 0 in coulomb_integral\n\n");
914 return -1;
915 }
916
917 for (i1 = 0; i1 < sf1.ni; i1++)
918 for (j1 = 0; j1 < sf1.nj; j1++)
919 for (k1 = 0; k1 < sf1.nk; k1++)
920 {
921
922 #ifdef PARA
923 if ((i1 * sf1.nj * sf1.nk + j1 * sf1.nk + k1) % size != rank)
924 continue;
925 #endif
926
927 #ifdef VERBOSE
928 if (rank == 0)
929 {
930 pnew = double_to_int(100.0 * double(i1 * sf1.nj * sf1.nk + j1 * sf1.nk + k1) / double(sf1.ni * sf1.nj * sf1.nk));
931 if (pnew != pold)
932 {
933 printf(" completed %3i%%\n", pnew);
934 pold = pnew;
935 }
936 }
937 #endif
938
939 p1.xx = sf1.origin.xx + sf1.stepv[0].xx * double(i1) + sf1.stepv[1].xx * double(j1) + sf1.stepv[2].xx * double(k1);
940 p1.yy = sf1.origin.yy + sf1.stepv[0].yy * double(i1) + sf1.stepv[1].yy * double(j1) + sf1.stepv[2].yy * double(k1);
941 p1.zz = sf1.origin.zz + sf1.stepv[0].zz * double(i1) + sf1.stepv[1].zz * double(j1) + sf1.stepv[2].zz * double(k1);
942
943 for (i2 = 0; i2 < sf2.ni; i2++)
944 for (j2 = 0; j2 < sf2.nj; j2++)
945 for (k2 = 0; k2 < sf2.nk; k2++)
946 {
947 p2.xx = sf2.origin.xx + sf2.stepv[0].xx * double(i2) + sf2.stepv[1].xx * double(j2) + sf2.stepv[2].xx * double(k2);
948 p2.yy = sf2.origin.yy + sf2.stepv[0].yy * double(i2) + sf2.stepv[1].yy * double(j2) + sf2.stepv[2].yy * double(k2);
949 p2.zz = sf2.origin.zz + sf2.stepv[0].zz * double(i2) + sf2.stepv[1].zz * double(j2) + sf2.stepv[2].zz * double(k2);
950
951 r2 = (p1.xx - p2.xx) * (p1.xx - p2.xx) + (p1.yy - p2.yy) * (p1.yy - p2.yy) + (p1.zz - p2.zz) * (p1.zz - p2.zz);
952
953 if (r2 > r2cutoff)
954 rinv = 1.0 / sqrt(r2);
955 else
956 rinv = tab_average(sf1.stepv, &p1, &p2, &(*offset));
957
958 if (rinv < -EPS9)
959 {
960 fprintf(stderr, "\nError: rinv < 0 in coulomb_integral\n\n");
961 return -1;
962 }
963
964 ww += sf1.scalar[i1][j1][k1] * sf2.scalar[i2][j2][k2] * rinv;
965 }
966 }
967
968 #ifdef PARA
969 MPI_Barrier(MPI_COMM_WORLD);
970 #endif
971
972 ww *= 0.5 * HARTREE * vol1 * vol2;
973 #ifdef PARA
974 MPI_Reduce(&ww, &rdummy, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD);
975 ww = rdummy;
976 #endif
977 *energy = ww;
978
979 #ifdef VERBOSE
980 if (rank == 0)
981 printf("\n");
982 #endif
983
984 return 0;
985 }
986
terminate(int ierr)987 int terminate(int ierr)
988 {
989 #ifdef PARA
990 if (ierr != 0)
991 MPI_Abort(MPI_COMM_WORLD, ierr);
992 MPI_Finalize();
993 #endif
994
995 return ierr;
996 }
997
main(int argc,char * argv[])998 int main(int argc, char *argv[])
999 {
1000 bool flag_overlap;
1001 int threshold_power, coulomb_power, rank, size, ii, jj, kk, ifile = 0, nfiles;
1002 #ifdef PARA
1003 int idummy, info;
1004 #endif
1005 int ierr = 0, na = 0;
1006 double threshold, wfnorm[2], energy, isovalue[2], rcutoff, r2cutoff;
1007 char pfn[MAXCHAR] = "icm.inp";
1008 char ifn[2][MAXCHAR], iff[2][MAXCHAR];
1009 CARTESIAN mpo, mpn, offset;
1010 cell_info ci;
1011 scalar_field sf[2];
1012
1013 #ifdef PARA
1014 info = MPI_Init(&argc, &argv);
1015 if (info != MPI_SUCCESS)
1016 {
1017 fprintf(stderr, "\nMPI initialization failed\n\n");
1018 return terminate(-1);
1019 }
1020 info = MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1021 info = MPI_Comm_size(MPI_COMM_WORLD, &size);
1022 #else
1023 rank = 0;
1024 size = 1;
1025 #endif
1026
1027 if (rank == 0)
1028 ierr = par_read(pfn, ifn[0], iff[0], ifn[1], iff[1], &threshold, &threshold_power, &coulomb_power, &mpo, &mpn);
1029 #ifdef PARA
1030 info = MPI_Bcast(&ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD);
1031 #endif
1032 if (ierr != 0)
1033 {
1034 if (rank == 0)
1035 fprintf(stderr, "\nError: failed to read %s\n\n", pfn);
1036 return terminate(-1);
1037 }
1038
1039 if(strcmp(ifn[1], "") == 0)
1040 {
1041 nfiles = 1;
1042 }
1043 else
1044 {
1045 nfiles = 2;
1046 }
1047 #ifdef PARA
1048 info = MPI_Bcast(&nfiles, 1, MPI_INTEGER, 0, MPI_COMM_WORLD);
1049 #endif
1050
1051 for(ifile = 0; ifile < nfiles; ifile++) {
1052 if (rank == 0)
1053 {
1054 if(ifile == 0)
1055 {
1056 ierr = par_read_cell(pfn, ci, '\0');
1057 }
1058 else
1059 {
1060 ierr = par_read_cell(pfn, ci, '2');
1061 }
1062 }
1063 #ifdef PARA
1064 info = MPI_Bcast(&ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD);
1065 #endif
1066 if (ierr != 0)
1067 {
1068 if (rank == 0)
1069 fprintf(stderr, "\nError: failed to read %s\n\n", pfn);
1070 return terminate(-1);
1071 }
1072
1073 if (rank == 0)
1074 {
1075 if (strcmp(iff[ifile], "cube") == 0)
1076 {
1077 ierr = cub_read(ifn[ifile], &na, ci.sfv, sf[ifile]);
1078 }
1079 else if (strcmp(iff[ifile], "xsf") == 0)
1080 {
1081 ierr = xsf_read(ifn[ifile], &na, ci.sfv, sf[ifile]);
1082 }
1083 else
1084 {
1085 ierr = -2;
1086 }
1087
1088 // we do not need atom info
1089 if (as != NULL) delete [] as;
1090 if (ap != NULL) delete [] ap;
1091 }
1092 #ifdef PARA
1093 info = MPI_Bcast(&ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD);
1094 #endif
1095 if (ierr == -2)
1096 {
1097 if (rank == 0)
1098 fprintf(stderr, "\nError: unrecognized input format %s\n\n", iff[ifile]);
1099 return terminate(-1);
1100 }
1101 else if (ierr == -1)
1102 {
1103 if (rank == 0)
1104 fprintf(stderr, "\nError: failed to read %s\n\n", ifn[ifile]);
1105 return terminate(-1);
1106 }
1107
1108 // FIXME: moving file 2 via uco or sco does not seem to work?
1109
1110 // printf(" Lattice vectors from file %s:\n", ifn[ifile]);
1111 // for (ii = 0; ii < 3; ii++)
1112 // printf(" v[%i] = %.6f %.6f %.6f (Ang)\n", ii, ci.sfv[ii].xx, ci.sfv[ii].yy, ci.sfv[ii].zz);
1113
1114 if (rank == 0)
1115 cell_set(sf[ifile].origin, ci.sfv, ci.uc, &ci.uco, ci.ucv, ci.ucf, ci.sc, &ci.sco, ci.scv, ci.scf);
1116
1117 if (rank == 0)
1118 if (ci.sc)
1119 ierr = scalar_clone(ci.uco, ci.ucv, ci.sco, ci.scv, sf[ifile]);
1120 #ifdef PARA
1121 info = MPI_Bcast(&ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD);
1122 #endif
1123 if (ierr != 0)
1124 {
1125 if (rank == 0)
1126 fprintf(stderr, "\nError: failed to build supercell\n\n");
1127 return terminate(-1);
1128 }
1129
1130 if (rank == 0)
1131 {
1132 if (threshold < 1.0 - EPS9)
1133 {
1134 isovalue[ifile] = isovalue_scale(threshold_power, threshold, sf[ifile]);
1135 ierr = scalar_trunc(isovalue[ifile], sf[ifile]);
1136 }
1137 else
1138 {
1139 isovalue[ifile] = 0.0;
1140 ierr = 0;
1141 }
1142 }
1143
1144 #ifdef PARA
1145 info = MPI_Bcast(&ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD);
1146 #endif
1147
1148 if (ierr != 0)
1149 {
1150 if (rank == 0)
1151 fprintf(stderr, "\nError: failed in scalar_trunc\n\n");
1152 return terminate(-1);
1153 }
1154
1155 if (rank == 0)
1156 ierr = scalar_norm(coulomb_power, &wfnorm[ifile], sf[ifile], ci.renorm);
1157 #ifdef PARA
1158 info = MPI_Bcast(&ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD);
1159 #endif
1160 if (ierr != 0)
1161 {
1162 if (rank == 0)
1163 fprintf(stderr, "\nError: failed in scalar_norm\n\n");
1164 return terminate(-1);
1165 }
1166
1167 if (rank == 0)
1168 {
1169 convert_to_bohr(sf[ifile]);
1170 if(nfiles == 1)
1171 {
1172 ierr = mirror_plane(&mpo, &mpn, sf[0], sf[1]);
1173 }
1174 else
1175 {
1176 ierr = 0;
1177 }
1178 }
1179 #ifdef PARA
1180 info = MPI_Bcast(&ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD);
1181 #endif
1182 if (ierr != 0)
1183 {
1184 if (rank == 0)
1185 fprintf(stderr, "\nError: failed in mirror_plane\n\n");
1186 return terminate(-1);
1187 }
1188
1189 #ifdef PARA
1190 info = MPI_Bcast(&sf[ifile].ni, 1, MPI_INTEGER, 0, MPI_COMM_WORLD);
1191 info = MPI_Bcast(&sf[ifile].nj, 1, MPI_INTEGER, 0, MPI_COMM_WORLD);
1192 info = MPI_Bcast(&sf[ifile].nk, 1, MPI_INTEGER, 0, MPI_COMM_WORLD);
1193
1194 info = MPI_Bcast(&sf[ifile].origin, 3, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD);
1195 info = MPI_Bcast(sf[ifile].stepv, 9, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD);
1196
1197 if (rank != 0)
1198 {
1199 sf[ifile].scalar = allocate_scalar(sf[ifile].ni, sf[ifile].nj, sf[ifile].nk);
1200 }
1201
1202 for (ii = 0; ii < sf[ifile].ni; ii++)
1203 for (jj = 0; jj < sf[ifile].nj; jj++)
1204 info = MPI_Bcast(sf[ifile].scalar[ii][jj], sf[ifile].nk, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD);
1205 #endif
1206 }
1207
1208 if(nfiles == 1)
1209 {
1210 #ifdef PARA
1211 info = MPI_Bcast(&sf[1].origin, 3, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD);
1212 info = MPI_Bcast(sf[1].stepv, 9, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD);
1213 #endif
1214
1215 sf[1].ni = sf[0].ni;
1216 sf[1].nj = sf[0].nj;
1217 sf[1].nk = sf[0].nk;
1218 sf[1].scalar = sf[0].scalar;
1219 }
1220
1221 if (rank == 0)
1222 {
1223 printf("\n");
1224 for(ifile = 0; ifile < 2; ifile++)
1225 {
1226 printf(" Parameters for grid %i:\n", ifile+1);
1227 printf(" grid = %i %i %i\n", sf[ifile].ni, sf[ifile].nj, sf[ifile].nk);
1228 printf(" Origin and step vectors\n");
1229 printf(" o%i = %.6f %.6f %.6f (Bohr)\n", ifile+1, sf[ifile].origin.xx, sf[ifile].origin.yy, sf[ifile].origin.zz);
1230 for (ii = 0; ii < 3; ii++)
1231 printf(" v%i[%i] = %.6f %.6f %.6f (Bohr)\n", ifile+1, ii, sf[ifile].stepv[ii].xx, sf[ifile].stepv[ii].yy, sf[ifile].stepv[ii].zz);
1232 if(ifile < nfiles)
1233 {
1234 printf(" wfn isovalue = %.15f\n", isovalue[ifile]);
1235 printf(" wfn norm = %.15f\n", wfnorm[ifile]);
1236 }
1237 printf("\n");
1238 }
1239 }
1240
1241 set_cutoff(sf[0].stepv, sf[1].stepv, &rcutoff, &r2cutoff);
1242
1243 if(nfiles == 1)
1244 {
1245 flag_overlap = check_overlap(rank, sf[0], sf[1], rcutoff);
1246 }
1247 else
1248 {
1249 // TODO: new algorithm to check this.
1250 flag_overlap = true;
1251 }
1252
1253 if (flag_overlap)
1254 {
1255 if(rank == 0)
1256 {
1257 printf("Wavefunction overlaps with its image. Using Monte Carlo averaging.\n");
1258 }
1259 offset = grid_offset(sf[0], sf[1]);
1260 rand_init();
1261 mc_average(rank, size, &offset, sf[0].stepv, sf[1].stepv);
1262 }
1263 else
1264 {
1265 for (ii = -NCELL; ii <= NCELL; ii++)
1266 for (jj = -NCELL; jj <= NCELL; jj++)
1267 for (kk = -NCELL; kk <= NCELL; kk++)
1268 ravg[ii+NCELL][jj+NCELL][kk+NCELL] = -1.0;
1269 }
1270
1271 ierr = coulomb_integral(rank, size, &offset, r2cutoff, &energy, sf[0], sf[1]);
1272 #ifdef PARA
1273 info = MPI_Allreduce(&ierr, &idummy, 1, MPI_INTEGER, MPI_SUM, MPI_COMM_WORLD);
1274 ierr = idummy;
1275 #endif
1276 if (ierr != 0)
1277 {
1278 if (rank == 0)
1279 fprintf(stderr, "\nError: failed in coulomb_integral with ierr = %i\n\n", ierr);
1280 return terminate(-1);
1281 }
1282 if (rank == 0)
1283 printf(" coulomb integral = %.15f eV\n\n", energy);
1284
1285 deallocate_scalar(sf[0].scalar, sf[0].ni, sf[0].nj);
1286
1287 if (nfiles == 2)
1288 {
1289 deallocate_scalar(sf[1].scalar, sf[1].ni, sf[1].nj);
1290 }
1291
1292 return terminate(0);
1293 }
1294
1295