tran_lcr_2c2_build_ham Subroutine

private subroutine tran_lcr_2c2_build_ham(pl_warning, real_space_ham, fermi_energy_list, kpt_latt, num_wann, transport, print_output, real_lattice, mp_grid, ham_r, irvec, nrpts, wannier_centres_translated, one_dim_vec, nrpts_one_dim, num_pl, coord, tran_sorted_idx, hC, hCR, hL0, hL1, hLC, hR0, hR1, hr_one_dim, irvec_max, stdout, seedname, timer, error, comm)

Uses

  • proc~~tran_lcr_2c2_build_ham~~UsesGraph proc~tran_lcr_2c2_build_ham tran_lcr_2c2_build_ham module~w90_constants w90_constants proc~tran_lcr_2c2_build_ham->module~w90_constants module~w90_error w90_error proc~tran_lcr_2c2_build_ham->module~w90_error module~w90_io w90_io proc~tran_lcr_2c2_build_ham->module~w90_io module~w90_types w90_types proc~tran_lcr_2c2_build_ham->module~w90_types module~w90_wannier90_types w90_wannier90_types proc~tran_lcr_2c2_build_ham->module~w90_wannier90_types module~w90_comms w90_comms module~w90_error->module~w90_comms module~w90_error_base w90_error_base module~w90_error->module~w90_error_base module~w90_io->module~w90_constants module~w90_types->module~w90_constants module~w90_wannier90_types->module~w90_constants module~w90_comms->module~w90_constants module~w90_comms->module~w90_error_base

Arguments

Type IntentOptional Attributes Name
logical, intent(in) :: pl_warning
type(real_space_ham_type), intent(inout) :: real_space_ham
real(kind=dp), intent(in), allocatable :: fermi_energy_list(:)
real(kind=dp), intent(in) :: kpt_latt(:,:)
integer, intent(in) :: num_wann
type(transport_type), intent(inout) :: transport
type(print_output_type), intent(in) :: print_output
real(kind=dp), intent(in) :: real_lattice(3,3)
integer, intent(in) :: mp_grid(3)
complex(kind=dp), intent(in) :: ham_r(:,:,:)
integer, intent(in) :: irvec(:,:)
integer, intent(inout) :: nrpts
real(kind=dp), intent(in) :: wannier_centres_translated(:,:)
integer, intent(inout) :: one_dim_vec
integer, intent(inout) :: nrpts_one_dim
integer, intent(inout) :: num_pl
integer, intent(in) :: coord(3)
integer, intent(in) :: tran_sorted_idx(:)
real(kind=dp), intent(inout), allocatable :: hC(:,:)
real(kind=dp), intent(inout), allocatable :: hCR(:,:)
real(kind=dp), intent(inout), allocatable :: hL0(:,:)
real(kind=dp), intent(inout), allocatable :: hL1(:,:)
real(kind=dp), intent(inout), allocatable :: hLC(:,:)
real(kind=dp), intent(inout), allocatable :: hR0(:,:)
real(kind=dp), intent(inout), allocatable :: hR1(:,:)
real(kind=dp), intent(inout), allocatable :: hr_one_dim(:,:,:)
integer, intent(inout) :: irvec_max
integer, intent(in) :: stdout
character(len=50), intent(in) :: seedname
type(timer_list_type), intent(inout) :: timer
type(w90_error_type), intent(out), allocatable :: error
type(w90_comm_type), intent(in) :: comm

Calls

