Octopus
atomic_orbital.F90
Go to the documentation of this file.
1!! Copyright (C) 2016 N. Tancogne-Dejean
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17
18#include "global.h"
19
25 use debug_oct_m
26 use global_oct_m
27 use, intrinsic :: iso_fortran_env
32 use math_oct_m
33 use mesh_oct_m
38 use ps_oct_m
40 use space_oct_m
45
46 implicit none
47
48 private
49
50 public :: &
60
61 character(len=1), parameter :: &
62 l_notation(0:3) = (/ 's', 'p', 'd', 'f' /)
63
64 integer, public, parameter :: MAX_L = 4
65
66contains
67
68 ! ---------------------------------------------------------
69 real(real64) function atomic_orbital_get_radius(species, mesh, iorb, ispin, truncation, threshold) result(radius)
70 class(species_t), intent(in) :: species
71 type(mesh_t), intent(in) :: mesh
72 integer, intent(in) :: iorb, ispin
73 integer(int64), intent(in) :: truncation
74 real(real64), intent(in) :: threshold
75
76 integer :: ii, ll, mm
77
78 push_sub(atomic_orbital_get_radius)
79
80 call species%get_iwf_ilm(iorb, ispin, ii, ll, mm)
81
82 if (truncation == option__aotruncation__ao_full) then
83 radius = species%get_iwf_radius(ii, ispin, threshold)
84 else
85 radius = species%get_iwf_radius(ii, ispin)
86
87 if (truncation == option__aotruncation__ao_box) then
88 ! if the orbital is larger than the size of the box, we restrict it to this size,
89 ! otherwise the orbital will overlap more than one time with the simulation box.
90 ! This would induces phase problem if the complete mesh is used instead of the sphere
91 radius = min(radius, minval(mesh%box%bounding_box_l(1:mesh%box%dim)-mesh%spacing(1:mesh%box%dim)*1.01_real64))
92 else
93 !If asked, we truncate the orbital to the radius on the projector spheres
94 !of the NL part of the pseudopotential.
95 !This is a way to garanty no overlap between orbitals of different atoms.
96 select type(species)
97 type is(pseudopotential_t)
98 radius = min(radius, species%get_radius())
99 end select
100 end if
101
102 end if
103 ! make sure that if the spacing is too large, the orbitals fit in a few points at least
104 radius = max(radius, m_two*maxval(mesh%spacing))
105
106 pop_sub(atomic_orbital_get_radius)
107 end function atomic_orbital_get_radius
108
109 ! ---------------------------------------------------------
111 subroutine atomic_orbital_init_submesh (namespace, space, latt, center, mesh, sm, radius)
112 type(namespace_t), intent(in) :: namespace
113 class(space_t), intent(in) :: space
114 type(lattice_vectors_t), intent(in) :: latt
115 real(real64), intent(in) :: center(:)
116 class(mesh_t), intent(in) :: mesh
117 type(submesh_t), intent(inout) :: sm
118 real(real64), intent(in) :: radius
119
121
122 if (sm%np == -1) then
123
124 select type (box => mesh%box)
125 type is (box_minimum_t)
126 if (radius > box%radius) then
127 message(1) = "The radius of an orbital set is bigger than the radius of the simulation box."
128 message(2) = "Increase the value of Radius or decrease the value of AOThreshold."
129 write(message(3),'(a,f8.5,a,i5,a)') 'The value of the radius is ', radius, ' Bohr.'
130 call messages_fatal(3, namespace=namespace)
131 end if
132
133 type is (box_sphere_t)
134 if (radius > box%radius) then
135 message(1) = "The radius of an orbital set is bigger than the radius of the simulation box."
136 message(2) = "Increase the value of Radius or decrease the value of AOThreshold."
137 write(message(3),'(a,f8.5,a,i5,a)') 'The value of the radius is ', radius, ' Bohr.'
138 call messages_fatal(3, namespace=namespace)
139 end if
140 if (norm2(center - box%center) + radius > box%radius) then
141 message(1) = "An orbital set has points outside of the simulation box."
142 message(2) = "Increase the value of Radius or decrease the value of AOThreshold."
143 write(message(3),'(a,f8.5,a,i5,a)') 'The value of the radius is ', radius, ' Bohr.'
144 call messages_fatal(3, namespace=namespace)
145 end if
146
147 type is (box_cylinder_t)
148 if (radius > box%radius) then
149 message(1) = "The radius of an orbital set is bigger than the radius of the simulation box."
150 message(2) = "Increase the value of Radius or decrease the value of AOThreshold."
151 write(message(3),'(a,f8.5,a,i5,a)') 'The value of the radius is ', radius, ' Bohr.'
152 call messages_fatal(3, namespace=namespace)
153 end if
154 if (radius > box%half_length) then
155 message(1) = "The radius of an orbital set is bigger than the length of the cylinder box."
156 message(2) = "Increase the value of XLength or decrease the value of AOThreshold."
157 write(message(3),'(a,f8.5,a,i5,a)') 'The value of the radius is ', radius, ' Bohr.'
158 call messages_fatal(3, namespace=namespace)
159 end if
160
161 if (norm2(center(2:mesh%box%dim) - box%center(2:mesh%box%dim)) + radius > box%radius) then
162 message(1) = "An orbital set has points outside of the simulation box."
163 message(2) = "Increase the value of Radius or decrease the value of AOThreshold."
164 write(message(3),'(a,f8.5,a,i5,a)') 'The value of the radius is ', radius, ' Bohr.'
165 call messages_fatal(3, namespace=namespace)
166 end if
167 if (abs(center(1) - box%center(1)) + radius > box%half_length) then
168 message(1) = "An orbital set has points outside of the simulation box."
169 message(2) = "Increase the value of Xlength or decrease the value of AOThreshold."
170 write(message(3),'(a,f8.5,a,i5,a)') 'The value of the radius is ', radius, ' Bohr.'
171 call messages_fatal(3, namespace=namespace)
172 end if
173
174 end select
175
176 !We initialise the submesh corresponding to the orbital
177 call submesh_init(sm, space, mesh, latt, center, radius)
178
179 end if
180
182
183 end subroutine atomic_orbital_init_submesh
184
185
186
187#include "undef.F90"
188#include "real.F90"
189#include "atomic_orbital_inc.F90"
190
191#include "undef.F90"
192#include "complex.F90"
193#include "atomic_orbital_inc.F90"
194
195end module atomic_orbital_oct_m
subroutine, public atomic_orbital_init_submesh(namespace, space, latt, center, mesh, sm, radius)
Initialize a submesh given a center and a radius.
subroutine, public zatomic_orbital_get_submesh_safe(species, submesh, ii, ll, mm, ispin, phi)
subroutine, public zget_atomic_orbital(namespace, space, latt, pos, species, mesh, sm, ii, ll, jj, os, orbind, radius, d_dim, use_mesh, normalize, index_shift)
This routine returns the atomic orbital basis – provided by the pseudopotential structure in geo.
character(len=1), dimension(0:3), parameter, public l_notation
real(real64) function, public atomic_orbital_get_radius(species, mesh, iorb, ispin, truncation, threshold)
subroutine, public dget_atomic_orbital(namespace, space, latt, pos, species, mesh, sm, ii, ll, jj, os, orbind, radius, d_dim, use_mesh, normalize, index_shift)
This routine returns the atomic orbital basis – provided by the pseudopotential structure in geo.
subroutine, public datomic_orbital_get_submesh(species, submesh, ii, ll, mm, ispin, phi, derivative)
subroutine, public datomic_orbital_get_submesh_safe(species, submesh, ii, ll, mm, ispin, phi)
subroutine, public zatomic_orbital_get_submesh(species, submesh, ii, ll, mm, ispin, phi, derivative)
real(real64), parameter, public m_two
Definition: global.F90:189
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:115
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
Definition: ps.F90:114