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_routine(wf_total, wf_per_pl, cells_per_pl, cond_dir, wannier_functions, atom_number, atomic_coordinates, hamiltonian_matrix, print_atomic_coordinates, print_all_permutations): from math import floor import os # asking the user how many unit cells on the left are to be removed try: left_cells = int(raw_input("\n Number of left cells to remove in the conductor : ")) right_cells = int(raw_input("\n Number of right cells to remove in the conductor : ")) print "" except: print "" print " Error in cut_conductor :" print " Could not transform the number of cells into" print " an integer" print " Exiting the program..." print "" sys.exit(1) # checking that some of the information in the *_tran_info.dat file # is actually compatible with some of the information about the matrix if wf_total-2*wf_per_pl!=hamiltonian_matrix.shape[0]: print "" print " Error in cut_conductor :" print " the number of Wannier Functions in the conductor" print " region is incompatible." print " In file *_tran_info.dat, this number is : %6i" %(wf_total-2*wf_per_pl) print " In the matrix file, this number is : %6i" %(hamiltonian_matrix.shape[0]) print " Exiting the program..." print "" sys.exit(1) # checking whether the number of cells are not too big num_wann_per_cell = int(wf_per_pl/cells_per_pl) max_cell_number = int(floor(hamiltonian_matrix.shape[0]/(2.0*num_wann_per_cell))) user_continue = "dummy" if left_cells > max_cell_number or right_cells > max_cell_number: print "" print " Warning in cut_conductor :" print " The number of unit cells to remove seems too big." print " The program expects at most %i to be removed on " %(max_cell_number) print " one side (for systems with the defect 'in the middle')" print " Do you still want to continue ?" while user_continue not in ['yes','no']: user_continue = str(raw_input("\n -> type 'yes' or 'no' : ")) if user_continue=='no': print " Exiting the program..." print "" sys.exit(1) # asking the user the number of atoms per unit cell if print_atomic_coordinates: try: atoms_per_cell = int(raw_input(" How many atoms in the lead unit cell : ")) print "" except: print "" print " Error in cut_conductor :" print " Could not transform the number of atoms per cell" print " into an integer" print " Exiting the program..." print "" sys.exit(1) # constructing the matrix and the atomic position files if not print_all_permutations: # creating a directory for storing the reduced matrix and # possibly the atomic coodinates os.mkdir("./%i_left_%i_right" %(left_cells,right_cells)) # first we construct the reduced matrix final_matrix = hamiltonian_matrix[left_cells*num_wann_per_cell:hamiltonian_matrix.shape[0]-right_cells*num_wann_per_cell, left_cells*num_wann_per_cell:hamiltonian_matrix.shape[0]-right_cells*num_wann_per_cell] write_htC("./%i_left_%i_right/%i_left_%i_right_htC.dat" %(left_cells, right_cells, left_cells, right_cells),final_matrix) # then optionnaly the atomic positions if print_atomic_coordinates: # computing the size of the reduced structure if cond_dir=='x': conductor_size = atomic_coordinates[-(cells_per_pl+right_cells)*atoms_per_cell].x - \ atomic_coordinates[(cells_per_pl+left_cells)*atoms_per_cell].x elif cond_dir=='y': conductor_size = atomic_coordinates[-(cells_per_pl+right_cells)*atoms_per_cell].y - \ atomic_coordinates[(cells_per_pl+left_cells)*atoms_per_cell].y else: conductor_size = atomic_coordinates[-(cells_per_pl+right_cells)*atoms_per_cell].z - \ atomic_coordinates[(cells_per_pl+left_cells)*atoms_per_cell].z # selecting the atoms in the reduced structure final_positions = atomic_coordinates[(cells_per_pl+left_cells)*atoms_per_cell:len(atomic_coordinates)-(cells_per_pl+right_cells)*atoms_per_cell] # translating the coordinates in the direction of conduction such # that the left-most atom is at 0 final_positions = translate_to_zero(final_positions,cond_dir) # writing the positions to an xyz file write_xyz("./%i_left_%i_right/%i_left_%i_right.xyz" %(left_cells, right_cells, left_cells, right_cells),final_positions,conductor_size) else: # here we do the same thing as above but for all possible cutting schemes for i in xrange(left_cells+1): for j in xrange(right_cells+1): # creating a directory for storing the reduced matrix and # possibly the atomic coodinates os.mkdir("./%i_left_%i_right" %(i,j)) # first we construct the reduced matrix final_matrix = hamiltonian_matrix[i*num_wann_per_cell:hamiltonian_matrix.shape[0]-j*num_wann_per_cell, i*num_wann_per_cell:hamiltonian_matrix.shape[0]-j*num_wann_per_cell] write_htC("./%i_left_%i_right/%i_left_%i_right_htC.dat" %(i,j,i,j),final_matrix) # then optionnaly the atomic positions if print_atomic_coordinates: # computing the size of the reduced structure if cond_dir=='x': conductor_size = atomic_coordinates[-(cells_per_pl+j)*atoms_per_cell].x - \ atomic_coordinates[(cells_per_pl+i)*atoms_per_cell].x elif cond_dir=='y': conductor_size = atomic_coordinates[-(cells_per_pl+j)*atoms_per_cell].y - \ atomic_coordinates[(cells_per_pl+i)*atoms_per_cell].y else: conductor_size = atomic_coordinates[-(cells_per_pl+j)*atoms_per_cell].z - \ atomic_coordinates[(cells_per_pl+i)*atoms_per_cell].z # selecting the atoms in the reduced structure final_positions = atomic_coordinates[(cells_per_pl+i)*atoms_per_cell:len(atomic_coordinates)-(cells_per_pl+j)*atoms_per_cell] # translating the coordinates in the direction of conduction such # that the left-most atom is at 0 final_positions = translate_to_zero(final_positions,cond_dir) # writing the positions to an xyz file write_xyz("./%i_left_%i_right/%i_left_%i_right.xyz" %(i,j,i,j),final_positions,conductor_size) # At last a simple Warning to the user for checking the atomic position files if print_atomic_coordinates: print "" print " WARNING :" print " In constructing the atomic position files, this program uses a" print " very simple sorting algorithm. Please visualize the structures" print " yourself in order to double check them." return
def main_routine(wf_total, wf_per_pl, cells_per_pl, cond_dir, second_dir, wannier_functions, atom_number, atomic_coordinates, hamiltonian_matrix): # making sure the user properly tuned the constraints function print "" print " Did you modify the 'constraints.py' module" print " to fit your system ?" constraints_modified = 'dummy' while constraints_modified not in ['yes','no']: constraints_modified = str(raw_input("\n -> type 'yes' or 'no' : ")) if constraints_modified=='no': print "" sys.exit(1) print "" # checking that some of the information in the *_tran_info.dat file # is actually compatible with some of the information about the matrix if wf_total-2*wf_per_pl!=hamiltonian_matrix.shape[0]: print "" print " Error in compactify_conductor :" print " the number of Wannier Functions in the conductor" print " region is incompatible." print " In file *_tran_info.dat, this number is : %6i" %(wf_total-2*wf_per_pl) print " In the matrix file, this number is : %6i" %(hamiltonian_matrix.shape[0]) print " Exiting the program..." print "" sys.exit(1) # creating two lists of indices. One for the backbone WF and one for # the defect WF. Those lists contain the indices of the WF backbone_list = [] defect_list = [] for i in xrange(wf_per_pl,wf_total-wf_per_pl): # this loop restricts to the WF in the # conductor region if constraints(wannier_functions[i].x,wannier_functions[i].y,wannier_functions[i].z): backbone_list.append(i-wf_per_pl) else: defect_list.append(i-wf_per_pl) # now we will re-order the Wannier Function basis in such a way that # the defect Wannier Functions will be "in the middle" middle_point = len(backbone_list)/2 final_list = backbone_list[:middle_point] + defect_list + backbone_list[middle_point:] # all we have to do now is re-construct the hamiltonian matrix with # this newly ordered basis reordered_hamiltonian_matrix = numpy.zeros((hamiltonian_matrix.shape[0], hamiltonian_matrix.shape[1]),dtype='float') for row in xrange(len(final_list)): for col in xrange(len(final_list)): reordered_hamiltonian_matrix[row,col] = hamiltonian_matrix[final_list[row],final_list[col]] # writing the new hamiltonian to a Wannier90 compatible file write_htC("compactified_htC.dat",reordered_hamiltonian_matrix) # generating the new *_tran_info.dat file PL1 = wannier_functions[:wf_per_pl] conductor = wannier_functions[wf_per_pl:-wf_per_pl] PL4 = wannier_functions[-wf_per_pl:] final_conductor = [] for index in final_list: final_conductor.append(conductor[index]) final_wf_list = PL1 + final_conductor + PL4 write_tran_info(wf_total, wf_per_pl, cells_per_pl, cond_dir, second_dir, final_wf_list, atom_number, atomic_coordinates) return
def main_routine(wf_total, wf_per_pl, cells_per_pl, cond_dir, second_dir, wannier_functions, atom_number, atomic_coordinates, matrix, angle, delta): # first we separate the left-most principal layer, the conductor region # and the right-most principal layer PL1 = wannier_functions[:wf_per_pl] conductor = wannier_functions[wf_per_pl:-wf_per_pl] PL4 = wannier_functions[-wf_per_pl:] # now we compute the unit vector for the axis of rotation point_A = barycenter(PL1) point_B = barycenter(PL4) unit_vector = (1.0/numpy.linalg.norm(point_B-point_A))*(point_B-point_A) if cond_dir=='x': reference = numpy.array([1.0,0.0,0.0]) elif cond_dir=='y': reference = numpy.array([0.0,1.0,0.0]) else: reference = numpy.array([0.0,0.0,1.0]) if numpy.dot(unit_vector,reference)<=0.95: print "" print " Warning in rotate_conductor :" print " The computed unit vector for the axis of" print " rotation seems to be off from the reference" print " unit vector : %s" %(cond_dir) print " The dot product of unit vector with %s is : %3.2f" %(cond_dir,numpy.dot(unit_vector,reference)) print "" user_answer = "" while user_answer not in ["yes", "no"]: user_answer = str(raw_input(" is this OK ? ('yes' or 'no') ")) if user_answer=='no': print " Exiting the program..." print "" sys.exit(1) # we search the groups of WF with similar centres. To do this # a group is identified by the index of the first WF in the group # and the group size gp_dict = {} gp_bool = numpy.zeros(len(conductor),dtype='bool') for i in xrange(len(conductor)): if gp_bool[i]==False: gp_bool[i] = True gp_size = 1 # for each wf we search for similar centres just around that wf for j in xrange(max(i-10,0),min(i+11,len(conductor))): if gp_bool[j]==False: if same_center(conductor[i],conductor[j]): gp_bool[j] = True gp_size += 1 # if gp_size is at least 2 we add this group to the dictionnary if gp_size >= 2: gp_dict[conductor[i].index] = gp_size # now we need to remove the redondant WF from the conductor not_to_add = [] for wf in conductor: if wf.index in gp_dict.keys(): for j in xrange(1,gp_dict[wf.index]): not_to_add.append(wf.index+j) reduced_conductor = [] for wf in conductor: if wf.index not in not_to_add: reduced_conductor.append(wf) # with the reduced_conductor list, we can rotate the centers reduced_rotated_conductor = rotate_wf(reduced_conductor,angle,unit_vector,point_A) # we then sort the rotated Wannier Functions sorted_reduced_conductor = sort(reduced_rotated_conductor, cond_dir, second_dir, delta) # we re-insert the WF with similar centers sorted_conductor = [] for wf in sorted_reduced_conductor: if wf.index not in gp_dict.keys(): sorted_conductor.append(wf) else: sorted_conductor.append(wf) for j in xrange(1,gp_dict[wf.index]): new_wf = wannier_function() pos_in_list = wf.index+j-conductor[0].index new_wf.setindex(conductor[pos_in_list].index) new_wf.setx(wf.x) new_wf.sety(wf.y) new_wf.setz(wf.z) new_wf.setonsite(conductor[pos_in_list].onsite) sorted_conductor.append(new_wf) # we now find the mapping between the original order of WF # and the final order after sorting final_order = [] reference = conductor[0].index for wf in sorted_conductor: final_order.append(wf.index-reference) # now we can reconstruct the matrix final_matrix = numpy.zeros((matrix.shape[0],matrix.shape[1]),dtype='float') for i in xrange(matrix.shape[0]): for j in xrange(matrix.shape[1]): final_matrix[i,j] = matrix[final_order[i],final_order[j]] write_htC('rotated_matrix_htC.dat',final_matrix) # at last we re-generate the *_tran_info.dat file final_wf_list = PL1 + sorted_conductor + PL4 final_atomic_coordinates = rotate_atoms(atomic_coordinates,angle,unit_vector,point_A) write_tran_info(wf_total, wf_per_pl, cells_per_pl, cond_dir, second_dir, final_wf_list, atom_number, final_atomic_coordinates) return