Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Memory usage: ▁▁▁▁▁▁▁▁▁▁▁▁ (max: 2.00MB, growth rate: 0%)
- hex_anneal_profile_v06.py: % of time = 100.00% out of 208.12s.
- ╷ ╷ ╷ ╷ ╷ ╷ ╷ ╷
- │Time │–––––– │–––––– │Memory │–––––– │––––––––––– │Copy │
- Line │Python │native │system │Python │avg │timeline/% │(MB/s) │hex_anneal_profile_v06.py
- ╺━━━━━━┿━━━━━━━┿━━━━━━━┿━━━━━━━┿━━━━━━━━┿━━━━━━━┿━━━━━━━━━━━━━━━┿━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸
- 1 │ │ │ │ │ 38M │▁▁▁▁▁▁▁▁▁ │ │import numpy as np
- 2 │ 2% │ │ │ │ 81M │▁▁▁▁▁▁▁▁▁ │ │import matplotlib.pyplot as plt
- 3 │ │ │ │ │ │ │ │from matplotlib.collections import LineCollection
- 4 │ │ │ │ │ │ │ │from matplotlib import colors as mcolors
- 5 │ │ │ │ │ 38M │▁▁▁▁▁▁▁▁▁ │ │from scipy.optimize import minimize
- 6 │ │ │ │ │ │ │ │import time
- 7 │ │ │ │ │ │ │ │
- 8 │ │ │ │ │ │ │ │class Problem():
- 9 │ │ │ │ │ │ │ │ def __init__(self, name=None, nmax=12, a_sub=1., k_v
- 10 │ │ │ │ │ │ │ │ h=1.0, k_bond=2., R=0., origin=np.zeros
- 11 │ │ │ │ │ │ │ │ self.name = str(name)
- 12 │ │ │ │ │ │ │ │ self.nmax = int(nmax)
- 13 │ │ │ │ │ │ │ │ self.a_sub = float(a_sub)
- 14 │ │ │ │ │ │ │ │ twopi = 2 * np.pi
- 15 │ │ │ │ │ │ │ │ r3o2 = np.sqrt(3) / 2
- 16 │ │ │ │ │ │ │ │ g = (twopi / (self.a_sub * r3o2)) * np.array([[0
- 17 │ │ │ │ │ │ │ │ self.g_sub = g[::-1] # for purposes of calculati
- 18 │ │ │ │ │ │ │ │ self.k_vert = float(k_vert)
- 19 │ │ │ │ │ │ │ │ self.a = float(a)
- 20 │ │ │ │ │ │ │ │ self.h = float(h)
- 21 │ │ │ │ │ │ │ │ self.k_bond = float(k_bond)
- 22 │ │ │ │ │ │ │ │ self.R = float(R)
- 23 │ │ │ │ │ │ │ │ self.origin = np.array(origin, dtype=float)
- 24 │ │ │ │ │ │ │ │ self.sig = float(sig)
- 25 │ │ │ │ │ │ │ │ self.seed = int(seed)
- 26 │ │ │ │ │ │ │ │ self.initial_hex_lattice(origin=origin)
- 27 │ │ │ │ │ │ │ │ np.random.seed(self.seed)
- 28 │ │ │ │ │ │ │ │ self.random = self.sig * np.random.random(self.x
- 29 │ │ │ │ │ │ │ │ self.x_initial = self.x0_init + self.random
- 30 │ │ │ │ │ │ │ │ self.x = self.x_initial.copy() # this array will
- 31 │ │ │ │ │ │ │ │ # self.x_final = None
- 32 │ │ │ │ │ │ │ │ self.n_atoms = self.x_initial.shape[0]
- 33 │ │ │ │ │ │ │ │ self.define_nearest_neighbor_bonds()
- 34 │ │ │ │ │ │ │ │ self.calculate_bond_energies()
- 35 │ │ │ │ │ │ │ │ self.calculate_surface_energies()
- 36 │ │ │ │ │ │ │ │
- 37 │ │ │ │ │ │ │ │ def initial_hex_lattice(self, origin):
- 38 │ │ │ │ │ │ │ │ """generates an N x 3 array of atom locations, o
- 39 │ │ │ │ │ │ │ │ Gaussian noise in 3D. The reduction to 1/6 sl
- 40 │ │ │ │ │ │ │ │ i, j = np.mgrid[-self.nmax:self.nmax+1, -self.nm
- 41 │ │ │ │ │ │ │ │ keep = (np.abs(i + j) <= self.nmax) * ~((i == 0)
- 42 │ │ │ │ │ │ │ │ i, j = [thing[keep] for thing in (i, j)]
- 43 │ │ │ │ │ │ │ │ r3o2 = np.sqrt(3) / 2.
- 44 │ │ │ │ │ │ │ │ x = self.a * (i + 0.5 * j)
- 45 │ │ │ │ │ │ │ │ y = self.a * r3o2 * j
- 46 │ │ │ │ │ │ │ │ s, c = [f(np.radians(self.R)) for f in (np.sin,
- 47 │ │ │ │ │ │ │ │ x, y = c * x - s * y, c * y + s * x
- 48 │ │ │ │ │ │ │ │ z = np.zeros_like(x)
- 49 │ │ │ │ │ │ │ │ # origin = np.array([0, 0, self.h])
- 50 │ │ │ │ │ │ │ │ self.x0_init = origin + np.vstack([np.zeros(3),
- 51 │ │ │ │ │ │ │ │ self.i = np.hstack(([0], i))
- 52 │ │ │ │ │ │ │ │ self.j = np.hstack(([0], j))
- 53 │ │ │ │ │ │ │ │ self.ij = np.stack((self.i, self.j), axis=1)
- 54 │ │ │ │ │ │ │ │
- 55 │ │ │ │ │ │ │ │ def define_nearest_neighbor_bonds(self):
- 56 │ │ │ │ │ │ │ │ """calculate index pairs for all nearest-neighbo
- 57 │ │ │ │ │ │ │ │ lattice"""
- 58 │ │ │ │ │ │ │ │ a_bonds, b_bonds, c_bonds = [], [], []
- 59 │ │ │ │ │ │ │ │ n_atom = np.arange(self.n_atoms)
- 60 │ │ │ │ │ │ │ │ A, B, C, D = (self.i < self.nmax, self.i + self.
- 61 │ │ │ │ │ │ │ │ self.j < self.nmax, self.i > -self
- 62 │ │ │ │ │ │ │ │ self.A, self.B, self.C, self.D = A, B, C, D
- 63 │ │ │ │ │ │ │ │ self.atoms_1a = n_atom[A * B]
- 64 │ │ │ │ │ │ │ │ self.atoms_1b = n_atom[B * C]
- 65 │ │ │ │ │ │ │ │ self.atoms_1c = n_atom[C * D]
- 66 │ │ │ │ │ │ │ │ self.atoms_2aij = self.ij[self.atoms_1a] + np.ar
- 67 │ │ │ │ │ │ │ │ self.atoms_2bij = self.ij[self.atoms_1b] + np.ar
- 68 │ │ │ │ │ │ │ │ self.atoms_2cij = self.ij[self.atoms_1c] + np.ar
- 69 │ │ │ │ │ │ │ │ self.atoms_2a = np.array([np.where(np.all(self.i
- 70 │ │ │ │ │ │ │ │ for atom in self.atoms_2aij
- 71 │ │ │ │ │ │ │ │ self.atoms_2b = np.array([np.where(np.all(self.i
- 72 │ │ │ │ │ │ │ │ for atom in self.atoms_2bij
- 73 │ │ │ │ │ │ │ │ self.atoms_2c = np.array([np.where(np.all(self.i
- 74 │ │ │ │ │ │ │ │ for atom in self.atoms_2cij
- 75 │ │ │ │ │ │ │ │ self.atoms_1 = np.hstack((self.atoms_1a, self.at
- 76 │ │ │ │ │ │ │ │ self.atoms_2 = np.hstack((self.atoms_2a, self.at
- 77 │ │ │ │ │ │ │ │
- 78 │ │ │ │ │ │ │ │ def calculate_bond_energies(self, which='x'):
- 79 │ │ │ │ │ │ │ │ """harmonic oscilator potential for bond lengths
- 80 │ │ │ │ │ │ │ │ with spring contsant 'k_bond'"""
- 81 │ │ │ │ │ │ │ │ array = getattr(self, which)
- 82 │ │ │ │ │ │ │ │ vectors = array[self.atoms_2] - array[self.atoms
- 83 │ │ │ │ │ │ │ │ self.bond_lengths = np.sqrt((vectors**2).sum(axi
- 84 │ │ │ │ │ │ │ │ self.bond_energies = self.k_bond * (self.bond_le
- 85 │ │ │ │ │ │ │ │
- 86 │ │ │ │ │ │ │ │ def calculate_surface_energies(self, which='x'):
- 87 │ │ │ │ │ │ │ │ """ applies smooth sinusoidal-like hexagonal pat
- 88 │ │ │ │ │ │ │ │ to a N x 2 grid of x-y points. Minimum at
- 89 │ │ │ │ │ │ │ │ array = getattr(self, which)
- 90 │ │ │ │ │ │ │ │ E = np.cos((array[:, :2, None] * self.g_sub).sum
- 91 │ │ │ │ │ │ │ │ result = (1.5 + E.sum(axis=1)) / 4.5
- 92 │ │ │ │ │ │ │ │ surface_energy_xy = 1. - (1.5 + E.sum(axis=-1))
- 93 │ │ │ │ │ │ │ │ surface_energy_z = self.k_vert * (self.x[:, 2] -
- 94 │ │ │ │ │ │ │ │ self.surface_energies = surface_energy_xy + surf
- 95 │ │ │ │ │ │ │ │
- 96 │ │ │ │ │ │ │ │ def get_energy(self, which='x'):
- 97 │ │ │ │ │ │ │ │ self.calculate_bond_energies(which)
- 98 │ │ │ │ │ │ │ │ self.calculate_surface_energies(which)
- 99 │ │ │ │ │ │ │ │ return self.bond_energies.sum() + self.surface_e
- 100 │ │ │ │ │ │ │ │
- 101 │ │ │ │ │ │ │ │ def potential_yx(self, yx):
- 102 │ │ │ │ │ │ │ │ """ applies smooth sinusoidal-like hexagonal pat
- 103 │ │ │ │ │ │ │ │ to a 2 x M x N y-x grid of points. Minimum a
- 104 │ │ │ │ │ 25M │▁▁▁▁▁▁▁▁▁ │ │ E = np.cos((yx[:, None, ...] * self.g_sub[::-1][
- 105 │ │ │ │ │ 4M │▁▁▁▁▁▁▁▁▁ │ │ result = 1. - (1.5 + E.sum(axis=0)) / 4.5 # then
- 106 │ │ │ │ │ │ │ │ return result
- 107 │ │ │ │ │ │ │ │
- 108 │ │ │ │ │ │ │ │ def plot_it(self, hw_pixels=250, cmap_sub='gray', cm
- 109 │ │ │ │ │ │ │ │ cmap_bonds='jet', linewidth=2.5, vmin=0.
- 110 │ │ │ │ │ │ │ │ array = getattr(self, which)
- 111 │ │ │ │ │ │ │ │ hw = 1.05 * np.abs(array[:, :2]).max() # largest
- 112 │ │ │ │ │ │ │ │ self.plot_scale = hw / hw_pixels # 0.05 angstro
- 113 │ │ │ │ │ │ │ │ self.yx = self.plot_scale * np.stack(np.mgrid[-h
- 114 │ │ │ │ │ 12M │▁▁▁▁▁▁▁▁▁ │ │ -hw_pix
- 115 │ │ │ │ │ │ │ │ self.substrate = self.potential_yx(yx=self.yx)
- 116 │ │ │ │ │ │ │ │ self.plot_extent = [self.yx[1].min(), self.yx[1]
- 117 │ │ │ │ │ │ │ │ self.yx[0].min(), self.yx[0]
- 118 │ │ │ │ │ │ │ │ print('self.substrate.shape: ', self.substrate.s
- 119 │ │ │ │ │ │ │ │ # energy histograms
- 120 │ │ │ │ │ │ │ │ a, b = np.histogram(self.surface_energies, bins=
- 121 │ │ │ │ │ │ │ │ c, d = np.histogram(self.bond_energies, bins=(se
- 122 │ │ │ │ │ │ │ │ # color coded bond lines
- 123 │ │ │ │ │ │ │ │ my_cmap = plt.get_cmap(cmap_bonds)
- 124 │ │ │ │ │ │ │ │ colors = my_cmap(self.bond_energies / self.bond_
- 125 │ │ │ │ │ │ │ │ linez = np.stack((self.x[bob.atoms_1][:, :2], se
- 126 │ │ │ │ │ │ │ │ ln_coll = LineCollection(linez, colors=colors, l
- 127 │ │ │ │ │ │ │ │
- 128 │ │ │ │ │ │ │ │
- 129 │ │ │ │ │ 4M │▁▁▁▁▁▁▁▁▁ │ │ fig = plt.figure(constrained_layout=False, figsi
- 130 │ │ │ │ │ │ │ │ gs = fig.add_gridspec(nrows=4, ncols=5, left=0.0
- 131 │ │ │ │ │ │ │ │ bottom=0.07, top=0.96, hsp
- 132 │ │ │ │ │ │ │ │ ax1 = fig.add_subplot(gs[:3, :])
- 133 │ │ │ │ │ │ │ │
- 134 │ │ │ │ │ │ │ │ # fig, ax = plt.subplots(1, 1, figsize=[9, 7.5])
- 135 │ │ │ │ │ │ │ │ ax1.imshow(self.substrate, origin='lower', exten
- 136 │ │ │ │ │ 2M │▁▁▁▁▁▁▁▁▁ │ │ cmap=cmap_sub, vmin=vmin, vmax=vmax) #
- 137 │ │ │ │ │ │ │ │ ax1.add_collection(ln_coll) # then bonds
- 138 │ │ │ │ │ │ │ │ x, y = self.x.T[:2]
- 139 │ │ │ │ │ │ │ │ ax1.scatter(x, y, c=self.surface_energies, cmap=
- 140 │ │ │ │ │ │ │ │ edgecolors='k', zorder=2) # then atom
- 141 │ │ │ │ │ │ │ │ ax1.set_ylabel('Angstroms')
- 142 │ │ │ │ │ │ │ │ ax2 = fig.add_subplot(gs[3:, 1:4])
- 143 │ │ │ │ │ │ │ │ ax2.plot(b[1:], a, label='surface energies')
- 144 │ │ │ │ │ │ │ │ ax2.plot(d[1:], c, label='bond energies')
- 145 │ │ │ │ │ │ │ │ ax2.legend()
- 146 │ │ │ │ │ │ │ │ ax2.set_yscale('log')
- 147 │ │ │ │ │ │ │ │ ax2.set_xlabel('energy')
- 148 │ 13% │ 2% │ │ │ 140M │▁▁▁▁▁▁▁▁▁ 1% │ 1 │ plt.show()
- 149 │ │ │ │ │ │ │ │
- 150 │ │ │ │ │ │ │ │def ang(i, j, k, l):
- 151 │ │ │ │ │ │ │ │ root3 = np.sqrt(3)
- 152 │ │ │ │ │ │ │ │ th_ij = np.arctan2(root3 * j, 2*i+j)
- 153 │ │ │ │ │ │ │ │ th_kl = np.arctan2(root3 * l, 2*k+l)
- 154 │ │ │ │ │ │ │ │ return np.degrees(th_ij - th_kl)
- 155 │ │ │ │ │ │ │ │
- 156 │ │ │ │ │ │ │ │
- 157 │ │ │ │ │ │ │ │#### NEXT
- 158 │ │ │ │ │ │ │ │# print old/new mean origin
- 159 │ │ │ │ │ │ │ │# print old/new mean rotation
- 160 │ │ │ │ │ │ │ │# print old/new mean bond length
- 161 │ │ │ │ │ │ │ │
- 162 │ │ │ │ │ │ │ │# is there any collective behavior?
- 163 │ │ │ │ │ │ │ │
- 164 │ │ │ │ │ │ │ │# BEGIN
- 165 │ │ │ │ │ │ │ │
- 166 │ │ │ │ │ │ │ │a_lattice = 3.5
- 167 │ │ │ │ │ │ │ │a_substrate = 2.9
- 168 │ │ │ │ │ │ │ │height = a_lattice
- 169 │ │ │ │ │ │ │ │R = 9.
- 170 │ │ │ │ │ │ │ │nmax = 12
- 171 │ │ │ │ │ │ │ │seed = 42
- 172 │ │ │ │ │ │ │ │
- 173 │ │ │ │ │ │ │ │origin = [0, 0, height]
- 174 │ │ │ │ │ │ │ │
- 175 │ │ │ │ │ │ │ │bob = Problem('bob', sig=0.2, k_bond=20, a_sub=a_substra
- 176 │ │ │ │ │ │ │ │ R=R, origin=origin, nmax=nmax, seed=seed)
- 177 │ │ │ │ │ │ │ │
- 178 │ │ │ │ │ │ │ │bob.plot_it()
- 179 │ │ │ │ │ │ │ │
- 180 │ │ │ │ │ │ │ │
- 181 │ │ │ │ │ │ │ │def mini_me(atom_positions_flattened, args):
- 182 │ │ │ │ │ │ │ │ g_sub, k_vert, a, h, k_bond, atoms_1, atoms_2 = args
- 183 │ │ │ │ │ │ │ │ atom_positions = atom_positions_flattened.reshape(-1
- 184 │ │ │ │ │ │ │ │ # bond energies
- 185 │ 12% │ 16% │ │ │ 2M │▁▁▁▁▁▁▁▁▁ 26% │ 24 │ vectors = atom_positions[atoms_2] - atom_positions[a
- 186 │ 5% │ 7% │ │ │ 2M │▁▁▁▁▁▁▁▁▁ 5% │ 33 │ bond_lengths = np.sqrt((vectors**2).sum(axis=1))
- 187 │ │ 2% │ │ │ │ │ 3 │ bond_energy = k_bond * ((bond_lengths - a)**2).sum()
- 188 │ │ │ │ │ │ │ │ # surface energies
- 189 │ 14% │ 23% │ │ │ 2M │▁▁▁▁▁▁▁▁▁ 4% │ 31 │ E = np.cos((atom_positions[:, :2, None] * g_sub).sum
- 190 │ 3% │ 4% │ │ │ │ │ 8 │ result = (1.5 + E.sum(axis=1)) / 4.5
- 191 │ 3% │ 3% │ │ │ │ │ 4 │ surface_energies_xy = 1. - (1.5 + E.sum(axis=-1)) /
- 192 │ │ │ │ │ │ │ │ surface_energies_z = k_vert * (atom_positions[:, 2]
- 193 │ │ │ │ │ │ │ │ surface_energy = (surface_energies_xy + surface_ener
- 194 │ │ │ │ │ │ │ │ return bond_energy + surface_energy
- 195 │ │ │ │ │ │ │ │
- 196 │ │ │ │ │ │ │ │
- 197 │ │ │ │ │ │ │ │atom_positions = bob.x.copy()
- 198 │ │ │ │ │ │ │ │
- 199 │ │ │ │ │ │ │ │parameters = ('g_sub', 'k_vert' , 'a', 'h', 'k_bond', 'a
- 200 │ │ │ │ │ │ │ │
- 201 │ │ │ │ │ │ │ │args = [getattr(bob, attr) for attr in parameters]
- 202 │ │ │ │ │ │ │ │
- 203 │ │ │ │ │ │ │ │if True:
- 204 │ │ │ │ │ │ │ │ print('start minimization!')
- 205 │ │ │ │ │ │ │ │ print('mini_me(atom_positions, args): ', mini_me(ato
- 206 │ │ │ │ │ │ │ │ maxiter = 1000
- 207 │ │ │ │ │ │ │ │ options = {'maxiter': maxiter}
- 208 │ │ │ │ │ │ │ │ t_start = time.process_time()
- 209 │ │ │ │ │ │ │ │ wow = minimize(mini_me, atom_positions.flatten(), ar
- 210 │ 9% │ 91% │ │ │ 95M │▁▁▁▁▁▁▁▁▁ 63% │ 37 │ tol=1e-2, options=options) # method='
- 211 │ │ │ │ │ │ │ │ process_time = time.process_time() - t_start
- 212 │ │ │ │ │ │ │ │ print('wow.fun: ', wow.fun)
- 213 │ │ │ │ │ │ │ │ print('wow.message: ', wow.message)
- 214 │ │ │ │ │ │ │ │ print('process time: ', process_time)
- 215 │ │ │ │ │ │ │ │ print('number of iterations: ', wow.nit)
- 216 │ │ │ │ │ │ │ │ print('iterartions per second: ', wow.nit / process_
- 217 │ │ │ │ │ │ │ │
- 218 │ │ │ │ │ │ │ │bob.x_final = wow.x.reshape(-1, 3) # insert final result
- 219 │ │ │ │ │ │ │ │
- 220 │ │ │ │ │ │ │ │print('bob.get_energy(which="x_initial"): ', round(bob.g
- 221 │ │ │ │ │ │ │ │print('bob.get_energy(which="x_final"): ', round(bob.get
- 222 │ │ │ │ │ │ │ │
- 223 │ │ │ │ │ │ │ │bob.plot_it(which='x_final')
- 224 │ │ │ │ │ │ │ │
- 225 │ │ │ │ │ │ │ │
- │ │ │ │ │ │ │ │
- ╶──────┼───────┼───────┼───────┼────────┼───────┼───────────────┼───────┼─────────────────────────────────────────────────────────╴
- │ │ │ │ │ │ │ │function summary for hex_anneal_profile_v06.py
- 55 │ │ │ │ │ │ │ │Problem.define_nearest_neighbor_bonds
- 101 │ │ │ │ │ 18M │▁▁▁▁▁▁▁▁▁ │ │Problem.potential_yx
- 108 │ 13% │ 2% │ │ │ 45M │▁▁▁▁▁▁▁▁▁ 1% │ 1 │Problem.plot_it
- 181 │ 37% │ 54% │ │ 1% │ 2M │▁▁▁▁▁▁▁▁▁ 35% │ 102 │ScalarFunction.mini_me
- ╵ ╵ ╵ ╵ ╵ ╵ ╵ ╵
- Top average memory consumption, by line:
- (1) 148: 140 MB
- (2) 210: 95 MB
- (3) 2: 81 MB
- (4) 1: 38 MB
- (5) 5: 38 MB
- generated by the scalene profiler
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement