35  use, 
intrinsic :: iso_fortran_env
 
   65    type(lattice_vectors_t) :: latt
 
   68    type(atom_t), 
allocatable :: atom(:)
 
   70    type(symmetries_t) :: symm
 
   72    type(distributed_t) :: atoms_dist
 
   74    integer, 
allocatable :: map_symm_atoms(:,:)
 
   75    integer, 
allocatable :: inv_map_symm_atoms(:,:)
 
   80    class(species_wrapper_t), 
allocatable  :: species(:)
 
   81    logical                                :: only_user_def
 
   82    logical,          
private              :: species_time_dependent
 
   84    logical                 :: force_total_enforce
 
   85    type(ion_interaction_t) :: ion_interaction
 
   88    logical,     
private :: apply_global_force
 
   89    type(tdf_t), 
private :: global_force_function
 
   92    generic   :: 
assignment(=) => copy
 
  119    procedure ions_constructor
 
  126    type(namespace_t),                 
intent(in)    :: namespace
 
  127    logical,                 
optional, 
intent(in)    :: print_info
 
  128    type(lattice_vectors_t), 
optional, 
intent(out)   :: latt_inp
 
  129    class(ions_t), 
pointer :: ions
 
  131    type(read_coords_info) :: xyz
 
  132    integer :: ia, ierr, idir
 
  133    character(len=100)  :: function_name
 
  134    real(real64) :: mindist
 
  135    real(real64), 
allocatable :: factor(:)
 
  136    integer, 
allocatable :: site_type(:)
 
  137    logical, 
allocatable :: spherical_site(:)
 
  138    real(real64), 
parameter :: threshold = 1e-5_real64
 
  139    type(species_factory_t) :: factory
 
  145    ions%namespace = namespace
 
  147    ions%space = 
space_t(namespace)
 
  158      message(1) = 
"Coordinates have not been defined." 
  167    safe_allocate(ions%atom(1:ions%natoms))
 
  168    do ia = 1, ions%natoms
 
  169      call atom_init(ions%atom(ia), ions%space%dim, xyz%atom(ia)%label)
 
  170      ions%pos(:,ia) = xyz%atom(ia)%x(1:ions%space%dim)
 
  172        ions%fixed(ia) = .not. xyz%atom(ia)%move
 
  176    if (
allocated(xyz%latvec)) 
then 
  186      do ia = 1, ions%natoms
 
  187        ions%pos(:, ia) = ions%latt%red_to_cart(ions%pos(:, ia))
 
  199    if (
present(latt_inp)) 
then 
  206    if (ions%space%has_mixed_periodicity()) 
then 
  207      safe_allocate(factor(ions%space%dim))
 
  208      do idir = 1, ions%space%periodic_dim
 
  211      do idir = ions%space%periodic_dim + 1, ions%space%dim
 
  212        factor(idir) = 
m_one/norm2(ions%latt%rlattice(1:ions%space%dim, idir))
 
  214      call ions%latt%scale(factor)
 
  215      safe_deallocate_a(factor)
 
  219    do ia = 1, ions%natoms
 
  220      ions%mass(ia) = ions%atom(ia)%species%get_mass()
 
  221      ions%charge(ia) = ions%atom(ia)%species%get_zval()
 
  225    if (ions%natoms > 1) 
then 
  227      if (mindist < threshold) 
then 
  228        write(
message(1), 
'(a)') 
"Some of the atoms seem to sit too close to each other." 
  229        write(
message(2), 
'(a)') 
"Please review your input files and the output geometry (in 'static/')." 
  230        write(
message(3), 
'(a, f12.6, 1x, a)') 
"Minimum distance = ", &
 
  236        call ions%write_xyz(trim(
static_dir)//
'/geometry')
 
  240        message(1) = 
"It cannot be correct to run with physical atoms so close." 
  246    safe_allocate(spherical_site(1:ions%natoms))
 
  247    safe_allocate(site_type(1:ions%natoms))
 
  248    do ia = 1, ions%natoms
 
  249      select type(spec => ions%atom(ia)%species)
 
  251        spherical_site(ia) = .false.
 
  253        spherical_site(ia) = .false.
 
  255        spherical_site(ia) = .false.
 
  257        spherical_site(ia) = .false.
 
  259        spherical_site(ia) = .
true.
 
  262      site_type(ia) = ions%atom(ia)%species%get_index()
 
  265    ions%symm = 
symmetries_t(ions%namespace, ions%space, ions%latt, ions%natoms, ions%pos, site_type, spherical_site)
 
  267    safe_deallocate_a(spherical_site)
 
  268    safe_deallocate_a(site_type)
 
  271    call ions%generate_mapping_symmetric_atoms()
 
  283    call parse_variable(namespace, 
'ForceTotalEnforce', .false., ions%force_total_enforce)
 
  299      ions%apply_global_force = .
true.
 
  301      call parse_variable(namespace, 
'TDGlobalForce', 
'none', function_name)
 
  302      call tdf_read(ions%global_force_function, namespace, trim(function_name), ierr)
 
  305        call messages_write(
"You have enabled the GlobalForce option but Octopus could not find")
 
  306        call messages_write(
"the '"//trim(function_name)//
"' function in the TDFunctions block.")
 
  312      ions%apply_global_force = .false.
 
  323    type(
ions_t),            
intent(inout) :: ions
 
  325    logical, 
