Source code for dxtb._src.calculators.properties.moments.dip

# This file is part of dxtb.
#
# SPDX-Identifier: Apache-2.0
# Copyright (C) 2024 Grimme Group
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Properties: Dipole Moment
=========================

Analytical calculation of dipole moment.

This module serves more as a short-cut for the calculation in
:class:`~dxtb.Calculator`, hiding some implementation details.
"""

from __future__ import annotations

from tad_mctc.data.getters import get_zvalence
from tad_mctc.math import einsum

from dxtb._src.typing import Tensor

__all__ = ["dipole", "dipole_xtb"]


[docs] def dipole( charge: Tensor, positions: Tensor, density: Tensor, integral: Tensor ) -> Tensor: r""" Analytical calculation of electric dipole moment with electric dipole contribution from nuclei (:math:`\sum_i(r_{ik} q_i)`) and electrons. Parameters ---------- charge : Tensor Atom-resolved charges. positions : Tensor Cartesian coordinates of all atoms (shape: ``(..., nat, 3)``). density : Tensor Density matrix. integral : Tensor Dipole integral. Returns ------- Tensor Electric dipole moment. Note ---- This version follows the `tblite` implementation, which employs ``r-rj`` as moment operator and requires the SCC charges for the nuclear dipole contribution. """ # TODO: Shape checks e_dipole = -einsum("...xij,...ij->...x", integral, density) n_dipole = einsum("...ix,...i->...x", positions, charge) return n_dipole + e_dipole
[docs] def dipole_xtb( numbers: Tensor, positions: Tensor, density: Tensor, integral: Tensor ) -> Tensor: r""" Analytical calculation of electric dipole moment with electric dipole contribution from nuclei (:math:`\sum_i(r_{ik} q_i)`) and electrons. Parameters ---------- numbers : Tensor Atomic numbers for all atoms in the system (shape: ``(..., nat)``). charge : Tensor Atom-resolved charges. positions : Tensor Cartesian coordinates of all atoms (shape: ``(..., nat, 3)``). density : Tensor Density matrix. integral : Tensor Dipole integral. Returns ------- Tensor Electric dipole moment. Note ---- This version follows the `xtb` implementation, where the ``r0`` moment operator is used and the nuclear contribution uses the valence charges. """ # TODO: Shape checks # electric component from dipole integral and density matrix e_dipole = -einsum("...xij,...ij->...x", integral, density) # moment operator "r0" combines with valence charges (xtb implementation) n_dipole = einsum( "...ix,...i->...x", positions, get_zvalence(numbers, device=positions.device, dtype=positions.dtype), ) dip = n_dipole + e_dipole return dip