35 use,
intrinsic :: iso_fortran_env
67 type(lattice_vectors_t) :: latt
70 type(atom_t),
allocatable :: atom(:)
72 type(symmetries_t) :: symm
74 type(distributed_t) :: atoms_dist
76 integer,
allocatable :: map_symm_atoms(:,:)
77 integer,
allocatable :: inv_map_symm_atoms(:,:)
82 class(species_wrapper_t),
allocatable :: species(:)
83 logical :: only_user_def
84 logical,
private :: species_time_dependent
86 logical :: force_total_enforce
87 type(ion_interaction_t) :: ion_interaction
90 logical,
private :: apply_global_force
91 type(tdf_t),
private :: global_force_function
94 generic ::
assignment(=) => copy
122 procedure ions_constructor
129 type(namespace_t),
intent(in) :: namespace
130 logical,
optional,
intent(in) :: print_info
131 type(lattice_vectors_t),
optional,
intent(out) :: latt_inp
132 class(ions_t),
pointer :: ions
134 type(read_coords_info) :: xyz
135 integer :: ia, ierr, idir
136 character(len=100) :: function_name
137 real(real64) :: mindist
138 real(real64),
allocatable :: factor(:)
139 integer,
allocatable :: site_type(:)
140 logical,
allocatable :: spherical_site(:)
141 real(real64),
parameter :: threshold = 1e-5_real64
142 type(species_factory_t) :: factory
148 ions%namespace = namespace
150 ions%space =
space_t(namespace)
161 message(1) =
"Coordinates have not been defined."
170 safe_allocate(ions%atom(1:ions%natoms))
171 do ia = 1, ions%natoms
172 call atom_init(ions%atom(ia), ions%space%dim, xyz%atom(ia)%label)
173 ions%pos(:,ia) = xyz%atom(ia)%x(1:ions%space%dim)
175 ions%fixed(ia) = .not. xyz%atom(ia)%move
179 if (
allocated(xyz%latvec))
then
189 do ia = 1, ions%natoms
190 ions%pos(:, ia) = ions%latt%red_to_cart(ions%pos(:, ia))
202 if (
present(latt_inp))
then
209 if (ions%space%has_mixed_periodicity())
then
210 safe_allocate(factor(ions%space%dim))
211 do idir = 1, ions%space%periodic_dim
214 do idir = ions%space%periodic_dim + 1, ions%space%dim
215 factor(idir) =
m_one/norm2(ions%latt%rlattice(1:ions%space%dim, idir))
217 call ions%latt%scale(factor)
218 safe_deallocate_a(factor)
222 do ia = 1, ions%natoms
223 ions%mass(ia) = ions%atom(ia)%species%get_mass()
224 ions%charge(ia) = ions%atom(ia)%species%get_zval()
228 if (ions%natoms > 1)
then
230 if (mindist < threshold)
then
231 write(
message(1),
'(a)')
"Some of the atoms seem to sit too close to each other."
232 write(
message(2),
'(a)')
"Please review your input files and the output geometry (in 'static/')."
233 write(
message(3),
'(a, f12.6, 1x, a)')
"Minimum distance = ", &
239 call ions%write_xyz(trim(
static_dir)//
'/geometry')
243 message(1) =
"It cannot be correct to run with physical atoms so close."
249 safe_allocate(spherical_site(1:ions%natoms))
250 safe_allocate(site_type(1:ions%natoms))
251 do ia = 1, ions%natoms
252 select type(spec => ions%atom(ia)%species)
254 spherical_site(ia) = .false.
256 spherical_site(ia) = .false.
258 spherical_site(ia) = .false.
260 spherical_site(ia) = .false.
262 spherical_site(ia) = .
true.
265 site_type(ia) = ions%atom(ia)%species%get_index()
268 ions%symm =
symmetries_t(ions%namespace, ions%space, ions%latt, ions%natoms, ions%pos, site_type, spherical_site)
270 safe_deallocate_a(spherical_site)
271 safe_deallocate_a(site_type)
274 call ions%generate_mapping_symmetric_atoms()
286 call parse_variable(namespace,
'ForceTotalEnforce', .false., ions%force_total_enforce)
302 ions%apply_global_force = .
true.
304 call parse_variable(namespace,
'TDGlobalForce',
'none', function_name)
305 call tdf_read(ions%global_force_function, namespace, trim(function_name), ierr)
308 call messages_write(
"You have enabled the GlobalForce option but Octopus could not find")
309 call messages_write(
"the '"//trim(function_name)//
"' function in the TDFunctions block.")
315 ions%apply_global_force = .false.
326 type(
ions_t),
intent(inout) :: ions
328 logical,
optional,
intent(in) :: print_info
330 logical :: print_info_, spec_user_defined
331 integer :: i, j, k, ispin
337 if (
present(print_info))
then
338 print_info_ = print_info
342 atoms1:
do i = 1, ions%natoms
346 ions%nspecies = ions%nspecies + 1
350 allocate(ions%species(1:ions%nspecies))
354 ions%only_user_def = .
true.
355 atoms2:
do i = 1, ions%natoms
360 ions%species(k)%s => factory%create_from_input(ions%namespace,
atom_get_label(ions%atom(j)), k)
362 select type(spec => ions%species(k)%s)
366 ions%only_user_def = .false.
369 select type(spec => ions%species(k)%s)
371 if (ions%space%dim /= 3)
then
372 message(1) =
"Pseudopotentials may only be used with Dimensions = 3."
377 if (ions%space%is_periodic() .and. ions%space%periodic_dim /= 2)
then
378 message(1) =
"Periodic jelium slab can only be used if PeriodicDim = 2"
389 ispin = min(2, ispin)
391 if (print_info_)
then
394 do i = 1, ions%nspecies
395 spec => ions%species(i)%s
396 call spec%build(ions%namespace, ispin, ions%space%dim, print_info=print_info_)
398 if (print_info_)
then
411 call parse_variable(ions%namespace,
'SpeciesTimeDependent', .false., ions%species_time_dependent)
413 do i = 1,ions%nspecies
414 select type(spec=>ions%species(i)%s)
416 spec_user_defined = .
true.
419 if (ions%species_time_dependent .and. .not. spec_user_defined)
then
424 do i = 1, ions%natoms
425 do j = 1, ions%nspecies
438 class(
ions_t),
intent(out) :: ions_out
439 class(
ions_t),
intent(in) :: ions_in
445 ions_out%latt = ions_in%latt
447 ions_out%natoms = ions_in%natoms
448 safe_allocate(ions_out%atom(1:ions_out%natoms))
449 ions_out%atom = ions_in%atom
451 ions_out%nspecies = ions_in%nspecies
452 allocate(ions_out%species(1:ions_out%nspecies))
453 ions_out%species = ions_in%species
455 ions_out%only_user_def = ions_in%only_user_def
459 safe_allocate(ions_out%map_symm_atoms(1:ions_in%natoms, 1:ions_in%symm%nops))
460 ions_out%map_symm_atoms = ions_in%map_symm_atoms
461 safe_allocate(ions_out%inv_map_symm_atoms(1:ions_in%natoms, 1:ions_in%symm%nops))
462 ions_out%inv_map_symm_atoms = ions_in%inv_map_symm_atoms
470 class(
ions_t),
intent(inout) :: this
484 class(
ions_t),
target,
intent(inout) :: this
489 select type (interaction)
499 class(
ions_t),
intent(inout) :: this
508 class(
ions_t),
intent(inout) :: this
509 character(len=*),
intent(in) :: label
524 class(
ions_t),
intent(in) :: partner
529 select type (interaction)
539 class(
ions_t),
intent(inout) :: partner
544 select type (interaction)
555 class(
ions_t),
intent(inout) :: this
561 do iatom = 1, this%natoms
562 this%pos(:, iatom) = this%latt%fold_into_cell(this%pos(:, iatom))
569 real(real64) function ions_min_distance(this, real_atoms_only) result(rmin)
570 class(
ions_t),
intent(in) :: this
571 logical,
optional,
intent(in) :: real_atoms_only
573 integer :: iatom, jatom, idir
574 real(real64) :: xx(this%space%dim)
575 logical :: real_atoms_only_
578 if (this%natoms == 1 .and. .not. this%space%is_periodic())
then
583 push_sub(ions_min_distance)
588 do iatom = 1, this%natoms
592 if (real_atoms_only_) cycle
594 do jatom = iatom + 1, this%natoms
598 if (real_atoms_only_) cycle
600 xx = abs(this%pos(:, iatom) - this%pos(:, jatom))
601 if (this%space%is_periodic())
then
602 xx = this%latt%cart_to_red(xx)
603 do idir = 1, this%space%periodic_dim
606 xx = this%latt%red_to_cart(xx)
608 rmin = min(norm2(xx), rmin)
612 if (.not. (this%only_user_def .and. real_atoms_only_))
then
614 do idir = 1, this%space%periodic_dim
615 rmin = min(rmin, norm2(this%latt%rlattice(:,idir)))
620 if(rmin < huge(rmin)/1e6_real64)
then
621 rmin = anint(rmin*1e6_real64)*1.0e-6_real64
624 pop_sub(ions_min_distance)
629 class(
ions_t),
intent(in) :: this
633 time_dependent = this%species_time_dependent
639 real(real64) function ions_val_charge(this, mask) result(val_charge)
640 class(
ions_t),
intent(in) :: this
641 logical,
optional,
intent(in) :: mask(:)
645 if (
present(mask))
then
646 val_charge = -sum(this%charge, mask=mask)
648 val_charge = -sum(this%charge)
656 class(
ions_t),
intent(in) :: this
657 logical,
optional,
intent(in) :: mask(:)
658 real(real64) :: dipole(this%space%dim)
665 do ia = 1, this%natoms
666 if (
present(mask))
then
667 if (.not. mask(ia)) cycle
669 dipole = dipole + this%charge(ia)*this%pos(:, ia)
671 dipole = p_proton_charge*dipole
678 class(
ions_t),
intent(inout) :: this
679 real(real64),
intent(in) :: xx(this%space%dim)
685 do iatom = 1, this%natoms
686 this%pos(:, iatom) = this%pos(:, iatom) - xx
694 class(
ions_t),
intent(inout) :: this
695 real(real64),
intent(in) :: from(this%space%dim)
696 real(real64),
intent(in) :: from2(this%space%dim)
697 real(real64),
intent(in) :: to(this%space%dim)
700 real(real64) :: m1(3, 3), m2(3, 3)
701 real(real64) :: m3(3, 3), f2(3), per(3)
702 real(real64) :: alpha, r
706 if (this%space%dim /= 3)
then
707 call messages_not_implemented(
"ions_rotate in other than 3 dimensions", namespace=this%namespace)
711 m1 = diagonal_matrix(3, m_one)
714 if (abs(to(2)) > 1d-150)
then
715 alpha =
atan2(to(2), to(1))
718 alpha =
atan2(norm2(to(1:2)), to(3))
719 call rotate(m1, -alpha, 2)
722 f2 = matmul(m1, from)
734 m2 = diagonal_matrix(3, m_one)
735 alpha =
atan2(per(1), per(2))
736 call rotate(m2, -alpha, 3)
739 m3 = diagonal_matrix(3, m_one)
740 alpha =
acos(min(sum(from*to), m_one))
741 call rotate(m3, -alpha, 2)
744 m2 = matmul(transpose(m2), matmul(m3, m2))
747 per = matmul(m2, matmul(m1, from2))
749 call rotate(m2, -alpha, 3)
752 m1 = matmul(transpose(m1), matmul(m2, m1))
756 do iatom = 1, this%natoms
757 f2 = this%pos(:, iatom)
758 this%pos(:, iatom) = matmul(m1, f2)
765 subroutine rotate(m, angle, dir)
766 real(real64),
intent(inout) :: m(3, 3)
767 real(real64),
intent(in) :: angle
768 integer,
intent(in) :: dir
770 real(real64) :: aux(3, 3), ca, sa
808 class(
ions_t),
intent(in) :: this
809 real(real64),
intent(in) :: time
810 real(real64) :: force(this%space%dim)
816 if (this%apply_global_force)
then
817 force(1) = units_to_atomic(units_inp%force, tdf(this%global_force_function, time))
824 subroutine ions_write_xyz(this, fname, append, comment, reduce_coordinates)
825 class(
ions_t),
intent(in) :: this
826 character(len=*),
intent(in) :: fname
827 logical,
optional,
intent(in) :: append
828 character(len=*),
optional,
intent(in) :: comment
829 logical,
optional,
intent(in) :: reduce_coordinates
831 integer :: iatom, idim, iunit
832 character(len=6) position
833 character(len=19) :: frmt
834 real(real64) :: red(this%space%dim)
836 if (.not. mpi_grp_is_root(mpi_world))
return
841 if (
present(append))
then
842 if (append) position =
'append'
844 if(.not.optional_default(reduce_coordinates, .false.))
then
845 iunit = io_open(trim(fname)//
'.xyz', this%namespace, action=
'write', position=position)
847 iunit = io_open(trim(fname)//
'.xyz_red', this%namespace, action=
'write', position=position)
850 write(iunit,
'(i4)') this%natoms
851 if (
present(comment))
then
852 write(iunit,
'(1x,a)') comment
854 write(iunit,
'(1x,a,a)')
'units: ', trim(units_abbrev(units_out%length_xyz_file))
857 write(unit=frmt, fmt=
"(a5,i2.2,a4,i2.2,a6)")
"(6x,a", label_len,
",2x,", this%space%dim,
"f12.6)"
858 do iatom = 1, this%natoms
859 if(.not.optional_default(reduce_coordinates, .false.))
then
860 write(unit=iunit, fmt=frmt) this%atom(iatom)%label, &
861 (units_from_atomic(units_out%length_xyz_file, this%pos(idim, iatom)), idim=1, this%space%dim)
863 red = this%latt%cart_to_red(this%pos(:, iatom))
864 write(unit=iunit, fmt=frmt) this%atom(iatom)%label, (red(idim), idim=1, this%space%dim)
874 class(
ions_t),
intent(inout) :: this
875 character(len=*),
intent(in) :: fname
876 character(len=*),
optional,
intent(in) :: comment
878 integer :: iatom, idir, iunit
879 character(len=19) :: frmt, dum
880 real(real64) :: tmp(this%space%dim)
884 iunit = io_open(trim(fname)//
'.xyz', this%namespace, action=
'read', position=
'rewind')
886 read(iunit,
'(i4)') this%natoms
887 if (
present(comment))
then
892 write(unit=frmt, fmt=
"(a5,i2.2,a4,i2.2,a6)")
"(6x,a", label_len,
",2x,", this%space%dim,
"f12.6)"
893 do iatom = 1, this%natoms
894 read(unit=iunit, fmt=frmt) dum, (tmp(idir), idir=1, this%space%dim)
896 this%pos(:, iatom) = units_to_atomic(units_out%length_xyz_file, tmp)
907 class(
ions_t),
intent(in) :: this
908 character(len=*),
intent(in) :: dir
910 type(lattice_iterator_t) :: latt_iter
911 real(real64) :: radius, pos(this%space%dim)
912 integer :: iatom, icopy, iunit
916 radius = maxval(m_half*norm2(this%latt%rlattice(:,1:this%space%periodic_dim), dim=1))*(m_one + m_epsilon)
917 latt_iter = lattice_iterator_t(this%latt, radius)
919 if (mpi_grp_is_root(mpi_world))
then
921 iunit = io_open(trim(dir)//
'/crystal.xyz', this%namespace, action=
'write')
923 write(iunit,
'(i9)') this%natoms*latt_iter%n_cells
924 write(iunit,
'(a)')
'#generated by Octopus'
926 do iatom = 1, this%natoms
927 do icopy = 1, latt_iter%n_cells
928 pos = units_from_atomic(units_out%length, this%pos(:, iatom) + latt_iter%get(icopy))
929 write(iunit,
'(a, 99f12.6)') this%atom(iatom)%label, pos
941 class(
ions_t),
intent(in) :: this
942 character(len=*),
intent(in) :: dir, fname
944 integer :: iunit, iatom, idir
945 real(real64) :: force(this%space%dim), center(this%space%dim)
946 character(len=20) frmt
948 if (.not. mpi_grp_is_root(mpi_world))
return
952 call io_mkdir(dir, this%namespace)
953 iunit = io_open(trim(dir)//
'/'//trim(fname)//
'.bild', this%namespace, action=
'write', &
956 write(frmt,
'(a,i0,a)')
'(a,2(', this%space%dim,
'f16.6,1x))'
958 write(iunit,
'(a)')
'.comment : force vectors in ['//trim(units_abbrev(units_out%force))//
']'
960 write(iunit,
'(a)')
'.color red'
962 do iatom = 1, this%natoms
963 center = units_from_atomic(units_out%length, this%pos(:, iatom))
964 force = units_from_atomic(units_out%force, this%tot_force(:, iatom))
965 write(iunit,
'(a,1x,i4,1x,a2,1x,a6,1x,f10.6,a)')
'.comment :', iatom, trim(this%atom(iatom)%label), &
966 'force:', norm2(force),
'['//trim(units_abbrev(units_out%force))//
']'
967 write(iunit,fmt=trim(frmt))
'.arrow', (center(idir), idir = 1, this%space%dim), &
968 (center(idir) + force(idir), idir = 1, this%space%dim)
979 class(
ions_t),
intent(in) :: this
980 character(len=*),
intent(in) :: filename
981 logical,
optional,
intent(in) :: ascii
983 integer :: iunit, iatom, ierr
985 real(real64),
allocatable :: data(:, :)
986 integer,
allocatable :: idata(:, :)
987 character(len=MAX_PATH_LEN) :: fullname
991 assert(this%space%dim == 3)
993 ascii_ = optional_default(ascii, .
true.)
995 fullname = trim(filename)//
".vtk"
997 iunit = io_open(trim(fullname), this%namespace, action=
'write')
999 write(iunit,
'(1a)')
'# vtk DataFile Version 3.0 '
1000 write(iunit,
'(6a)')
'Generated by octopus ', trim(conf%version),
' - git: ', &
1001 trim(conf%git_commit),
" configuration: ", trim(conf%config_time)
1004 write(iunit,
'(1a)')
'ASCII'
1006 write(iunit,
'(1a)')
'BINARY'
1009 write(iunit,
'(1a)')
'DATASET POLYDATA'
1011 write(iunit,
'(a,i9,a)')
'POINTS ', this%natoms,
' double'
1014 do iatom = 1, this%natoms
1015 write(iunit,
'(3f12.6)') this%pos(1:3, iatom)
1018 call io_close(iunit)
1019 safe_allocate(
data(1:3, 1:this%natoms))
1020 do iatom = 1, this%natoms
1021 data(1:3, iatom) = this%pos(1:3, iatom)
1023 call io_binary_write(io_workpath(fullname, this%namespace), i4_to_i8(3*this%natoms),
data, &
1024 ierr, nohead = .
true., fendian = io_binary_is_little_endian())
1025 safe_deallocate_a(data)
1026 iunit = io_open(trim(fullname), this%namespace, action=
'write', position =
'append')
1027 write(iunit,
'(1a)')
''
1030 write(iunit,
'(a,2i9)')
'VERTICES ', this%natoms, 2*this%natoms
1033 do iatom = 1, this%natoms
1034 write(iunit,
'(2i9)') 1, iatom - 1
1037 call io_close(iunit)
1038 safe_allocate(idata(1:2, 1:this%natoms))
1039 do iatom = 1, this%natoms
1041 idata(2, iatom) = iatom - 1
1043 call io_binary_write(io_workpath(fullname, this%namespace), i4_to_i8(2*this%natoms), idata, &
1044 ierr, nohead = .
true., fendian = io_binary_is_little_endian())
1045 safe_deallocate_a(idata)
1046 iunit = io_open(trim(fullname), this%namespace, action=
'write', position =
'append')
1047 write(iunit,
'(1a)')
''
1050 write(iunit,
'(a,i9)')
'POINT_DATA', this%natoms
1051 write(iunit,
'(a)')
'SCALARS element integer'
1052 write(iunit,
'(a)')
'LOOKUP_TABLE default'
1055 do iatom = 1, this%natoms
1056 write(iunit,
'(i9)') nint(this%atom(iatom)%species%get_z())
1059 call io_close(iunit)
1061 safe_allocate(idata(1:this%natoms, 1))
1063 do iatom = 1, this%natoms
1064 idata(iatom, 1) = nint(this%atom(iatom)%species%get_z())
1067 call io_binary_write(io_workpath(fullname, this%namespace), i4_to_i8(this%natoms), idata, &
1068 ierr, nohead = .
true., fendian = io_binary_is_little_endian())
1070 safe_deallocate_a(idata)
1072 iunit = io_open(trim(fullname), this%namespace, action=
'write', position =
'append')
1073 write(iunit,
'(1a)')
''
1076 call io_close(iunit)
1083 type(
ions_t),
intent(inout) :: ions
1089 call distributed_end(ions%atoms_dist)
1091 call ion_interaction_end(ions%ion_interaction)
1093 safe_deallocate_a(ions%atom)
1096 if(
allocated(ions%species))
then
1097 do i = 1, ions%nspecies
1099 if(
associated(ions%species(i)%s))
deallocate(ions%species(i)%s)
1101 deallocate(ions%species)
1105 call charged_particles_end(ions)
1107 safe_deallocate_a(ions%map_symm_atoms)
1108 safe_deallocate_a(ions%inv_map_symm_atoms)
1118 class(
ions_t),
intent(inout) :: ions
1119 type(lattice_vectors_t),
intent(in) :: latt
1120 logical,
intent(in) :: symmetrize
1125 call ions%latt%update(latt%rlattice)
1128 if (symmetrize)
then
1129 call symmetries_update_lattice_vectors(ions%symm, latt, ions%space%dim)
1142 class(
ions_t),
intent(inout) :: ions
1144 integer :: iatom, iop, iatom_symm, dim4symms
1145 real(real64) :: ratom(ions%space%dim)
1149 safe_allocate(ions%map_symm_atoms(1:ions%natoms, 1:ions%symm%nops + ions%symm%nops_nonsymmorphic))
1150 safe_allocate(ions%inv_map_symm_atoms(1:ions%natoms, 1:ions%symm%nops + ions%symm%nops_nonsymmorphic))
1153 dim4symms = min(3, ions%space%dim)
1156 do iop = 1, ions%symm%nops
1157 do iatom = 1, ions%natoms
1159 ratom(1:dim4symms) = symm_op_apply_inv_cart(ions%symm%ops(iop), ions%pos(:, iatom))
1161 ratom(:) = ions%latt%fold_into_cell(ratom(:))
1164 do iatom_symm = 1, ions%natoms
1165 if (all(abs(ratom(:) - ions%pos(:, iatom_symm)) < symprec))
exit
1168 if (iatom_symm > ions%natoms)
then
1169 write(message(1),
'(a,i6)')
'Internal error: could not find symmetric partner for atom number', iatom
1170 write(message(2),
'(a,i3,a)')
'with symmetry operation number ', iop,
'.'
1171 call messages_fatal(2, namespace=ions%namespace)
1174 ions%map_symm_atoms(iatom, iop) = iatom_symm
1175 ions%inv_map_symm_atoms(iatom_symm, iop) = iatom
1180 do iop = 1, ions%symm%nops_nonsymmorphic
1181 do iatom = 1, ions%natoms
1183 ratom(1:dim4symms) = symm_op_apply_inv_cart(ions%symm%non_symmorphic_ops(iop), ions%pos(:, iatom))
1185 ratom(:) = ions%latt%fold_into_cell(ratom(:))
1188 do iatom_symm = 1, ions%natoms
1189 if (all(abs(ratom(:) - ions%pos(:, iatom_symm)) < symprec))
exit
1192 if (iatom_symm > ions%natoms)
then
1193 write(message(1),
'(a,i6)')
'Internal error: could not find symmetric partner for atom number', iatom
1194 write(message(2),
'(a,i3,a)')
'with symmetry operation number ', iop,
'.'
1195 call messages_fatal(2, namespace=ions%namespace)
1198 ions%map_symm_atoms(iatom, ions%symm%nops+iop) = iatom_symm
1199 ions%inv_map_symm_atoms(iatom_symm, ions%symm%nops+iop) = iatom
1212 class(
ions_t),
intent(inout) :: ions
1214 integer :: iatom, iop, iatom_sym
1215 real(real64) :: ratom(ions%space%dim)
1216 real(real64),
allocatable :: new_pos(:,:)
1220 safe_allocate(new_pos(1:ions%space%dim, 1:ions%natoms))
1222 do iatom = 1, ions%natoms
1223 new_pos(:, iatom) = m_zero
1226 do iop = 1, ions%symm%nops
1227 iatom_sym = ions%inv_map_symm_atoms(iatom, iop)
1228 ratom = symm_op_apply_inv_cart(ions%symm%ops(iop), ions%pos(:, iatom_sym))
1229 ratom = ions%latt%fold_into_cell(ratom)
1230 new_pos(:, iatom) = new_pos(:, iatom) + ratom
1234 do iop = 1, ions%symm%nops_nonsymmorphic
1235 iatom_sym = ions%inv_map_symm_atoms(iatom, iop + ions%symm%nops)
1236 ratom = symm_op_apply_inv_cart(ions%symm%non_symmorphic_ops(iop), ions%pos(:, iatom_sym))
1237 ratom = ions%latt%fold_into_cell(ratom)
1238 new_pos(:, iatom) = new_pos(:, iatom) + ratom
1241 new_pos(:, iatom) = new_pos(:, iatom) / (ions%symm%nops + ions%symm%nops_nonsymmorphic)
1250 class(
ions_t),
intent(inout) :: ions
1252 type(spglibdataset) :: spg_dataset
1253 character(len=11) :: symbol =
""
1254 integer,
allocatable :: site_type(:)
1255 integer :: space_group, ia
1257 if(.not. ions%space%is_periodic())
return
1261 safe_allocate(site_type(1:ions%natoms))
1262 do ia = 1, ions%natoms
1263 site_type(ia) = ions%atom(ia)%species%get_index()
1266 spg_dataset = symmetries_get_spg_dataset(ions%namespace, ions%space, ions%latt, ions%natoms, ions%pos, site_type)
1268 safe_deallocate_a(site_type)
1270 if (spg_dataset%spglib_error /= 0)
then
1275 space_group = spg_dataset%spacegroup_number
1276 symbol = spg_dataset%international_symbol
1278 write(message(1),
'(a, i4)')
'Info: Space group No. ', space_group
1279 write(message(2),
'(2a)')
'Info: International: ', trim(symbol)
1280 call messages_info(2, namespace=ions%namespace)
double acos(double __x) __attribute__((__nothrow__
double sin(double __x) __attribute__((__nothrow__
double cos(double __x) __attribute__((__nothrow__
double atan2(double __y, double __x) __attribute__((__nothrow__
double floor(double __x) __attribute__((__nothrow__
subroutine rotate(m, angle, dir)
pure character(len=len_trim(adjustl(this%label))) function, public atom_get_label(this)
subroutine, public atom_init(this, dim, label, species)
subroutine, public atom_get_species(this, species)
subroutine, public atom_set_species(this, species)
This module handles the calculation mode.
integer, parameter, public p_strategy_states
parallelization in states
subroutine, public charged_particles_copy(this, cp_in)
subroutine, public charged_particles_init_interaction_as_partner(partner, interaction)
subroutine, public charged_particles_update_quantity(this, label)
subroutine, public charged_particles_init_interaction(this, interaction)
subroutine, public charged_particles_copy_quantities_to_interaction(partner, interaction)
subroutine, public charged_particles_init(this, np)
The init routine is a module level procedure This has the advantage that different classes can have d...
subroutine, public distributed_nullify(this, total)
subroutine, public distributed_init(this, total, comm, tag, scalapack_compat)
Distribute N instances across M processes of communicator comm
subroutine, public distributed_copy(in, out)
@Brief Create a copy of a distributed instance
real(real64), parameter, public m_huge
character(len= *), parameter, public static_dir
real(real64), parameter, public m_half
real(real64), parameter, public m_one
This module defines the abstract interaction_t class, and some auxiliary classes for interactions.
subroutine, public io_mkdir(fname, namespace, parents)
subroutine, public ion_interaction_init_parallelization(this, natoms, mc)
subroutine, public ion_interaction_init(this, namespace, space, natoms)
subroutine ions_init_interaction(this, interaction)
subroutine ions_update_lattice_vectors(ions, latt, symmetrize)
Regenerate the ions information after update of the lattice vectors.
class(ions_t) function, pointer ions_constructor(namespace, print_info, latt_inp)
subroutine ions_fold_atoms_into_cell(this)
real(real64) function, dimension(this%space%dim) ions_global_force(this, time)
subroutine ions_copy(ions_out, ions_in)
subroutine ions_update_quantity(this, label)
subroutine ions_generate_mapping_symmetric_atoms(ions)
Given the symmetries of the system, we create a mapping that tell us for each atom and symmetry,...
subroutine ions_write_xyz(this, fname, append, comment, reduce_coordinates)
subroutine ions_init_species(ions, factory, print_info)
subroutine ions_finalize(ions)
subroutine ions_initialize(this)
subroutine ions_read_xyz(this, fname, comment)
subroutine ions_write_vtk_geometry(this, filename, ascii)
subroutine ions_rotate(this, from, from2, to)
subroutine ions_translate(this, xx)
subroutine ions_symmetrize_atomic_coord(ions)
Symmetrizes atomic coordinates by applying all symmetries.
subroutine ions_print_spacegroup(ions)
Prints the spacegroup of the system for periodic systems.
real(real64) function ions_min_distance(this, real_atoms_only)
real(real64) function, dimension(this%space%dim) ions_dipole(this, mask)
subroutine ions_write_bild_forces_file(this, dir, fname)
subroutine ions_write_crystal(this, dir)
This subroutine creates a crystal by replicating the geometry and writes the result to dir.
logical function ions_has_time_dependent_species(this)
subroutine ions_partition(this, mc)
subroutine ions_init_interaction_as_partner(partner, interaction)
subroutine ions_copy_quantities_to_interaction(partner, interaction)
real(real64) function ions_val_charge(this, mask)
This module is intended to contain "only mathematical" functions and procedures.
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
character(len=512), private msg
subroutine, public messages_warning(no_lines, all_nodes, namespace)
subroutine, public messages_obsolete_variable(namespace, name, rep)
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
subroutine, public messages_input_error(namespace, var, details, row, column)
subroutine, public messages_experimental(name, namespace)
This module handles the communicators for the various parallelization strategies.
logical function, public parse_is_defined(namespace, name)
integer, parameter, public read_coords_reduced
subroutine, public read_coords_init(gf)
integer, parameter, public xyz_flags_move
subroutine, public read_coords_end(gf)
subroutine, public read_coords_read(what, gf, space, namespace)
subroutine, public species_factory_init(factory, namespace)
subroutine, public species_factory_end(factory)
subroutine, public tdf_read(f, namespace, function_name, ierr)
This function initializes "f" from the TDFunctions block.
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
character(len=20) pure function, public units_abbrev(this)
This module defines the unit system, used for input and output.
type(unit_system_t), public units_out
abstract interaction class
surrogate interaction class to avoid circular dependencies between modules.
Stores all communicators and groups.
An abstract class for species. Derived classes include jellium, all electron, and pseudopotential spe...