(git:374b731)
Loading...
Searching...
No Matches
negf_vectors.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Routines to deal with vectors in 3-D real space.
10! **************************************************************************************************
11
13 USE kinds, ONLY: dp
17#include "./base/base_uses.f90"
18
19 IMPLICIT NONE
20 PRIVATE
21
22 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'negf_vectors'
23
25
26CONTAINS
27
28! **************************************************************************************************
29!> \brief compute direction vector of the given contact
30!> \param origin origin
31!> \param direction_vector direction vector
32!> \param origin_bias origin which will be used to apply the external bias
33!> (in contrast with 'origin' it does not include screening region)
34!> \param direction_vector_bias direction vector which will be used to apply the external bias
35!> (together with 'origin_bias' it defines a contact region where
36!> the external potential is kept constant)
37!> \param atomlist_screening atoms belonging to the contact's screening region
38!> \param atomlist_bulk atoms belonging to the contact's bulk region
39!> \param subsys QuickStep subsystem
40!> \author Sergey Chulkov
41! **************************************************************************************************
42 SUBROUTINE contact_direction_vector(origin, direction_vector, origin_bias, direction_vector_bias, &
43 atomlist_screening, atomlist_bulk, subsys)
44 REAL(kind=dp), DIMENSION(3), INTENT(out) :: origin, direction_vector, origin_bias, &
45 direction_vector_bias
46 INTEGER, DIMENSION(:), INTENT(in) :: atomlist_screening, atomlist_bulk
47 TYPE(qs_subsys_type), POINTER :: subsys
48
49 CHARACTER(LEN=*), PARAMETER :: routinen = 'contact_direction_vector'
50
51 INTEGER :: handle, iatom, natoms_bulk, &
52 natoms_screening, nparticles
53 REAL(kind=dp) :: proj, proj_max, proj_min, proj_min_bias
54 REAL(kind=dp), DIMENSION(3) :: vector
55 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
56
57 CALL timeset(routinen, handle)
58 CALL qs_subsys_get(subsys, particle_set=particle_set)
59
60 natoms_screening = SIZE(atomlist_screening)
61 natoms_bulk = SIZE(atomlist_bulk)
62 nparticles = SIZE(particle_set)
63
64 cpassert(natoms_screening > 0)
65 cpassert(natoms_bulk > 0)
66 cpassert(nparticles > 0)
67
68 ! geometrical centre of the first contact unit cell
69 origin = particle_set(atomlist_screening(1))%r
70 DO iatom = 2, natoms_screening
71 origin = origin + particle_set(atomlist_screening(iatom))%r
72 END DO
73 origin = origin/real(natoms_screening, kind=dp)
74
75 ! geometrical centre of the second contact unit cell
76 direction_vector = particle_set(atomlist_bulk(1))%r
77 DO iatom = 2, natoms_bulk
78 direction_vector = direction_vector + particle_set(atomlist_bulk(iatom))%r
79 END DO
80 direction_vector = direction_vector/real(natoms_bulk, kind=dp)
81
82 ! vector between the geometrical centers of the first and the second contact unit cells
83 direction_vector = direction_vector - origin
84
85 ! the point 'center_of_coords0' belongs to the first unit cell, so the lowest projection of any point
86 ! from the first unit cell on the direction vector 'center_of_coords1 - center_of_coords0' should be <= 0
87 proj_min = 0.0_dp
88 proj_min_bias = 0.0_dp
89 DO iatom = 1, natoms_screening
90 vector = particle_set(atomlist_screening(iatom))%r - origin
91 proj = projection_on_direction_vector(vector, direction_vector)
92
93 IF (proj < proj_min) proj_min = proj
94 IF (proj > proj_min_bias) proj_min_bias = proj
95 END DO
96
97 ! the point 'center_of_coords1' belongs to the given contact, so the highest projection should be >= 1
98 proj_max = 1.0_dp
99 DO iatom = 1, nparticles
100 vector = particle_set(iatom)%r - origin
101 proj = projection_on_direction_vector(vector, direction_vector)
102
103 IF (proj > proj_max) proj_max = proj
104 END DO
105
106 ! adjust the origin, so it lies on a plane between the given contact and the scattering region
107 origin_bias = origin + proj_min_bias*direction_vector
108 origin = origin + proj_min*direction_vector
109
110 ! rescale the vector, so the last atom of the given contact and the point 'origin + direction_vector' lie on
111 ! the same plane parallel to the 'origin' plane -- which separates the contact from the scattering region.
112 direction_vector_bias = (proj_max - proj_min_bias)*direction_vector
113 direction_vector = (proj_max - proj_min)*direction_vector
114
115 CALL timestop(handle)
116 END SUBROUTINE contact_direction_vector
117
118! **************************************************************************************************
119!> \brief project the 'vector' onto the direction 'vector0'. Both vectors should have the same origin.
120!> \param vector vector to project
121!> \param vector0 direction vector
122!> \return projection (in terms of the direction vector's length)
123!> \author Sergey Chulkov
124!> \note \parblock
125!> & vector
126!> /
127!> /
128!> /
129!> *---|------> vector0
130!> l = proj * | vector0 |
131!>\endparblock
132! **************************************************************************************************
133 PURE FUNCTION projection_on_direction_vector(vector, vector0) RESULT(proj)
134 REAL(kind=dp), DIMENSION(3), INTENT(in) :: vector, vector0
135 REAL(kind=dp) :: proj
136
137 REAL(kind=dp) :: len2, len2_v0, len2_v1
138 REAL(kind=dp), DIMENSION(3) :: vector1
139
140 vector1 = vector - vector0
141 len2 = dot_product(vector, vector)
142 len2_v0 = dot_product(vector0, vector0)
143 len2_v1 = dot_product(vector1, vector1)
144
145 proj = 0.5_dp*((len2 - len2_v1)/len2_v0 + 1.0_dp)
147END MODULE negf_vectors
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Routines to deal with vectors in 3-D real space.
pure real(kind=dp) function, public projection_on_direction_vector(vector, vector0)
project the 'vector' onto the direction 'vector0'. Both vectors should have the same origin.
subroutine, public contact_direction_vector(origin, direction_vector, origin_bias, direction_vector_bias, atomlist_screening, atomlist_bulk, subsys)
compute direction vector of the given contact
Define the data structure for the particle information.
types that represent a quickstep subsys
subroutine, public qs_subsys_get(subsys, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell, cell_ref, use_ref_cell, energy, force, qs_kind_set, cp_subsys, nelectron_total, nelectron_spin)
...