# -*- coding: utf-8 -*-
import numpy
from mm import MM
from params import airebo_parm
from params import consts
from lib import libairebo
TRUE_NAME = {'Carbon' : 'C', 'Hydrogen' : 'H', 'C': 'C', 'H' : 'H'}
"""
"""
class REBOMessage(object):
def __init__(self, a, b, full_links, num_full_links, NC, NH):
self.a = a
self.b = b
self.full_links = full_links
self.num_full_links = num_full_links
self.NC = NC
self.NH = NH
def b_cast_airebo(comm, struct, parm, a, b):
procid = comm.Get_rank()
for sender in xrange(comm.Get_size()):
msg = None
if (sender == procid):
fl = struct.full_links[a:b]
nfl = struct.num_full_links[a:b]
nc = parm['NC_full'][a:b]
nh = parm['NH_full'][a:b]
msg = REBOMessage(a, b, fl, nfl, nc, nh)
comm.Barrier()
msg = comm.bcast(msg, root = sender)
if (sender != procid):
ia, ib = msg.a, msg.b
struct.full_links[ia : ib] = msg.full_links
struct.num_full_links[ia : ib] = msg.num_full_links
parm['NC_full'][ia : ib] = msg.NC
parm['NH_full'][ia : ib] = msg.NH
comm.Barrier()
class AIREBOException(Exception):
def __init__(self, message):
super(AIREBOException, self).__init__(message)
[docs]class AIREBO(MM):
"""
This class is the successor of class MM
Constructor of class AIREBO:
Args:
struct(structure): nanostructure
ff_params(list): list of names of potentials functions
"""
def __init__(self, struct, ff_params, comm = None):
if not ff_params:
ff_params = ["u_rebo", "u_tors", "u_lj"]
self.parm = airebo_parm.getAIREBO_parm()
self.parm["atypes"] = ["C", "H"]
self.parm['use_tors'] = "u_tors" in ff_params
self.parm['use_lj'] = "u_lj" in ff_params
super(AIREBO, self).__init__(struct, libairebo, ff_params, self.parm)
self.update_neighbours(0, self.struct.n_atoms)
fc = self.forces
def nforces(f, a, b):
fc(f, a, b)
self.update_neighbours(a, b)
if comm:
b_cast_airebo(comm, self.struct, self.parm, a, b)
self.forces = nforces
[docs] def preprocessing(self, struct):
"""
It corrects atom type and atom boxnames, group them and find out. Masses is taken from parameters.
"""
struct = self.struct
atypes = self.parm["atypes"]
if not hasattr(struct, "atom_types"):
struct.atom_types = numpy.zeros(struct.n_atoms, numpy.int32)
calc_mass = False
if not hasattr(struct, "mass"):
calc_mass = True
struct.mass = numpy.zeros(struct.n_atoms, numpy.float)
if hasattr(struct, "atom_names"):
for i, name in enumerate(struct.atom_names):
if name in atypes:
struct.atom_types[i] = atypes.index(name)
if calc_mass:
struct.mass[i] = consts.ATOM_MASS[TRUE_NAME[name]]
else:
if name in TRUE_NAME:
struct.atom_types[i] = atypes.index(TRUE_NAME[name])
if calc_mass:
struct.mass[i] = consts.ATOM_MASS[TRUE_NAME[name]]
else:
raise AIREBOException("Wrong atom type name %s" % name)
else:
raise AIREBOException("Error: didn't find attribute 'atom_names' for object of structure.")
self.parm['NC_full'] = numpy.zeros(struct.n_atoms, numpy.float)
self.parm['NH_full'] = numpy.zeros(struct.n_atoms, numpy.float)
self.g = lambda costh, Nij, ati, : libairebo.g(costh, Nij, ati, self.parm["G_coefs"])
self.P = lambda x, y, ati, atj : libairebo.bicubic_spline(x, y, ati, atj, self.parm["P_coefs"])
self.F = lambda x, y, z, ati, atj : libairebo.tricubic_spline(x, y, z, ati, atj, self.parm["F_coefs"])
self.T = lambda x, y, z, ati, atj : libairebo.tricubic_spline(x, y, z, ati, atj, self.parm["T_coefs"])
self.update_neighbours = lambda a, b : libairebo.update_neighbours(self.struct.__dict__, self.parm, a, b)
return True
[docs] def init_cutoff(self, r_in, r_out, cutoff_neighbours):
"""
Args:
r_in(float): internal cutoff radius
r_out(float): external cutoff radius
cutoff_neighbours(list): list of neighbours get into the field with r_out radius
"""
self.parm["use_cutoff"] = True
self.parm["cutoff_r"] = r_in
self.parm["cutoff_d"] = r_out - r_in
self.update_cutoff(cutoff_neighbours)
[docs] def update_cutoff(self, cutoff_neighbours):
"""
Updates list of neighbours in cutoff area
Args:
cutoff_neighbours(list): list of neighbours
"""
self.struct.cutoff_neighbours = map(list, map(set, cutoff_neighbours))