UNPKG

molstar

Version:

A comprehensive macromolecular library.

134 lines (133 loc) 6.55 kB
"use strict"; /** * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info. * * Inspired by https://github.com/dgasmith/gau2grid. * * @author David Sehnal <david.sehnal@gmail.com> */ Object.defineProperty(exports, "__esModule", { value: true }); exports.sphericalCollocation = void 0; var tslib_1 = require("tslib"); var linear_algebra_1 = require("../../mol-math/linear-algebra"); var array_1 = require("../../mol-util/array"); var spherical_functions_1 = require("./spherical-functions"); function sphericalCollocation(grid, orbital, taskCtx) { return tslib_1.__awaiter(this, void 0, void 0, function () { var _a, basis, sphericalOrder, cutoffThreshold, baseCount, _i, _b, atom, _c, _d, shell, _e, _f, L, matrix, baseIndex, _g, _h, atom, _j, _k, shell, amIndex, _l, _m, L, alpha; return tslib_1.__generator(this, function (_o) { switch (_o.label) { case 0: _a = grid.params, basis = _a.basis, sphericalOrder = _a.sphericalOrder, cutoffThreshold = _a.cutoffThreshold; baseCount = 0; for (_i = 0, _b = basis.atoms; _i < _b.length; _i++) { atom = _b[_i]; for (_c = 0, _d = atom.shells; _c < _d.length; _c++) { shell = _d[_c]; for (_e = 0, _f = shell.angularMomentum; _e < _f.length; _e++) { L = _f[_e]; if (L > 4) { // TODO: will L > 4 be required? Would need to precompute more functions in that case. throw new Error('Angular momentum L > 4 not supported.'); } baseCount += 2 * L + 1; } } } matrix = new Float32Array(grid.npoints); baseIndex = 0; _g = 0, _h = basis.atoms; _o.label = 1; case 1: if (!(_g < _h.length)) return [3 /*break*/, 8]; atom = _h[_g]; _j = 0, _k = atom.shells; _o.label = 2; case 2: if (!(_j < _k.length)) return [3 /*break*/, 7]; shell = _k[_j]; amIndex = 0; _l = 0, _m = shell.angularMomentum; _o.label = 3; case 3: if (!(_l < _m.length)) return [3 /*break*/, 6]; L = _m[_l]; alpha = (0, spherical_functions_1.normalizeBasicOrder)(L, orbital.alpha.slice(baseIndex, baseIndex + 2 * L + 1), sphericalOrder); baseIndex += 2 * L + 1; collocationBasis(matrix, grid, L, shell.coefficients[amIndex++], shell.exponents, atom.center, cutoffThreshold, alpha); if (!taskCtx.shouldUpdate) return [3 /*break*/, 5]; return [4 /*yield*/, taskCtx.update({ message: 'Computing...', current: baseIndex, max: baseCount, isIndeterminate: false, })]; case 4: _o.sent(); _o.label = 5; case 5: _l++; return [3 /*break*/, 3]; case 6: _j++; return [3 /*break*/, 2]; case 7: _g++; return [3 /*break*/, 1]; case 8: return [2 /*return*/, matrix]; } }); }); } exports.sphericalCollocation = sphericalCollocation; function collocationBasis(matrix, grid, L, coefficients, exponents, center, cutoffThreshold, alpha) { var ncoeff = exponents.length; var sphericalFunc = spherical_functions_1.SphericalFunctions[L]; var cx = center[0], cy = center[1], cz = center[2]; var ny = grid.dimensions[1], nz = grid.dimensions[2]; var gdx = grid.delta[0], gdy = grid.delta[1], gdz = grid.delta[2]; var sx = grid.box.min[0], sy = grid.box.min[1], sz = grid.box.min[2]; var cutoffRadius = cutoffThreshold > 0 ? Math.sqrt(-Math.log(cutoffThreshold) / (0, array_1.arrayMin)(exponents)) : 10000; var cutoffSquared = cutoffRadius * cutoffRadius; var radiusBox = getRadiusBox(grid, center, cutoffRadius); var iMin = radiusBox[0][0], jMin = radiusBox[0][1], kMin = radiusBox[0][2]; var iMax = radiusBox[1][0], jMax = radiusBox[1][1], kMax = radiusBox[1][2]; for (var i = iMin; i <= iMax; i++) { var x = sx + gdx * i - cx; var oX = i * ny * nz; for (var j = jMin; j <= jMax; j++) { var y = sy + gdy * j - cy; var oY = oX + j * nz; for (var k = kMin; k <= kMax; k++) { var z = sz + gdz * k - cz; var R2 = x * x + y * y + z * z; if (R2 > cutoffSquared) { continue; } var gaussianSum = 0; for (var c = 0; c < ncoeff; c++) { gaussianSum += coefficients[c] * Math.exp(-exponents[c] * R2); } var sphericalSum = L === 0 ? alpha[0] : sphericalFunc(alpha, x, y, z); matrix[k + oY] += gaussianSum * sphericalSum; } } } } function getRadiusBox(grid, center, radius) { var r = linear_algebra_1.Vec3.create(radius, radius, radius); var min = linear_algebra_1.Vec3.scaleAndAdd((0, linear_algebra_1.Vec3)(), center, r, -1); var max = linear_algebra_1.Vec3.add((0, linear_algebra_1.Vec3)(), center, r); linear_algebra_1.Vec3.sub(min, min, grid.box.min); linear_algebra_1.Vec3.sub(max, max, grid.box.min); linear_algebra_1.Vec3.div(min, min, grid.delta); linear_algebra_1.Vec3.floor(min, min); linear_algebra_1.Vec3.max(min, min, (0, linear_algebra_1.Vec3)()); linear_algebra_1.Vec3.div(max, max, grid.delta); linear_algebra_1.Vec3.ceil(max, max); linear_algebra_1.Vec3.min(max, max, linear_algebra_1.Vec3.subScalar((0, linear_algebra_1.Vec3)(), grid.dimensions, 1)); return [min, max]; }