optional,       
intent(in)    :: print_info
 
  327    logical :: print_info_, spec_user_defined
 
  328    integer :: i, j, k, ispin
 
  334    if (
present(print_info)) 
then 
  335      print_info_ = print_info
 
  339    atoms1:  
do i = 1, ions%natoms
 
  343      ions%nspecies = ions%nspecies + 1
 
  347    allocate(ions%species(1:ions%nspecies))
 
  351    ions%only_user_def = .
true.
 
  352    atoms2: 
do i = 1, ions%natoms
 
  357      ions%species(k)%s => factory%create_from_input(ions%namespace, 
atom_get_label(ions%atom(j)), k)
 
  359      select type(spec => ions%species(k)%s)
 
  363        ions%only_user_def = .false.
 
  366      select type(spec => ions%species(k)%s)
 
  368        if (ions%space%dim /= 3) 
then 
  369          message(1) = 
"Pseudopotentials may only be used with Dimensions = 3." 
  374        if (ions%space%is_periodic() .and. ions%space%periodic_dim /= 2) 
then 
  375          message(1) = 
"Periodic jelium slab can only be used if PeriodicDim = 2" 
  386    ispin = min(2, ispin)
 
  388    if (print_info_) 
then 
  391    do i = 1, ions%nspecies
 
  392      spec => ions%species(i)%s
 
  393      call spec%build(ions%namespace, ispin, ions%space%dim, print_info=print_info_)
 
  395    if (print_info_) 
then 
  408    call parse_variable(ions%namespace, 
'SpeciesTimeDependent', .false., ions%species_time_dependent)
 
  410    do i = 1,ions%nspecies
 
  411      select type(spec=>ions%species(i)%s)
 
  413        spec_user_defined = .
true.
 
  416    if (ions%species_time_dependent .and. .not. spec_user_defined) 
then 
  421    do i = 1, ions%natoms
 
  422      do j = 1, ions%nspecies
 
  435    class(
ions_t),     
intent(out) :: ions_out
 
  436    class(
ions_t),     
intent(in)  :: ions_in
 
  442    ions_out%latt = ions_in%latt
 
  444    ions_out%natoms = ions_in%natoms
 
  445    safe_allocate(ions_out%atom(1:ions_out%natoms))
 
  446    ions_out%atom = ions_in%atom
 
  448    ions_out%nspecies = ions_in%nspecies
 
  449    allocate(ions_out%species(1:ions_out%nspecies))
 
  450    ions_out%species = ions_in%species
 
  452    ions_out%only_user_def     = ions_in%only_user_def
 
  456    safe_allocate(ions_out%map_symm_atoms(1:ions_in%natoms, 1:ions_in%symm%nops))
 
  457    ions_out%map_symm_atoms = ions_in%map_symm_atoms
 
  458    safe_allocate(ions_out%inv_map_symm_atoms(1:ions_in%natoms, 1:ions_in%symm%nops))
 
  459    ions_out%inv_map_symm_atoms = ions_in%inv_map_symm_atoms
 
  467    class(
ions_t),               
intent(inout) :: this
 
  481    class(
ions_t),        
target, 
intent(inout) :: this
 
  486    select type (interaction)
 
  496    class(
ions_t), 
intent(inout) :: this
 
  505    class(
ions_t), 
intent(inout) :: this
 
  506    integer,       
intent(in)    :: iq
 
  511    assert(this%quantities(iq)%updated_on_demand)
 
  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))
 
 1150    safe_allocate(ions%inv_map_symm_atoms(1:ions%natoms, 1:ions%symm%nops))
 
 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
 
 1186    class(
ions_t),    
intent(inout) :: ions
 
 1188    integer :: iatom, iop, iatom_sym
 
 1189    real(real64) :: ratom(ions%space%dim)
 
 1190    real(real64), 
allocatable :: new_pos(:,:)
 
 1194    safe_allocate(new_pos(1:ions%space%dim, 1:ions%natoms))
 
 1196    do iatom = 1, ions%natoms
 
 1197      new_pos(:, iatom) = m_zero
 
 1198      do iop = 1, ions%symm%nops
 
 1199        iatom_sym = ions%inv_map_symm_atoms(iatom, iop)
 
 1200        ratom = symm_op_apply_inv_cart(ions%symm%ops(iop), ions%pos(:, iatom_sym))
 
 1201        ratom = ions%latt%fold_into_cell(ratom)
 
 1202        new_pos(:, iatom) = new_pos(:, iatom) + ratom
 
 1204      new_pos(:, iatom) = new_pos(:, iatom) / ions%symm%nops
 
 1208    safe_deallocate_a(new_pos)
 
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, iq)
 
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_initial_conditions(this)
 
subroutine ions_copy(ions_out, ions_in)
 
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_read_xyz(this, fname, comment)
 
subroutine ions_write_vtk_geometry(this, filename, ascii)
 
subroutine ions_update_quantity(this, iq)
 
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.
 
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...