Source code for cat_optimize
'''
Adds optimization functionality to the ORR catalyst structure
'''
import random
import numpy as np
import sys
sys.path.append('/home/vlachos/mpnunez/Github/Structure-Optimization/ORR/')
from Cat_structure import cat_structure
[docs]class cat_optimize(cat_structure):
'''
Inherits ORR catalyst structure and adds optimization functionality
'''
Pt_Pt_1nn_dist = 2.77 # angstrom
def __init__(self):
'''
Call superclass constructor
'''
#super(cat_optimize, self).__init__(met_name = 'Pt', facet = 111, dim1 = 12, dim2 = 12)
cat_structure.__init__(self, met_name = 'Pt', facet = 111, dim1 = 12, dim2 = 12)
self.atom_last_moved = None
self.weights = [0., -1.]
[docs] def geo_crossover(self, x1, x2, pt1 = 1, pt2 = 1):
'''
Geometry-based crossover. Partions the catalyst surface into regions in a checkerboard style and performs crossover.
:param x1: Mom
:param x2: Dad
:param pt1: By default, use 1-point crossover in first dimension
:param pt2: By default, use 1-point crossover in second dimension
:returns: Two offspring
'''
x_bounds = [random.random() for i in xrange(pt1)]
y_bounds = [random.random() for i in xrange(pt2)]
frac_coords = self.atoms_obj_template.get_scaled_positions()
for i in xrange(len(x1)):
# Find whether it is an even or odd cell
score = 0
for bound in x_bounds:
if frac_coords[self.variable_atoms[i],0] > bound:
score += 1
for bound in y_bounds:
if frac_coords[self.variable_atoms[i],1] > bound:
score += 1
# Swap if it is in an even cell
if score % 2 == 0:
x1[i], x2[i] = x2[i], x1[i]
return x1, x2
def eval_x(self, x):
x = np.array(x)
self.evaluated = False
# Build the defected graph
self.defected_graph = self.template_graph.copy_data()
for i in range(len(x)):
if x[i] == 0:
self.defected_graph.remove_vertex(self.variable_atoms[i])
return self.get_OFs()
[docs] def get_OF(self):
'''
:param weights: Weights for the objective functions
:returns: A single objective function that is a linear superposition of the other objectives
'''
return self.weights[0] * self.eval_surface_energy() + self.weights[1] * self.eval_current_density()
[docs] def get_OFs(self):
'''
Evaluate the objective functions
:returns: 2-ple of surface energy and current density
'''
return self.eval_surface_energy(), self.eval_current_density() #+ np.random.normal(loc=0.0, scale=0.025)
def rand_move(self):
self.atom_last_moved = random.choice(self.variable_atoms)
self.flip_atom(self.atom_last_moved)
def revert_last(self):
self.flip_atom(self.atom_last_moved)