(git:3add494)
grid_cpu_collocate.c
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* CP2K: A general program to perform molecular dynamics simulations */
3 /* Copyright 2000-2024 CP2K developers group <https://cp2k.org> */
4 /* */
5 /* SPDX-License-Identifier: BSD-3-Clause */
6 /*----------------------------------------------------------------------------*/
7 
8 #include <assert.h>
9 #include <float.h>
10 #include <limits.h>
11 #include <math.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 
16 #define GRID_DO_COLLOCATE 1
17 #include "../common/grid_common.h"
18 #include "grid_cpu_collint.h"
19 #include "grid_cpu_collocate.h"
20 #include "grid_cpu_integrate.h"
21 #include "grid_cpu_prepare_pab.h"
22 
23 /*******************************************************************************
24  * \brief Writes the given arguments into a .task file.
25  * See grid_replay.h for details.
26  * \author Ole Schuett
27  ******************************************************************************/
28 static void write_task_file(
29  const bool orthorhombic, const int border_mask, const enum grid_func func,
30  const int la_max, const int la_min, const int lb_max, const int lb_min,
31  const double zeta, const double zetb, const double rscale,
32  const double dh[3][3], const double dh_inv[3][3], const double ra[3],
33  const double rab[3], const int npts_global[3], const int npts_local[3],
34  const int shift_local[3], const int border_width[3], const double radius,
35  const int o1, const int o2, const int n1, const int n2,
36  const double pab[n2][n1], const double *grid) {
37 
38  static int counter = 1;
39  int my_number;
40 
41 #pragma omp critical
42  my_number = counter++;
43 
44  char filename[100];
45  snprintf(filename, sizeof(filename), "grid_collocate_%05i.task", my_number);
46 
47  const int D = DBL_DECIMAL_DIG;
48  FILE *fp = fopen(filename, "w+");
49  fprintf(fp, "#Grid task v10\n");
50  fprintf(fp, "orthorhombic %i\n", orthorhombic);
51  fprintf(fp, "border_mask %i\n", border_mask);
52  fprintf(fp, "func %i\n", func);
53  fprintf(fp, "la_max %i\n", la_max);
54  fprintf(fp, "la_min %i\n", la_min);
55  fprintf(fp, "lb_max %i\n", lb_max);
56  fprintf(fp, "lb_min %i\n", lb_min);
57  fprintf(fp, "zeta %.*e\n", D, zeta);
58  fprintf(fp, "zetb %.*e\n", D, zetb);
59  fprintf(fp, "rscale %.*e\n", D, rscale);
60  for (int i = 0; i < 3; i++)
61  fprintf(fp, "dh %i %.*e %.*e %.*e\n", i, D, dh[i][0], D, dh[i][1], D,
62  dh[i][2]);
63  for (int i = 0; i < 3; i++)
64  fprintf(fp, "dh_inv %i %.*e %.*e %.*e\n", i, D, dh_inv[i][0], D,
65  dh_inv[i][1], D, dh_inv[i][2]);
66  fprintf(fp, "ra %.*e %.*e %.*e\n", D, ra[0], D, ra[1], D, ra[2]);
67  fprintf(fp, "rab %.*e %.*e %.*e\n", D, rab[0], D, rab[1], D, rab[2]);
68  fprintf(fp, "npts_global %i %i %i\n", npts_global[0], npts_global[1],
69  npts_global[2]);
70  fprintf(fp, "npts_local %i %i %i\n", npts_local[0], npts_local[1],
71  npts_local[2]);
72  fprintf(fp, "shift_local %i %i %i\n", shift_local[0], shift_local[1],
73  shift_local[2]);
74  fprintf(fp, "border_width %i %i %i\n", border_width[0], border_width[1],
75  border_width[2]);
76  fprintf(fp, "radius %.*e\n", D, radius);
77  fprintf(fp, "o1 %i\n", o1);
78  fprintf(fp, "o2 %i\n", o2);
79  fprintf(fp, "n1 %i\n", n1);
80  fprintf(fp, "n2 %i\n", n2);
81 
82  for (int i = 0; i < n2; i++) {
83  for (int j = 0; j < n1; j++) {
84  fprintf(fp, "pab %i %i %.*e\n", i, j, D, pab[i][j]);
85  }
86  }
87 
88  const int npts_local_total = npts_local[0] * npts_local[1] * npts_local[2];
89 
90  int ngrid_nonzero = 0;
91  for (int i = 0; i < npts_local_total; i++) {
92  if (grid[i] != 0.0) {
93  ngrid_nonzero++;
94  }
95  }
96  fprintf(fp, "ngrid_nonzero %i\n", ngrid_nonzero);
97 
98  for (int k = 0; k < npts_local[2]; k++) {
99  for (int j = 0; j < npts_local[1]; j++) {
100  for (int i = 0; i < npts_local[0]; i++) {
101  const double val =
102  grid[k * npts_local[1] * npts_local[0] + j * npts_local[0] + i];
103  if (val != 0.0) {
104  fprintf(fp, "grid %i %i %i %.*e\n", i, j, k, D, val);
105  }
106  }
107  }
108  }
109 
110  double hab[n2][n1];
111  double forces[2][3] = {0};
112  double virials[2][3][3] = {0};
113  memset(hab, 0, n2 * n1 * sizeof(double));
114 
115  const bool compute_tau = (func == GRID_FUNC_DADB);
116 
117  grid_cpu_integrate_pgf_product(orthorhombic, compute_tau, border_mask, la_max,
118  la_min, lb_max, lb_min, zeta, zetb, dh, dh_inv,
119  ra, rab, npts_global, npts_local, shift_local,
120  border_width, radius, o1, o2, n1, n2, grid,
121  hab, pab, forces, virials, NULL, NULL, NULL);
122 
123  for (int i = o2; i < ncoset(lb_max) + o2; i++) {
124  for (int j = o1; j < ncoset(la_max) + o1; j++) {
125  fprintf(fp, "hab %i %i %.*e\n", i, j, D, hab[i][j]);
126  }
127  }
128  fprintf(fp, "force_a %.*e %.*e %.*e\n", D, forces[0][0], D, forces[0][1], D,
129  forces[0][2]);
130  fprintf(fp, "force_b %.*e %.*e %.*e\n", D, forces[1][0], D, forces[1][1], D,
131  forces[1][2]);
132  for (int i = 0; i < 3; i++)
133  fprintf(fp, "virial %i %.*e %.*e %.*e\n", i, D,
134  virials[0][i][0] + virials[1][i][0], D,
135  virials[0][i][1] + virials[1][i][1], D,
136  virials[0][i][2] + virials[1][i][2]);
137 
138  fprintf(fp, "#THE_END\n");
139  fclose(fp);
140  printf("Wrote %s\n", filename);
141 }
142 
143 /*******************************************************************************
144  * \brief Collocates a single product of primitiv Gaussians.
145  * See grid_cpu_collocate.h for details.
146  * \author Ole Schuett
147  ******************************************************************************/
148 static void collocate_internal(
149  const bool orthorhombic, const int border_mask, const enum grid_func func,
150  const int la_max, const int la_min, const int lb_max, const int lb_min,
151  const double zeta, const double zetb, const double rscale,
152  const double dh[3][3], const double dh_inv[3][3], const double ra[3],
153  const double rab[3], const int npts_global[3], const int npts_local[3],
154  const int shift_local[3], const int border_width[3], const double radius,
155  const int o1, const int o2, const int n1, const int n2,
156  const double pab[n2][n1], double *grid) {
157 
158  int la_min_diff, la_max_diff, lb_min_diff, lb_max_diff;
159  grid_cpu_prepare_get_ldiffs(func, &la_min_diff, &la_max_diff, &lb_min_diff,
160  &lb_max_diff);
161 
162  const int la_min_cab = imax(la_min + la_min_diff, 0);
163  const int lb_min_cab = imax(lb_min + lb_min_diff, 0);
164  const int la_max_cab = la_max + la_max_diff;
165  const int lb_max_cab = lb_max + lb_max_diff;
166  const int n1_cab = ncoset(la_max_cab);
167  const int n2_cab = ncoset(lb_max_cab);
168 
169  const size_t cab_size = n2_cab * n1_cab;
170  double cab[cab_size];
171  memset(cab, 0, cab_size * sizeof(double));
172 
173  grid_cpu_prepare_pab(func, o1, o2, la_max, la_min, lb_max, lb_min, zeta, zetb,
174  n1, n2, pab, n1_cab, n2_cab, (double(*)[n1_cab])cab);
175  cab_to_grid(orthorhombic, border_mask, la_max_cab, la_min_cab, lb_max_cab,
176  lb_min_cab, zeta, zetb, rscale, dh, dh_inv, ra, rab, npts_global,
177  npts_local, shift_local, border_width, radius, cab, grid);
178 }
179 
180 /*******************************************************************************
181  * \brief Public entry point. A thin wrapper with the only purpose of calling
182  * write_task_file when DUMP_TASKS = true.
183  * \author Ole Schuett
184  ******************************************************************************/
186  const bool orthorhombic, const int border_mask, const enum grid_func func,
187  const int la_max, const int la_min, const int lb_max, const int lb_min,
188  const double zeta, const double zetb, const double rscale,
189  const double dh[3][3], const double dh_inv[3][3], const double ra[3],
190  const double rab[3], const int npts_global[3], const int npts_local[3],
191  const int shift_local[3], const int border_width[3], const double radius,
192  const int o1, const int o2, const int n1, const int n2,
193  const double pab[n2][n1], double *grid) {
194 
195  // Set this to true to write each task to a file.
196  const bool DUMP_TASKS = false;
197 
198  double *grid_before = NULL;
199  const size_t npts_local_total = npts_local[0] * npts_local[1] * npts_local[2];
200 
201  if (DUMP_TASKS) {
202  const size_t sizeof_grid = sizeof(double) * npts_local_total;
203  grid_before = malloc(sizeof_grid);
204  memcpy(grid_before, grid, sizeof_grid);
205  memset(grid, 0, sizeof_grid);
206  }
207 
208  collocate_internal(orthorhombic, border_mask, func, la_max, la_min, lb_max,
209  lb_min, zeta, zetb, rscale, dh, dh_inv, ra, rab,
210  npts_global, npts_local, shift_local, border_width, radius,
211  o1, o2, n1, n2, pab, grid);
212 
213  if (DUMP_TASKS) {
214  write_task_file(orthorhombic, border_mask, func, la_max, la_min, lb_max,
215  lb_min, zeta, zetb, rscale, dh, dh_inv, ra, rab,
216  npts_global, npts_local, shift_local, border_width, radius,
217  o1, o2, n1, n2, pab, grid);
218 
219  for (size_t i = 0; i < npts_local_total; i++) {
220  grid[i] += grid_before[i];
221  }
222  free(grid_before);
223  }
224 }
225 
226 // EOF
static int imax(int x, int y)
Returns the larger of two given integer (missing from the C standard)
static GRID_HOST_DEVICE int ncoset(const int l)
Number of Cartesian orbitals up to given angular momentum quantum.
Definition: grid_common.h:73
grid_func
@ GRID_FUNC_DADB
static void const int const int const int const int const int const double const int const int const int int GRID_CONST_WHEN_COLLOCATE double GRID_CONST_WHEN_INTEGRATE double * grid
static void const int const int i
static void const int const int const int const int const int const double const int const int const int npts_local[3]
static void write_task_file(const bool orthorhombic, const int border_mask, const enum grid_func func, const int la_max, const int la_min, const int lb_max, const int lb_min, const double zeta, const double zetb, const double rscale, const double dh[3][3], const double dh_inv[3][3], const double ra[3], const double rab[3], const int npts_global[3], const int npts_local[3], const int shift_local[3], const int border_width[3], const double radius, const int o1, const int o2, const int n1, const int n2, const double pab[n2][n1], const double *grid)
Writes the given arguments into a .task file. See grid_replay.h for details.
static void collocate_internal(const bool orthorhombic, const int border_mask, const enum grid_func func, const int la_max, const int la_min, const int lb_max, const int lb_min, const double zeta, const double zetb, const double rscale, const double dh[3][3], const double dh_inv[3][3], const double ra[3], const double rab[3], const int npts_global[3], const int npts_local[3], const int shift_local[3], const int border_width[3], const double radius, const int o1, const int o2, const int n1, const int n2, const double pab[n2][n1], double *grid)
Collocates a single product of primitiv Gaussians. See grid_cpu_collocate.h for details.
void grid_cpu_collocate_pgf_product(const bool orthorhombic, const int border_mask, const enum grid_func func, const int la_max, const int la_min, const int lb_max, const int lb_min, const double zeta, const double zetb, const double rscale, const double dh[3][3], const double dh_inv[3][3], const double ra[3], const double rab[3], const int npts_global[3], const int npts_local[3], const int shift_local[3], const int border_width[3], const double radius, const int o1, const int o2, const int n1, const int n2, const double pab[n2][n1], double *grid)
Public entry point. A thin wrapper with the only purpose of calling write_task_file when DUMP_TASKS =...
void grid_cpu_integrate_pgf_product(const bool orthorhombic, const bool compute_tau, const int border_mask, const int la_max, const int la_min, const int lb_max, const int lb_min, const double zeta, const double zetb, const double dh[3][3], const double dh_inv[3][3], const double ra[3], const double rab[3], const int npts_global[3], const int npts_local[3], const int shift_local[3], const int border_width[3], const double radius, const int o1, const int o2, const int n1, const int n2, const double *grid, double hab[n2][n1], const double pab[n2][n1], double forces[2][3], double virials[2][3][3], double hdab[n2][n1][3], double hadb[n2][n1][3], double a_hdab[n2][n1][3][3])
Integrates a single task. See grid_cpu_integrate.h for details.
void grid_cpu_prepare_pab(const enum grid_func func, const int o1, const int o2, const int la_max, const int la_min, const int lb_max, const int lb_min, const double zeta, const double zetb, const int n1, const int n2, const double pab[n2][n1], const int n1_prep, const int n2_prep, double pab_prep[n2_prep][n1_prep])
Selects and transforms a sub-block of the given density matrix block. See grid_cpu_prepare_pab....
void grid_cpu_prepare_get_ldiffs(const enum grid_func func, int *la_min_diff, int *la_max_diff, int *lb_min_diff, int *lb_max_diff)
Returns block size changes due to transformation grid_prepare_pab.
static void cab_to_grid(const bool orthorhombic, const int border_mask, const int la_max, const int la_min, const int lb_max, const int lb_min, const double zeta, const double zetb, const double rscale, const double dh[3][3], const double dh_inv[3][3], const double ra[3], const double rab[3], const int npts_global[3], const int npts_local[3], const int shift_local[3], const int border_width[3], const double radius, GRID_CONST_WHEN_COLLOCATE double *cab, GRID_CONST_WHEN_INTEGRATE double *grid)
Collocates coefficients C_ab onto the grid.