Octopus
target_classical.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
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
22 use debug_oct_m
23 use epot_oct_m
24 use global_oct_m
25 use grid_oct_m
27 use ions_oct_m
29 use, intrinsic :: iso_fortran_env
36 use parser_oct_m
39 use space_oct_m
41 use string_oct_m
42 use target_oct_m
43 use td_oct_m
44
45 implicit none
46
47 private
48 public :: target_classical_t
49
51 type, extends(target_t) :: target_classical_t
52 private
53 character(len=4096) :: classical_input_string
54 character(len=1024), allocatable :: mom_der_array(:,:)
55 character(len=1024), allocatable :: pos_der_array(:,:)
56 contains
57 procedure :: init => target_init_classical
58 procedure :: cleanup => target_end_classical
59 procedure :: j1 => target_j1_classical
60 procedure :: apply_chi => target_chi_classical
61 procedure :: output => target_output_classical
62 end type target_classical_t
63
64
65contains
66
67 ! ----------------------------------------------------------------------
69 subroutine target_init_classical(tg, gr, kpoints, namespace, space, ions, qcs, td, w0, oct, ep, restart)
70 class(target_classical_t), intent(inout) :: tg
71 type(grid_t), intent(in) :: gr
72 type(kpoints_t), intent(in) :: kpoints
73 type(namespace_t), intent(in) :: namespace
74 class(space_t), intent(in) :: space
75 type(ions_t), intent(in) :: ions
76 type(opt_control_state_t), intent(inout) :: qcs
77 type(td_t), intent(in) :: td
78 real(real64), intent(in) :: w0
79 type(oct_t), intent(in) :: oct
80 type(epot_t), intent(inout) :: ep
81 type(restart_t), intent(inout) :: restart
82
83 integer :: jj, ist, jst
84 type(block_t) :: blk
85 character(len=1024) :: expression
86 push_sub(target_init_classical)
87
88 tg%move_ions = td%ions_dyn%ions_move()
89 tg%dt = td%dt
90 assert(tg%move_ions)
91
92 !%Variable OCTClassicalTarget
93 !%Type block
94 !%Section Calculation Modes::Optimal Control
95 !%Description
96 !% If <tt>OCTTargetOperator = oct_tg_classical</tt>, the you must supply this block.
97 !% It should contain a string (e.g. "(q[1,1]-q[1,2])*p[2,1]") with a mathematical
98 !% expression in terms of two arrays, q and p, that represent the position and momenta
99 !% of the classical variables. The first index runs through the various classical particles,
100 !% and the second index runs through the spatial dimensions.
101 !%
102 !% In principle, the block only contains one entry (string). However, if the expression is very
103 !% long, you can split it into various lines (one column each) that will be concatenated.
104 !%
105 !% The QOCT algorithm will attempt to maximize this expression, at the end of the propagation.
106 !%End
107 if (parse_block(namespace, 'OCTClassicalTarget', blk) == 0) then
108 tg%classical_input_string = " "
109 do jj = 0, parse_block_n(blk) - 1
110 call parse_block_string(blk, jj, 0, expression)
111 tg%classical_input_string = trim(tg%classical_input_string) // trim(expression)
112 end do
113 call parse_block_end(blk)
114 else
115 message(1) = 'If OCTTargetOperator = oct_tg_classical, then you must give the shape'
116 message(2) = 'of this target in the block "OCTClassicalTarget".'
117 call messages_fatal(2, namespace=namespace)
118 end if
119
120 !%Variable OCTMomentumDerivatives
121 !%Type block
122 !%Section Calculation Modes::Optimal Control
123 !%Description
124 !% This block should contain the derivatives of the expression given in
125 !% <tt>OCTClassicalTarget</tt> with respect to the p array components.
126 !% Each line corresponds to a different classical particle, whereas the
127 !% columns correspond to each spatial dimension: the (i,j) block component
128 !% corresponds with the derivative wrt p[i,j].
129 !%End
130 if (parse_block(namespace, 'OCTMomentumDerivatives', blk) == 0) then
131 safe_allocate(tg%mom_der_array(1:ions%natoms,1:ions%space%dim))
132 do ist = 0, ions%natoms - 1
133 do jst = 0, ions%space%dim - 1
134 call parse_block_string(blk, ist, jst, tg%mom_der_array(ist+1, jst+1))
135 end do
136 end do
137 call parse_block_end(blk)
138 else if (oct%algorithm == option__octscheme__oct_cg .or. oct%algorithm == option__octscheme__oct_bfgs) then
139 message(1) = 'If "OCTTargetOperator = oct_classical" and "OCTScheme = oct_cg" or'
140 message(2) = '"OCTScheme = oct_bfgs", then you must define the blocks "OCTClassicalTarget",'
141 message(3) = '"OCTPositionDerivatives" AND "OCTMomentumDerivatives"'
142 call messages_fatal(3, namespace=namespace)
143 end if
144
145 !%Variable OCTPositionDerivatives
146 !%Type block
147 !%Section Calculation Modes::Optimal Control
148 !%Description
149 !% This block should contain the derivatives of the expression given in
150 !% <tt>OCTClassicalTarget</tt> with respect to the q array components.
151 !% Each line corresponds to a different classical particle, whereas the
152 !% columns correspond to each spatial dimension: the (i,j) block component
153 !% corresponds with the derivative wrt q[i,j].
154 !%End
155 if (parse_block(namespace, 'OCTPositionDerivatives', blk) == 0) then
156 safe_allocate(tg%pos_der_array(1:ions%natoms,1:ions%space%dim))
157 do ist = 0, ions%natoms-1
158 do jst = 0, ions%space%dim-1
159 call parse_block_string(blk, ist, jst, tg%pos_der_array(ist+1, jst+1))
160 end do
161 end do
162 call parse_block_end(blk)
163 else if (oct%algorithm == option__octscheme__oct_cg .or. oct%algorithm == option__octscheme__oct_bfgs) then
164 message(1) = 'If "OCTTargetOperator = oct_tg_classical" and "OCTScheme = oct_cg" or'
165 message(2) = '"OCTScheme = oct_bfgs", then you must define the blocks "OCTClassicalTarget",'
166 message(3) = '"OCTPositionDerivatives" AND "OCTMomentumDerivatives"'
167 call messages_fatal(3, namespace=namespace)
168 end if
169
170 pop_sub(target_init_classical)
171 end subroutine target_init_classical
172 ! ----------------------------------------------------------------------
173
174 ! ----------------------------------------------------------------------
176 subroutine target_end_classical(tg, oct)
177 class(target_classical_t), intent(inout) :: tg
178 type(oct_t), intent(in) :: oct
179
180 push_sub(target_end_classical)
181
182 safe_deallocate_a(tg%pos_der_array)
183 safe_deallocate_a(tg%mom_der_array)
184
185 pop_sub(target_end_classical)
186 end subroutine target_end_classical
187 ! ----------------------------------------------------------------------
188
189
190 ! ----------------------------------------------------------------------
192 subroutine target_output_classical(tg, namespace, space, gr, dir, ions, hm, outp)
193 class(target_classical_t), intent(inout) :: tg
194 type(namespace_t), intent(in) :: namespace
195 class(space_t), intent(in) :: space
196 type(grid_t), intent(in) :: gr
197 character(len=*), intent(in) :: dir
198 type(ions_t), intent(in) :: ions
199 type(hamiltonian_elec_t), intent(in) :: hm
200 type(output_t), intent(in) :: outp
201
204 end subroutine target_output_classical
205 ! ----------------------------------------------------------------------
206
207
208 ! ----------------------------------------------------------------------
210 real(real64) function target_j1_classical(tg, namespace, gr, kpoints, qcpsi, ions) result(j1)
211 class(target_classical_t), intent(inout) :: tg
212 type(namespace_t), intent(in) :: namespace
213 type(grid_t), intent(in) :: gr
214 type(kpoints_t), intent(in) :: kpoints
215 type(opt_control_state_t), intent(inout) :: qcpsi
216 type(ions_t), optional, intent(in) :: ions
217
218 real(real64), pointer :: q(:, :), p(:, :)
219 real(real64) :: dummy(3)
220 character(len=4096) :: inp_string
221
222 push_sub(target_j1_classical)
223
224 q => opt_control_point_q(qcpsi)
225 p => opt_control_point_p(qcpsi)
226
227 inp_string = tg%classical_input_string
228 call parse_array(inp_string, q, 'q')
229 call parse_array(inp_string, p, 'p')
230 call conv_to_c_string(inp_string)
231 call parse_expression(j1, dummy(1), 1, dummy(1:3), dummy(1), dummy(1), inp_string)
232
233 nullify(q)
234 nullify(p)
235 pop_sub(target_j1_classical)
236 end function target_j1_classical
237 ! ----------------------------------------------------------------------
238
239
240 ! ----------------------------------------------------------------------
242 subroutine target_chi_classical(tg, namespace, gr, kpoints, qcpsi_in, qcchi_out, ions)
243 class(target_classical_t), intent(inout) :: tg
244 type(namespace_t), intent(in) :: namespace
245 type(grid_t), intent(in) :: gr
246 type(kpoints_t), intent(in) :: kpoints
247 type(opt_control_state_t), target, intent(inout) :: qcpsi_in
248 type(opt_control_state_t), target, intent(inout) :: qcchi_out
249 type(ions_t), intent(in) :: ions
250
251 integer :: ist, jst, ib, iqn
252 character(len=1024) :: temp_string
253 real(real64) :: df_dv, dummy(3)
254 real(real64), pointer :: q(:, :), p(:, :), tq(:, :), tp(:, :)
255 type(states_elec_t), pointer :: chi
256 push_sub(target_chi_classical)
257
258 tq => opt_control_point_q(qcchi_out)
259 tp => opt_control_point_p(qcchi_out)
260 q => opt_control_point_q(qcpsi_in)
261 p => opt_control_point_p(qcpsi_in)
262 tq = m_zero
263 tp = m_zero
264
265 do ist = 1, ions%natoms
266 do jst=1, ions%space%dim
267 temp_string = tg%mom_der_array(ist, jst)
268 call parse_array(temp_string, p, 'p')
269 call parse_array(temp_string, q, 'q')
270 call conv_to_c_string(temp_string)
271 call parse_expression(df_dv, dummy(1), 1, dummy(1:3), dummy(1), dummy(1), temp_string)
272 tq(ist, jst) = -df_dv
273 end do
274 end do
275
276 do ist = 1, ions%natoms
277 do jst=1, ions%space%dim
278 temp_string = tg%pos_der_array(ist, jst)
279 call parse_array(temp_string, p, 'p')
280 call parse_array(temp_string, q, 'q')
281 call conv_to_c_string(temp_string)
282 call parse_expression(df_dv, dummy(1), 1, dummy(1:3), dummy(1), dummy(1), temp_string)
283 tp(ist, jst) = df_dv
284 end do
285 end do
286
287 chi => opt_control_point_qs(qcchi_out)
288
289 !We assume that there is no time-independent operator.
290 do iqn = chi%d%kpt%start, chi%d%kpt%end
291 do ib = chi%group%block_start, chi%group%block_end
292 call batch_set_zero(chi%group%psib(ib, iqn))
293 end do
294 end do
295
296 nullify(tq)
297 nullify(tp)
298 nullify(q)
299 nullify(p)
300 nullify(chi)
301 pop_sub(target_chi_classical)
302 end subroutine target_chi_classical
303 ! ----------------------------------------------------------------------
304
306!! Local Variables:
307!! mode: f90
308!! coding: utf-8
309!! End:
This module implements common operations on batches of mesh functions.
Definition: batch_ops.F90:118
This module implements the underlying real-space grid.
Definition: grid.F90:119
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
This module contains the definition of the oct_t data type, which contains some of the basic informat...
This module holds the "opt_control_state_t" datatype, which contains a quantum-classical state.
real(real64) function, dimension(:, :), pointer, public opt_control_point_p(ocs)
real(real64) function, dimension(:, :), pointer, public opt_control_point_q(ocs)
this module contains the low-level part of the output system
Definition: output_low.F90:117
subroutine, public parse_block_string(blk, l, c, res, convert_to_c)
Definition: parser.F90:818
subroutine, public parse_array(inp_string, x, arraychar)
A very primitive way to "preprocess" a string that contains reference to the elements of a two-dimens...
Definition: parser.F90:713
integer function, public parse_block(namespace, name, blk, check_varinfo_)
Definition: parser.F90:623
subroutine, public conv_to_c_string(str)
converts to c string
Definition: string.F90:234
subroutine target_output_classical(tg, namespace, space, gr, dir, ions, hm, outp)
The classical target has no associated grid output.
subroutine target_init_classical(tg, gr, kpoints, namespace, space, ions, qcs, td, w0, oct, ep, restart)
subroutine target_end_classical(tg, oct)
subroutine target_chi_classical(tg, namespace, gr, kpoints, qcpsi_in, qcchi_out, ions)
real(real64) function target_j1_classical(tg, namespace, gr, kpoints, qcpsi, ions)
Optimal-control targets: abstract base class and public interface.
Definition: target.F90:132
Definition: td.F90:116
Description of the grid, containing information on derivatives, stencil, and symmetries.
Definition: grid.F90:171
!brief The oct_t datatype stores the basic information about how the OCT run is done.
This is the datatype that contains the objects that are propagated: in principle this could be both t...
output handler class
Definition: output_low.F90:166
Target on the classical degrees of freedom.
Abstract optimal-control target.
Definition: target.F90:172