def getRandomKMC(voltage_range, N, M, xdim=1, ydim=1, zdim=0): # Define electrodes electrodes = np.zeros((8, 4)) electrodes[0] = [ 0, ydim / 4, 0, random.random() * 2 * voltage_range - voltage_range ] electrodes[1] = [ 0, 3 * ydim / 4, 0, random.random() * 2 * voltage_range - voltage_range ] electrodes[2] = [ xdim, ydim / 4, 0, random.random() * 2 * voltage_range - voltage_range ] electrodes[3] = [ xdim, 3 * ydim / 4, 0, random.random() * 2 * voltage_range - voltage_range ] electrodes[4] = [ xdim / 4, 0, 0, random.random() * 2 * voltage_range - voltage_range ] electrodes[5] = [ 3 * xdim / 4, 0, 0, random.random() * 2 * voltage_range - voltage_range ] electrodes[6] = [ xdim / 4, ydim, 0, random.random() * 2 * voltage_range - voltage_range ] electrodes[7] = [3 * xdim / 4, ydim, 0, 0] #%% Initialize simulation object kmc = kmc_dn.kmc_dn(N, M, xdim, ydim, 0, electrodes=electrodes) return kmc
def getRandomDn(self): newDn = kmc_dn.kmc_dn(self.dn.N, self.dn.M, self.dn.xdim, self.dn.ydim, self.dn.zdim, electrodes=self.dn.electrodes, acceptors=self.dn.acceptors, donors=self.dn.donors, copy_from = self.dn) newDn.tests = self.tests self.init_random_voltages(newDn) return newDn
def randomSearch(self, time_budget): #Random search just to see if other searches have some intelligence in them. self.setStrategy(len(self.simulation_strategy) - 1) errors = [] vals = [] diffs = [] best = self.evaluate_error(self.dn) bestDn = kmc_dn.kmc_dn(self.dn.N, self.dn.M, self.dn.xdim, self.dn.ydim, self.dn.zdim, electrodes=self.dn.electrodes, copy_from=self.dn) real_start_time = time.time() time_difference = time.time() - real_start_time while time_difference < time_budget: print(time_difference) self.dn.initialize() error = self.evaluate_error(self.dn) val = self.validate_error(self.dn) vals.append(val) diffs.append(math.fabs(error - val)) if error < best: self.copyDnFromBtoA(bestDn, self.dn) best = error errors.append(error) time_difference = time.time() - real_start_time return bestDn, errors, vals, diffs
def generate_sample_test(N_acceptors, N_donors, electrode_placements, N_tests, fileName): electrodes = np.zeros((len(electrode_placements), 4)) for i in range(len(electrode_placements)): for j in range(3): electrodes[i][j] = electrode_placements[i][j] kmc = kmc_dn.kmc_dn(N_acceptors, N_donors, 1, 1, 0, electrodes = electrodes) tests = [] for t in range(N_tests): volts = [] expected_currents = [] for i in range(len(electrode_placements)-1): volt = random.random()-0.5 volt = math.fabs(volt)/volt*volt*volt*320 kmc.electrodes[i][3]=volt volts.append(volt) kmc.electrodes[len(electrode_placements)-1][3]=0 kmc.update_V() volts.append(0) kmc.go_simulation(hops=100000, record=True) for i in range(len(kmc.current)): expected_currents.append((i, kmc.current[i])) if len(expected_currents) > 0: tests.append((volts, expected_currents)) print ("test %d: %s"%(t, str(tests[t]))) plt.clf() kmc_utils.visualize_traffic(kmc, 111, "Example network") plt.savefig(fileName) return tests
def getAdjustedDn(self, dn, adjustment): newDn = kmc_dn.kmc_dn(dn.N, dn.M, dn.xdim, dn.ydim, self.dn.zdim, electrodes=dn.electrodes, acceptors=dn.acceptors, donors=dn.donors, copy_from = dn) newDn.true_voltage = dn.true_voltage + adjustment[0] for i in range(self.N): newDn.electrodes[i+2][3] = newDn.electrodes[i+2][3] + adjustment[i+1] self.checkRange(newDn) return newDn
def getRandomDn(self): #Return random dn. Used in initialization of searches. newDn = kmc_dn.kmc_dn(self.dn.N, self.dn.M, self.dn.xdim, self.dn.ydim, self.dn.zdim, electrodes=self.dn.electrodes, copy_from=self.dn) return newDn
def getTests(prefix, amount, start=0): kmcs = [] for j in range(start, amount + start): kmc = kmc_dn.kmc_dn(10, 3, 1, 1, 0) script_dir = os.path.dirname( __file__) #<-- absolute dir the script is in rel_path = "tests/%s/test%d.kmc" % (prefix, j) abs_file_path = os.path.join(script_dir, rel_path) kmc.loadSelf(abs_file_path) kmcs.append(kmc) return kmcs
def openKmc(abs_file_path): ''' This returns a kmc_dn object that is in the given absolute file path. :param abs_file_path: path to the kmc_dn object :return: kmc_dn object ''' kmc = kmc_dn.kmc_dn(10, 3, 1, 1, 0) kmc.loadSelf(abs_file_path) return kmc
def yieldNeighbours(self): shifts = [self.x_resolution, -self.x_resolution] options = [(i+2, shifts[j]) for i in range(self.N) for j in range(len(shifts))] indexes = [x for x in range(len(options))] random.shuffle(indexes) for index in indexes: option = options[index] electrode_voltage = self.dn.electrodes[option[0]][3] + option[1] if math.fabs(electrode_voltage) < self.voltage_range: newDn = kmc_dn.kmc_dn(self.dn.N, self.dn.M, self.dn.xdim, self.dn.ydim, 0, electrodes = self.dn.electrodes, acceptors=self.dn.acceptors, donors=self.dn.donors, copy_from=self.dn) newDn.electrodes[option[0]][3] = electrode_voltage yield newDn, option[0], (0, 0)
def yieldNeighbours(self): ''' Yields neighbours of current state. Used by greedy and simulated annealing algorithms. This is the implementation for dopant placement search. ''' N = self.dn.N + self.dn.M shifts = [(self.x_resolution, 0), (-self.x_resolution, 0), (0, self.y_resolution), (0, -self.y_resolution), (self.x_resolution, self.y_resolution), (-self.x_resolution, self.y_resolution), (-self.x_resolution, -self.y_resolution), (self.x_resolution, -self.y_resolution)] options = [(i, shifts[j][0], shifts[j][1]) for i in range(N) for j in range(len(shifts))] indexes = [x for x in range(len(options))] random.shuffle(indexes) for index in indexes: option = options[index] if option[0] < self.dn.N: dopant = self.dn.acceptors[option[0]] pos = (dopant[0] + option[1], dopant[1] + option[2]) else: donor = self.dn.donors[option[0] - self.dn.N] pos = (donor[0] + option[1], donor[1] + option[2]) if self.doesPositionFit(pos[0], pos[1]): newDn = kmc_dn.kmc_dn(self.dn.N, self.dn.M, self.xdim, self.ydim, 0, electrodes=self.dn.electrodes, acceptors=self.dn.acceptors, donors=self.dn.donors, copy_from=self.dn) newDn.xCoords = self.dn.xCoords.copy() newDn.yCoords = self.dn.yCoords.copy() newDn.xCoords[option[0]] = pos[0] newDn.yCoords[option[0]] = pos[1] if option[0] < self.dn.N: newDn.acceptors[option[0]][0] = pos[0] newDn.acceptors[option[0]][1] = pos[1] else: newDn.donors[option[0] - self.dn.N][0] = pos[0] newDn.donors[option[0] - self.dn.N][1] = pos[1] newDn.initialize(dopant_placement=False, charge_placement=False) yield newDn, option[0], pos
def profile(N=30, M=3, hops=1100000, tests=100): xdim = 1 # Length along x dimension ydim = 1 # Length along y dimension zdim = 0 # Length along z dimension #res = 1 # Resolution of laplace grid #%% Initialize simulation object for i in range(0, tests): # Define electrodes electrodes = np.zeros((8, 4)) voltage_range = 600 electrodes[0] = [ 0, ydim / 4, 0, (random.random() - 0.5) * voltage_range ] electrodes[1] = [ 0, 3 * ydim / 4, 0, (random.random() - 0.5) * voltage_range ] electrodes[2] = [ xdim, ydim / 4, 0, (random.random() - 0.5) * voltage_range ] electrodes[3] = [ xdim, 3 * ydim / 4, 0, (random.random() - 0.5) * voltage_range ] electrodes[4] = [ xdim / 4, 0, 0, (random.random() - 0.5) * voltage_range ] electrodes[5] = [ 3 * xdim / 4, 0, 0, (random.random() - 0.5) * voltage_range ] electrodes[6] = [ xdim / 4, ydim, 0, (random.random() - 0.5) * voltage_range ] electrodes[7] = [3 * xdim / 4, ydim, 0, 0] kmc = kmc_dn.kmc_dn(N, M, xdim, ydim, zdim, electrodes=electrodes) print("i:%d\n" % (i)) kmc.go_simulation(hops=hops, goSpecificFunction="wrapperSimulateRecord")
import kmc_dopant_networks as kmc_dn import kmc_dopant_networks_utils as kmc_dn_utils import numpy as np import matplotlib.pyplot as plt #%% Parameters N = 30 M = 3 xdim = 1 ydim = 1 zdim = 0 #%% Initialization kmc = kmc_dn.kmc_dn(N, M, xdim, ydim, zdim) #%% Plot histogram of site energies (i.e. impurity band) plt.hist(kmc.E_constant, bins = 50) plt.show()
for k in range(len(layout)): #%% System setup xdim = 1 ydim = 1 acceptors = acceptor_layouts[layout[k]] donors = donor_layouts[layout[k]] electrodes = np.zeros((2, 4)) electrodes[0] = [0, ydim / 2, 0, 10] electrodes[1] = [xdim, ydim / 2, 0, 0] #%% Initialize system kmc = kmc_dn.kmc_dn(1, 0, xdim, ydim, 0, electrodes=electrodes, callback='none') kmc.load_acceptors(acceptors) kmc.load_donors(donors) #%% Simulation loop for i in range(len(I_0)): for j in range(len(ab_R)): # Set constants kmc.kT = kT kmc.I_0 = I_0[i] kmc.ab = ab_R[j] * kmc.R kmc.initialize(dopant_placement=False)
donors = np.zeros((9, 3)) for i in range(3): for j in range(3): donors[3 * i + j] = [ i * xdim / 5 + 1.5 * xdim / 5, j * ydim / 5 + 1.5 * ydim / 5, 0 ] electrodes = np.zeros((2, 4)) electrodes[0] = [0, ydim / 2, 0, 10] electrodes[1] = [xdim, ydim / 2, 0, 0] kT = 1 I_0 = 1 * kT ab_R = 0.1 VkT = 1000 #%% Initialize system kmc = kmc_dn.kmc_dn(1, 5, xdim, ydim, 0, electrodes=electrodes) kmc.load_acceptors(acceptors) kmc.load_donors(donors) kmc = kmc_dn.kmc_dn(16, 9, xdim, ydim, 0, electrodes=electrodes) tic = time.time() bias = np.linspace(-VkT * kT / kmc.e, VkT * kT / kmc.e, 100) #%% Simulation loop # Set constants kmc.kT = kT kmc.I_0 = I_0 kmc.ab = ab_R * kmc.R kmc.initialize(placement=False) # Simulate current_sim = kmc_dn_utils.IV(kmc, 0, bias, prehops=10000, hops=10000) current = current_sim[:, 0]
electrodes = np.zeros((3, 4)) electrodes[0] = [0, ydim / 4, 0, 0] electrodes[1] = [0, 3 * ydim / 4, 0, 0] electrodes[2] = [xdim, ydim / 4, 0, 0] static_electrodes = np.zeros((5, 4)) static_electrodes[0] = [xdim, 3 * ydim / 4, 0, 0] static_electrodes[1] = [xdim / 4, 0, 0, 0] static_electrodes[2] = [3 * xdim / 4, 0, 0, 0] static_electrodes[3] = [xdim / 4, ydim, 0, 0] static_electrodes[4] = [3 * xdim / 4, ydim, 0, 0] kmc = kmc_dn.kmc_dn(1, 0, xdim, ydim, 0, electrodes=electrodes, static_electrodes=static_electrodes) kmc.load_acceptors(acceptor_layouts[layout]) kmc.load_donors(donor_layouts[layout]) # Parameters kT = cf.kT I_0 = cf.I_0 ab_R = cf.ab_R prehops = cf.prehops hops = cf.hops kmc.kT = kT kmc.I_0 = I_0
# Define 8 electrodes electrodes = np.zeros((8, 4)) electrodes[0] = [0, ydim / 4, 0, 0] electrodes[1] = [0, 3 * ydim / 4, 0, 0] electrodes[2] = [xdim, ydim / 4, 0, 10] electrodes[3] = [xdim, 3 * ydim / 4, 0, 0] electrodes[4] = [xdim / 4, 0, 0, 0] electrodes[5] = [3 * xdim / 4, 0, 0, 0] electrodes[6] = [xdim / 4, ydim, 0, 0] electrodes[7] = [3 * xdim / 4, ydim, 0, 0] kmc = kmc_dn.kmc_dn(N, M, xdim, ydim, 0, electrodes=electrodes, callback_traffic=True) # Parameters gene = [0.3730247, 0.94274381, 0.49073662, 0.89030952, 0.30259412] output_electrode = 2 kT = 1 I_0 = 50 * kT V_high = 500 * kT ab_R = 0.25 prehops = 10000 hops = 100000 kmc.kT = kT
import kmc_dopant_networks_utils as kmc_dn_utils #%% Parameters N = 10 # Number of acceptors M = 0 # Number of donors xdim = 1 # Length along x dimension ydim = 1 # Length along y dimension zdim = 0 # Length along z dimension mu = 1 # Chemical potential n = 5 # Amount of carriers hops = int(1E4) # Hops per validation run points = 1000 # Amount of points for plotting convergence avg = 10 # Amount of validation runs #%% Initialize simulation object kmc = kmc_dn.kmc_dn(N, M, xdim, ydim, zdim, mu=mu) #%% Run validation # Prerun validation function once for compilation (E_microstates, p_theory, hops_array, p_sim_interval) = kmc_dn_utils.validate_boltzmann(kmc, hops=10, n=n, points=1, mu=mu, standalone=False) p_sim = np.zeros((avg, p_theory.shape[0], points)) # Actual validation loop for i in range(avg): tic = time.time()
# Experiment to visualize the average occupancy of each # acceptor. import kmc_dopant_networks as kmc_dn import kmc_dopant_networks_utils as kmc_dn_utils import numpy as np import matplotlib.pyplot as plt #%% Parameters N = 50 M = 5 xdim = 1 ydim = 1 zdim = 0 #%% Initialize simulation object kmc = kmc_dn.kmc_dn(N, M, xdim, ydim, zdim, callback='callback_dwelltime') kmc.I_0 = 100 * kmc.kT #%% Simulate hops = 100000 kmc.simulate_discrete(hops=hops) #%% Visualize fig = kmc_dn_utils.visualize_dwelltime(kmc) plt.show()
# Define electrodes electrodes = np.zeros((2, 4)) # Electrodes with their voltage electrodes[0] = [0, ydim / 2, 0, 10] # Left electrode electrodes[1] = [xdim, ydim / 2, 0, -10] # Right electrode # Initialize other parameters times = np.zeros(len(N)) #%% Run simulation loops for i in range(len(N)): # Initialize new object kmc = kmc_dn.kmc_dn(N[i], M, xdim, ydim, zdim, electrodes=electrodes, res=res) # Simulate hops and time tic = time.time() kmc.simulate(hops=hops) times[i] = time.time() - tic #%% Visualize() plt.plot(N, times, '.') plt.title('$10^4$ hops') plt.ylabel('Time (s)') plt.xlabel('Amount of acceptors')
#%% Parameters N = 1 # Number of acceptors M = 0 # Number of donors xdim = 1 # Length along x dimension ydim = 0 # Length along y dimension zdim = 0 # Length along z dimension mu = 0 # Chemical potential hops = int(1E5) # Hops per validation run avg = 10 electrodes = np.zeros((2, 4)) electrodes[0] = [0, 0, 0, 10] electrodes[1] = [xdim, 0, 0, 0] #%% Initialize simulation object kmc = kmc_dn.kmc_dn(N, M, xdim, ydim, zdim, mu=mu, electrodes=electrodes) # Set U_0 = kmc.kT U_0 = 0.1 * kmc.kT # Place single atom in middle of domain acceptors = np.array([[xdim / 2, 0, 0]]) kmc.load_acceptors(acceptors) # Set ab >> R, such that distance does not matter kmc.ab = 100000 * kmc.R kmc.initialize(V=False, dopant_placement=False) #%% Current simulation with backgate # Voltages
# Define 8 electrodes electrodes = np.zeros((8, 4)) electrodes[0] = [0, ydim / 4, 0, 10] electrodes[1] = [0, 3 * ydim / 4, 0, 0] electrodes[2] = [xdim, ydim / 4, 0, 10] electrodes[3] = [xdim, 3 * ydim / 4, 0, 0] electrodes[4] = [xdim / 4, 0, 0, 10] electrodes[5] = [3 * xdim / 4, 0, 0, 0] electrodes[6] = [xdim / 4, ydim, 0, 10] electrodes[7] = [3 * xdim / 4, ydim, 0, 0] if (cf.use_random_layout): kmc = kmc_dn.kmc_dn(cf.layoutsize, cf.layoutsize // 10, xdim, ydim, 0, electrodes=electrodes) else: kmc = kmc_dn.kmc_dn(1, 0, xdim, ydim, 0, electrodes=electrodes) kmc.load_acceptors(acceptor_layouts[layout]) kmc.load_donors(donor_layouts[layout]) # Parameters kT = cf.kT I_0 = cf.I_0 ab_R = cf.ab_R prehops = cf.prehops hops = cf.hops kmc.kT = kT
# Load layouts acceptor_layouts = np.load('acceptor_layouts.npy') donor_layouts = np.load('donor_layouts.npy') # Define 8 electrodes electrodes = np.zeros((8, 4)) electrodes[0] = [0, ydim / 4, 0, 0] electrodes[1] = [0, 3 * ydim / 4, 0, 0] electrodes[2] = [xdim, ydim / 4, 0, 10] electrodes[3] = [xdim, 3 * ydim / 4, 0, 0] electrodes[4] = [xdim / 4, 0, 0, 0] electrodes[5] = [3 * xdim / 4, 0, 0, 0] electrodes[6] = [xdim / 4, ydim, 0, 0] electrodes[7] = [3 * xdim / 4, ydim, 0, 0] kmc = kmc_dn.kmc_dn(1, 0, xdim, ydim, 0, electrodes=electrodes) kmc.load_acceptors(acceptor_layouts[layout]) kmc.load_donors(donor_layouts[layout]) # Parameters gene = [0.5884281, 0.49808138, 0.55724021, 0.68831492, 0.56113931] avg = 1 output_electrode = 2 kT = 1 I_0 = 50 * kT V_high = 500 * kT ab_R = 0.25 prehops = 1000 hops = 10000 res = 10
def getRandomDn(N_acceptors, N_donors): electrodes = get8Electrodes(1, 1) dn = kmc_dn.kmc_dn(N_acceptors, N_donors, 1, 1, 0, electrodes = electrodes) return dn