# -*- coding: utf-8 -*-
"""Contains a class for using the 3D Wiener number as a CV."""
import numpy as np
import itertools as it
from .. import constants as c
from . import cvfunctions as cvf
from .cv import cv
[docs]class cv_wiener(cv):
"""
3D Wiener number as 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
-----------------
exclude_h : bool
do not include distances to hydrogen atoms (default: False)
"""
def __init__(self, idx, symbols, **kwargs):
"""Construct Wiener number CV object."""
cv.__init__(self, idx, symbols, **kwargs)
self.x = np.linspace(0., 1., 200)
self.exclude_h = self.get_kwargs("exclude_h", default=False)
self.au2unit = c.a0
self.reset_width()
[docs] def set_s_and_ds(self, coords):
"""
Calculate Wiener number and its gradient for the current set of coordinates.
Parameters
----------
coords : np.2darray
cartesian coordinates of the molecule (shape: (N, 3))
"""
nat = len(coords)
wiener = 0.0
dwiener = np.zeros_like(coords)
for p in it.combinations(range(nat), 2):
if self.exclude_h == True and ("H" in [self.symbols[p_i] for p_i in p]):
continue
wiener += cvf.bond(coords[[p]])
dwiener[[p]] += cvf.dbond(coords[[p]])
self.s = wiener
self.ds_dr = dwiener
with open("wiener.dat", "a") as f:
f.write("%14.6f\n" % (wiener*self.au2unit))
[docs]def get_wiener(symbols, coords, exclude_h=True):
"""
Return Wiener number.
Parameters
----------
coords : np.2darray
cartesian coordinates of the molecule (shape: (N, 3))
exclude_h : bool
do not include distances to hydrogen atoms (default: False)
Returns
-------
wiener : float
Wiener number
"""
nat = len(coords)
wiener = 0.0
for p in it.combinations(range(nat), 2):
if exclude_h == True and ("H" in [symbols[p_i] for p_i in p]):
continue
wiener += cvf.bond(coords[[p]])
return wiener