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 spec_user_defined = .false.
414 do i = 1,ions%nspecies
415 select type(spec=>ions%species(i)%s)
417 spec_user_defined = .
true.
420 if (ions%species_time_dependent .and. .not. spec_user_defined)
then
425 do i = 1, ions%natoms
426 do j = 1, ions%nspecies
439 class(
ions_t),
intent(out) :: ions_out
440 class(
ions_t),
intent(in) :: ions_in
446 ions_out%latt = ions_in%latt
448 ions_out%natoms = ions_in%natoms
449 safe_allocate(ions_out%atom(1:ions_out%natoms))
450 ions_out%atom = ions_in%atom
452 ions_out%nspecies = ions_in%nspecies
453 allocate(ions_out%species(1:ions_out%nspecies))
454 ions_out%species = ions_in%species
456 ions_out%only_user_def = ions_in%only_user_def
460 safe_allocate(ions_out%map_symm_atoms(1:ions_in%natoms, 1:ions_in%symm%nops + ions_in%symm%nops_nonsymmorphic))
461 ions_out%map_symm_atoms = ions_in%map_symm_atoms
462 safe_allocate(ions_out%inv_map_symm_atoms(1:ions_in%natoms, 1:ions_in%symm%nops + ions_in%symm%nops_nonsymmorphic))
463 ions_out%inv_map_symm_atoms = ions_in%inv_map_symm_atoms
471 class(
ions_t),
intent(inout) :: this
485 class(
ions_t),
target,
intent(inout) :: this
490 select type (interaction)
500 class(
ions_t),
intent(inout) :: this
509 class(
ions_t),
intent(inout) :: this
510 character(len=*),
intent(in) :: label
525 class(
ions_t),
intent(in) :: partner
530 select type (interaction)
540 class(
ions_t),
intent(inout) :: partner
545 select type (interaction)
556 class(
ions_t),
intent(inout) :: this
562 do iatom = 1, this%natoms
563 this%pos(:, iatom) = this%latt%fold_into_cell(this%pos(:, iatom))
570 real(real64) function ions_min_distance(this, real_atoms_only) result(rmin)
571 class(
ions_t),
intent(in) :: this
572 logical,
optional,
intent(in) :: real_atoms_only
574 integer :: iatom, jatom, idir
575 real(real64) :: xx(this%space%dim)
576 logical :: real_atoms_only_
579 if (this%natoms == 1 .and. .not. this%space%is_periodic())
then
584 push_sub(ions_min_distance)
589 do iatom = 1, this%natoms
593 if (real_atoms_only_) cycle
595 do jatom = iatom + 1, this%natoms
599 if (real_atoms_only_) cycle
601 xx = abs(this%pos(:, iatom) - this%pos(:, jatom))
602 if (this%space%is_periodic())
then
603 xx = this%latt%cart_to_red(xx)
604 do idir = 1, this%space%periodic_dim
607 xx = this%latt%red_to_cart(xx)
609 rmin = min(norm2(xx), rmin)
613 if (.not. (this%only_user_def .and. real_atoms_only_))
then
615 do idir = 1, this%space%periodic_dim
616 rmin = min(rmin, norm2(this%latt%rlattice(:,idir)))
621 if(rmin < huge(rmin)/1e6_real64)
then
622 rmin = anint(rmin*1e6_real64)*1.0e-6_real64
625 pop_sub(ions_min_distance)
630 class(
ions_t),
intent(in) :: this
634 time_dependent = this%species_time_dependent
640 real(real64) function ions_val_charge(this, mask) result(val_charge)
641 class(
ions_t),
intent(in) :: this
642 logical,
optional,
intent(in) :: mask(:)
646 if (
present(mask))
then
647 val_charge = -sum(this%charge, mask=mask)
649 val_charge = -sum(this%charge)
657 class(
ions_t),
intent(in) :: this
658 logical,
optional,
intent(in) :: mask(:)
659 real(real64) :: dipole(this%space%dim)
666 do ia = 1, this%natoms
667 if (
present(mask))
then
668 if (.not. mask(ia)) cycle
670 dipole = dipole + this%charge(ia)*this%pos(:, ia)
672 dipole = p_proton_charge*dipole
679 class(
ions_t),
intent(inout) :: this
680 real(real64),
intent(in) :: xx(this%space%dim)
686 do iatom = 1, this%natoms
687 this%pos(:, iatom) = this%pos(:, iatom) - xx
695 class(
ions_t),
intent(inout) :: this
696 real(real64),
intent(in) :: from(this%space%dim)
697 real(real64),
intent(in) :: from2(this%space%dim)
698 real(real64),
intent(in) :: to(this%space%dim)
701 real(real64) :: m1(3, 3), m2(3, 3)
702 real(real64) :: m3(3, 3), f2(3), per(3)
703 real(real64) :: alpha, r
707 if (this%space%dim /= 3)
then
708 call messages_not_implemented(
"ions_rotate in other than 3 dimensions", namespace=this%namespace)
712 m1 = diagonal_matrix(3, m_one)
715 if (abs(to(2)) > 1d-150)
then
716 alpha =
atan2(to(2), to(1))
719 alpha =
atan2(norm2(to(1:2)), to(3))
720 call rotate(m1, -alpha, 2)
723 f2 = matmul(m1, from)
735 m2 = diagonal_matrix(3, m_one)
736 alpha =
atan2(per(1), per(2))
737 call rotate(m2, -alpha, 3)
740 m3 = diagonal_matrix(3, m_one)
741 alpha =
acos(min(sum(from*to), m_one))
742 call rotate(m3, -alpha, 2)
745 m2 = matmul(transpose(m2), matmul(m3, m2))
748 per = matmul(m2, matmul(m1, from2))
750 call rotate(m2, -alpha, 3)
753 m1 = matmul(transpose(m1), matmul(m2, m1))
757 do iatom = 1, this%natoms
758 f2 = this%pos(:, iatom)
759 this%pos(:, iatom) = matmul(m1, f2)
766 subroutine rotate(m, angle, dir)
767 real(real64),
intent(inout) :: m(3, 3)
768 real(real64),
intent(in) :: angle
769 integer,
intent(in) :: dir
771 real(real64) :: aux(3, 3), ca, sa
809 class(
ions_t),
intent(in) :: this
810 real(real64),
intent(in) :: time
811 real(real64) :: force(this%space%dim)
817 if (this%apply_global_force)
then
818 force(1) = units_to_atomic(units_inp%force, tdf(this%global_force_function, time))
825 subroutine ions_write_xyz(this, fname, append, comment, reduce_coordinates)
826 class(
ions_t),
intent(in) :: this
827 character(len=*),
intent(in) :: fname
828 logical,
optional,
intent(in) :: append
829 character(len=*),
optional,
intent(in) :: comment
830 logical,
optional,
intent(in) :: reduce_coordinates
832 integer :: iatom, idim, iunit
833 character(len=6) position
834 character(len=19) :: frmt
835 real(real64) :: red(this%space%dim)
837 if (.not. mpi_grp_is_root(mpi_world))
return
842 if (
present(append))
then
843 if (append) position =
'append'
845 if(.not.optional_default(reduce_coordinates, .false.))
then
846 iunit = io_open(trim(fname)//
'.xyz', this%namespace, action=
'write', position=position)
848 iunit = io_open(trim(fname)//
'.xyz_red', this%namespace, action=
'write', position=position)
851 write(iunit,
'(i4)') this%natoms
852 if (
present(comment))
then
853 write(iunit,
'(1x,a)') comment
855 write(iunit,
'(1x,a,a)')
'units: ', trim(units_abbrev(units_out%length_xyz_file))
858 write(unit=frmt, fmt=
"(a5,i2.2,a4,i2.2,a6)")
"(6x,a", label_len,
",2x,", this%space%dim,
"f12.6)"
859 do iatom = 1, this%natoms
860 if(.not.optional_default(reduce_coordinates, .false.))
then
861 write(unit=iunit, fmt=frmt) this%atom(iatom)%label, &
862 (units_from_atomic(units_out%length_xyz_file, this%pos(idim, iatom)), idim=1, this%space%dim)
864 red = this%latt%cart_to_red(this%pos(:, iatom))
865 write(unit=iunit, fmt=frmt) this%atom(iatom)%label, (red(idim), idim=1, this%space%dim)
875 class(
ions_t),
intent(inout) :: this
876 character(len=*),
intent(in) :: fname
877 character(len=*),
optional,
intent(in) :: comment
879 integer :: iatom, idir, iunit
880 character(len=19) :: frmt, dum
881 real(real64) :: tmp(this%space%dim)
885 iunit = io_open(trim(fname)//
'.xyz', this%namespace, action=
'read', position=
'rewind')
887 read(iunit,
'(i4)') this%natoms
888 if (
present(comment))
then
893 write(unit=frmt, fmt=
"(a5,i2.2,a4,i2.2,a6)")
"(6x,a", label_len,
",2x,", this%space%dim,
"f12.6)"
894 do iatom = 1, this%natoms
895 read(unit=iunit, fmt=frmt) dum, (tmp(idir), idir=1, this%space%dim)
897 this%pos(:, iatom) = units_to_atomic(units_out%length_xyz_file, tmp)
908 class(
ions_t),
intent(in) :: this
909 character(len=*),
intent(in) :: dir
911 type(lattice_iterator_t) :: latt_iter
912 real(real64) :: radius, pos(this%space%dim)
913 integer :: iatom, icopy, iunit
917 radius = maxval(m_half*norm2(this%latt%rlattice(:,1:this%space%periodic_dim), dim=1))*(m_one + m_epsilon)
918 latt_iter = lattice_iterator_t(this%latt, radius)
920 if (mpi_grp_is_root(mpi_world))
then
922 iunit = io_open(trim(dir)//
'/crystal.xyz', this%namespace, action=
'write')
924 write(iunit,
'(i9)') this%natoms*latt_iter%n_cells
925 write(iunit,
'(a)')
'#generated by Octopus'
927 do iatom = 1, this%natoms
928 do icopy = 1, latt_iter%n_cells
929 pos = units_from_atomic(units_out%length, this%pos(:, iatom) + latt_iter%get(icopy))
930 write(iunit,
'(a, 99f12.6)') this%atom(iatom)%label, pos
942 class(
ions_t),
intent(in) :: this
943 character(len=*),
intent(in) :: dir, fname
945 integer :: iunit, iatom, idir
946 real(real64) :: force(this%space%dim), center(this%space%dim)
947 character(len=20) frmt
949 if (.not. mpi_grp_is_root(mpi_world))
return
953 call io_mkdir(dir, this%namespace)
954 iunit = io_open(trim(dir)//
'/'//trim(fname)//
'.bild', this%namespace, action=
'write', &
957 write(frmt,
'(a,i0,a)')
'(a,2(', this%space%dim,
'f16.6,1x))'
959 write(iunit,
'(a)')
'.comment : force vectors in ['//trim(units_abbrev(units_out%force))//
']'
961 write(iunit,
'(a)')
'.color red'
963 do iatom = 1, this%natoms
964 center = units_from_atomic(units_out%length, this%pos(:, iatom))
965 force = units_from_atomic(units_out%force, this%tot_force(:, iatom))
966 write(iunit,
'(a,1x,i4,1x,a2,1x,a6,1x,f10.6,a)')
'.comment :', iatom, trim(this%atom(iatom)%label), &
967 'force:', norm2(force),
'['//trim(units_abbrev(units_out%force))//
']'
968 write(iunit,fmt=trim(frmt))
'.arrow', (center(idir), idir = 1, this%space%dim), &
969 (center(idir) + force(idir), idir = 1, this%space%dim)
980 class(
ions_t),
intent(in) :: this
981 character(len=*),
intent(in) :: filename
982 logical,
optional,
intent(in) :: ascii
984 integer :: iunit, iatom, ierr
986 real(real64),
allocatable :: data(:, :)
987 integer,
allocatable :: idata(:, :)
988 character(len=MAX_PATH_LEN) :: fullname
992 assert(this%space%dim == 3)
994 ascii_ = optional_default(ascii, .
true.)
996 fullname = trim(filename)//
".vtk"
998 iunit = io_open(trim(fullname), this%namespace, action=
'write')
1000 write(iunit,
'(1a)')
'# vtk DataFile Version 3.0 '
1001 write(iunit,
'(6a)')
'Generated by octopus ', trim(conf%version),
' - git: ', &
1002 trim(conf%git_commit),
" configuration: ", trim(conf%config_time)
1005 write(iunit,
'(1a)')
'ASCII'
1007 write(iunit,
'(1a)')
'BINARY'
1010 write(iunit,
'(1a)')
'DATASET POLYDATA'
1012 write(iunit,
'(a,i9,a)')
'POINTS ', this%natoms,
' double'
1015 do iatom = 1, this%natoms
1016 write(iunit,
'(3f12.6)') this%pos(1:3, iatom)
1019 call io_close(iunit)
1020 safe_allocate(
data(1:3, 1:this%natoms))
1021 do iatom = 1, this%natoms
1022 data(1:3, iatom) = this%pos(1:3, iatom)
1024 call io_binary_write(io_workpath(fullname, this%namespace), i4_to_i8(3*this%natoms),
data, &
1025 ierr, nohead = .
true., fendian = io_binary_is_little_endian())
1026 safe_deallocate_a(data)
1027 iunit = io_open(trim(fullname), this%namespace, action=
'write', position =
'append')
1028 write(iunit,
'(1a)')
''
1031 write(iunit,
'(a,2i9)')
'VERTICES ', this%natoms, 2*this%natoms
1034 do iatom = 1, this%natoms
1035 write(iunit,
'(2i9)') 1, iatom - 1
1038 call io_close(iunit)
1039 safe_allocate(idata(1:2, 1:this%natoms))
1040 do iatom = 1, this%natoms
1042 idata(2, iatom) = iatom - 1
1044 call io_binary_write(io_workpath(fullname, this%namespace), i4_to_i8(2*this%natoms), idata, &
1045 ierr, nohead = .
true., fendian = io_binary_is_little_endian())
1046 safe_deallocate_a(idata)
1047 iunit = io_open(trim(fullname), this%namespace, action=
'write', position =
'append')
1048 write(iunit,
'(1a)')
''
1051 write(iunit,
'(a,i9)')
'POINT_DATA', this%natoms
1052 write(iunit,
'(a)')
'SCALARS element integer'
1053 write(iunit,
'(a)')
'LOOKUP_TABLE default'
1056 do iatom = 1, this%natoms
1057 write(iunit,
'(i9)') nint(this%atom(iatom)%species%get_z())
1060 call io_close(iunit)
1062 safe_allocate(idata(1:this%natoms, 1))
1064 do iatom = 1, this%natoms
1065 idata(iatom, 1) = nint(this%atom(iatom)%species%get_z())
1068 call io_binary_write(io_workpath(fullname, this%namespace), i4_to_i8(this%natoms), idata, &
1069 ierr, nohead = .
true., fendian = io_binary_is_little_endian())
1071 safe_deallocate_a(idata)
1073 iunit = io_open(trim(fullname), this%namespace, action=
'write', position =
'append')
1074 write(iunit,
'(1a)')
''
1077 call io_close(iunit)
1084 type(
ions_t),
intent(inout) :: ions
1090 call distributed_end(ions%atoms_dist)
1092 call ion_interaction_end(ions%ion_interaction)
1094 safe_deallocate_a(ions%atom)
1097 if(
allocated(ions%species))
then
1098 do i = 1, ions%nspecies
1100 if(
associated(ions%species(i)%s))
deallocate(ions%species(i)%s)
1102 deallocate(ions%species)
1106 call charged_particles_end(ions)
1108 safe_deallocate_a(ions%map_symm_atoms)
1109 safe_deallocate_a(ions%inv_map_symm_atoms)
1119 class(
ions_t),
intent(inout) :: ions
1120 type(lattice_vectors_t),
intent(in) :: latt
1121 logical,
intent(in) :: symmetrize
1126 call ions%latt%update(latt%rlattice)
1129 if (symmetrize)
then
1130 call symmetries_update_lattice_vectors(ions%symm, latt, ions%space%dim)
1143 class(
ions_t),
intent(inout) :: ions
1145 integer :: iatom, iop, iatom_symm, dim4symms
1146 real(real64) :: ratom(ions%space%dim)
1150 safe_allocate(ions%map_symm_atoms(1:ions%natoms, 1:ions%symm%nops + ions%symm%nops_nonsymmorphic))
1151 safe_allocate(ions%inv_map_symm_atoms(1:ions%natoms, 1:ions%symm%nops + ions%symm%nops_nonsymmorphic))
1154 dim4symms = min(3, ions%space%dim)
1157 do iop = 1, ions%symm%nops
1158 do iatom = 1, ions%natoms
1160 ratom(1:dim4symms) = symm_op_apply_inv_cart(ions%symm%ops(iop), ions%pos(:, iatom))
1162 ratom(:) = ions%latt%fold_into_cell(ratom(:))
1165 do iatom_symm = 1, ions%natoms
1166 if (all(abs(ratom(:) - ions%pos(:, iatom_symm)) < symprec))
exit
1169 if (iatom_symm > ions%natoms)
then
1170 write(message(1),
'(a,i6)')
'Internal error: could not find symmetric partner for atom number', iatom
1171 write(message(2),
'(a,i3,a)')
'with symmetry operation number ', iop,
'.'
1172 call messages_fatal(2, namespace=ions%namespace)
1175 ions%map_symm_atoms(iatom, iop) = iatom_symm
1176 ions%inv_map_symm_atoms(iatom_symm, iop) = iatom
1181 do iop = 1, ions%symm%nops_nonsymmorphic
1182 do iatom = 1, ions%natoms
1184 ratom(1:dim4symms) = symm_op_apply_inv_cart(ions%symm%non_symmorphic_ops(iop), ions%pos(:, iatom))
1186 ratom(:) = ions%latt%fold_into_cell(ratom(:))
1189 do iatom_symm = 1, ions%natoms
1190 if (all(abs(ratom(:) - ions%pos(:, iatom_symm)) < symprec))
exit
1193 if (iatom_symm > ions%natoms)
then
1194 write(message(1),
'(a,i6)')
'Internal error: could not find symmetric partner for atom number', iatom
1195 write(message(2),
'(a,i3,a)')
'with symmetry operation number ', iop,
'.'
1196 call messages_fatal(2, namespace=ions%namespace)
1199 ions%map_symm_atoms(iatom, ions%symm%nops+iop) = iatom_symm
1200 ions%inv_map_symm_atoms(iatom_symm, ions%symm%nops+iop) = iatom
1213 class(
ions_t),
intent(inout) :: ions
1215 integer :: iatom, iop, iatom_sym
1216 real(real64) :: ratom(ions%space%dim)
1217 real(real64),
allocatable :: new_pos(:,:)
1221 safe_allocate(new_pos(1:ions%space%dim, 1:ions%natoms))
1223 do iatom = 1, ions%natoms
1224 new_pos(:, iatom) = m_zero
1227 do iop = 1, ions%symm%nops
1228 iatom_sym = ions%inv_map_symm_atoms(iatom, iop)
1229 ratom = symm_op_apply_inv_cart(ions%symm%ops(iop), ions%pos(:, iatom_sym))
1230 ratom = ions%latt%fold_into_cell(ratom)
1231 new_pos(:, iatom) = new_pos(:, iatom) + ratom
1235 do iop = 1, ions%symm%nops_nonsymmorphic
1236 iatom_sym = ions%inv_map_symm_atoms(iatom, iop + ions%symm%nops)
1237 ratom = symm_op_apply_inv_cart(ions%symm%non_symmorphic_ops(iop), ions%pos(:, iatom_sym))
1238 ratom = ions%latt%fold_into_cell(ratom)
1239 new_pos(:, iatom) = new_pos(:, iatom) + ratom
1242 new_pos(:, iatom) = new_pos(:, iatom) / (ions%symm%nops + ions%symm%nops_nonsymmorphic)
1252 class(
ions_t),
intent(inout) :: ions
1254 type(spglibdataset) :: spg_dataset
1255 character(len=11) :: symbol =
""
1256 integer,
allocatable :: site_type(:)
1257 integer :: space_group, ia
1259 if(.not. ions%space%is_periodic())
return
1263 safe_allocate(site_type(1:ions%natoms))
1264 do ia = 1, ions%natoms
1265 site_type(ia) = ions%atom(ia)%species%get_index()
1268 spg_dataset = symmetries_get_spg_dataset(ions%namespace, ions%space, ions%latt, ions%natoms, ions%pos, site_type)
1270 safe_deallocate_a(site_type)
1272 if (spg_dataset%spglib_error /= 0)
then
1277 space_group = spg_dataset%spacegroup_number
1278 symbol = spg_dataset%international_symbol
1280 write(message(1),
'(a, i4)')
'Info: Space group No. ', space_group
1281 write(message(2),
'(2a)')
'Info: International: ', trim(symbol)
1282 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...