def main(): # command-line options parser = optparse.OptionParser() parser.add_option('-f', '--file', dest="tran_info_file", help="name of the *_tran_info.dat file") parser.add_option('-m', '--matrix', dest="hamiltonian_matrix", help="name of the Hamiltonian matrix (*_htC.dat)") options, remainder = parser.parse_args() # if the program is called without options it prints the help menu if len(sys.argv[1:])==0: parser.print_help() sys.exit(0) # Printing some information with date and time print header print " program compactify_conductor.py" print " program started on %s at %s" %(time.strftime("%A, %d %B %Y",time.localtime()), time.strftime("%H:%M:%S",time.localtime())) print "" # loading the data in the *_tran_info.dat file (wf_total, wf_per_pl, cells_per_pl, cond_dir, second_dir, wannier_functions, atom_number, atomic_coordinates) = read_tran_info(options.tran_info_file) # loading the Hamiltonian matrix hamiltonian_matrix = read_htC(options.hamiltonian_matrix) # calling the program's main routine t_start = time.time() main_routine(wf_total, wf_per_pl, cells_per_pl, cond_dir, second_dir, wannier_functions, atom_number, atomic_coordinates, hamiltonian_matrix) t_stop = time.time() # printing some timing informations print "" elapsed_time = t_stop - t_start if elapsed_time < 1.0: print " Execution time : %6.2f ms" %(elapsed_time*1000) else: print " Execution time : %6.2f s " %(elapsed_time) print "" return
def build_hamiltonian(defect_list,principal_layer,path,system_type): # finding out the list of distinct defects distinct_defects = [] for defect in defect_list: if defect not in distinct_defects: distinct_defects.append(defect) # now we will load the matrices of the needed distinct defects # and gather them in a dictionnary. Also we will extract the matrix # sizes hamiltonian_matrices = {} hamiltonian_matrix_sizes = {} for defect in distinct_defects: filename = "" for string in os.listdir(path+"/"+defect): if '_htC.dat' in string: filename = string conductor_matrix = read_htC(path+"/"+defect+"/"+filename) hamiltonian_matrices[defect] = conductor_matrix hamiltonian_matrix_sizes[defect] = conductor_matrix.shape[0] # loading the H00 and H01 matrices of the lead filename = "" for string in os.listdir(path+"/"+principal_layer): if '_htC.dat' in string: filename = string (h00_matrix,h01_matrix) = read_lead(path+"/"+principal_layer+"/"+filename) h00_size = h00_matrix.shape[0] h01_size = h01_matrix.shape[0] hamiltonian_matrices[principal_layer] = (h00_matrix,h01_matrix) hamiltonian_matrix_sizes[principal_layer] = (h00_size,h01_size) # determining the nbandc parameter H_sizes = [] for defect in hamiltonian_matrix_sizes.keys(): if defect!=principal_layer: H_sizes.append(hamiltonian_matrix_sizes[defect]+1) H_sizes.append(h00_size+h01_size) nbandc = max(H_sizes) # asking the user for the number of unit cells per principal layer try: num_cell_in_pl = int( raw_input('\n how many unit cells in one principal layer : ') ) except: print "" print " Error in system_builder :" print " the program could not convert the number of unit" print " cells into an integer" print " Exiting the program..." print "" sys.exit(1) num_wf_in_cell = h00_size / num_cell_in_pl # a small check if num_cell_in_pl*num_wf_in_cell!=h00_size: print "" print " Error in system_builder :" print " The number of unit cells in a principal layer " print " multiplied by the number of Wannier Functions " print " per cell does not add up to the number of WFs " print " in a principal layer. You probably entered a " print " wrong number of unit cells. " print " Exiting the program... " print "" sys.exit(1) # asking the user about the number of buffer unit cells to # "squeeze in" between the defects in the system try: buffer_num = int( raw_input('\n how many buffer unit cells between defects : ') ) except: print "" print " Error in system_builder :" print " the program could not convert the number of buffer" print " unit cells into an integer" print " Exiting the program..." print "" sys.exit(1) # size of the final Hamiltonian matrix total_size = 2*h00_size for defect in defect_list: if defect==principal_layer: total_size += h00_size else: total_size += hamiltonian_matrix_sizes[defect] total_size += len(defect_list)*num_wf_in_cell*buffer_num ### it is now time to build the final matrix ### from math import ceil # starting with a zero matrix with the right size dis_matrix = numpy.zeros((total_size,total_size),dtype='float') # updating the defect list by adding one principal layer at # the beginning of the structure and one at the end. This ensures # a clean connection with the leads. defect_list = [principal_layer]+defect_list+[principal_layer] # Main loop over the defect index offset = 0 # this parameter is used in the loop as a reference point for i in xrange(len(defect_list)): # Starting by inserting the defect matrices with their "left" # padding. Special attention is to be taken for the very first # and the very last defects that correspond to the beginning and # terminating lead principal layers if i==0 or i==len(defect_list)-1: dis_matrix[offset:offset+h00_size,offset:offset+h00_size] = hamiltonian_matrices[principal_layer][0] offset += h00_size else: # inserting the padding matrix first if defect_list[i]==principal_layer: def_size = h00_size def_matrix = hamiltonian_matrices[principal_layer][0] num_cell = int( buffer_num + num_cell_in_pl ) else: def_size = hamiltonian_matrix_sizes[defect_list[i]] def_matrix = hamiltonian_matrices[defect_list[i]] num_cell = int( buffer_num + float(def_size)/(2.0*num_wf_in_cell) ) if buffer_num >= 1: num_pl = int( ceil(float(num_cell) / float(num_cell_in_pl)) ) dummy_matrix = build_pristine( num_pl, hamiltonian_matrices[principal_layer][0], hamiltonian_matrices[principal_layer][1] ) dis_matrix[offset:offset+num_cell*num_wf_in_cell,offset:offset+num_cell*num_wf_in_cell] = \ dummy_matrix[:num_cell*num_wf_in_cell,:num_cell*num_wf_in_cell] # then inserting the defect matrix itself dis_matrix[offset+buffer_num*num_wf_in_cell:offset+buffer_num*num_wf_in_cell+def_size, offset+buffer_num*num_wf_in_cell:offset+buffer_num*num_wf_in_cell+def_size] = def_matrix offset += buffer_num*num_wf_in_cell+def_size # Now we have to connect the defects together (off-diagonal elements) # We exclude the last defect since this one is not connected with any # other defect "to the right" if i <= len(defect_list)-2: if defect_list[i]==principal_layer: def_size_a = h00_size def_matrix_a = hamiltonian_matrices[principal_layer][0] else: def_size_a = hamiltonian_matrix_sizes[defect_list[i]] def_matrix_a = hamiltonian_matrices[defect_list[i]] if defect_list[i+1]==principal_layer: def_size_b = h00_size def_matrix_b = hamiltonian_matrices[principal_layer][0] else: def_size_b = hamiltonian_matrix_sizes[defect_list[i+1]] def_matrix_b = hamiltonian_matrices[defect_list[i+1]] # if both the current defect and the next one are principal layers, we # insert simply H01 as a connection matrix if defect_list[i]==principal_layer and defect_list[i+1]==principal_layer: dis_matrix[offset-h00_size:offset,offset:offset+h00_size] = hamiltonian_matrices[principal_layer][1] dis_matrix[offset:offset+h00_size,offset-h00_size:offset] = numpy.transpose(hamiltonian_matrices[principal_layer][1]) # case where the current defect is a principal layer elif defect_list[i]==principal_layer: num_cell_a = num_cell_in_pl num_cell_b = int( buffer_num + float(def_size_b)/(2.0*num_wf_in_cell) ) if num_cell_b==0: num_cell_b = int( buffer_num + ceil(float(def_size_b)/(2.0*num_wf_in_cell)) ) num_cell_c = min(num_cell_a,num_cell_b) if num_cell_c >= num_cell_in_pl: dis_matrix[offset-h00_size:offset,offset:offset+h00_size] = hamiltonian_matrices[principal_layer][1] dis_matrix[offset:offset+h00_size,offset-h00_size:offset] = numpy.transpose(hamiltonian_matrices[principal_layer][1]) else: dis_matrix[offset-num_cell_c*num_wf_in_cell:offset,offset:offset+num_cell_c*num_wf_in_cell] = \ hamiltonian_matrices[principal_layer][1][h00_size-num_cell_c*num_wf_in_cell:,:num_cell_c*num_wf_in_cell] dis_matrix[offset:offset+num_cell_c*num_wf_in_cell,offset-num_cell_c*num_wf_in_cell:offset] = \ numpy.transpose(hamiltonian_matrices[principal_layer][1][h00_size-num_cell_c*num_wf_in_cell:,:num_cell_c*num_wf_in_cell]) # case where the next defect is a principal layer elif defect_list[i+1]==principal_layer: num_cell_b = num_cell_in_pl + buffer_num num_cell_a = int( float(def_size_a)/(2.0*num_wf_in_cell) ) if num_cell_a==0: num_cell_a = int( ceil(float(def_size_a)/(2.0*num_wf_in_cell)) ) num_cell_c = min(num_cell_a,num_cell_b) if num_cell_c >= num_cell_in_pl: dis_matrix[offset-h00_size:offset,offset:offset+h00_size] = hamiltonian_matrices[principal_layer][1] dis_matrix[offset:offset+h00_size,offset-h00_size:offset] = numpy.transpose(hamiltonian_matrices[principal_layer][1]) else: dis_matrix[offset-num_cell_c*num_wf_in_cell:offset,offset:offset+num_cell_c*num_wf_in_cell] = \ hamiltonian_matrices[principal_layer][1][h00_size-num_cell_c*num_wf_in_cell:,:num_cell_c*num_wf_in_cell] dis_matrix[offset:offset+num_cell_c*num_wf_in_cell,offset-num_cell_c*num_wf_in_cell:offset] = \ numpy.transpose(hamiltonian_matrices[principal_layer][1][h00_size-num_cell_c*num_wf_in_cell:,:num_cell_c*num_wf_in_cell]) # case where both the current and the next defect are not principal layers else: num_cell_a = int( float(def_size_a)/(2.0*num_wf_in_cell) ) if num_cell_a==0: num_cell_a = int( ceil(float(def_size_a)/(2.0*num_wf_in_cell)) ) num_cell_b = int( buffer_num + float(def_size_b)/(2.0*num_wf_in_cell) ) if num_cell_b==0: num_cell_b = int( buffer_num + ceil(float(def_size_b)/(2.0*num_wf_in_cell)) ) num_cell_c = min(num_cell_a,num_cell_b) if num_cell_c >= num_cell_in_pl: dis_matrix[offset-h00_size:offset,offset:offset+h00_size] = hamiltonian_matrices[principal_layer][1] dis_matrix[offset:offset+h00_size,offset-h00_size:offset] = numpy.transpose(hamiltonian_matrices[principal_layer][1]) else: dis_matrix[offset-num_cell_c*num_wf_in_cell:offset,offset:offset+num_cell_c*num_wf_in_cell] = \ hamiltonian_matrices[principal_layer][1][h00_size-num_cell_c*num_wf_in_cell:,:num_cell_c*num_wf_in_cell] dis_matrix[offset:offset+num_cell_c*num_wf_in_cell,offset-num_cell_c*num_wf_in_cell:offset] = \ numpy.transpose(hamiltonian_matrices[principal_layer][1][h00_size-num_cell_c*num_wf_in_cell:,:num_cell_c*num_wf_in_cell]) # writing the system's Hamiltonian matrix to file write_htC("%s_system_htC.dat" %("./"+system_type),dis_matrix) # creating the final directory os.system("rm -rf %s_system/" %(system_type)) os.mkdir("%s_system" %(system_type)) os.system("mv %s_system_htC.dat %s_system/." %(system_type,system_type)) # adding the H_L, H_LC and H_CR matrices hl_file = open("./%s_system/%s_system_htL.dat" %(system_type,system_type),'w') hl_file.write(' # Left lead matrix with H00 and H01 \n') hl_file.write(' %6i \n' %(h00_size,)) for j in xrange(h00_size): for i in xrange(h00_size): hl_file.write(' %10.6f' %(hamiltonian_matrices[principal_layer][0][i,j],)) hl_file.write(' \n') hl_file.write(' %6i \n' %(h01_size,)) for j in xrange(h01_size): for i in xrange(h01_size): hl_file.write(' %10.6f' %(hamiltonian_matrices[principal_layer][1][i,j],)) hl_file.write(' \n') hl_file.close() hlc_file = open("./%s_system/%s_system_htLC.dat" %(system_type,system_type),'w') hlc_file.write(' # Left lead - Conductor matrix H_LC \n') hlc_file.write(' %6i %6i \n' %(h01_size,h01_size)) for j in xrange(h01_size): for i in xrange(h01_size): hlc_file.write(' %10.6f' %(hamiltonian_matrices[principal_layer][1][i,j],)) hlc_file.write(' \n') hlc_file.close() hcr_file = open("./%s_system/%s_system_htCR.dat" %(system_type,system_type),'w') hcr_file.write(' # Conductor - Right lead matrix H_CR \n') hcr_file.write(' %6i %6i \n' %(h01_size,h01_size)) for j in xrange(h01_size): for i in xrange(h01_size): hcr_file.write(' %10.6f' %(hamiltonian_matrices[principal_layer][1][i,j],)) hcr_file.write(' \n') hcr_file.close() # At last the Wannier90 master input file w90_input = open("./%s_system/%s_system.win" %(system_type,system_type),'w') w90_input.write("# %s system with %6i defect(s) \n" %(system_type,len(defect_list)-2,)) w90_input.write("# written by 'system_builder.py' on %s at %s \n" %(time.strftime("%A, %d %B %Y",time.localtime()), time.strftime("%H:%M:%S",time.localtime()))) w90_input.write("\n") w90_input.write("transport = .true. \n") w90_input.write("transport_mode = lcr \n") w90_input.write("tran_read_ht = .true. \n") w90_input.write("tran_use_same_lead = .true. \n") w90_input.write("tran_win_min = -3.0 \n") w90_input.write("tran_win_max = 2.0 \n") w90_input.write("tran_energy_step = 0.01 \n") w90_input.write("tran_num_ll = %6i \n" %(h00_size,)) w90_input.write("tran_num_rr = %6i \n" %(h00_size,)) w90_input.write("tran_num_cc = %6i \n" %(total_size,)) w90_input.write("tran_num_lc = %6i \n" %(h00_size,)) w90_input.write("tran_num_cr = %6i \n" %(h00_size,)) w90_input.write("tran_num_bandc = %6i \n" %(nbandc,)) w90_input.close() return (num_cell_in_pl,buffer_num)
def main(): # command-line options parser = optparse.OptionParser() parser.add_option('-f', '--file', dest="tran_info_file", help="name of the *_tran_info.dat file") parser.add_option('-m', '--matrix', dest="hamiltonian_matrix", help="name of the Hamiltonian matrix (*_htC.dat)") parser.add_option('-p', '--positions', dest="atomic_positions", action="store_true", help="whether of not the atomic positions are\n"+ "also printed") parser.add_option('-a', '--all', dest="all_permutations", action="store_true", help="if activated, the program prints all the\n"+ "hamiltonian matrices resulting from all\n"+ "possible cutting schemes") options, remainder = parser.parse_args() # if the program is called without options it prints the help menu if len(sys.argv[1:])==0: parser.print_help() sys.exit(0) # Printing some information with date and time print header print " program cut_conductor.py" print " program started on %s at %s" %(time.strftime("%A, %d %B %Y",time.localtime()), time.strftime("%H:%M:%S",time.localtime())) print "" # loading the data in the *_tran_info.dat file (wf_total, wf_per_pl, cells_per_pl, cond_dir, second_dir, wannier_functions, atom_number, atomic_coordinates_unsorted) = read_tran_info(options.tran_info_file) # loading the Hamiltonian matrix hamiltonian_matrix = read_htC(options.hamiltonian_matrix) # sort the atomic coordinates in the direction of conduction atomic_coordinates = sort_positions(atomic_coordinates_unsorted,cond_dir) # calling the program's main routine t_start = time.time() main_routine(wf_total, wf_per_pl, cells_per_pl, cond_dir, wannier_functions, atom_number, atomic_coordinates, hamiltonian_matrix, options.atomic_positions, options.all_permutations) t_stop = time.time() # printing some timing informations print "" elapsed_time = t_stop - t_start if elapsed_time < 1.0: print " Execution time : %6.2f ms" %(elapsed_time*1000) else: print " Execution time : %6.2f s " %(elapsed_time) print "" return
def main(): # command-line options parser = optparse.OptionParser() parser.add_option('-f', '--file', dest="tran_info_file", help="name of the *_tran_info.dat file") parser.add_option('-m', '--matrix', dest="hamiltonian_matrix", help="name of the Hamiltonian matrix (*_htC.dat)") parser.add_option('-a', '--angle', dest="angle", type="float", default=0.0, help="angle of rotation in radian") parser.add_option('-d', '--delta', dest="delta", type="float", default=0.15, help="distance threshold for WF grouping.\n"+ "use the same value as the one in the\n"+ "Wannier90 master input file") options, remainder = parser.parse_args() # if the program is called without options it prints the help menu if len(sys.argv[1:])==0: parser.print_help() sys.exit(0) # Printing some information with date and time print header print " program rotate_conductor.py" print " program started on %s at %s" %(time.strftime("%A, %d %B %Y",time.localtime()), time.strftime("%H:%M:%S",time.localtime())) print "" # loading the data in the *_tran_info.dat file (wf_total, wf_per_pl, cells_per_pl, cond_dir, second_dir, wannier_functions, atom_number, atomic_coordinates) = read_tran_info(options.tran_info_file) # loading the Hamiltonian matrix hamiltonian_matrix = read_htC(options.hamiltonian_matrix) # calling the program's main routine t_start = time.time() main_routine(wf_total, wf_per_pl, cells_per_pl, cond_dir, second_dir, wannier_functions, atom_number, atomic_coordinates, hamiltonian_matrix, options.angle, options.delta) t_stop = time.time() # printing some timing informations print "" elapsed_time = t_stop - t_start if elapsed_time < 1.0: print " Execution time : %6.2f ms" %(elapsed_time*1000) else: print " Execution time : %6.2f s " %(elapsed_time) print "" return