30 use,
intrinsic :: iso_fortran_env
59 character(len=4096) :: vel_input_string
60 character(len=1024),
allocatable :: vel_der_array(:,:)
61 real(real64),
allocatable :: grad_local_pot(:,:,:)
62 real(real64),
allocatable :: rho(:)
63 real(real64),
allocatable :: td_fitness(:)
79 subroutine target_init_velocity(tg, gr, kpoints, namespace, space, ions, qcs, td, w0, oct, ep, restart)
80 class(target_velocity_t),
intent(inout) :: tg
81 type(grid_t),
intent(in) :: gr
82 type(kpoints_t),
intent(in) :: kpoints
83 type(namespace_t),
intent(in) :: namespace
84 class(space_t),
intent(in) :: space
85 type(ions_t),
intent(in) :: ions
86 type(opt_control_state_t),
intent(inout) :: qcs
87 type(td_t),
intent(in) :: td
88 real(real64),
intent(in) :: w0
89 type(oct_t),
intent(in) :: oct
90 type(epot_t),
intent(inout) :: ep
91 type(restart_t),
intent(inout) :: restart
93 integer :: iatom, ist, jst, jj
94 real(real64),
allocatable :: vl(:), vl_grad(:,:)
96 character(len=1024) :: expression
151 if (
parse_block(namespace,
'OCTVelocityTarget', blk) == 0)
then
152 tg%vel_input_string =
" "
155 tg%vel_input_string = trim(tg%vel_input_string) // trim(expression)
159 message(1) =
'If OCTTargetOperator = oct_tg_velocity, then you must give the shape'
160 message(2) =
'of this target in the block "OCTVelocityTarget".'
164 tg%move_ions = td%ions_dyn%ions_move()
165 if (tg%move_ions)
then
166 message(1) =
'If OCTTargetOperator = oct_tg_velocity, then you must not allow the ions'
167 message(2) =
'to move. If you want to move the ions, then you can get the same functionality'
168 message(3) =
'with OCTTargetOperator = oct_tg_classical.'
172 if (oct%algorithm == option__octscheme__oct_cg .or. oct%algorithm == option__octscheme__oct_bfgs)
then
173 if (
parse_block(namespace,
'OCTVelocityDerivatives', blk) == 0)
then
174 safe_allocate(tg%vel_der_array(1:ions%natoms,1:gr%box%dim))
175 do ist=0, ions%natoms-1
176 do jst=0, gr%box%dim-1
182 message(1) =
'If OCTTargetOperator = oct_tg_velocity, and'
183 message(2) =
'OCTScheme = oct_cg, or OCTScheme = oct_bfgs then you must define the'
184 message(3) =
'blocks "OCTVelocityTarget" AND "OCTVelocityDerivatives"'
189 safe_allocate(tg%grad_local_pot(1:ions%natoms, 1:gr%np, 1:gr%box%dim))
190 safe_allocate(vl(1:gr%np_part))
191 safe_allocate(vl_grad(1:gr%np, 1:gr%box%dim))
192 safe_allocate(tg%rho(1:gr%np))
195 do iatom = 1, ions%natoms
199 ions%pos(:, iatom), iatom, vl)
203 tg%grad_local_pot(iatom, ist, jst) = vl_grad(ist, jst)
207 safe_deallocate_a(vl)
208 safe_deallocate_a(vl_grad)
217 safe_allocate(tg%td_fitness(0:td%max_iter))
228 type(
oct_t),
intent(in) :: oct
232 if (oct%algorithm == option__octscheme__oct_cg .or. oct%algorithm == option__octscheme__oct_bfgs)
then
233 safe_deallocate_a(tg%vel_der_array)
234 safe_deallocate_a(tg%grad_local_pot)
235 safe_deallocate_a(tg%rho)
237 safe_deallocate_a(tg%td_fitness)
247 class(
space_t),
intent(in) :: space
248 type(
grid_t),
intent(in) :: gr
249 character(len=*),
intent(in) :: dir
250 type(
ions_t),
intent(in) :: ions
257 call output_states(outp, namespace, space, trim(dir), tg%st, gr, ions, hm, -1)
266 real(real64) function target_j1_velocity(tg, namespace, gr, kpoints, qcpsi, ions) result(j1)
269 type(
grid_t),
intent(in) :: gr
272 type(
ions_t),
optional,
intent(in) :: ions
275 real(real64) :: f_re, dummy(3)
276 real(real64),
allocatable :: x(:, :)
277 character(len=4096) :: inp_string
278 push_sub(target_j1_velocity)
280 safe_allocate(x(1:ions%natoms, 1:ions%space%dim))
281 do i = 1, ions%natoms
282 x(i, :) = ions%vel(:, i)
287 inp_string = tg%vel_input_string
290 call parse_expression(f_re, dummy(1), 1, dummy(1:3), dummy(1), dummy(1), inp_string)
294 pop_sub(target_j1_velocity)
302 type(namespace_t),
intent(in) :: namespace
303 type(grid_t),
intent(in) :: gr
304 type(kpoints_t),
intent(in) :: kpoints
305 type(opt_control_state_t),
target,
intent(inout) :: qcpsi_in
306 type(opt_control_state_t),
target,
intent(inout) :: qcchi_out
307 type(ions_t),
intent(in) :: ions
309 integer :: ip, ist, jst, ik, ib
310 character(len=1024) :: temp_string
311 real(real64) :: df_dv, dummy(3)
312 real(real64),
allocatable :: x(:, :)
313 type(states_elec_t),
pointer :: chi_out
316 chi_out => opt_control_point_qs(qcchi_out)
319 do ik = chi_out%d%kpt%start, chi_out%d%kpt%end
320 do ib = chi_out%group%block_start, chi_out%group%block_end
321 call batch_set_zero(chi_out%group%psib(ib, ik))
325 safe_allocate(x(1:ions%natoms, 1:ions%space%dim))
326 do ip = 1, ions%natoms
327 x(ip, :) = ions%vel(:, ip)
334 do ist = 1, ions%natoms
336 temp_string = tg%vel_der_array(ist, jst)
337 call parse_array(temp_string, x,
'v')
338 call conv_to_c_string(temp_string)
339 call parse_expression(df_dv, dummy(1), 1, dummy(1:3), dummy(1), dummy(1), temp_string)
340 tg%rho(:) = tg%rho(:) + df_dv*tg%grad_local_pot(ist,:,jst)/ions%mass(ist)
354 type(states_elec_t),
intent(inout) :: psi
355 type(grid_t),
intent(in) :: gr
356 type(kpoints_t),
intent(in) :: kpoints
357 real(real64),
intent(in) :: time
358 type(states_elec_t),
intent(inout) :: inh
359 integer,
intent(in) :: iter
361 integer :: ik, ist, ip, idim
362 complex(real64),
allocatable :: zpsi(:)
366 safe_allocate(zpsi(1:gr%np))
368 do ik = inh%d%kpt%start, inh%d%kpt%end
369 do ist = inh%st_start, inh%st_end
370 do idim = 1, inh%d%dim
371 call states_elec_get_state(psi, gr, idim, ist, ik, zpsi)
373 zpsi(ip) = -psi%occ(ist, ik)*tg%rho(ip)*zpsi(ip)
375 call states_elec_set_state(inh, gr, idim, ist, ik, zpsi)
380 safe_deallocate_a(zpsi)
392 type(namespace_t),
intent(in) :: namespace
393 class(space_t),
intent(in) :: space
394 type(hamiltonian_elec_t),
intent(inout) :: hm
395 type(grid_t),
intent(in) :: gr
396 type(ions_t),
intent(inout) :: ions
397 type(partner_list_t),
intent(in) :: ext_partners
398 type(states_elec_t),
intent(inout) :: psi
399 integer,
intent(in) :: time
400 integer,
intent(in) :: max_time
402 complex(real64),
allocatable :: opsi(:, :), zpsi(:, :)
403 integer :: iatom, ik, ist, idim
407 tg%td_fitness(time) = m_zero
409 safe_allocate(zpsi(1:gr%np_part, 1))
410 safe_allocate(opsi(1:gr%np_part, 1))
413 do iatom = 1, ions%natoms
414 ions%tot_force(:, iatom) = hm%ep%fii(1:gr%box%dim, iatom)
417 do idim = 1, gr%box%dim
418 call states_elec_get_state(psi, gr, ist, ik, zpsi)
419 opsi(1:gr%np, 1) = tg%grad_local_pot(iatom, 1:gr%np, idim)*zpsi(1:gr%np, 1)
420 ions%tot_force(idim, iatom) = ions%tot_force(idim, iatom) &
421 + real(psi%occ(ist, ik)*zmf_dotp(gr, psi%d%dim, opsi, zpsi), real64)
426 safe_deallocate_a(opsi)
427 safe_deallocate_a(zpsi)
430 if ((time == 0) .or. (time == max_time)) dt = tg%dt * m_half
431 do iatom = 1, ions%natoms
432 ions%vel(:, iatom) = ions%vel(:, iatom) + ions%tot_force(:, iatom) * dt / ions%mass(iatom)
This module implements common operations on batches of mesh functions.
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
subroutine, public dderivatives_grad(der, ff, op_ff, ghost_update, set_bc, to_cartesian)
apply the gradient to a mesh function
subroutine, public epot_local_potential(ep, namespace, space, latt, mesh, species, pos, iatom, vpsl)
real(real64), parameter, public m_zero
This module implements the underlying real-space grid.
This module defines classes and functions for interaction partners.
subroutine, public io_mkdir(fname, namespace, parents)
This module defines various routines, operating on mesh functions.
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
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.
this module contains the low-level part of the output system
this module contains the output system
subroutine, public output_states(outp, namespace, space, dir, st, gr, ions, hm, iter)
subroutine, public parse_block_string(blk, l, c, res, convert_to_c)
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...
integer function, public parse_block(namespace, name, blk, check_varinfo_)
subroutine, public conv_to_c_string(str)
converts to c string
Optimal-control targets: abstract base class and public interface.
real(real64) function target_j1_velocity(tg, namespace, gr, kpoints, qcpsi, ions)
subroutine target_init_velocity(tg, gr, kpoints, namespace, space, ions, qcs, td, w0, oct, ep, restart)
subroutine target_inh_velocity(tg, psi, gr, kpoints, time, inh, iter)
Inhomogeneous term for the velocity target.
subroutine target_end_velocity(tg, oct)
subroutine target_tdcalc_velocity(tg, namespace, space, hm, gr, ions, ext_partners, psi, time, max_time)
subroutine target_chi_velocity(tg, namespace, gr, kpoints, qcpsi_in, qcchi_out, ions)
subroutine target_output_velocity(tg, namespace, space, gr, dir, ions, hm, outp)
Description of the grid, containing information on derivatives, stencil, and symmetries.
!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...
Abstract optimal-control target.
Target as a function of the ionic velocities.