proc~~tran_lcr_2c2_build_ham~~CallsGraph proc~tran_lcr_2c2_build_ham tran_lcr_2c2_build_ham proc~io_date io_date proc~tran_lcr_2c2_build_ham->proc~io_date proc~io_stopwatch_start io_stopwatch_start proc~tran_lcr_2c2_build_ham->proc~io_stopwatch_start proc~io_stopwatch_stop io_stopwatch_stop proc~tran_lcr_2c2_build_ham->proc~io_stopwatch_stop proc~set_error_alloc set_error_alloc proc~tran_lcr_2c2_build_ham->proc~set_error_alloc proc~set_error_dealloc set_error_dealloc proc~tran_lcr_2c2_build_ham->proc~set_error_dealloc proc~set_error_fatal set_error_fatal proc~tran_lcr_2c2_build_ham->proc~set_error_fatal proc~tran_cut_hr_one_dim tran_cut_hr_one_dim proc~tran_lcr_2c2_build_ham->proc~tran_cut_hr_one_dim proc~tran_reduce_hr tran_reduce_hr proc~tran_lcr_2c2_build_ham->proc~tran_reduce_hr proc~comms_sync_error comms_sync_error proc~set_error_alloc->proc~comms_sync_error proc~set_base_error set_base_error proc~set_error_alloc->proc~set_base_error proc~set_error_dealloc->proc~comms_sync_error proc~set_error_dealloc->proc~set_base_error proc~set_error_fatal->proc~comms_sync_error proc~set_error_fatal->proc~set_base_error proc~tran_cut_hr_one_dim->proc~io_stopwatch_start proc~tran_cut_hr_one_dim->proc~io_stopwatch_stop proc~tran_reduce_hr->proc~io_stopwatch_start proc~tran_reduce_hr->proc~io_stopwatch_stop proc~tran_reduce_hr->proc~set_error_alloc proc~tran_reduce_hr->proc~set_error_fatal

Called by

proc~~tran_lcr_2c2_build_ham~~CalledByGraph proc~tran_lcr_2c2_build_ham tran_lcr_2c2_build_ham proc~tran_main tran_main proc~tran_main->proc~tran_lcr_2c2_build_ham proc~w90_transport w90_transport proc~w90_transport->proc~tran_main program~wannier wannier program~wannier->proc~w90_transport

