spherical-functions.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /**
  2. * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * Inspired by https://github.com/dgasmith/gau2grid.
  5. *
  6. * @author David Sehnal <david.sehnal@gmail.com>
  7. */
  8. // gaussian:
  9. // R_0, R^+_1, R^-_1, ..., R^+_l, R^-_l
  10. // cca:
  11. // R^-_(l), R^-_(l-1), ..., R_0, ..., R^+_(l-1), R^+_l
  12. // cca-reverse:
  13. // R^+_(l), R^+_(l-1), ..., R_0, ..., R^-_(l-1), R^-_l
  14. export type SphericalBasisOrder = 'gaussian' | 'cca' | 'cca-reverse';
  15. export function normalizeBasicOrder(
  16. L: number,
  17. alpha: number[],
  18. order: SphericalBasisOrder
  19. ) {
  20. if (order === 'gaussian' || L === 0) return alpha;
  21. const ret: number[] = [alpha[L]];
  22. for (let l = 0; l < L; l++) {
  23. const a = alpha[L - l - 1],
  24. b = alpha[L + l + 1];
  25. if (order === 'cca') ret.push(b, a);
  26. else ret.push(a, b);
  27. }
  28. return ret;
  29. }
  30. export type SphericalFunc = (
  31. alpha: number[],
  32. x: number,
  33. y: number,
  34. z: number
  35. ) => number;
  36. export const SphericalFunctions: SphericalFunc[] = [L0, L1, L2, L3, L4];
  37. // L_i functions were auto-generated.
  38. function L0(alpha: number[], x: number, y: number, z: number) {
  39. return alpha[0];
  40. }
  41. function L1(alpha: number[], x: number, y: number, z: number) {
  42. return alpha[0] * z + alpha[1] * x + alpha[2] * y;
  43. }
  44. function L2(alpha: number[], x: number, y: number, z: number) {
  45. const xx = x * x, yy = y * y, zz = z * z;
  46. return (
  47. alpha[0] * (-0.5 * xx - 0.5 * yy + zz) +
  48. alpha[1] * (1.7320508075688772 * x * z) +
  49. alpha[2] * (1.7320508075688772 * y * z) +
  50. alpha[3] * (0.8660254037844386 * xx - 0.8660254037844386 * yy) +
  51. alpha[4] * (1.7320508075688772 * x * y)
  52. );
  53. }
  54. function L3(alpha: number[], x: number, y: number, z: number) {
  55. const xx = x * x, yy = y * y, zz = z * z;
  56. const xxx = xx * x, yyy = yy * y, zzz = zz * z;
  57. return (
  58. alpha[0] * (-1.5 * xx * z - 1.5 * yy * z + zzz) +
  59. alpha[1] * (-0.6123724356957945 * xxx - 0.6123724356957945 * x * yy + 2.449489742783178 * x * zz) +
  60. alpha[2] * (-0.6123724356957945 * xx * y - 0.6123724356957945 * yyy + 2.449489742783178 * y * zz) +
  61. alpha[3] * (1.9364916731037085 * xx * z - 1.9364916731037085 * yy * z) +
  62. alpha[4] * (3.872983346207417 * x * y * z) +
  63. alpha[5] * (0.7905694150420949 * xxx - 2.3717082451262845 * x * yy) +
  64. alpha[6] * (2.3717082451262845 * xx * y - 0.7905694150420949 * yyy)
  65. );
  66. }
  67. function L4(alpha: number[], x: number, y: number, z: number) {
  68. const xx = x * x, yy = y * y, zz = z * z;
  69. const xxx = xx * x, yyy = yy * y, zzz = zz * z;
  70. const xxxx = xxx * x, yyyy = yyy * y, zzzz = zzz * z;
  71. return (
  72. alpha[0] * (0.375 * xxxx + 0.75 * xx * yy + 0.375 * yyyy - 3.0 * xx * zz - 3.0 * yy * zz + zzzz) +
  73. alpha[1] * (-2.3717082451262845 * xxx * z - 2.3717082451262845 * x * yy * z + 3.1622776601683795 * x * zzz) +
  74. alpha[2] * (-2.3717082451262845 * xx * y * z - 2.3717082451262845 * yyy * z + 3.1622776601683795 * y * zzz) +
  75. alpha[3] * (-0.5590169943749475 * xxxx + 0.5590169943749475 * yyyy + 3.3541019662496847 * xx * zz - 3.3541019662496847 * yy * zz) +
  76. alpha[4] * (-1.118033988749895 * xxx * y - 1.118033988749895 * x * yyy + 6.708203932499369 * x * y * zz) +
  77. alpha[5] * (2.091650066335189 * xxx * z + -6.274950199005566 * x * yy * z) +
  78. alpha[6] * (6.274950199005566 * xx * y * z + -2.091650066335189 * yyy * z) +
  79. alpha[7] * (0.739509972887452 * xxxx - 4.437059837324712 * xx * yy + 0.739509972887452 * yyyy) +
  80. alpha[8] * (2.958039891549808 * xxx * y + -2.958039891549808 * x * yyy)
  81. );
  82. }