Octopus
target_hhg.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
19#include "global.h"
20
23 use debug_oct_m
25 use epot_oct_m
26 use fft_oct_m
27 use global_oct_m
28 use grid_oct_m
30 use io_oct_m
31 use ions_oct_m
34 use, intrinsic :: iso_fortran_env
41 use output_oct_m
43 use parser_oct_m
46 use space_oct_m
49 use target_oct_m
50 use td_oct_m
52
53
54 implicit none
55
56 private
57 public :: &
60
62 type, extends(target_t) :: target_hhg_t
63 private
64 integer :: hhg_nks
65 integer, allocatable :: hhg_k(:)
66 real(real64), allocatable :: hhg_alpha(:)
67 real(real64), allocatable :: hhg_a(:)
68 real(real64) :: hhg_w0
69 real(real64), allocatable :: td_fitness(:)
70 contains
71 procedure :: init => target_init_hhg
72 procedure :: cleanup => target_end_hhg
73 procedure :: j1 => target_j1_hhg
74 procedure :: apply_chi => target_chi_hhg
75 procedure :: output => target_output_hhg
76 procedure :: tdcalc => target_tdcalc_hhg
77 end type target_hhg_t
78
80 type, extends(target_t) :: target_hhgnew_t
81 private
82 real(real64), allocatable :: grad_local_pot(:,:,:)
83 real(real64), allocatable :: rho(:)
84 complex(real64), allocatable :: acc(:, :)
85 complex(real64), allocatable :: vel(:, :)
86 complex(real64), allocatable :: gvec(:, :)
87 real(real64), allocatable :: alpha(:)
88 character(len=1000) :: plateau_string
89 real(real64), allocatable :: td_fitness(:)
90 type(fft_t) :: fft_handler
91 contains
92 procedure :: init => target_init_hhgnew
93 procedure :: cleanup => target_end_hhgnew
94 procedure :: j1 => target_j1_hhgnew
95 procedure :: apply_chi => target_chi_hhgnew
96 procedure :: output => target_output_hhgnew
97 procedure :: tdcalc => target_tdcalc_hhgnew
98 procedure :: inh => target_inh_hhgnew
99 procedure :: init_propagation => target_init_propagation_hhgnew
100 end type target_hhgnew_t
101
102
103contains
104
105
106
107 ! ----------------------------------------------------------------------
109 subroutine target_init_hhg(tg, gr, kpoints, namespace, space, ions, qcs, td, w0, oct, ep, restart)
110 class(target_hhg_t), intent(inout) :: tg
111 type(grid_t), intent(in) :: gr
112 type(kpoints_t), intent(in) :: kpoints
113 type(namespace_t), intent(in) :: namespace
114 class(space_t), intent(in) :: space
115 type(ions_t), intent(in) :: ions
116 type(opt_control_state_t), intent(inout) :: qcs
117 type(td_t), intent(in) :: td
118 real(real64), intent(in) :: w0
119 type(oct_t), intent(in) :: oct
120 type(epot_t), intent(inout) :: ep
121 type(restart_t), intent(inout) :: restart
122
123 integer :: jj
124 type(block_t) :: blk
125 push_sub(target_init_hhg)
126
127 tg%move_ions = td%ions_dyn%ions_move()
128
129 !%Variable OCTOptimizeHarmonicSpectrum
130 !%Type block
131 !%Default no
132 !%Section Calculation Modes::Optimal Control
133 !%Description
134 !% (Experimental)
135 !% If <tt>OCTTargetOperator = oct_tg_hhg</tt>, the target is the harmonic emission spectrum.
136 !% In that case, you must supply an <tt>OCTOptimizeHarmonicSpectrum</tt> block in the <tt>inp</tt>
137 !% file. The target is given, in general, by:
138 !%
139 !% <math>J_1 = \int_0^\infty d\omega \alpha(\omega) H(\omega)</math>,
140 !%
141 !% where <math>H(\omega)</math> is the harmonic spectrum generated by the system, and
142 !% <math>\alpha(\omega)</math> is some function that determines what exactly we want
143 !% to optimize. The role of the <tt>OCTOptimizeHarmonicSpectrum</tt> block is to determine
144 !% this <math>\alpha(\omega)</math> function. Currently, this function is defined as:
145 !%
146 !% <math>\alpha(\omega) = \sum_{L=1}^{M} \frac{\alpha_L}{a_L} \sqcap( (\omega - L\omega_0)/a_L )</math>,
147 !%
148 !% where <math>\omega_0</math> is the carrier frequency. <math>M</math> is
149 !% the number of columns in the <tt>OCTOptimizeHarmonicSpectrum</tt> block. The values of <i>L</i> will be listed
150 !% in the first row of this block; <math>\alpha_L</math> in the second row, and <math>a_L</math> in
151 !% the third.
152 !%
153 !% Example:
154 !%
155 !% <tt>%OCTOptimizeHarmonicSpectrum
156 !% <br>&nbsp;&nbsp; 7 | 9 | 11
157 !% <br>&nbsp;&nbsp; -1 | 1 | -1
158 !% <br>&nbsp;&nbsp; 0.01 | 0.01 | 0.01
159 !% <br>%</tt>
160 !%
161 !%End
162 if (parse_is_defined(namespace, 'OCTOptimizeHarmonicSpectrum')) then
163 if (parse_block(namespace, 'OCTOptimizeHarmonicSpectrum', blk) == 0) then
164 tg%hhg_nks = parse_block_cols(blk, 0)
165 safe_allocate( tg%hhg_k(1:tg%hhg_nks))
166 safe_allocate(tg%hhg_alpha(1:tg%hhg_nks))
167 safe_allocate( tg%hhg_a(1:tg%hhg_nks))
168 do jj = 1, tg%hhg_nks
169 call parse_block_integer(blk, 0, jj - 1, tg%hhg_k(jj))
170 call parse_block_float(blk, 1, jj - 1, tg%hhg_alpha(jj))
171 call parse_block_float(blk, 2, jj - 1, tg%hhg_a(jj))
172 end do
173 call parse_block_end(blk)
174 else
175 message(1) = '"OCTOptimizeHarmonicSpectrum" has to be specified as a block.'
176 call messages_info(1, namespace=namespace)
177 call messages_input_error(namespace, 'OCTOptimizeHarmonicSpectrum')
178 end if
179 else
180 write(message(1), '(a)') 'If "OCTTargetOperator = oct_tg_hhg", you must supply an'
181 write(message(2), '(a)') '"OCTOptimizeHarmonicSpectrum" block.'
182 call messages_fatal(2, namespace=namespace)
183 end if
185 tg%hhg_w0 = w0
186 tg%dt = td%dt
187 safe_allocate(tg%td_fitness(0:td%max_iter))
188 tg%td_fitness = m_zero
191 end subroutine target_init_hhg
194 ! ----------------------------------------------------------------------
196 subroutine target_init_hhgnew(tg, gr, kpoints, namespace, space, ions, qcs, td, w0, oct, ep, restart)
197 class(target_hhgnew_t), intent(inout) :: tg
198 type(grid_t), intent(in) :: gr
199 type(kpoints_t), intent(in) :: kpoints
200 type(namespace_t), intent(in) :: namespace
201 class(space_t), intent(in) :: space
202 type(ions_t), intent(in) :: ions
203 type(opt_control_state_t), intent(inout) :: qcs
204 type(td_t), intent(in) :: td
205 real(real64), intent(in) :: w0
206 type(oct_t), intent(in) :: oct
207 type(epot_t), intent(inout) :: ep
208 type(restart_t), intent(inout) :: restart
209
210 integer :: ist, jst, iunit, jj, nn(3), optimize_parity(3)
211 logical :: optimize(3)
212 real(real64) :: dw, psi_re, psi_im, ww
213 real(real64), allocatable :: vl(:), vl_grad(:,:)
214 push_sub(target_init_hhgnew)
215
216 tg%move_ions = td%ions_dyn%ions_move()
217
218 ! We allocate many things that are perhaps not necessary if we use a direct optimization scheme.
219 safe_allocate(tg%vel(1:td%max_iter+1, 1:gr%box%dim))
220 safe_allocate(tg%acc(1:td%max_iter+1, 1:gr%box%dim))
221 safe_allocate(tg%gvec(1:td%max_iter+1, 1:gr%box%dim))
222 safe_allocate(tg%alpha(1:td%max_iter))
223
224 ! The following is a temporary hack, that assumes only one atom at the origin of coordinates.
225 if (ions%natoms > 1) then
226 message(1) = 'If "OCTTargetOperator = oct_tg_hhgnew", then you can only have one atom.'
227 call messages_fatal(1, namespace=namespace)
228 end if
229
230 ! The following is a temporary hack, that assumes only one atom at the origin of coordinates.
231 if (ions%natoms > 1) then
232 message(1) = 'If "OCTTargetOperator = oct_tg_hhgnew", then you can only have one atom.'
233 call messages_fatal(1, namespace=namespace)
234 end if
235
236 safe_allocate(tg%grad_local_pot(1:ions%natoms, 1:gr%np, 1:gr%box%dim))
237 safe_allocate(vl(1:gr%np_part))
238 safe_allocate(vl_grad(1:gr%np, 1:gr%box%dim))
239 safe_allocate(tg%rho(1:gr%np))
240
241 vl(:) = m_zero
242 vl_grad(:,:) = m_zero
243 call epot_local_potential(ep, namespace, ions%space, ions%latt, gr, ions%atom(1)%species, &
244 ions%pos(:, 1), 1, vl)
245 call dderivatives_grad(gr%der, vl, vl_grad)
246 do jst=1, gr%box%dim
247 do ist = 1, gr%np
248 tg%grad_local_pot(1, ist, jst) = vl_grad(ist, jst)
249 end do
250 end do
251 ! Note that the calculation of the gradient of the potential
252 ! is wrong at the borders of the box, since it assumes zero boundary
253 ! conditions. The best way to solve this problems is to define the
254 ! target making use of the definition of the forces based on the gradient
255 ! of the density, rather than on the gradient of the potential.
256
257
258 !%Variable OCTHarmonicWeight
259 !%Type string
260 !%Default "1"
261 !%Section Calculation Modes::Optimal Control
262 !%Description
263 !% (Experimental) If <tt>OCTTargetOperator = oct_tg_plateau</tt>, then the function to optimize is the integral of the
264 !% harmonic spectrum <math>H(\omega)</math>, weighted with a function <math>f(\omega)</math>
265 !% that is defined as a string here. For example, if
266 !% you set <tt>OCTHarmonicWeight = "step(w-1)"</tt>, the function to optimize is
267 !% the integral of <math>step(\omega-1)*H(\omega)</math>, <i>i.e.</i>
268 !% <math>\int_1^{\infty} H \left( \omega \right) d\omega</math>.
269 !% In practice, it is better if you also set an upper limit, <i>e.g.</i>
270 !% <math>f(\omega) = step(\omega-1) step(2-\omega)</math>.
271 !%End
272 call parse_variable(namespace, 'OCTHarmonicWeight', '1', tg%plateau_string)
273 tg%dt = td%dt
274 safe_allocate(tg%td_fitness(0:td%max_iter))
275 tg%td_fitness = m_zero
276
277 iunit = io_open('.alpha', namespace, action='write')
278 dw = (m_two * m_pi) / (td%max_iter * tg%dt)
279 do jj = 0, td%max_iter - 1
280 ww = jj * dw
281 call parse_expression(psi_re, psi_im, "w", ww, tg%plateau_string)
282 tg%alpha(jj+1) = psi_re
283 write(iunit, *) ww, psi_re
284 end do
285 call io_close(iunit)
286
287 nn(1:3) = (/ td%max_iter, 1, 1 /)
288 optimize(1:3) = .false.
289 optimize_parity(1:3) = -1
290 call fft_init(tg%fft_handler, nn(1:3), 1, fft_complex, fftlib_fftw, optimize, optimize_parity)
292 pop_sub(target_init_hhgnew)
293 end subroutine target_init_hhgnew
294
295
296 ! ----------------------------------------------------------------------
298 subroutine target_end_hhg(tg, oct)
299 class(target_hhg_t), intent(inout) :: tg
300 type(oct_t), intent(in) :: oct
301
302 push_sub(target_end_hhg)
303
304 safe_deallocate_a(tg%hhg_k)
305 safe_deallocate_a(tg%hhg_alpha)
306 safe_deallocate_a(tg%hhg_a)
307 safe_deallocate_a(tg%td_fitness)
308
309 pop_sub(target_end_hhg)
310 end subroutine target_end_hhg
311
312
313 ! ----------------------------------------------------------------------
314 subroutine target_output_hhg(tg, namespace, space, gr, dir, ions, hm, outp)
315 class(target_hhg_t), intent(inout) :: tg
316 type(namespace_t), intent(in) :: namespace
317 class(space_t), intent(in) :: space
318 type(grid_t), intent(in) :: gr
319 character(len=*), intent(in) :: dir
320 type(ions_t), intent(in) :: ions
321 type(hamiltonian_elec_t), intent(in) :: hm
322 type(output_t), intent(in) :: outp
323
324 push_sub(target_output_hhg)
325
326 call io_mkdir(trim(dir), namespace)
327 call output_states(outp, namespace, space, trim(dir), tg%st, gr, ions, hm, -1)
328
329 pop_sub(target_output_hhg)
330 end subroutine target_output_hhg
331 ! ----------------------------------------------------------------------
332
333
334 ! ----------------------------------------------------------------------
335 subroutine target_output_hhgnew(tg, namespace, space, gr, dir, ions, hm, outp)
336 class(target_hhgnew_t), intent(inout) :: tg
337 type(namespace_t), intent(in) :: namespace
338 class(space_t), intent(in) :: space
339 type(grid_t), intent(in) :: gr
340 character(len=*), intent(in) :: dir
341 type(ions_t), intent(in) :: ions
342 type(hamiltonian_elec_t), intent(in) :: hm
343 type(output_t), intent(in) :: outp
344
345 push_sub(target_output_hhgnew)
346
347 call io_mkdir(trim(dir), namespace)
348 call output_states(outp, namespace, space, trim(dir), tg%st, gr, ions, hm, -1)
349
350 pop_sub(target_output_hhgnew)
351 end subroutine target_output_hhgnew
352 ! ----------------------------------------------------------------------
353
354
355 ! ----------------------------------------------------------------------
357 subroutine target_end_hhgnew(tg, oct)
358 class(target_hhgnew_t), intent(inout) :: tg
359 type(oct_t), intent(in) :: oct
360
361 push_sub(target_end_hhgnew)
362
363 if ((oct%algorithm == option__octscheme__oct_cg) .or. (oct%algorithm == option__octscheme__oct_bfgs)) then
364 safe_deallocate_a(tg%grad_local_pot)
365 safe_deallocate_a(tg%rho)
366 safe_deallocate_a(tg%vel)
367 safe_deallocate_a(tg%acc)
368 safe_deallocate_a(tg%gvec)
369 safe_deallocate_a(tg%alpha)
370 safe_deallocate_a(tg%td_fitness)
371 call fft_end(tg%fft_handler)
372 end if
373
374 pop_sub(target_end_hhgnew)
375 end subroutine target_end_hhgnew
376
377
378 ! ----------------------------------------------------------------------
380 real(real64) function target_j1_hhg(tg, namespace, gr, kpoints, qcpsi, ions) result(j1)
381 class(target_hhg_t), intent(inout) :: tg
382 type(namespace_t), intent(in) :: namespace
383 type(grid_t), intent(in) :: gr
384 type(kpoints_t), intent(in) :: kpoints
385 type(opt_control_state_t), intent(inout) :: qcpsi
386 type(ions_t), optional, intent(in) :: ions
387
388 integer :: maxiter, jj
389 real(real64) :: aa, ww, maxhh, omega
390 complex(real64), allocatable :: ddipole(:)
391 push_sub(target_j1_hhg)
392
393 maxiter = size(tg%td_fitness) - 1
394 safe_allocate(ddipole(0:maxiter))
395 ddipole = m_z0
396 ddipole = tg%td_fitness
397
398 j1 = m_zero
399
400 call spectrum_hsfunction_init(tg%dt, 0, maxiter, maxiter, ddipole)
401 do jj = 1, tg%hhg_nks
402 aa = tg%hhg_a(jj) * tg%hhg_w0
403 ww = tg%hhg_k(jj) * tg%hhg_w0
404 call spectrum_hsfunction_min(namespace, ww - aa, ww + aa, omega, maxhh)
405 j1 = j1 + tg%hhg_alpha(jj) * log(-maxhh)
406 end do
408
409 safe_deallocate_a(ddipole)
410 pop_sub(target_j1_hhg)
411 end function target_j1_hhg
412
413
414 ! ----------------------------------------------------------------------
416 real(real64) function target_j1_hhgnew(tg, namespace, gr, kpoints, qcpsi, ions) result(j1)
417 class(target_hhgnew_t), intent(inout) :: tg
418 type(namespace_t), intent(in) :: namespace
419 type(grid_t), intent(in) :: gr
420 type(kpoints_t), intent(in) :: kpoints
421 type(opt_control_state_t), intent(inout) :: qcpsi
422 type(ions_t), optional, intent(in) :: ions
423
424 integer :: maxiter, i
425 real(real64) :: dw, ww
426 push_sub(target_j1_hhgnew)
427
428 maxiter = size(tg%td_fitness) - 1
429 dw = (m_two * m_pi) / (maxiter * tg%dt)
430 j1 = m_zero
431 do i = 0, maxiter - 1
432 ww = i * dw
433 j1 = j1 + dw * tg%alpha(i+1) * sum(abs(tg%vel(i+1, 1:gr%box%dim))**2)
434 end do
435
436 pop_sub(target_j1_hhgnew)
437 end function target_j1_hhgnew
438
439
440 ! ----------------------------------------------------------------------
442 subroutine target_chi_hhg(tg, namespace, gr, kpoints, qcpsi_in, qcchi_out, ions)
443 class(target_hhg_t), intent(inout) :: tg
444 type(namespace_t), intent(in) :: namespace
445 type(grid_t), intent(in) :: gr
446 type(kpoints_t), intent(in) :: kpoints
447 type(opt_control_state_t), target, intent(inout) :: qcpsi_in
448 type(opt_control_state_t), target, intent(inout) :: qcchi_out
449 type(ions_t), intent(in) :: ions
450
451 integer :: ik, ib
452 type(states_elec_t), pointer :: chi_out
453 push_sub(target_chi_hhg)
454
455 chi_out => opt_control_point_qs(qcchi_out)
456
457 !we have a time-dependent target --> Chi(T)=0
458 do ik = chi_out%d%kpt%start, chi_out%d%kpt%end
459 do ib = chi_out%group%block_start, chi_out%group%block_end
460 call batch_set_zero(chi_out%group%psib(ib, ik))
461 end do
462 end do
463
464 nullify(chi_out)
465 pop_sub(target_chi_hhg)
466 end subroutine target_chi_hhg
467
468
469 ! ----------------------------------------------------------------------
471 subroutine target_chi_hhgnew(tg, namespace, gr, kpoints, qcpsi_in, qcchi_out, ions)
472 class(target_hhgnew_t), intent(inout) :: tg
473 type(namespace_t), intent(in) :: namespace
474 type(grid_t), intent(in) :: gr
475 type(kpoints_t), intent(in) :: kpoints
476 type(opt_control_state_t), target, intent(inout) :: qcpsi_in
477 type(opt_control_state_t), target, intent(inout) :: qcchi_out
478 type(ions_t), intent(in) :: ions
479
480 integer :: ik, ib
481 type(states_elec_t), pointer :: chi_out
482 push_sub(target_chi_hhgnew)
483
484 chi_out => opt_control_point_qs(qcchi_out)
485
486 !we have a time-dependent target --> Chi(T)=0
487 do ik = chi_out%d%kpt%start, chi_out%d%kpt%end
488 do ib = chi_out%group%block_start, chi_out%group%block_end
489 call batch_set_zero(chi_out%group%psib(ib, ik))
490 end do
491 end do
492
493 nullify(chi_out)
494 pop_sub(target_chi_hhgnew)
495 end subroutine target_chi_hhgnew
496
497
498 ! ---------------------------------------------------------
500 subroutine target_init_propagation_hhgnew(tg)
501 class(target_hhgnew_t), intent(inout) :: tg
503
504 tg%vel = m_z0
505 tg%gvec = m_z0
506 tg%acc = m_z0
507
509 end subroutine target_init_propagation_hhgnew
510
512 ! ---------------------------------------------------------------
514 subroutine target_inh_hhgnew(tg, psi, gr, kpoints, time, inh, iter)
515 class(target_hhgnew_t), intent(inout) :: tg
516 type(states_elec_t), intent(inout) :: psi
517 type(grid_t), intent(in) :: gr
518 type(kpoints_t), intent(in) :: kpoints
519 real(real64), intent(in) :: time
520 type(states_elec_t), intent(inout) :: inh
521 integer, intent(in) :: iter
522
523 integer :: ik, ist, ip, idim
524 complex(real64), allocatable :: zpsi(:)
525 complex(real64) :: gvec(gr%box%dim)
526
527 push_sub(target_inh_hhgnew)
528
529 safe_allocate(zpsi(1:gr%np))
530
531 gvec(:) = real(tg%gvec(iter + 1, :), real64)
532
533 do ik = inh%d%kpt%start, inh%d%kpt%end
534 do ist = inh%st_start, inh%st_end
535 do idim = 1, inh%d%dim
536 call states_elec_get_state(psi, gr, idim, ist, ik, zpsi)
537 do ip = 1, gr%np
538 zpsi(ip) = -psi%occ(ist, ik)*m_two*sum(tg%grad_local_pot(1, ip, 1:gr%box%dim)*gvec(:))*zpsi(ip)
539 end do
540 call states_elec_set_state(inh, gr, idim, ist, ik, zpsi)
541 end do
542 end do
543 end do
544
545 safe_deallocate_a(zpsi)
546
547 pop_sub(target_inh_hhgnew)
548 end subroutine target_inh_hhgnew
549 !----------------------------------------------------------
550
551
552 ! ---------------------------------------------------------
555 subroutine target_tdcalc_hhgnew(tg, namespace, space, hm, gr, ions, ext_partners, psi, time, max_time)
556 class(target_hhgnew_t), intent(inout) :: tg
557 type(namespace_t), intent(in) :: namespace
558 class(space_t), intent(in) :: space
559 type(hamiltonian_elec_t), intent(inout) :: hm
560 type(grid_t), intent(in) :: gr
561 type(ions_t), intent(inout) :: ions
562 type(partner_list_t), intent(in) :: ext_partners
563 type(states_elec_t), intent(inout) :: psi
564 integer, intent(in) :: time
565 integer, intent(in) :: max_time
567 complex(real64), allocatable :: opsi(:, :), zpsi(:, :)
568 integer :: iw, ia, ist, idim, ik
569 real(real64) :: acc(gr%box%dim), dt, dw
570
571 push_sub(target_tdcalc_hhgnew)
572
573 tg%td_fitness(time) = m_zero
574
575 ! If the ions move, the tg is computed in the propagation routine.
576 if (.not. target_move_ions(tg)) then
577
578 safe_allocate(opsi(1:gr%np_part, 1))
579 safe_allocate(zpsi(1:gr%np_part, 1))
580
581 opsi = m_z0
582 ! WARNING This does not work for spinors.
583 ! The following is a temporary hack. It assumes only one atom at the origin.
584 do ik = 1, psi%nik
585 do ist = 1, psi%nst
586 call states_elec_get_state(psi, gr, ist, ik, zpsi)
587 do idim = 1, gr%box%dim
588 opsi(1:gr%np, 1) = tg%grad_local_pot(1, 1:gr%np, idim)*zpsi(1:gr%np, 1)
589 acc(idim) = acc(idim) + real( psi%occ(ist, ik) * zmf_dotp(gr, psi%d%dim, opsi, zpsi), real64)
590 tg%acc(time+1, idim) = tg%acc(time+1, idim) + psi%occ(ist, ik)*zmf_dotp(gr, psi%d%dim, opsi, zpsi)
591 end do
592 end do
593 end do
594
595 safe_deallocate_a(opsi)
596 safe_deallocate_a(zpsi)
597
598 end if
599
600 dt = tg%dt
601 dw = (m_two * m_pi/(max_time * tg%dt))
602 if (time == max_time) then
603 tg%acc(1, 1:gr%box%dim) = m_half * (tg%acc(1, 1:gr%box%dim) + tg%acc(max_time+1, 1:gr%box%dim))
604 do ia = 1, gr%box%dim
605 call zfft_forward(tg%fft_handler, tg%acc(1:max_time, ia), tg%vel(1:max_time, ia))
606 end do
607 tg%vel = tg%vel * tg%dt
608 do iw = 1, max_time
609 ! We add the one-half dt term because when doing the propagation we want the value at interpolated times.
610
611 tg%acc(iw, 1:gr%box%dim) = tg%vel(iw, 1:gr%box%dim) * tg%alpha(iw) * exp(m_zi * (iw-1) * dw * m_half * dt)
612 end do
613 do ia = 1, gr%box%dim
614 call zfft_backward(tg%fft_handler, tg%acc(1:max_time, ia), tg%gvec(1:max_time, ia))
615 end do
616 tg%gvec(max_time + 1, 1:gr%box%dim) = tg%gvec(1, 1:gr%box%dim)
617 tg%gvec = tg%gvec * (m_two * m_pi/ tg%dt)
618 end if
619
620 pop_sub(target_tdcalc_hhgnew)
621 end subroutine target_tdcalc_hhgnew
622 ! ----------------------------------------------------------------------
623
624
625 ! ---------------------------------------------------------
628 subroutine target_tdcalc_hhg(tg, namespace, space, hm, gr, ions, ext_partners, psi, time, max_time)
629 class(target_hhg_t), intent(inout) :: tg
630 type(namespace_t), intent(in) :: namespace
631 class(space_t), intent(in) :: space
632 type(hamiltonian_elec_t), intent(inout) :: hm
633 type(grid_t), intent(in) :: gr
634 type(ions_t), intent(inout) :: ions
635 type(partner_list_t), intent(in) :: ext_partners
636 type(states_elec_t), intent(inout) :: psi
637 integer, intent(in) :: time
638 integer, intent(in) :: max_time
639
640 real(real64) :: acc(space%dim)
641
642 push_sub(target_tdcalc_hhg)
643
644 call td_calc_tacc(namespace, space, gr, ions, ext_partners, psi, hm, acc, time*tg%dt)
645 tg%td_fitness(time) = acc(1)
646
647 pop_sub(target_tdcalc_hhg)
648 end subroutine target_tdcalc_hhg
649 ! ----------------------------------------------------------------------
651end module target_hhg_oct_m
652
653!! Local Variables:
654!! mode: f90
655!! coding: utf-8
656!! End:
double log(double __x) __attribute__((__nothrow__
double exp(double __x) __attribute__((__nothrow__
This module implements common operations on batches of mesh functions.
Definition: batch_ops.F90:118
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)
Definition: epot.F90:511
Fast Fourier Transform module. This module provides a single interface that works with different FFT ...
Definition: fft.F90:120
subroutine, public fft_init(this, nn, dim, type, library, optimize, optimize_parity, comm, mpi_grp, use_aligned)
Definition: fft.F90:400
subroutine, public fft_end(this)
Definition: fft.F90:773
integer, parameter, public fft_complex
Definition: fft.F90:174
integer, parameter, public fftlib_fftw
Definition: fft.F90:179
real(real64), parameter, public m_two
Definition: global.F90:202
real(real64), parameter, public m_zero
Definition: global.F90:200
real(real64), parameter, public m_pi
some mathematical constants
Definition: global.F90:198
complex(real64), parameter, public m_z0
Definition: global.F90:210
This module implements the underlying real-space grid.
Definition: grid.F90:119
This module defines classes and functions for interaction partners.
Definition: io.F90:116
subroutine, public io_close(iunit, grp)
Definition: io.F90:467
subroutine, public io_mkdir(fname, namespace, parents)
Definition: io.F90:361
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
Definition: io.F90:402
This module defines various routines, operating on mesh functions.
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
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:691
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
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
Definition: output_low.F90:117
this module contains the output system
Definition: output.F90:117
subroutine, public output_states(outp, namespace, space, dir, st, gr, ions, hm, iter)
Definition: output.F90:1091
logical function, public parse_is_defined(namespace, name)
Definition: parser.F90:463
integer function, public parse_block(namespace, name, blk, check_varinfo_)
Definition: parser.F90:623
subroutine, public spectrum_hsfunction_min(namespace, aa, bb, omega_min, func_min)
Definition: spectrum.F90:1587
subroutine, public spectrum_hsfunction_init(dt, is, ie, niter, acc)
Definition: spectrum.F90:1538
subroutine, public spectrum_hsfunction_end
Definition: spectrum.F90:1573
subroutine target_init_hhgnew(tg, gr, kpoints, namespace, space, ions, qcs, td, w0, oct, ep, restart)
Definition: target_hhg.F90:292
subroutine target_tdcalc_hhgnew(tg, namespace, space, hm, gr, ions, ext_partners, psi, time, max_time)
Definition: target_hhg.F90:651
subroutine target_output_hhgnew(tg, namespace, space, gr, dir, ions, hm, outp)
Definition: target_hhg.F90:431
subroutine target_end_hhgnew(tg, oct)
Definition: target_hhg.F90:453
subroutine target_init_hhg(tg, gr, kpoints, namespace, space, ions, qcs, td, w0, oct, ep, restart)
Definition: target_hhg.F90:205
real(real64) function target_j1_hhg(tg, namespace, gr, kpoints, qcpsi, ions)
Definition: target_hhg.F90:476
subroutine target_end_hhg(tg, oct)
Definition: target_hhg.F90:394
real(real64) function target_j1_hhgnew(tg, namespace, gr, kpoints, qcpsi, ions)
Definition: target_hhg.F90:512
subroutine target_chi_hhgnew(tg, namespace, gr, kpoints, qcpsi_in, qcchi_out, ions)
The HHG targets are time-dependent, so chi(T) = 0.
Definition: target_hhg.F90:567
subroutine target_output_hhg(tg, namespace, space, gr, dir, ions, hm, outp)
Definition: target_hhg.F90:410
subroutine target_chi_hhg(tg, namespace, gr, kpoints, qcpsi_in, qcchi_out, ions)
The HHG targets are time-dependent, so chi(T) = 0.
Definition: target_hhg.F90:538
subroutine target_tdcalc_hhg(tg, namespace, space, hm, gr, ions, ext_partners, psi, time, max_time)
Definition: target_hhg.F90:724
subroutine target_inh_hhgnew(tg, psi, gr, kpoints, time, inh, iter)
Inhomogeneous term for the hhgnew target.
Definition: target_hhg.F90:610
subroutine target_init_propagation_hhgnew(tg)
Per-propagation reset for the hhgnew target.
Definition: target_hhg.F90:596
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 harmonic emission spectrum (peak optimization).
Definition: target_hhg.F90:157
Target on the harmonic spectrum integrated with a weight function.
Definition: target_hhg.F90:175
Abstract optimal-control target.
Definition: target.F90:172