# -*- coding: utf-8 -*-
"""Contains a class for using the coordination number of an atom as a CV."""
import numpy as np
import matplotlib.pyplot as plt
from .. import constants as c
from . import cvfunctions as cvf
from .cv import cv
[docs]class cv_cn(cv):
"""
Coordination number as a collective variable, inherits from `metafalcon.cvs.cv.cv`.
Parameters
----------
idx : int
index of collective variable in the input file
symbols : list of str
atomic symbols of the molecule
**kwargs :
See below
Keyword Arguments
-----------------
atom : int
atom index for the calculation of the coordination number
reference : list of int
indices of reference atoms to be included (default: all atoms other than `atom`)
n : int
first exponent
m : int
second exponent
d : "auto" or float or list of float
single distance or list of distances for all atoms in `reference` (default: 'auto')
"""
def __init__(self, idx, symbols, **kwargs):
"""Construct coordination number CV object."""
cv.__init__(self, idx, symbols, **kwargs)
self.atom = self.get_kwargs("atom")
nat = len(self.symbols)
self.ref = self.get_kwargs("reference", default=[i for i in range(nat) if i != self.atom])
self.n = self.get_kwargs("n")
self.m = self.get_kwargs("m")
if kwargs["d"] == "auto": # if set to auto, determine d for every atom pair from cov. radii
self.d = [cvf.get_d(self.symbols, self.atom, atom2) for atom2 in self.ref]
# print(self.d)
elif type(kwargs["d"]) == type([]): # if list is parsed, take it as it is
self.d = list(np.array(kwargs["d"])/c.a0)
elif type(kwargs["d"]) == type(0.0): # if float is parsed, use it for all atom pairs
self.d = len(self.ref)*[kwargs["d"]/c.a0]
self.x = np.linspace(0., 1., 200)
self.ticks = None
[docs] def set_s_and_ds(self, coords):
"""
Calculate angle and its gradient for the current set of coordinates.
Parameters
----------
coords : np.2darray
cartesian coordinates of the molecule (shape: (N, 3))
"""
cn, dcn = cvf.cn(self.symbols, coords, self.atom, self.n, self.m, self.d, self.ref)
self.s = cn
self.ds_dr = dcn