1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
import numpy as np
from ga_molecular_crystal_relax import relax
from ase.ga import get_raw_score
from ase.ga.cutandsplicepairing import CutAndSplicePairing
from ase.ga.data import DataConnection
from ase.ga.offspring_creator import OperationSelector
from ase.ga.ofp_comparator import OFPComparator
from ase.ga.population import Population
from ase.ga.soft_mutation import SoftMutation
from ase.ga.standardmutations import (
RattleMutation,
RattleRotationalMutation,
RotationalMutation,
StrainMutation,
)
from ase.ga.utilities import CellBounds, closest_distances_generator
from ase.io import write
da = DataConnection('gadb.db')
# Various items needed for initializing the genetic operators
slab = da.get_slab()
atom_numbers_to_optimize = da.get_atom_numbers_to_optimize()
n_top = len(atom_numbers_to_optimize)
blmin = closest_distances_generator(atom_numbers_to_optimize, 1.0)
cellbounds = CellBounds(
bounds={'phi': [30, 150], 'chi': [30, 150], 'psi': [30, 150]}
)
# Note the "use_tags" keyword argument being used
# to signal that we want to preserve molecular identity
# via the tags
pairing = CutAndSplicePairing(
slab,
n_top,
blmin,
p1=1.0,
p2=0.0,
minfrac=0.15,
cellbounds=cellbounds,
number_of_variable_cell_vectors=3,
use_tags=True,
)
rattlemut = RattleMutation(
blmin, n_top, rattle_prop=0.3, rattle_strength=0.5, use_tags=True
)
strainmut = StrainMutation(
blmin, stddev=0.7, cellbounds=cellbounds, use_tags=True
)
rotmut = RotationalMutation(blmin, fraction=0.3, min_angle=0.5 * np.pi)
rattlerotmut = RattleRotationalMutation(rattlemut, rotmut)
blmin_soft = closest_distances_generator(atom_numbers_to_optimize, 0.8)
softmut = SoftMutation(blmin_soft, bounds=[2.0, 5.0], use_tags=True)
operators = OperationSelector(
[5, 1, 1, 1, 1, 1],
[pairing, rattlemut, strainmut, rotmut, rattlerotmut, softmut],
)
# Relaxing the initial candidates
while da.get_number_of_unrelaxed_candidates() > 0:
a = da.get_an_unrelaxed_candidate()
relax(a)
da.add_relaxed_step(a)
# The structure comparator for the population
comp = OFPComparator(
n_top=n_top,
dE=1.0,
cos_dist_max=5e-3,
rcut=10.0,
binwidth=0.05,
pbc=[True, True, True],
sigma=0.05,
nsigma=4,
recalculate=False,
)
# The population
population = Population(
data_connection=da, population_size=10, comparator=comp, logfile='log.txt'
)
current_pop = population.get_current_population()
strainmut.update_scaling_volume(current_pop, w_adapt=0.5, n_adapt=4)
pairing.update_scaling_volume(current_pop, w_adapt=0.5, n_adapt=4)
# Test a few new candidates
n_to_test = 10
for step in range(n_to_test):
print(f'Now starting configuration number {step}', flush=True)
# Generate a new candidate
a3 = None
while a3 is None:
a1, a2 = population.get_two_candidates()
a3, desc = operators.get_new_individual([a1, a2])
# Relax it and add to database
da.add_unrelaxed_candidate(a3, description=desc)
relax(a3)
da.add_relaxed_step(a3)
# Update the population
population.update()
current_pop = population.get_current_population()
write('current_population.traj', current_pop)
# Update the strain mutation and pairing operators
if step % 10 == 0:
strainmut.update_scaling_volume(current_pop, w_adapt=0.5, n_adapt=4)
pairing.update_scaling_volume(current_pop, w_adapt=0.5, n_adapt=4)
# Print out information for easier follow-up/analysis/plotting:
print(
'Step %d %s %.3f %.3f %.3f'
% (step, desc, get_raw_score(a1), get_raw_score(a2), get_raw_score(a3))
)
print(
'Step %d highest raw score in pop: %.3f'
% (step, get_raw_score(current_pop[0]))
)
print('GA finished after step %d' % step)
hiscore = get_raw_score(current_pop[0])
print('Highest raw score = %8.4f eV' % hiscore)
write('all_candidates.traj', da.get_all_relaxed_candidates())
write('current_population.traj', current_pop)
|