示例#1
0
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
示例#2
0
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)
示例#3
0
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
示例#4
0
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