Fills the atom data block
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(settings_type), | intent(inout) | :: | settings | |||
| type(atom_data_type), | intent(inout) | :: | atom_data | |||
| logical, | intent(in) | :: | lunits |
Do we expect a first line with the units |
||
| real(kind=dp), | intent(in) | :: | real_lattice(3,3) | |||
| real(kind=dp), | intent(in) | :: | bohr | |||
| type(w90_error_type), | intent(out), | allocatable | :: | error | ||
| type(w90_comm_type), | intent(in) | :: | comm |
subroutine readwrite_get_atoms(settings, atom_data, lunits, real_lattice, bohr, error, comm) !================================================! ! !! Fills the atom data block ! !================================================! use w90_utility, only: utility_frac_to_cart, utility_cart_to_frac, utility_inverse_mat use w90_error, only: w90_error_type, set_error_input, set_error_alloc implicit none type(atom_data_type), intent(inout) :: atom_data type(w90_error_type), allocatable, intent(out) :: error type(w90_comm_type), intent(in) :: comm type(settings_type), intent(inout) :: settings logical, intent(in) :: lunits !! Do we expect a first line with the units real(kind=dp), intent(in) :: real_lattice(3, 3) real(kind=dp), intent(in) :: bohr real(kind=dp) :: inv_lattice(3, 3) real(kind=dp) :: atoms_pos_frac_tmp(3, atom_data%num_atoms) real(kind=dp) :: atoms_pos_cart_tmp(3, atom_data%num_atoms) character(len=20) :: keyword integer :: in, ins, ine, loop, i, line_e, line_s, counter integer :: i_temp, loop2, max_sites, ierr, ic logical :: found_e, found_s, found, frac character(len=maxlen) :: dummy, end_st, start_st character(len=maxlen) :: ctemp(atom_data%num_atoms) character(len=maxlen) :: atoms_label_tmp(atom_data%num_atoms) logical :: lconvert call utility_inverse_mat(real_lattice, inv_lattice) keyword = "atoms_cart" frac = .false. call w90_readwrite_get_block_length(settings, "atoms_frac", found, i_temp, error, comm) if (allocated(error)) return if (found) then keyword = "atoms_frac" frac = .true. end if found_s = .false. found_e = .false. start_st = 'begin '//trim(keyword) end_st = 'end '//trim(keyword) do loop = 1, settings%num_lines ins = index(settings%in_data(loop), trim(keyword)) if (ins == 0) cycle in = index(settings%in_data(loop), 'begin') if (in == 0 .or. in > 1) cycle line_s = loop if (found_s) then call set_error_input(error, 'Error: Found '//trim(start_st)//' more than once in input file', comm) return end if found_s = .true. end do do loop = 1, settings%num_lines ine = index(settings%in_data(loop), trim(keyword)) if (ine == 0) cycle in = index(settings%in_data(loop), 'end') if (in == 0 .or. in > 1) cycle line_e = loop if (found_e) then call set_error_input(error, 'Error: Found '//trim(end_st)//' more than once in input file', comm) return end if found_e = .true. end do if (.not. found_e) then call set_error_input(error, 'Error: Found '//trim(start_st)//' but no '//trim(end_st)//' in input file', comm) return end if if (line_e <= line_s) then call set_error_input(error, 'Error: '//trim(end_st)//' comes before '//trim(start_st)//' in input file', comm) return end if lconvert = .false. if (lunits) then dummy = settings%in_data(line_s + 1) if (index(dummy, 'ang') .ne. 0) then lconvert = .false. elseif (index(dummy, 'bohr') .ne. 0) then lconvert = .true. else call set_error_input(error, 'Error: Units in block atoms_cart not recognised in readwrite_get_atoms', comm) return end if settings%in_data(line_s) (1:maxlen) = ' ' line_s = line_s + 1 end if counter = 0 do loop = line_s + 1, line_e - 1 dummy = settings%in_data(loop) counter = counter + 1 if (frac) then read (dummy, *, err=240, end=240) atoms_label_tmp(counter), (atoms_pos_frac_tmp(i, counter), i=1, 3) else read (dummy, *, err=240, end=240) atoms_label_tmp(counter), (atoms_pos_cart_tmp(i, counter), i=1, 3) end if end do if (lconvert) atoms_pos_cart_tmp = atoms_pos_cart_tmp*bohr settings%in_data(line_s:line_e) (1:maxlen) = ' ' if (frac) then do loop = 1, atom_data%num_atoms call utility_frac_to_cart(atoms_pos_frac_tmp(:, loop), atoms_pos_cart_tmp(:, loop), real_lattice) end do else do loop = 1, atom_data%num_atoms call utility_cart_to_frac(atoms_pos_cart_tmp(:, loop), atoms_pos_frac_tmp(:, loop), inv_lattice) end do end if ! Now we sort the data into the proper structures atom_data%num_species = 1 ctemp(1) = atoms_label_tmp(1) do loop = 2, atom_data%num_atoms do loop2 = 1, loop - 1 if (trim(atoms_label_tmp(loop)) == trim(atoms_label_tmp(loop2))) exit if (loop2 == loop - 1) then atom_data%num_species = atom_data%num_species + 1 ctemp(atom_data%num_species) = atoms_label_tmp(loop) end if end do end do allocate (atom_data%species_num(atom_data%num_species), stat=ierr) if (ierr /= 0) then call set_error_alloc(error, 'Error allocating atoms_species_num in readwrite_get_atoms', comm) return end if allocate (atom_data%label(atom_data%num_species), stat=ierr) if (ierr /= 0) then call set_error_alloc(error, 'Error allocating atoms_label in readwrite_get_atoms', comm) return end if allocate (atom_data%symbol(atom_data%num_species), stat=ierr) if (ierr /= 0) then call set_error_alloc(error, 'Error allocating atoms_symbol in readwrite_get_atoms', comm) return end if atom_data%species_num(:) = 0 do loop = 1, atom_data%num_species atom_data%label(loop) = ctemp(loop) do loop2 = 1, atom_data%num_atoms if (trim(atom_data%label(loop)) == trim(atoms_label_tmp(loop2))) then atom_data%species_num(loop) = atom_data%species_num(loop) + 1 end if end do end do max_sites = maxval(atom_data%species_num) allocate (atom_data%pos_cart(3, max_sites, atom_data%num_species), stat=ierr) if (ierr /= 0) then call set_error_alloc(error, 'Error allocating atoms_pos_cart in readwrite_get_atoms', comm) return end if do loop = 1, atom_data%num_species counter = 0 do loop2 = 1, atom_data%num_atoms if (trim(atom_data%label(loop)) == trim(atoms_label_tmp(loop2))) then counter = counter + 1 !atom_data%pos_frac(:, counter, loop) = atoms_pos_frac_tmp(:, loop2) atom_data%pos_cart(:, counter, loop) = atoms_pos_cart_tmp(:, loop2) end if end do end do ! Strip any numeric characters from atoms_label to get atoms_symbol do loop = 1, atom_data%num_species atom_data%symbol(loop) (1:2) = atom_data%label(loop) (1:2) ic = ichar(atom_data%symbol(loop) (2:2)) if ((ic .lt. ichar('a')) .or. (ic .gt. ichar('z'))) & atom_data%symbol(loop) (2:2) = ' ' end do return 240 call set_error_alloc(error, 'Error: Problem reading block keyword '//trim(keyword), comm) return end subroutine readwrite_get_atoms