#!/usr/bin/env python
"""Contains different analytic potential wall functions for application on a CV."""
import numpy as np
import matplotlib.pyplot as plt
[docs]def polynomial_upper(x, s=1.0, offset=0.0, exp=2., **kwargs):
"""
upper quartic wall potential that is used for x values higher than offset
Parameters
----------
x : 1darray or float
x value(s) to be evaluated
s : float
scaling factor (default: 1.0)
offset : float
horizontal shift of the wall (default: 0.0)
exp : float
exponent (default: 2.0)
Returns
-------
y : 1darray or float
potential for the given x values
"""
if type(x) == np.ndarray:
z = x <= offset
x_wall, x_zero = x[~z], x[z]
y_zero = np.zeros_like(x_zero)
y_wall = (s*(x_wall-offset))**exp
return np.concatenate((y_zero, y_wall))
else:
if x <= offset:
return 0.0
else:
return (s*(x-offset))**exp
[docs]def dpolynomial_upper(x, s=1.0, offset=0.0, exp=2., **kwargs):
"""
derivative of upper quartic wall potential that is used for x values higher than offset
Parameters
----------
x : 1darray or float
x value(s) to be evaluated
s : float
scaling factor (default: 1.0)
offset : float
horizontal shift of the wall (default: 0.0)
exp : float
exponent (default: 2.0)
Returns
-------
y : 1darray or float
potential for the given x values
"""
if type(x) == np.ndarray:
z = x <= offset
x_wall, x_zero = x[~z], x[z]
y_zero = np.zeros_like(x_zero)
y_wall = exp*s**exp*(x_wall-offset)**(exp-1)
return np.concatenate((y_zero, y_wall))
else:
if x <= offset:
return 0.0
else:
return exp*s**exp*(x-offset)**(exp-1)
[docs]def polynomial_lower(x, s=1.0, offset=0.0, exp=2., **kwargs):
"""
lower quartic wall potential that is used for x values lower than offset
Parameters
----------
x : 1darray or float
x value(s) to be evaluated
s : float
scaling factor (default: 1.0)
offset : float
horizontal shift of the wall (default: 0.0)
exp : float
exponent (default: 2.0)
Returns
-------
y : 1darray or float
potential for the given x values
"""
if exp % 2:
s *= -1
if type(x) == np.ndarray:
z = x >= offset
x_wall, x_zero = x[~z], x[z]
y_zero = np.zeros_like(x_zero)
y_wall = (s*(x_wall-offset))**exp
return np.concatenate((y_wall, y_zero))
else:
if x >= offset:
return 0.0
else:
return (s*(x-offset))**exp
[docs]def dpolynomial_lower(x, s=1.0, offset=0.0, exp=2., **kwargs):
"""
derivative of lower quartic wall potential that is used for x values higher than offset
Parameters
----------
x : 1darray or float
x value(s) to be evaluated
s : float
scaling factor (default: 1.0)
offset : float
horizontal shift of the wall (default: 0.0)
exp : float
exponent (default: 2.0)
Returns
-------
y : 1darray or float
potential for the given x values
"""
if exp % 2:
s *= -1
if type(x) == np.ndarray:
z = x >= offset
x_wall, x_zero = x[~z], x[z]
y_zero = np.zeros_like(x_zero)
y_wall = exp*s**exp*(x_wall-offset)**(exp-1)
return np.concatenate((y_wall, y_zero))
else:
if x >= offset:
return 0.0
else:
return exp*s**exp*(x-offset)**(exp-1)
[docs]def log_upper(x, offset=0.0, c1=5., c2=5., **kwargs):
"""
upper logarithmic wall potential that is used for x values higher than offset
Parameters
----------
x : 1darray or float
x value(s) to be evaluated
offset : float
horizontal shift of the wall (default: 0.0)
c1 : float
weight factor in (kcal mol^-1)^-1 (default: 5.0)
c2 : float
strongness factor in kcal mol^-1 (default: 5.0)
Returns
-------
y : 1darray or float
potential for the given x values
"""
if type(x) == np.ndarray:
z = x <= offset
x_wall, x_zero = x[~z], x[z]
y_zero = np.zeros_like(x_zero)
y_wall = c1*c2**2*np.log(1+((x_wall-offset)/c2)**2)
return np.concatenate((y_zero, y_wall))
else:
if x <= offset:
return 0.0
else:
return c1*c2**2*np.log(1+((x-offset)/c2)**2)
[docs]def dlog_upper(x, offset=0.0, c1=5., c2=5., **kwargs):
"""
derivative of upper logarithmic wall potential that is used for x values higher than offset
Parameters
----------
x : 1darray or float
x value(s) to be evaluated
offset : float
horizontal shift of the wall (default: 0.0)
c1 : float
weight factor in (kcal mol^-1)^-1 (default: 5.0)
c2 : float
strongness factor in kcal mol^-1 (default: 5.0)
Returns
-------
y : 1darray or float
potential for the given x values
"""
if type(x) == np.ndarray:
z = x <= offset
x_wall, x_zero = x[~z], x[z]
y_zero = np.zeros_like(x_zero)
y_wall = 2*c1*(x_wall-offset)/(1+((x_wall-offset)/c2)**2)
return np.concatenate((y_zero, y_wall))
else:
if x <= offset:
return 0.0
else:
return 2*c1*(x-offset)/(1+((x-offset)/c2)**2)
[docs]def log_lower(x, offset=0.0, c1=5., c2=5., **kwargs):
"""
upper logarithmic wall potential that is used for x values lower than offset
Parameters
----------
x : 1darray or float
x value(s) to be evaluated
offset : float
horizontal shift of the wall (default: 0.0)
c1 : float
weight factor in (kcal mol^-1)^-1 (default: 5.0)
c2 : float
strongness factor in kcal mol^-1 (default: 5.0)
Returns
-------
y : 1darray or float
potential for the given x values
"""
if type(x) == np.ndarray:
z = x >= offset
x_wall, x_zero = x[~z], x[z]
y_zero = np.zeros_like(x_zero)
y_wall = c1*c2**2*np.log(1+((x_wall-offset)/c2)**2)
return np.concatenate((y_wall, y_zero))
else:
if x >= offset:
return 0.0
else:
return c1*c2**2*np.log(1+((x-offset)/c2)**2)
[docs]def dlog_lower(x, offset=0.0, c1=5., c2=5., **kwargs):
"""
derivative of lower logarithmic wall potential that is used for x values lower than offset
Parameters
----------
x : 1darray or float
x value(s) to be evaluated
offset : float
horizontal shift of the wall (default: 0.0)
c1 : float
weight factor in (kcal mol^-1)^-1 (default: 5.0)
c2 : float
strongness factor in kcal mol^-1 (default: 5.0)
Returns
-------
y : 1darray or float
potential for the given x values
"""
if type(x) == np.ndarray:
z = x >= offset
x_wall, x_zero = x[~z], x[z]
y_zero = np.zeros_like(x_zero)
y_wall = 2*c1*(x_wall-offset)/(1+((x_wall-offset)/c2)**2)
return np.concatenate((y_wall, y_zero))
else:
if x >= offset:
return 0.0
else:
return 2*c1*(x-offset)/(1+((x-offset)/c2)**2)
[docs]def plot_wall(wallfunc, xmin=0.0, xmax=1.0, **kwargs):
"""
Plot the wall in the given x-range in order check parameters.
Parameters
----------
wallfunc : function
one of :func:`polynomial_upper() <metafalcon.wall.polynomial_upper>`,
:func:`polynomial_lower() <metafalcon.wall.polynomial_lower>`,
:func:`log_upper() <metafalcon.wall.log_upper>` or
:func:`log_lower() <metafalcon.wall.log_lower>`
xmin : float
lowest x-value to be plotted
xmax : float
highest x-value to be plotted
kwargs :
keyword arguments for the respective wall function
"""
x = np.linspace(xmin, xmax, 200)
plt.plot(x, wallfunc(x, **kwargs))
plt.xlabel("x")
plt.ylabel("wall potential")
plt.show()