from sys import argv
from numpy import where, array, finfo, float64, arange, zeros, savetxt
from math import sin, cos, pi
from contextlib import suppress
[docs]def strings():
"""
Mango Strings XYZ file generation.
commandline parameters
[radius]%[tolerance] [number of particles] [postion Phi] [position Theta] [magnetisation Phi] [magnetisation Theta]
Phi and Theta are the azimuthal angle and the polar angle for position and magnetisation,
they are optional and default to aligning along the z axis.
-h help
-v verbose
"""
if '-h' in argv:
print(strings.__doc__)
exit(0)
v = v_print("-v" in argv)
with suppress(ValueError):
del argv[argv.index('-v')]
radius = argv[1]
if '%' in radius:
r = radius.split('%')
radius = float(r[0]) + float(r[0]) * float(r[1]) / 100
r = f'{r[0]}%{r[1]}'
else:
radius = float(radius)
r = radius
no_mol = int(argv[2])
no_mol_arr = arange(no_mol)
try:
p, t = list(array([argv[3], argv[4]], dtype=float) * (pi / 180))
mp, mt = list(array([argv[5], argv[6]], dtype=float) * (pi / 180))
except IndexError:
v.print('Using default direction (z)')
p = mp = t = mt = 0
unit, munit = (r_unit(p, t), r_unit(mp, mt))
v.print('Position Unit vector', unit)
v.print('Magnetic Unit vector', munit)
start = - (unit * radius * (no_mol - 1))
xyz = zeros((no_mol, 9))
xyz[:, 0:3] = start + (no_mol_arr[:, None] * radius * 2 * unit)
xyz[:, 6:9] += munit
v.print(xyz)
header = f' {no_mol}\n # Generated with mango strings generator'
savetxt(f'string_{no_mol}r{r}.xyz', xyz, fmt='MNP {}'.format(9 * ' % .8e'), comments='', header=header)
[docs]def r_unit(p, t):
unit = array([sin(t) * cos(p), sin(t) * sin(p), cos(t)])
return where(unit < finfo(float64).eps, where(unit > -finfo(float64).eps, 0, unit), unit)
[docs]class v_print():
def __init__(self, verbose):
if verbose:
self.print = self._print
else:
self.print = self._dont_print
@staticmethod
def _print(*a, **k):
return print(*a, **k)
@staticmethod
def _dont_print(*args):
pass
if __name__ == '__main__':
strings()