"""An example module involving isotensional asymptotics.
This module contains a ``main`` function that allows the asymptotic
approaches to be compared to exact approaches, when available, and
otherwise to the numerical quadrature approach.
The results are plotted using ``matplotlib``.
When executed at the command line, flags are passed as keyword arguments.
Example:
Compare the asymptotic approaches to the exact approach for the EFJC
model for a few nondimensional energy scales:
::
python -m ufjc.examples.asymptotics --varepsilon_list 10 25 100 1000
"""
[docs]def main(**kwargs):
r"""Main function for the module.
This is the main function, called when executing the module from the
command line, also available when importing the module.
Args:
**kwargs: Arbitrary keyword arguments.
Passed to ``uFJC`` instantiation.
Example:
.. plot::
Compare the asymptotic approaches for many models and parameters:
>>> from ufjc.examples import asymptotics
>>> asymptotics.main(potential='harmonic',
... varepsilon_list=[10, 25, 100, 1000])
>>> asymptotics.main(potential='log-squared',
... varepsilon_list=[10, 25, 250])
>>> asymptotics.main(potential='morse',
... varepsilon_list=[10, 25, 250])
>>> asymptotics.main(potential='lennard-jones',
... varepsilon_list=[1, 2, 5, 15])
>>> asymptotics.main(potential='mie', n=10, m=4,
... varepsilon_list=[1, 2, 5, 15])
>>> asymptotics.main(potential='polynomial',
... coefficients=[1, 2, 3],
... varepsilon_list=[10, 25, 100])
Example:
Export .csv files for external use:
>>> from ufjc.examples import asymptotics
>>> asymptotics.main(potential='harmonic',
... varepsilon_list=[10, 25, 100, 1000], csv=1)
>>> asymptotics.main(potential='morse',
... varepsilon_list=[10, 25, 100, 1000], csv=1)
"""
# Import external modules
import numpy as np
import matplotlib.pyplot as plt
# Import internal modules
from ufjc import uFJC
# Option to show plots or export .csv files
export_csv_not_plot = kwargs.get('csv', 0) == 1
if export_csv_not_plot is False:
plt.figure()
# Repeat for all values of varepsilon
for varepsilon in kwargs.get('varepsilon_list'):
# Function to produce a file name for .csv output
def filename(model, approach):
return './fig-' + str(model.potential) + '-' + \
str(approach) + '-varepsilon-' + str(varepsilon) + '.csv'
# Create the single-chain model
model = uFJC(varepsilon=varepsilon, **kwargs)
# If harmonic potentials, use the exact solution
if model.potential == 'harmonic':
eta_scale = model.varepsilon
eta = np.linspace(1e-2, 0.3*model.varepsilon,
int(kwargs.get('num_points_eta', 100)))
if export_csv_not_plot is True:
data = np.vstack((model.gamma(eta, approach='exact'),
eta/eta_scale)).T
np.savetxt(filename(model, 'exact'), data, delimiter=",")
else:
plt.plot(model.gamma(eta, approach='exact'), eta/eta_scale,
label=r'$\varepsilon=$' + str(varepsilon))
# Otherwise use a numerical calculation
else:
if model.potential == 'polynomial':
eta_scale = model.varepsilon
else:
eta_scale = model.eta_max
eta = np.linspace(1e-2, 0.99*eta_scale,
int(kwargs.get('num_points_eta', 100)))
if export_csv_not_plot is True:
data = np.vstack((model.gamma(eta, approach='quadrature'),
eta/eta_scale)).T
np.savetxt(filename(model, 'quad'), data, delimiter=",")
else:
plt.plot(model.gamma(eta, approach='quadrature'),
eta/eta_scale,
label=r'$\varepsilon=$' + str(varepsilon))
# The asymptotic approaches
if export_csv_not_plot is True:
data = np.vstack((model.gamma(eta, approach='asymptotic'),
eta/eta_scale)).T
np.savetxt(filename(model, 'asymptotic'), data, delimiter=",")
else:
plt.plot(model.gamma(eta, approach='asymptotic'),
eta/eta_scale, 'k:')
# The reduced asymptotic results
if export_csv_not_plot is True:
data = np.vstack((model.gamma(eta, approach='reduced'),
eta/eta_scale)).T
np.savetxt(filename(model, 'reduced'), data, delimiter=",")
else:
plt.plot(model.gamma(eta, approach='reduced'),
eta/eta_scale, 'k--')
# Show the results if plotting
if export_csv_not_plot is False:
# Create linestyle (approach) legend
if model.potential == 'harmonic':
plt.plot(np.nan, np.nan, 'k', label='exact')
else:
plt.plot(np.nan, np.nan, 'k', label='quadrature')
plt.plot(np.nan, np.nan, 'k:', label='asymptotic')
plt.plot(np.nan, np.nan, 'k--', label='reduced')
# Plot labels and legend
plt.legend()
plt.xlabel(r'$\gamma$')
plt.ylabel(r'$\eta/\eta_\mathrm{max}$')
plt.title(model.potential + '-FJC isotensional ' + r'$\gamma(\eta)$')
plt.show()
if __name__ == '__main__': # pragma: no cover
# Import external modules
import argparse
# Parse args
parser = argparse.ArgumentParser()
parser.add_argument('-u', '--potential', type=str, default='harmonic')
parser.add_argument('-l', '--varepsilon_list', nargs='+', type=float,
required=True)
# Parse arbitrary float args
for arg in parser.parse_known_args()[1]:
if arg.startswith('--'):
parser.add_argument(arg.split('=')[0], type=float)
# Execute main function with passed args as kwargs
main(**vars(parser.parse_args()))