19#include "../common/grid_common.h"
30 const int cmax,
const int *
const lb_cube,
const int *
const cube_center) {
37 for (
int i = 0;
i < 3;
i++) {
38 for (
int ig = 0; ig < handler->
cube.
size[
i]; ig++) {
52 for (
int kg = 0; kg < handler->
cube.
size[0]; kg++) {
53 const int k =
map[0][kg];
55 (2 * (kg + lb_cube[0]) - 1) / 2;
56 const double kr = kd * handler->
dh[2][2];
57 const double kremain = disr_radius * disr_radius - kr * kr;
61 const int jgmin = ceil(-1e-8 - sqrt(kremain) * handler->
dh_inv[1][1]);
62 for (
int jg = jgmin; jg <= (1 - jgmin); jg++) {
63 const int j =
map[1][jg - lb_cube[1]];
64 const double jr = ((2 * jg - 1) >> 1) *
66 const double jremain = kremain - jr * jr;
69 const int xmin = ceil(-1e-8 - sqrt(jremain) * handler->
dh_inv[0][0]);
70 const int xmax = 1 - xmin;
73 for (
int x = xmin - lb_cube[2];
74 x <
imin((xmax - lb_cube[2]), handler->
cube.
size[2]); x++) {
75 const int x1 =
map[2][x];
80 int lower_corner[3] = {k, j, x1};
81 int upper_corner[3] = {k + 1, j + 1, x1 + 1};
85 &x, lower_corner + 2, upper_corner + 2, xwindow);
87 if (upper_corner[2] - lower_corner[2]) {
88 const int position1[3] = {kg, jg - lb_cube[1], x};
93 double *restrict dst = &
idx3(handler->
cube, position1[0],
94 position1[1], position1[2]);
96 double *restrict src = &
idx3(handler->
grid, lower_corner[0],
97 lower_corner[1], lower_corner[2]);
99 const int sizex = upper_corner[2] - lower_corner[2];
101 for (
int x = 0; x < sizex; x++) {
109 x += upper_corner[2] - lower_corner[2] - 1;
119 const int cmax,
const int *
const lb_cube,
const int *
const ub_cube,
120 const double *
const roffset,
const int *
const cube_center) {
122 const double a = handler->
dh[0][0] * handler->
dh[0][0] +
123 handler->
dh[0][1] * handler->
dh[0][1] +
124 handler->
dh[0][2] * handler->
dh[0][2];
125 const double a_inv = 1.0 / a;
132 for (
int i = 0;
i < 3;
i++) {
133 for (
int ig = 0; ig < handler->
cube.
size[
i]; ig++) {
147 for (
int k = 0; k < handler->
cube.
size[0]; k++) {
148 const int iz =
map[0][k];
153 const double tz = (k + lb_cube[0] - roffset[0]);
154 const double z[3] = {tz * handler->
dh[2][0], tz * handler->
dh[2][1],
155 tz * handler->
dh[2][2]};
157 for (
int j = 0; j < handler->
cube.
size[1]; j++) {
158 const int iy =
map[1][j];
163 const double ty = (j - roffset[1] + lb_cube[1]);
164 const double y[3] = {z[0] + ty * handler->
dh[1][0],
165 z[1] + ty * handler->
dh[1][1],
166 z[2] + ty * handler->
dh[1][2]};
173 -2.0 * (handler->
dh[0][0] * (roffset[2] * handler->
dh[0][0] - y[0]) +
174 handler->
dh[0][1] * (roffset[2] * handler->
dh[0][1] - y[1]) +
175 handler->
dh[0][2] * (roffset[2] * handler->
dh[0][2] - y[2]));
177 const double c = (roffset[2] * handler->
dh[0][0] - y[0]) *
178 (roffset[2] * handler->
dh[0][0] - y[0]) +
179 (roffset[2] * handler->
dh[0][1] - y[1]) *
180 (roffset[2] * handler->
dh[0][1] - y[1]) +
181 (roffset[2] * handler->
dh[0][2] - y[2]) *
182 (roffset[2] * handler->
dh[0][2] - y[2]) -
183 disr_radius * disr_radius;
185 double delta = b * b - 4.0 * a * c;
192 const int xmin =
imax(ceil((-b - delta) * 0.5 * a_inv), lb_cube[2]);
193 const int xmax =
imin(floor((-b + delta) * 0.5 * a_inv), ub_cube[2]);
195 int lower_corner[3] = {iz, iy, xmin};
196 int upper_corner[3] = {iz + 1, iy + 1, xmin};
198 for (
int x = xmin - lb_cube[2];
199 x <
imin((xmax - lb_cube[2]), handler->
cube.
size[2]); x++) {
200 const int x1 =
map[2][x];
207 lower_corner + 2, upper_corner + 2, xwindow);
209 if (upper_corner[2] - lower_corner[2]) {
210 const int position1[3] = {k, j, x};
215 double *__restrict__ src = &
idx3(handler->
grid, lower_corner[0],
216 lower_corner[1], lower_corner[2]);
217 double *__restrict__ dst =
218 &
idx3(handler->
cube, position1[0], position1[1], position1[2]);
220 const int sizex = upper_corner[2] - lower_corner[2];
224 for (
int x = 0; x < sizex; x++) {
231 x += upper_corner[2] - lower_corner[2] - 1;
239 const _task *prev_task,
243 if (prev_task != NULL) {
248 const int iatom = prev_task->
iatom;
249 const int jatom = prev_task->
jatom;
250 const int iset = prev_task->
iset;
251 const int jset = prev_task->
jset;
257 const int block_num = prev_task->
block_num;
258 double *
const block = &blocks[ctx->
block_offsets[block_num]];
260 const int ncoseta = ncoset(ibasis->
lmax[iset]);
261 const int ncosetb = ncoset(jbasis->
lmax[jset]);
263 const int ncoa = ibasis->
npgf[iset] * ncoseta;
264 const int ncob = jbasis->
npgf[jset] * ncosetb;
266 const int nsgf_seta = ibasis->
nsgf_set[iset];
267 const int nsgf_setb = jbasis->
nsgf_set[jset];
268 const int nsgfa = ibasis->
nsgf;
269 const int nsgfb = jbasis->
nsgf;
270 const int sgfa = ibasis->
first_sgf[iset] - 1;
271 const int sgfb = jbasis->
first_sgf[jset] - 1;
272 const int maxcoa = ibasis->
maxco;
273 const int maxcob = jbasis->
maxco;
291 m1.a = &jbasis->
sphi[sgfb * maxcob];
301 if (iatom <= jatom) {
312 m2.b = &ibasis->
sphi[sgfa * maxcoa];
314 m2.c = block + sgfb * nsgfa + sgfa;
325 m2.a = &ibasis->
sphi[sgfa * maxcoa];
329 m2.c = block + sgfa * nsgfb + sgfb;
341 const int iatom = task->
iatom;
342 const int jatom = task->
jatom;
345 const int iset = task->
iset;
346 const int jset = task->
jset;
349 const int ncoseta = ncoset(ibasis->
lmax[iset]);
350 const int ncosetb = ncoset(jbasis->
lmax[jset]);
352 const int ncoa = ibasis->
npgf[iset] * ncoseta;
353 const int ncob = jbasis->
npgf[jset] * ncosetb;
361 const double ftz[2],
const double *
const rab,
363 const double axpm0 =
idx2(vab[0],
idx(b),
idx(a));
364 for (
int i = 0;
i < 3;
i++) {
368 idx2(force[0], 0,
i) += pab * (ftz[0] * aip1 - a.l[
i] * aim1);
369 idx2(force[0], 1,
i) +=
370 pab * (ftz[1] * (aip1 - rab[
i] * axpm0) - b.l[
i] * bim1);
375 const double ftz[2],
const double *
const rab,
377 for (
int i = 0;
i < 3;
i++) {
378 for (
int j = 0; j < 3; j++) {
379 idx3(virial[0], 0,
i, j) +=
385 for (
int i = 0;
i < 3;
i++) {
386 for (
int j = 0; j < 3; j++) {
387 idx3(virial[0], 1,
i, j) +=
398void update_all(
const bool compute_forces,
const bool compute_virial,
400 const double *
const ftz,
const double *rab,
const tensor *vab,
401 const double pab,
double *hab,
tensor *forces,
406 if (compute_forces) {
410 if (compute_virial) {
415static void update_tau(
const bool compute_forces,
const bool compute_virial,
417 const double *
const rab,
const tensor *
const vab,
418 const double pab,
double *
const hab,
tensor *forces,
421 for (
int i = 0;
i < 3;
i++) {
423 0.5 * a.l[
i] * b.l[
i], ftz, rab, vab, pab, hab, forces, virials);
425 -0.5 * ftz[0] * b.l[
i], ftz, rab, vab, pab, hab, forces,
428 -0.5 * a.l[
i] * ftz[1], ftz, rab, vab, pab, hab, forces,
431 0.5 * ftz[0] * ftz[1], ftz, rab, vab, pab, hab, forces, virials);
437 const tensor *
const pab,
const bool compute_tau,
438 const bool compute_forces,
439 const bool compute_virial,
tensor *
const forces,
441 double zeta[2] = {task->
zeta[0] * 2.0, task->
zeta[1] * 2.0};
442 for (
int lb = task->
lmin[1]; lb <= task->
lmax[1]; lb++) {
443 for (
int la = task->
lmin[0]; la <= task->
lmax[0]; la++) {
444 for (
int bx = 0; bx <= lb; bx++) {
445 for (
int by = 0; by <= lb - bx; by++) {
446 const int bz = lb - bx - by;
447 const orbital b = {{bx, by, bz}};
448 const int idx_b = task->
offset[1] +
idx(b);
449 for (
int ax = 0; ax <= la; ax++) {
450 for (
int ay = 0; ay <= la - ax; ay++) {
451 const int az = la - ax - ay;
452 const orbital a = {{ax, ay, az}};
453 const int idx_a = task->
offset[0] +
idx(a);
454 double *habval = &
idx2(hab[0], idx_b, idx_a);
455 const double prefactor =
idx2(pab[0], idx_b, idx_a);
459 update_tau(compute_forces, compute_virial, a, b, zeta,
460 task->
rab, vab, prefactor, habval, forces, virial);
462 update_all(compute_forces, compute_virial, a, b, 1.0, zeta,
463 task->
rab, vab, prefactor, habval, forces, virial);
478 const int *lower_boundaries_cube,
const int *cube_center) {
485 for (
int i = 0;
i < 3;
i++) {
486 for (
int ig = 0; ig < handler->
cube.
size[
i]; ig++) {
487 map[
i][ig] =
modulo(cube_center[
i] + ig + lower_boundaries_cube[
i] -
503 for (
int z = 0; (z < handler->
cube.
size[0]); z++) {
504 const int z1 =
map[0][z];
510 handler->
cube.
size[0], z1, &z, lower_corner, upper_corner,
514 if (upper_corner[0] - lower_corner[0]) {
515 for (
int y = 0; y < handler->
cube.
size[1]; y++) {
516 const int y1 =
map[1][y];
524 lower_corner + 1, upper_corner + 1, ywindow);
526 if (upper_corner[1] - lower_corner[1]) {
527 for (
int x = 0; x < handler->
cube.
size[2]; x++) {
528 const int x1 =
map[2][x];
535 &x, lower_corner + 2, upper_corner + 2, xwindow);
537 if (upper_corner[2] - lower_corner[2]) {
538 const int position1[3] = {z, y, x};
554 x += upper_corner[2] - lower_corner[2] - 1;
560 y += upper_corner[1] - lower_corner[1] - 1;
566 z += upper_corner[0] - lower_corner[0] - 1;
572 const bool use_ortho,
const double zetp,
const double rp[3],
573 const double radius) {
577 const int lp = handler->
coef.
size[0] - 1;
581 int lb_cube[3], ub_cube[3];
592 use_ortho, radius, (
const double(*)[3])handler->
dh,
593 (
const double(*)[3])handler->
dh_inv, rp, &disr_radius, roffset,
594 cubecenter, lb_cube, ub_cube, cube_size);
628 int perm[3] = {2, 0, 1};
641 ub_cube[2], lp,
cmax, zetp,
642 &
idx3(handler->
pol, perm[2], 0, 0));
644 ub_cube[1], lp,
cmax, zetp,
645 &
idx3(handler->
pol, perm[1], 0, 0));
647 ub_cube[0], lp,
cmax, zetp,
648 &
idx3(handler->
pol, perm[0], 0, 0));
652 dx[2] = handler->
dh[0][0] * handler->
dh[0][0] +
653 handler->
dh[0][1] * handler->
dh[0][1] +
654 handler->
dh[0][2] * handler->
dh[0][2];
656 dx[1] = handler->
dh[1][0] * handler->
dh[1][0] +
657 handler->
dh[1][1] * handler->
dh[1][1] +
658 handler->
dh[1][2] * handler->
dh[1][2];
660 dx[0] = handler->
dh[2][0] * handler->
dh[2][0] +
661 handler->
dh[2][1] * handler->
dh[2][1] +
662 handler->
dh[2][2] * handler->
dh[2][2];
665 lp,
cmax, zetp * dx[2],
666 &
idx3(handler->
pol, perm[2], 0, 0));
668 lp,
cmax, zetp * dx[1],
669 &
idx3(handler->
pol, perm[1], 0, 0));
671 lp,
cmax, zetp * dx[0],
672 &
idx3(handler->
pol, perm[0], 0, 0));
676 zetp, roffset, (
const double(*)[3])handler->
dh, lb_cube, ub_cube,
682 if (!use_ortho && !use_ortho_forced) {
684 handler, disr_radius,
cmax, lb_cube, ub_cube, roffset, cubecenter);
687 lb_cube, cubecenter);
693 if (!use_ortho && !use_ortho_forced)
734 1, &
idx3(handler->
pol, 0, 0, 0), 1);
746 grid_context *
const ctx,
const int level,
const bool calculate_tau,
747 const bool calculate_forces,
const bool calculate_virial,
748 const int *
const shift_local,
const int *
const border_width,
755#pragma omp parallel default(shared)
757 const int num_threads = omp_get_num_threads();
758 const int thread_id = omp_get_thread_num();
760 double *hab_block_local = NULL;
762 if (num_threads == 1) {
765 hab_block_local = ((
double *)ctx->
scratch) +
766 thread_id * (hab_blocks->
size /
sizeof(double));
767 memset(hab_block_local, 0, hab_blocks->
size);
770 tensor work, pab, hab, vab, forces_local_, virial_local_,
771 forces_local_pair_, virial_local_pair_;
772 memset(&work, 0,
sizeof(
tensor));
773 memset(&pab, 0,
sizeof(
tensor));
774 memset(&hab, 0,
sizeof(
tensor));
775 memset(&vab, 0,
sizeof(
tensor));
776 memset(&forces_local_, 0,
sizeof(
tensor));
777 memset(&virial_local_, 0,
sizeof(
tensor));
778 memset(&forces_local_pair_, 0,
sizeof(
tensor));
779 memset(&virial_local_pair_, 0,
sizeof(
tensor));
788 if (calculate_tau || calculate_forces || calculate_virial) {
795 if (calculate_virial) {
820 if (calculate_forces) {
825 memset(forces_local_.
data, 0,
sizeof(
double) * forces_local_.
alloc_size_);
826 memset(virial_local_.
data, 0,
sizeof(
double) * virial_local_.
alloc_size_);
834 (
const double(*)[3])
grid->dh_inv);
838 for (
int d = 0; d < 3; d++)
844 const _task *prev_task = NULL;
845#pragma omp for schedule(static)
848 const _task *task = &ctx->
tasks[level][itask];
850 if (task->
level != level) {
851 printf(
"level %d, %d\n", task->
level, level);
857 if (calculate_forces) {
891 lmin[0] =
imax(lmin[0], 0);
892 lmin[1] =
imax(lmin[1], 0);
924 if (calculate_forces) {
925 memset(forces_local_pair_.
data, 0,
927 memset(virial_local_pair_.
data, 0,
932 task, &vab, &pab, calculate_tau, calculate_forces, calculate_virial,
943 if (calculate_forces) {
944 const double scaling = (task->
iatom == task->
jatom) ? 1.0 : 2.0;
946 scaling *
idx2(forces_local_pair_, 0, 0);
948 scaling *
idx2(forces_local_pair_, 0, 1);
950 scaling *
idx2(forces_local_pair_, 0, 2);
953 scaling *
idx2(forces_local_pair_, 1, 0);
955 scaling *
idx2(forces_local_pair_, 1, 1);
957 scaling *
idx2(forces_local_pair_, 1, 2);
958 if (calculate_virial) {
959 for (
int i = 0;
i < 3;
i++) {
960 for (
int j = 0; j < 3; j++) {
961 idx2(virial_local_,
i, j) +=
962 scaling * (
idx3(virial_local_pair_, 0,
i, j) +
963 idx3(virial_local_pair_, 1,
i, j));
974 if (num_threads > 1) {
977 const int hab_size = hab_blocks->
size /
sizeof(double);
978 if ((hab_size / num_threads) >= 2) {
979 const int block_size =
980 hab_size / num_threads + (hab_size % num_threads);
982 for (
int bk = 0; bk < num_threads; bk++) {
983 int bk_id = (bk + thread_id) % num_threads;
984 size_t begin = bk_id * block_size;
985 size_t end =
imin((bk_id + 1) * block_size, hab_size);
986 cblas_daxpy(end - begin, 1.0, hab_block_local + begin, 1,
991 const int hab_size = hab_blocks->
size /
sizeof(double);
998 if (calculate_forces) {
999 if (num_threads > 1) {
1001 const int block_size = forces_->
alloc_size_ / num_threads +
1004 for (
int bk = 0; bk < num_threads; bk++) {
1005 int bk_id = (bk + thread_id) % num_threads;
1006 int begin = bk_id * block_size;
1009 forces_->
data + begin, 1);
1024 if (calculate_virial) {
1026 for (
int i = 0;
i < 3;
i++) {
1027 for (
int j = 0; j < 3; j++) {
1028 idx2(virial_[0],
i, j) +=
idx2(virial_local_,
i, j);
1039 if (calculate_forces) {
1040 free(forces_local_.
data);
1041 free(virial_local_.
data);
1042 free(virial_local_pair_.
data);
1043 free(forces_local_pair_.
data);
1053 void *ptr,
const bool compute_tau,
const int natoms,
const int nlevels,
1055 offload_buffer *hab_blocks,
double forces[natoms][3],
double virial[3][3]) {
1060 assert(ctx->
nlevels == nlevels);
1061 assert(ctx->
natoms == natoms);
1073 for (
int level = 0; level < ctx->
nlevels; level++) {
1078 layout->
dh_inv, grids[level]);
1079 ctx->
grid[level].
data = grids[level]->host_buffer;
1082 bool calculate_virial = (virial != NULL);
1083 bool calculate_forces = (forces != NULL);
1086 if (calculate_forces) {
1095 for (
int level = 0; level < ctx->
nlevels; level++) {
1100 &forces_, &virial_);
1103 if (calculate_forces) {
1104 if (calculate_virial) {
1105 virial[0][0] =
idx2(virial_, 0, 0);
1106 virial[0][1] =
idx2(virial_, 0, 1);
1107 virial[0][2] =
idx2(virial_, 0, 2);
1108 virial[1][0] =
idx2(virial_, 1, 0);
1109 virial[1][1] =
idx2(virial_, 1, 1);
1110 virial[1][2] =
idx2(virial_, 1, 2);
1111 virial[2][0] =
idx2(virial_, 2, 0);
1112 virial[2][1] =
idx2(virial_, 2, 1);
1113 virial[2][2] =
idx2(virial_, 2, 2);
1116 memcpy(forces[0], forces_.
data,
sizeof(
double) * forces_.
alloc_size_);
static int imax(int x, int y)
Returns the larger of two given integers (missing from the C standard)
static int imin(int x, int y)
Returns the smaller of the two integers (missing from the C standard).
#define GRID_PRAGMA_SIMD(OBJS, N)
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
static GRID_HOST_DEVICE orbital up(const int i, const orbital a)
Increase i'th component of given orbital angular momentum.
static GRID_HOST_DEVICE int idx(const orbital a)
Return coset index of given orbital angular momentum.
static GRID_HOST_DEVICE orbital down(const int i, const orbital a)
Decrease i'th component of given orbital angular momentum.
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 cmax
static void const int const int const int const int const int const double const int map[3][2 *cmax+1]
void grid_compute_vab(const int *const lmin, const int *const lmax, const int lp, const double prefactor, const tensor *const alpha, const tensor *const coef_xyz, tensor *vab)
void grid_transform_coef_jik_to_yxz(const double dh[3][3], const tensor *coef_xyz)
void grid_prepare_alpha_dgemm(const double ra[3], const double rb[3], const double rp[3], const int *lmax, tensor *alpha)
void grid_fill_pol_dgemm(const bool transpose, const double dr, const double roffset, const int pol_offset, const int xmin, const int xmax, const int lp, const int cmax, const double zetp, double *pol_)
void extract_blocks(grid_context *const ctx, const _task *const task, const offload_buffer *pab_blocks, tensor *const work, tensor *const pab)
void tensor_reduction_for_collocate_integrate(double *scratch, const double alpha, const bool *const orthogonal, const struct tensor_ *Exp, const struct tensor_ *co, const struct tensor_ *p_alpha_beta_reduced_, struct tensor_ *cube)
void initialize_basis_vectors(collocation_integration *const handler, const double dh[3][3], const double dh_inv[3][3])
void initialize_W_and_T(collocation_integration *const handler, const tensor *cube, const tensor *coef)
void set_grid_parameters(tensor *grid, const bool orthorhombic, const int grid_full_size[3], const int grid_local_size[3], const int shift_local[3], const int border_width[3], const double dh[3][3], const double dh_inv[3][3], offload_buffer *grid_)
static void rotate_and_store_coefficients(grid_context *const ctx, const _task *prev_task, const _task *task, tensor *const hab, tensor *work, double *blocks)
static void update_tau(const bool compute_forces, const bool compute_virial, const orbital a, const orbital b, const double ftz[2], const double *const rab, const tensor *const vab, const double pab, double *const hab, tensor *forces, tensor *virials)
void integrate_one_grid_level_dgemm(grid_context *const ctx, const int level, const bool calculate_tau, const bool calculate_forces, const bool calculate_virial, const int *const shift_local, const int *const border_width, const offload_buffer *const pab_blocks, offload_buffer *const hab_blocks, tensor *forces_, tensor *virial_)
void extract_cube_within_spherical_cutoff_generic(struct collocation_integration_ *const handler, const double disr_radius, const int cmax, const int *const lb_cube, const int *const ub_cube, const double *const roffset, const int *const cube_center)
void update_force_pair(orbital a, orbital b, const double pab, const double ftz[2], const double *const rab, const tensor *const vab, tensor *force)
void update_virial_pair(orbital a, orbital b, const double pab, const double ftz[2], const double *const rab, const tensor *const vab, tensor *virial)
void grid_dgemm_integrate_task_list(void *ptr, const bool compute_tau, const int natoms, const int nlevels, const offload_buffer *const pab_blocks, offload_buffer *grids[nlevels], offload_buffer *hab_blocks, double forces[natoms][3], double virial[3][3])
Integrate all tasks of in given list from given grids using matrix - matrix multiplication.
void extract_cube_within_spherical_cutoff_ortho(struct collocation_integration_ *const handler, const double disr_radius, const int cmax, const int *const lb_cube, const int *const cube_center)
static void update_hab_forces_and_stress(const _task *task, const tensor *const vab, const tensor *const pab, const bool compute_tau, const bool compute_forces, const bool compute_virial, tensor *const forces, tensor *const virial, tensor *const hab)
void grid_integrate(collocation_integration *const handler, const bool use_ortho, const double zetp, const double rp[3], const double radius)
void extract_cube(struct collocation_integration_ *handler, const int cmax, const int *lower_boundaries_cube, const int *cube_center)
void update_all(const bool compute_forces, const bool compute_virial, const orbital a, const orbital b, const double f, const double *const ftz, const double *rab, const tensor *vab, const double pab, double *hab, tensor *forces, tensor *virials)
void apply_non_orthorombic_corrections(const bool plane[restrict 3], const tensor *const Exp, tensor *const cube)
void calculate_non_orthorombic_corrections_tensor(const double mu_mean, const double *r_ab, const double basis[3][3], const int *const xmin, const int *const xmax, bool plane[3], tensor *const Exp)
void tensor_copy(tensor *const b, const tensor *const a)
size_t realloc_tensor(tensor *t)
void alloc_tensor(tensor *t)
static void setup_grid_window(tensor *const grid, const int *const shift_local, const int *const border_width, const int border_mask)
static void initialize_tensor_4(struct tensor_ *a, int n1, int n2, int n3, int n4)
static void initialize_tensor_3(struct tensor_ *a, int n1, int n2, int n3)
static void initialize_tensor_2(struct tensor_ *a, int n1, int n2)
int compute_cube_properties(const bool ortho, const double radius, const double dh[3][3], const double dh_inv[3][3], const double *rp, double *disr_radius, double *roffset, int *cubecenter, int *lb_cube, int *ub_cube, int *cube_size)
double cblas_ddot(const int N, const double *X, const int incX, const double *Y, const int incY)
void extract_sub_grid(const int *lower_corner, const int *upper_corner, const int *position, const tensor *const grid, tensor *const subgrid)
void compute_interval(const int *const map, const int full_size, const int size, const int cube_size, const int x1, int *x, int *const lower_corner, int *const upper_corner, const Interval window)
void cblas_daxpy(const int N, const double alpha, const double *X, const int incX, double *Y, const int incY)
void cblas_dgemv(const CBLAS_LAYOUT order, const CBLAS_TRANSPOSE TransA, const int M, const int N, const double alpha, const double *A, const int lda, const double *X, const int incX, const double beta, double *Y, const int incY)
void dgemm_simplified(dgemm_params *const m)
Internal representation of a basis set.
grid_basis_set ** basis_sets
struct collocation_integration_ ** handler
Internal representation of a buffer.
Orbital angular momentum.