Source Code

  subroutine tran_lcr_2c2_build_ham(pl_warning, real_space_ham, fermi_energy_list, kpt_latt, &
                                    num_wann, transport, print_output, real_lattice, mp_grid, &
                                    ham_r, irvec, nrpts, wannier_centres_translated, one_dim_vec, &
                                    nrpts_one_dim, num_pl, coord, tran_sorted_idx, hC, hCR, hL0, &
                                    hL1, hLC, hR0, hR1, hr_one_dim, irvec_max, stdout, seedname, &
                                    timer, error, comm)
    !================================================!
    ! Builds hamiltonians blocks required for the
    ! Greens function caclulations of the quantum
    ! conductance according to the 2c2 geometry.
    ! Leads are also symmetrised, in that unit cell
    ! sub-blocks are copied to create truely ideal
    ! leads.
    !================================================!

    use w90_constants, only: dp, eps5
    use w90_io, only: io_date, io_stopwatch_start, io_stopwatch_stop
    use w90_types, only: print_output_type, timer_list_type
    use w90_wannier90_types, only: transport_type, real_space_ham_type
    use w90_error, only: w90_error_type, set_error_fatal, set_error_alloc, set_error_dealloc

    implicit none

    ! arguments
    integer, intent(in) :: coord(3)
    integer, intent(in) :: irvec(:, :)
    integer, intent(inout) :: irvec_max
    integer, intent(in) :: mp_grid(3)
    integer, intent(in) :: num_wann
    integer, intent(inout) :: nrpts
    integer, intent(inout) :: nrpts_one_dim
    integer, intent(inout) :: num_pl
    integer, intent(inout) :: one_dim_vec
    integer, intent(in) :: stdout
    integer, intent(in) :: tran_sorted_idx(:)

    real(kind=dp), allocatable, intent(inout) :: hr_one_dim(:, :, :) ! de/realloc'd below
    real(kind=dp), allocatable, intent(inout) :: hC(:, :)
    real(kind=dp), allocatable, intent(inout) :: hCR(:, :)
    real(kind=dp), allocatable, intent(inout) :: hL0(:, :)
    real(kind=dp), allocatable, intent(inout) :: hL1(:, :)
    real(kind=dp), allocatable, intent(inout) :: hLC(:, :)
    real(kind=dp), allocatable, intent(inout) :: hR0(:, :)
    real(kind=dp), allocatable, intent(inout) :: hR1(:, :)
    real(kind=dp), intent(in) :: real_lattice(3, 3)
    real(kind=dp), intent(in) :: wannier_centres_translated(:, :)

    complex(kind=dp), intent(in) :: ham_r(:, :, :)

    real(kind=dp), allocatable, intent(in) :: fermi_energy_list(:)
    real(kind=dp), intent(in) :: kpt_latt(:, :)

    type(print_output_type), intent(in) :: print_output
    type(real_space_ham_type), intent(inout) :: real_space_ham
    type(transport_type), intent(inout) :: transport
    type(timer_list_type), intent(inout) :: timer
    type(w90_error_type), allocatable, intent(out) :: error
    type(w90_comm_type), intent(in) :: comm

    character(len=50), intent(in)  :: seedname

    logical, intent(in) :: pl_warning

    ! local variables
    integer                :: i, j, k, num_wann_cell_ll, file_unit, ierr, band_size
    integer                :: fermi_n
    real(kind=dp), allocatable  :: sub_block(:, :)
    real(kind=dp)          :: PL_length, dist, dist_vec(3)
    character(len=9)       :: cdate, ctime

    if (print_output%timing_level > 1) call io_stopwatch_start('tran: lcr_2c2_build_ham', timer)

    fermi_n = 0
    if (allocated(fermi_energy_list)) fermi_n = size(fermi_energy_list)
    if (fermi_n > 1) then
      call set_error_fatal(error, "Error in tran_lcr_2c2_build_ham: nfermi>1. " &
                           //"Set the fermi level using the input parameter 'fermi_evel'", comm)
      return
    end if

    allocate (hL0(transport%num_ll, transport%num_ll), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating hL0 in tran_lcr_2c2_build_ham', comm)
      return
    end if
    allocate (hL1(transport%num_ll, transport%num_ll), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating hL1 in tran_lcr_2c2_build_ham', comm)
      return
    end if
    allocate (hR0(transport%num_ll, transport%num_ll), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating hR0 in tran_lcr_2c2_build_ham', comm)
      return
    end if
    allocate (hR1(transport%num_ll, transport%num_ll), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating hR1 in tran_lcr_2c2_build_ham', comm)
      return
    end if
    allocate (hLC(transport%num_ll, transport%num_ll), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating hLC in tran_lcr_2c2_build_ham', comm)
      return
    end if
    allocate (hCR(transport%num_ll, transport%num_ll), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating hCR in tran_lcr_2c2_build_ham', comm)
      return
    end if
    allocate (hC(num_wann - (2*transport%num_ll), num_wann - (2*transport%num_ll)), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating hC in tran_lcr_2c2_build_ham', comm)
      return
    end if

    !This checks that only the gamma point is used in wannierisation
    !This is necessary since this calculation only makes sense if we
    !have periodicity over the supercell.
    !BGS, I think (0, 0, 0) in kpt_latt should work as well as in kpt_cart
    if ((size(kpt_latt, 2) .ne. 1) .and. (kpt_latt(1, 1) .eq. 0.0_dp) &
        .and. (kpt_latt(2, 1) .eq. 0.0_dp) .and. (kpt_latt(3, 1) .eq. 0.0_dp)) then
      call set_error_fatal(error, 'Calculation must be performed at gamma only', comm)
      return
    end if

    num_wann_cell_ll = transport%num_ll/transport%num_cell_ll

    allocate (sub_block(num_wann_cell_ll, num_wann_cell_ll), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating sub_block in tran_lcr_2c2_build_ham', comm)
      return
    end if

    !Build hL0 & hL1

    hL0 = 0.0_dp
    hL1 = 0.0_dp

    !Loop over the sub_blocks corresponding to distinct unit cells inside the principal layer

    do i = 1, transport%num_cell_ll

      !Each sub_block will be duplicated along the corresponding diagonal. This ensures the correct symmetry for the leads.

      sub_block = 0.0_dp

      !Extract matrix elements from hr_one_dim needed for hL0 (and lower triangular sub_blocks of hL1)

      do j = 1, num_wann_cell_ll
        do k = 1, num_wann_cell_ll
          sub_block(j, k) = hr_one_dim(tran_sorted_idx(j), tran_sorted_idx((i - 1)*num_wann_cell_ll + k), 0)
        end do
      end do

      !Filling up hL0 sub_block by sub_block

      do j = 1, transport%num_cell_ll - i + 1

        !Fill diagonal and upper diagonal sub_blocks

        hL0((j - 1)*num_wann_cell_ll + 1:j*num_wann_cell_ll, &
            (j - 1)*num_wann_cell_ll + 1 + (i - 1)*num_wann_cell_ll:j*num_wann_cell_ll + (i - 1)*num_wann_cell_ll) = sub_block

        !Fill lower diagonal sub_blocks

        if (i .gt. 1) then
          hL0((j - 1)*num_wann_cell_ll + 1 + (i - 1)*num_wann_cell_ll:j*num_wann_cell_ll + (i - 1)*num_wann_cell_ll, &
              (j - 1)*num_wann_cell_ll + 1:j*num_wann_cell_ll) = transpose(sub_block)
        end if
      end do

      !Filling up non-diagonal hL1 sub_blocks (nothing need be done for i=1)

      if (i .gt. 1) then
        do j = 1, i - 1
          hL1((transport%num_cell_ll - (i - j))*num_wann_cell_ll + 1:(transport%num_cell_ll - (i - 1 - j))*num_wann_cell_ll, &
              (j - 1)*num_wann_cell_ll + 1:j*num_wann_cell_ll) = sub_block
        end do
      end if

      ! MS: Get diagonal and upper triangular sublocks for hL1 - use periodic image of PL4

      sub_block = 0.0_dp

      if (i == 1) then !Do diagonal only
        do j = 1, num_wann_cell_ll
          do k = 1, num_wann_cell_ll
            sub_block(j, k) = hr_one_dim( &
                              tran_sorted_idx(num_wann - transport%num_ll + j), &
                              tran_sorted_idx((i - 1)*num_wann_cell_ll + k), 0)
          end do
        end do

        ! MS: Now fill subblocks of hL1

        do j = 1, transport%num_cell_ll - i + 1
          hL1((j - 1)*num_wann_cell_ll + 1:j*num_wann_cell_ll, &
              (j - 1)*num_wann_cell_ll + 1 + (i - 1)*num_wann_cell_ll:j*num_wann_cell_ll + (i - 1)* &
              num_wann_cell_ll) = sub_block
        end do
      end if
    end do

    !Special case tran_num_cell_ll=1, the diagonal sub-block of hL1 is hL1, so cannot be left as zero

    if (transport%num_cell_ll .eq. 1) then
      do j = num_wann - num_wann_cell_ll + 1, num_wann
        do k = 1, num_wann_cell_ll
          hL1(j - num_wann + num_wann_cell_ll, k) = hr_one_dim(tran_sorted_idx(j), tran_sorted_idx(k), 0)
        end do
      end do
    end if

    !Build hR0 & hR1

    hR0 = 0.0_dp
    hR1 = 0.0_dp

    !Loop over the sub_blocks corresponding to distinct unit cells inside the principal layer

    do i = 1, transport%num_cell_ll

      !Each sub_block will be duplicated along the corresponding diagonal. This ensures the correct symmetry for the leads.

      sub_block = 0.0_dp

      !Extract matrix elements from hr_one_dim needed for hR0 (and lower triangular sub_blocks of hR1)

      do j = 1, num_wann_cell_ll
        do k = 1, num_wann_cell_ll
          sub_block(j, k) = hr_one_dim(tran_sorted_idx(num_wann - i*(num_wann_cell_ll) + j), &
                                       tran_sorted_idx(num_wann - num_wann_cell_ll + k), 0)
        end do
      end do

      !Filling up hR0 sub_block by sub_block

      do j = 1, transport%num_cell_ll - i + 1

        !Fill diagonal and upper diagonal sub_blocks

        hR0((j - 1)*num_wann_cell_ll + 1:j*num_wann_cell_ll, &
            (j - 1)*num_wann_cell_ll + 1 + (i - 1)*num_wann_cell_ll:j*num_wann_cell_ll + (i - 1)*num_wann_cell_ll) = sub_block

        !Fill lower diagonal sub_blocks

        if (i .gt. 1) then
          hR0((j - 1)*num_wann_cell_ll + 1 + (i - 1)*num_wann_cell_ll:j*num_wann_cell_ll + (i - 1)*num_wann_cell_ll, &
              (j - 1)*num_wann_cell_ll + 1:j*num_wann_cell_ll) = transpose(sub_block)
        end if
      end do

      !Filling up non-diagonal hR1 sub_blocks (nothing need be done for i=1)

      if (i .gt. 1) then
        do j = 1, i - 1
          hR1((transport%num_cell_ll - (i - j))*num_wann_cell_ll + 1:(transport%num_cell_ll - (i - 1 - j))*num_wann_cell_ll, &
              (j - 1)*num_wann_cell_ll + 1:j*num_wann_cell_ll) = sub_block
        end do
      end if

      ! MS: Get diagonal and upper triangular sublocks for hR1 - use periodic image of PL1

      sub_block = 0.0_dp

      if (i == 1) then  !Do diagonal only
        do j = 1, num_wann_cell_ll
          do k = 1, num_wann_cell_ll
            sub_block(j, k) = hr_one_dim(tran_sorted_idx((i - 1)*num_wann_cell_ll + k), &
                                         tran_sorted_idx(num_wann - transport%num_ll + j), 0)
          end do
        end do

        ! MS: Now fill subblocks of hR1

        do j = 1, transport%num_cell_ll - i + 1
          hR1((j - 1)*num_wann_cell_ll + 1:j*num_wann_cell_ll, &
              (j - 1)*num_wann_cell_ll + 1 + (i - 1)*num_wann_cell_ll:j*num_wann_cell_ll + (i - 1)*num_wann_cell_ll) = sub_block
        end do
      end if
    end do

    !Special case tran_num_cell_ll=1, the diagonal sub-block of hR1 is hR1, so cannot be left as zero

    if (transport%num_cell_ll .eq. 1) then
      do j = 1, num_wann_cell_ll
        do k = num_wann - num_wann_cell_ll + 1, num_wann
          hR1(k - num_wann + num_wann_cell_ll, j) = hr_one_dim(tran_sorted_idx(j), tran_sorted_idx(k), 0)
        end do
      end do
    end if

    !Building hLC

    hLC = 0.0_dp
    do i = 1, transport%num_ll
      do j = transport%num_ll + 1, 2*transport%num_ll
        hLC(i, j - transport%num_ll) = hr_one_dim(tran_sorted_idx(i), tran_sorted_idx(j), 0)
      end do
    end do
!----!
! MS ! Rely on dist_cutoff doing the work here, as it cuts element-wise, not block wise (incorrect)
!----!
!    if (transport%num_cell_ll .gt. 1) then
!        do j=1,transport%num_cell_ll
!            do k=1,transport%num_cell_ll
!                if (k .ge. j) then
!                    hLC((j-1)*num_wann_cell_ll+1:j*num_wann_cell_ll,(k-1)*num_wann_cell_ll+1:k*num_wann_cell_ll)=0.0_dp
!                endif
!            enddo
!        enddo
!    endif
!---!
!end!
!---!

    !Building hC

    hC = 0.0_dp

    band_size = 0
    if (real_space_ham%dist_cutoff_hc .ne. real_space_ham%dist_cutoff) then
      real_space_ham%dist_cutoff = real_space_ham%dist_cutoff_hc
      write (stdout, *) 'Applying dist_cutoff_hc to Hamiltonian for construction of hC'
      deallocate (hr_one_dim, stat=ierr)
      if (ierr /= 0) then
        call set_error_dealloc(error, 'Error deallocating hr_one_dim in tran_lcr_2c2_build_ham', comm)
        return
      end if
      call tran_reduce_hr(real_space_ham, ham_r, hr_one_dim, real_lattice, irvec, mp_grid, &
                          irvec_max, nrpts, nrpts_one_dim, num_wann, one_dim_vec, &
                          print_output%timing_level, stdout, timer, error, comm)
      if (allocated(error)) return

      call tran_cut_hr_one_dim(real_space_ham, transport, print_output, hr_one_dim, real_lattice, &
                               wannier_centres_translated, mp_grid, irvec_max, num_pl, num_wann, &
                               one_dim_vec, stdout, timer)

    end if

    do i = transport%num_ll + 1, num_wann - transport%num_ll
      do j = transport%num_ll + 1, num_wann - transport%num_ll
        hC(i - transport%num_ll, j - transport%num_ll) = hr_one_dim(tran_sorted_idx(i), tran_sorted_idx(j), 0)

        ! Impose a ham_cutoff of 1e-4 eV to reduce tran_num_bandc (and in turn hCband, and speed up transport)

        if (abs(hC(i - transport%num_ll, j - transport%num_ll)) .lt. 10.0_dp*eps5) then
          hC(i - transport%num_ll, j - transport%num_ll) = 0.0_dp
          band_size = max(band_size, abs(i - j))
        end if
      end do
    end do

    !Building hCR

    hCR = 0.0_dp
    do i = num_wann - 2*transport%num_ll + 1, num_wann - transport%num_ll
      do j = num_wann - transport%num_ll + 1, num_wann
        hCR(i - (num_wann - 2*transport%num_ll), j - (num_wann - transport%num_ll)) = &
          hr_one_dim(tran_sorted_idx(i), tran_sorted_idx(j), 0)
      end do
    end do
!----!
! MS ! Rely on dist_cutoff doing the work here, as it cuts element-wise, not block wise (incorrect)
!----!
!    if (transport%num_cell_ll .gt. 1) then
!        do j=1,transport%num_cell_ll
!            do k=1,transport%num_cell_ll
!                if (k .ge. j) then
!                    hCR((j-1)*num_wann_cell_ll+1:j*num_wann_cell_ll,(k-1)*num_wann_cell_ll+1:k*num_wann_cell_ll)=0.0_dp
!                endif
!            enddo
!        enddo
!    endif
!---!
!end!
!---!

    !Subtract the Fermi energy from the diagonal elements of hC,hL0,hR0

    do i = 1, transport%num_ll
      hL0(i, i) = hL0(i, i) - fermi_energy_list(1)
      hR0(i, i) = hR0(i, i) - fermi_energy_list(1)
    end do
    do i = 1, num_wann - (2*transport%num_ll)
      hC(i, i) = hC(i, i) - fermi_energy_list(1)
    end do

    !Define tran_num_** parameters that are used later in tran_lcr

    transport%num_rr = transport%num_ll
    transport%num_lc = transport%num_ll
    transport%num_cr = transport%num_ll
    transport%num_cc = num_wann - (2*transport%num_ll)

    ! Set appropriate tran_num_bandc if has not been set (0.0_dp is default value)

    if (transport%num_bandc .eq. 0.0_dp) then
      transport%num_bandc = min(band_size + 1, (transport%num_cc + 1)/2 + 1)
    end if

    ! MS: Find and print effective PL length

    if (.not. pl_warning) then
      PL_length = 0.0_dp
      do i = 1, transport%num_ll
        do j = 1, transport%num_ll
          if (abs(hL1(i, j)) .gt. 0.0_dp) then
            if (index(real_space_ham%dist_cutoff_mode, 'one_dim') .gt. 0) then
              dist = abs(wannier_centres_translated(coord(1), tran_sorted_idx(i)) &
                         - wannier_centres_translated(coord(1), tran_sorted_idx(j + transport%num_ll)))
            else
              dist_vec(:) = wannier_centres_translated(:, tran_sorted_idx(i)) &
                            - wannier_centres_translated(:, tran_sorted_idx(j + transport%num_ll))
              dist = sqrt(dot_product(dist_vec, dist_vec))
            end if
            PL_length = max(PL_length, dist)
          end if
          if (abs(hR1(i, j)) .gt. 0.0_dp) then
            if (index(real_space_ham%dist_cutoff_mode, 'one_dim') .gt. 0) then
              dist = abs(wannier_centres_translated(coord(1), tran_sorted_idx(num_wann - 2*transport%num_ll + i)) &
                         - wannier_centres_translated(coord(1), tran_sorted_idx(num_wann - transport%num_ll + j)))
            else
              dist_vec(:) = wannier_centres_translated(:, tran_sorted_idx(num_wann - 2*transport%num_ll + i)) &
                            - wannier_centres_translated(:, tran_sorted_idx(num_wann - transport%num_ll + j))
              dist = sqrt(dot_product(dist_vec, dist_vec))
            end if
            PL_length = max(PL_length, dist)
          end if
        end do
      end do
      write (stdout, '(1x,a,f12.6,a)') 'Approximate effective principal layer length is: ', PL_length, ' Ang.'
    end if

    !Writing to file:

    if (transport%write_ht) then
      write (stdout, *) '------------------------------- Writing ht files  ----------------------------'

      open (newunit=file_unit, file=trim(seedname)//'_htL.dat', status='unknown', form='formatted', action='write')

      call io_date(cdate, ctime)
      write (file_unit, *) 'written on '//cdate//' at '//ctime ! Date and time
      write (file_unit, '(I6)') transport%num_ll
      write (file_unit, '(6F12.6)') ((hL0(j, i), j=1, transport%num_ll), i=1, transport%num_ll)
      write (file_unit, '(I6)') transport%num_ll
      write (file_unit, '(6F12.6)') ((hL1(j, i), j=1, transport%num_ll), i=1, transport%num_ll)

      close (file_unit)
      write (stdout, *) ' '//trim(seedname)//'_htL.dat  written'

      !hR
      open (newunit=file_unit, file=trim(seedname)//'_htR.dat', status='unknown', form='formatted', action='write')

      call io_date(cdate, ctime)
      write (file_unit, *) 'written on '//cdate//' at '//ctime ! Date and time
      write (file_unit, '(I6)') transport%num_rr
      write (file_unit, '(6F12.6)') ((hR0(j, i), j=1, transport%num_rr), i=1, transport%num_rr)
      write (file_unit, '(I6)') transport%num_rr
      write (file_unit, '(6F12.6)') ((hR1(j, i), j=1, transport%num_rr), i=1, transport%num_rr)

      close (file_unit)
      write (stdout, *) ' '//trim(seedname)//'_htR.dat  written'

      !hLC
      open (newunit=file_unit, file=trim(seedname)//'_htLC.dat', status='unknown', form='formatted', action='write')

      call io_date(cdate, ctime)
      write (file_unit, *) 'written on '//cdate//' at '//ctime ! Date and time
      write (file_unit, '(2I6)') transport%num_ll, transport%num_lc
      write (file_unit, '(6F12.6)') ((hLC(j, i), j=1, transport%num_lc), i=1, transport%num_lc)

      close (file_unit)
      write (stdout, *) ' '//trim(seedname)//'_htLC.dat written'

      !hCR
      open (newunit=file_unit, file=trim(seedname)//'_htCR.dat', status='unknown', form='formatted', action='write')

      call io_date(cdate, ctime)
      write (file_unit, *) 'written on '//cdate//' at '//ctime ! Date and time
      write (file_unit, '(2I6)') transport%num_cr, transport%num_rr
      write (file_unit, '(6F12.6)') ((hCR(j, i), j=1, transport%num_cr), i=1, transport%num_cr)

      close (file_unit)
      write (stdout, *) ' '//trim(seedname)//'_htCR.dat written'

      !hC
      open (newunit=file_unit, file=trim(seedname)//'_htC.dat', status='unknown', form='formatted', action='write')

      call io_date(cdate, ctime)
      write (file_unit, *) 'written on '//cdate//' at '//ctime ! Date and time
      write (file_unit, '(I6)') transport%num_cc
      write (file_unit, '(6F12.6)') ((hC(j, i), j=1, transport%num_cc), i=1, transport%num_cc)

      close (file_unit)
      write (stdout, *) ' '//trim(seedname)//'_htC.dat  written'

      write (stdout, *) '------------------------------------------------------------------------------'
    end if

    deallocate (sub_block, stat=ierr)
    if (ierr /= 0) then
      call set_error_dealloc(error, 'Error deallocating sub_block in tran_lcr_2c2_build_ham', comm)
      return
    end if

    if (print_output%timing_level > 1) call io_stopwatch_stop('tran: lcr_2c2_build_ham', timer)

    return

  end subroutine tran_lcr_2c2_build_ham