# -*- coding: utf-8 -*-
import numpy
import logging
[docs]class MM(object):
"""
Wrap class for computational modules of molecular mechanical method.
Constructor of class:
Args:
struct(structure): nanostructure
lib(module): dynamic library
ff_functions(list): list of names of force field functions
ff_params(list): list of names of parameters of force field functions
"""
def __init__(self, struct, lib, ff_functions, ff_params):
self.struct = struct
self.parm = ff_params
if self.preprocessing(struct):
self.loadMMFunctions(ff_functions, lib)
self.loadForceFunction(lib)
self.abs_Q_e = 1.62e-19
else:
raise Exception()
[docs] def preprocessing(self, struct):
"""
It checks matching of atom types and atom names of structure with
the same parameters of force field. If there are no atom types in structure
function rebuilds it from atom names. If there are no atom names, it prints, that
it's not possible to check out correctness of atom types.
"""
id_of_type_name = self.parm["id_of_type_name"]
if hasattr(struct, "atom_names") and hasattr(struct, "atom_types"):
for i, at in enumerate(struct.atom_names):
if struct.atom_types[i] != id_of_type_name[at]:
loggging.error(u"Несовпадение номеров типов атомов структуры и типов атомов параметров.")
return False
elif hasattr(struct, "atom_names") and not hasattr(struct, "atom_types"):
atypes = numpy.array([numpy.int32(id_of_type_name[x]) for x in struct.atom_names])
struct.atom_types = atypes
elif not hasattr(struct, "atom_names") and hasattr(struct, "atom_types"):
logging.warning(u"Невозможно проверить правильность типов атомов. Отсутствует параметр 'atom_names' в объекте Structure.")
else:
logging.error(u"Отсутствуют параметры 'atom_names' и 'atom_types' в объекте Structure.")
return True
[docs] def loadMMFunctions(self, ff_functions, lib):
"""
Args:
ff_functions(list): list of names of atom types
lib(module): dynamic library for molecular mechanics computation
"""
self.functions = []
self.functions_i = []
self.functions_ij = []
def get_func(name, lib):
def func():
return getattr(lib, name)(self.struct.__dict__, self.parm)
if name[-2:] == "_i":
def func(i):
return getattr(lib, name)(self.struct.__dict__, self.parm, i)
return func
if name[-3:] == "_ij":
def func(i, j):
return getattr(lib, name)(self.struct.__dict__, self.parm, i, j)
return func
return func
for f_type in ff_functions:
for sufix in ["", "_i", "_ij"]:
func = get_func(f_type + sufix, lib)
setattr(self, f_type + sufix, func)
getattr(self, "functions" + sufix).append(func)
[docs] def loadForceFunction(self, lib):
"""
Adds function 'forces' to module
Args:
lib(module): dynamic library
"""
def get_func(name, lib):
def func(coords, a, b):
return getattr(lib, name)(self.struct.__dict__, self.parm, coords, a, b)
return func
if hasattr(lib, "forces"):
func = get_func("forces", lib)
setattr(self, "forces", func)
[docs] def compute(self):
"""
Returns energy of structure
"""
u = 0.0
for func in self.functions:
u += func()
return u
[docs] def compute_i(self, i):
"""
Returns summ of energies, calculated by functions from list 'functions_i'
"""
u = 0.0
for func in self.functions_i:
u += func(i)
return u
[docs] def compute_ij(self, i, j):
"""
Returns summ of energies, calculated by functions from list 'functions_ij'
"""
u = 0.0
for func in self.functions_ij:
u += func(i, j)
return u * self.abs_Q_e