Octopus
opt_control.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
26 use debug_oct_m
30 use filter_oct_m
31 use global_oct_m
32 use grid_oct_m
34 use initst_oct_m
35 use ions_oct_m
36 use iso_c_binding
37 use, intrinsic :: iso_fortran_env
38 use io_oct_m
40 use lasers_oct_m
41 use loct_oct_m
42 use math_oct_m
45 use mpi_oct_m, only: mpi_world
51 use output_oct_m
52 use parser_oct_m
61 use target_oct_m
63 use td_oct_m
64
65 implicit none
66
67 private
68 public :: &
75
76
78 type(filter_t), save :: filter
79 type(oct_t), save :: oct
80 type(oct_iterator_t), save :: iterator
81 type(target_t), save :: oct_target
82 type(opt_control_state_t), save :: initial_st
83
84
86 type(controlfunction_t), save :: par_
87 type(electrons_t), pointer :: sys_
88 type(hamiltonian_elec_t), pointer :: hm_
89 type(td_t), pointer :: td_
90 real(real64), allocatable :: x_(:)
91 integer :: index_
92
93contains
94
95 ! ---------------------------------------------------------
96 subroutine opt_control_run(system)
97 class(*), intent(inout) :: system
98
99 push_sub(opt_control_run)
100
101 select type (system)
102 class is (multisystem_basic_t)
103 message(1) = "CalculationMode = opt_control not implemented for multi-system calculations"
104 call messages_fatal(1, namespace=system%namespace)
105 type is (electrons_t)
106 call opt_control_run_legacy(system)
107 end select
108
109 pop_sub(opt_control_run)
110 end subroutine opt_control_run
111
114 subroutine opt_control_run_legacy(sys)
115 type(electrons_t), target, intent(inout) :: sys
116
117 type(td_t), target :: td
118 type(controlfunction_t) :: par, par_new, par_prev
119 logical :: stop_loop
120 real(real64) :: j1
121 type(oct_prop_t) :: prop_chi, prop_psi
122 type(states_elec_t) :: psi
123
124 type(lasers_t), pointer :: lasers
125
126 push_sub(opt_control_run_legacy)
127
128 if (sys%hm%pcm%run_pcm) then
129 call messages_not_implemented("PCM for CalculationMode /= gs or td", namespace=sys%namespace)
130 end if
131
132 if (sys%kpoints%use_symmetries) then
133 call messages_experimental("KPoints symmetries with CalculationMode = opt_control", namespace=sys%namespace)
134 end if
135
136 ! Creates a directory where the optimal control stuff will be written. The name of the directory
137 ! is stored in the preprocessor macro OCT_DIR, which should be defined in src/include/global.h
138 call io_mkdir(oct_dir, sys%namespace)
139
140 ! Initializes the time propagator. Then, it forces the propagation to be self consistent, in case
141 ! the theory level is not "independent particles".
142 call td_init(td, sys%namespace, sys%space, sys%gr, sys%ions, sys%st, sys%ks, sys%hm, sys%ext_partners, sys%outp)
143 if (sys%hm%theory_level /= independent_particles) call propagator_elec_set_scf_prop(td%tr, threshold = 1.0e-14_real64)
144
145 ! Read general information about how the OCT run will be made, from inp file. "oct_read_inp" is
146 ! in the opt_control_global_oct_m module (like the definition of the oct_t data type)
147 call oct_read_inp(oct, sys%namespace)
148
149 ! Read info about, and prepare, the control functions
150 call controlfunction_mod_init(sys%ext_partners, sys%namespace, td%dt, td%max_iter, oct%mode_fixed_fluence)
151 call controlfunction_init(par, td%dt, td%max_iter)
152 call controlfunction_set(par, sys%ext_partners)
153 ! This prints the initial control parameters, exactly as described in the inp file,
154 ! that is, without applying any envelope or filter.
155 call controlfunction_write(oct_dir//'initial_laser_inp', par, sys%namespace)
157 call controlfunction_to_h(par, sys%ext_partners)
158 call messages_print_with_emphasis(msg="TD ext. fields after processing", namespace=sys%namespace)
159 lasers => list_get_lasers(sys%ext_partners)
160 if(associated(lasers)) call laser_write_info(lasers%lasers, namespace=sys%namespace)
161 call messages_print_with_emphasis(namespace=sys%namespace)
162 call controlfunction_write(oct_dir//'initial_laser', par, sys%namespace)
163
164
165 ! Startup of the iterator data type (takes care of counting iterations, stopping, etc).
166 call oct_iterator_init(iterator, sys%namespace, par)
167
168
169 ! Initialization of the propagation_oct_m module.
170 call propagation_mod_init(td%max_iter, oct%eta, oct%delta, oct%number_checkpoints, &
171 (oct%algorithm == option__octscheme__oct_zbr98), &
172 (oct%algorithm == option__octscheme__oct_cg) .or. &
173 (oct%algorithm == option__octscheme__oct_bfgs) .or. &
174 (oct%algorithm == option__octscheme__oct_nlopt_lbfgs))
177 ! If filters are to be used, they also have to be initialized.
178 call filter_init(td%max_iter, sys%namespace, td%dt, filter)
179 call filter_write(filter, sys%namespace)
180
182 ! Figure out the starting wavefunction(s), and the target.
183 call initial_state_init(sys, initial_st)
184 call target_init(sys%gr, sys%kpoints, sys%namespace, sys%space, sys%ions, initial_st, td, &
185 controlfunction_w0(par), oct_target, oct, sys%hm%ep, sys%mc)
187 ! Sanity checks.
188 call check_faulty_runmodes(sys, td%tr)
189
190
191 ! Informative output.
192 call opt_control_get_qs(psi, initial_st)
193 call output_states(sys%outp, sys%namespace, sys%space, oct_dir//'initial', psi, sys%gr, sys%ions, sys%hm, -1)
194 call target_output(oct_target, sys%namespace, sys%space, sys%gr, oct_dir//'target', sys%ions, sys%hm, sys%outp)
195 call states_elec_end(psi)
196
197
198 ! mode switcher; here is where the real run is made.
199 select case (oct%algorithm)
200 case (option__octscheme__oct_zbr98)
201 message(1) = "Info: Starting OCT iteration using scheme: ZBR98"
202 call messages_info(1, namespace=sys%namespace)
203 call scheme_zbr98()
204 case (option__octscheme__oct_wg05)
205 message(1) = "Info: Starting OCT iteration using scheme: WG05"
206 call messages_info(1, namespace=sys%namespace)
207 call scheme_wg05()
208 case (option__octscheme__oct_zr98)
209 message(1) = "Info: Starting OCT iteration using scheme: ZR98"
210 call messages_info(1, namespace=sys%namespace)
211 call scheme_mt03()
212 case (option__octscheme__oct_mt03)
213 message(1) = "Info: Starting OCT iteration using scheme: MT03"
214 call messages_info(1, namespace=sys%namespace)
215 call scheme_mt03()
216 case (option__octscheme__oct_krotov)
217 message(1) = "Info: Starting OCT iteration using scheme: KROTOV"
218 call messages_info(1, namespace=sys%namespace)
219 call scheme_mt03()
220 case (option__octscheme__oct_straight_iteration)
221 message(1) = "Info: Starting OCT iterations using scheme: STRAIGHT ITERATION"
222 call messages_info(1, namespace=sys%namespace)
224 case (option__octscheme__oct_cg)
225 message(1) = "Info: Starting OCT iterations using scheme: CONJUGATE GRADIENTS"
226 call messages_info(1, namespace=sys%namespace)
227 call scheme_cg()
228 case (option__octscheme__oct_bfgs)
229 message(1) = "Info: Starting OCT iterations using scheme: BFGS"
230 call messages_info(1, namespace=sys%namespace)
231 call scheme_cg()
232 case (option__octscheme__oct_direct)
233 message(1) = "Info: Starting OCT iterations using scheme: DIRECT OPTIMIZATION (NELDER-MEAD)"
234 call messages_info(1, namespace=sys%namespace)
235 call scheme_direct()
236 case (option__octscheme__oct_nlopt_bobyqa)
237 message(1) = "Info: Starting OCT iterations using scheme: DIRECT OPTIMIZATION (NLOPT - BOBYQA)"
238 call messages_info(1, namespace=sys%namespace)
239 call scheme_nlopt()
240 case (option__octscheme__oct_nlopt_lbfgs)
241 message(1) = "Info: Starting OCT iterations using scheme: DIRECT OPTIMIZATION (NLOPT - LBFGS)"
242 call messages_info(1, namespace=sys%namespace)
243 call scheme_nlopt()
244 case default
245 call messages_input_error(sys%namespace, 'OCTScheme')
246 end select
247
248 ! do final test run: propagate initial state with optimal field
249 call oct_finalcheck(sys, td)
250
251 ! clean up
252 call controlfunction_end(par)
253 call oct_iterator_end(iterator, sys%namespace)
254 call filter_end(filter)
255 call td_end(td)
256 call opt_control_state_end(initial_st)
257 call target_end(oct_target, oct)
259
261
262 contains
263
264
265 ! ---------------------------------------------------------
266 subroutine scheme_straight_iteration()
268
270 call controlfunction_copy(par_new, par)
271 ctr_loop: do
272 call controlfunction_copy(par_prev, par)
273 call f_striter(sys, td, par, j1)
274 stop_loop = iteration_manager(sys%namespace, j1, par_prev, par, iterator)
275 if (clean_stop(sys%mc%master_comm) .or. stop_loop) exit ctr_loop
276 end do ctr_loop
277
278 call controlfunction_end(par_new)
279 call controlfunction_end(par_prev)
281 end subroutine scheme_straight_iteration
282 ! ---------------------------------------------------------
283
284
285 ! ---------------------------------------------------------
286 subroutine scheme_mt03()
287 type(opt_control_state_t) :: psi
289
290 call opt_control_state_null(psi)
291 call opt_control_state_copy(psi, initial_st)
292 call oct_prop_init(prop_chi, sys%namespace, "chi", sys%gr, sys%mc)
293 call oct_prop_init(prop_psi, sys%namespace, "psi", sys%gr, sys%mc)
294
295 call controlfunction_copy(par_new, par)
296 ctr_loop: do
297 call controlfunction_copy(par_prev, par)
298 call f_iter(sys, td, psi, par, prop_psi, prop_chi, j1)
299 stop_loop = iteration_manager(sys%namespace, j1, par, par_prev, iterator)
300 if (clean_stop(sys%mc%master_comm) .or. stop_loop) exit ctr_loop
301 end do ctr_loop
302
303 call opt_control_state_end(psi)
304 call oct_prop_end(prop_chi)
305 call oct_prop_end(prop_psi)
306 call controlfunction_end(par_new)
307 call controlfunction_end(par_prev)
309 end subroutine scheme_mt03
310 ! ---------------------------------------------------------
311
312
313 ! ---------------------------------------------------------
314 subroutine scheme_wg05()
315 type(opt_control_state_t) :: psi
317
318 call oct_prop_init(prop_chi, sys%namespace, "chi", sys%gr, sys%mc)
319 call oct_prop_init(prop_psi, sys%namespace, "psi", sys%gr, sys%mc)
320
321 if (oct%mode_fixed_fluence) then
323 end if
324
325 call opt_control_state_null(psi)
326
327 call controlfunction_copy(par_new, par)
328 ctr_loop: do
329 call controlfunction_copy(par_prev, par)
330 call f_wg05(sys, td, psi, par, prop_psi, prop_chi, j1)
331 stop_loop = iteration_manager(sys%namespace, j1, par, par_prev, iterator)
332 if (clean_stop(sys%mc%master_comm) .or. stop_loop) exit ctr_loop
333 end do ctr_loop
334
335 call opt_control_state_end(psi)
336 call oct_prop_end(prop_chi)
337 call oct_prop_end(prop_psi)
338 call controlfunction_end(par_new)
339 call controlfunction_end(par_prev)
341 end subroutine scheme_wg05
342 ! ---------------------------------------------------------
343
344
345 ! ---------------------------------------------------------
346 subroutine scheme_zbr98()
347 type(opt_control_state_t) :: qcpsi
349
350 call opt_control_state_null(qcpsi)
351 call opt_control_state_copy(qcpsi, initial_st)
352 call oct_prop_init(prop_chi, sys%namespace, "chi", sys%gr, sys%mc)
353 call oct_prop_init(prop_psi, sys%namespace, "psi", sys%gr, sys%mc)
354
355 call controlfunction_copy(par_prev, par)
356 call propagate_forward(sys, td, par, oct_target, qcpsi, prop_psi)
357 j1 = target_j1(oct_target, sys%namespace, sys%gr, sys%kpoints, qcpsi)
358 stop_loop = iteration_manager(sys%namespace, j1, par, par_prev, iterator)
359 if (clean_stop(sys%mc%master_comm) .or. stop_loop) then
360 call opt_control_state_end(qcpsi)
361 call oct_prop_end(prop_chi)
362 call oct_prop_end(prop_psi)
364 return
365 end if
366
367 call controlfunction_copy(par_new, par)
368 ctr_loop: do
369 call controlfunction_copy(par_prev, par)
370 call f_zbr98(sys, td, qcpsi, prop_psi, prop_chi, par)
371 j1 = target_j1(oct_target, sys%namespace, sys%gr, sys%kpoints, qcpsi)
372 stop_loop = iteration_manager(sys%namespace, j1, par, par_prev, iterator)
373 if (clean_stop(sys%mc%master_comm) .or. stop_loop) exit ctr_loop
374 end do ctr_loop
375
376 call opt_control_state_end(qcpsi)
377 call oct_prop_end(prop_chi)
378 call oct_prop_end(prop_psi)
379 call controlfunction_end(par_new)
380 call controlfunction_end(par_prev)
382 end subroutine scheme_zbr98
383 ! ---------------------------------------------------------
384
385
386 ! ---------------------------------------------------------
387 subroutine scheme_cg()
388 integer :: dof, ierr, maxiter
389 real(real64):: step, minvalue
390 real(real64), allocatable :: theta(:)
391 real(real64), allocatable :: x(:)
392 real(real64) :: f
393 type(opt_control_state_t) :: qcpsi
395
397
398 call opt_control_state_null(qcpsi)
399 call opt_control_state_copy(qcpsi, initial_st)
400 call propagate_forward(sys, td, par, oct_target, qcpsi)
401 f = - target_j1(oct_target, sys%namespace, sys%gr, sys%kpoints, qcpsi, sys%ions) - controlfunction_j2(par)
402 call opt_control_state_end(qcpsi)
403 call iteration_manager_direct(-f, par, iterator, sys)
404 if (oct_iterator_maxiter(iterator) == 0) then
405 ! Nothing to do.
407 return
408 end if
410 if (oct%random_initial_guess) call controlfunction_randomize(par)
411
412 ! Set the module pointers, so that the opt_control_cg_calc and opt_control_cg_write_info routines
413 ! can use them.
414 call controlfunction_copy(par_, par)
415 sys_ => sys
416 hm_ => sys%hm
417 td_ => td
418
419 dof = controlfunction_dof(par)
420 safe_allocate(x(1:dof))
421 safe_allocate(theta(1:dof))
422 call controlfunction_get_theta(par, theta)
423 x = theta
424
425 step = oct%direct_step * m_pi
426 maxiter = oct_iterator_maxiter(iterator) - 1
427
428 select case (oct%algorithm)
429 case (option__octscheme__oct_bfgs)
430 call minimize_multidim(minmethod_bfgs2, dof, x, step, 0.1_real64, &
431 real(oct_iterator_tolerance(iterator), real64), real(oct_iterator_tolerance(iterator), real64), &
432 maxiter, opt_control_cg_calc, opt_control_cg_write_info, minvalue, ierr)
433 case (option__octscheme__oct_cg)
434 call minimize_multidim(minmethod_fr_cg, dof, x, step, 0.1_real64, &
435 real(oct_iterator_tolerance(iterator), real64), real(oct_iterator_tolerance(iterator), real64), &
436 maxiter, opt_control_cg_calc, opt_control_cg_write_info, minvalue, ierr)
437 end select
438
439 if (ierr /= 0) then
440 if (ierr <= 1024) then
441 message(1) = "Error occurred during the GSL minimization procedure:"
442 call loct_strerror(ierr, message(2))
443 call messages_fatal(2, namespace=sys%namespace)
444 else
445 message(1) = "The optimization did not meet the convergence criterion."
446 call messages_info(1, namespace=sys%namespace)
447 end if
448 end if
449
450 call controlfunction_end(par_)
451 safe_deallocate_a(x)
452 safe_deallocate_a(theta)
454 end subroutine scheme_cg
455 ! ---------------------------------------------------------
456
457
458 ! ---------------------------------------------------------
459 subroutine scheme_direct()
460 integer :: ierr, maxiter
461 real(real64):: minvalue, step
462 real(real64), allocatable :: theta(:)
463 real(real64), allocatable :: x(:)
464 real(real64) :: f
465 integer :: dim
466 type(opt_control_state_t) :: qcpsi
467
469
471 dim = controlfunction_dof(par)
472
473 call opt_control_state_null(qcpsi)
474 call opt_control_state_copy(qcpsi, initial_st)
475 call propagate_forward(sys, td, par, oct_target, qcpsi)
476 f = - target_j1(oct_target, sys%namespace, sys%gr, sys%kpoints, qcpsi, sys%ions) - controlfunction_j2(par)
477 call opt_control_state_end(qcpsi)
478 call iteration_manager_direct(-f, par, iterator, sys)
479 if (oct_iterator_maxiter(iterator) == 0) then
480 ! Nothing to do.
482 return
483 end if
484
485 safe_allocate(x(1:dim))
486 safe_allocate(theta(1:dim))
487
488 if (oct%random_initial_guess) call controlfunction_randomize(par)
489
490 ! Set the module pointers, so that the opt_control_direct_calc and opt_control_direct_message_info routines
491 ! can use them.
492 call controlfunction_copy(par_, par)
493 sys_ => sys
494 hm_ => sys%hm
495 td_ => td
496
497 ! theta may be in single precision, whereas x is always double precision.
498 call controlfunction_get_theta(par, theta)
499 x = theta
500
501 step = oct%direct_step * m_pi
502 maxiter = oct_iterator_maxiter(iterator)
503
504 call minimize_multidim_nograd(minmethod_nmsimplex, dim, x, step, &
505 real(oct_iterator_tolerance(iterator), real64) , maxiter, &
506 opt_control_direct_calc, opt_control_direct_message_info, minvalue, ierr)
507
508 if (ierr /= 0) then
509 if (ierr <= 1024) then
510 message(1) = "Error occurred during the GSL minimization procedure:"
511 call loct_strerror(ierr, message(2))
512 call messages_fatal(2, namespace=sys%namespace)
513 else
514 message(1) = "The OCT direct optimization did not meet the convergence criterion."
515 call messages_info(1, namespace=sys%namespace)
516 end if
517 end if
518
519 call controlfunction_end(par_)
520 safe_deallocate_a(x)
521 safe_deallocate_a(theta)
523 end subroutine scheme_direct
524 ! ---------------------------------------------------------
525
526
527 ! ---------------------------------------------------------
528 subroutine scheme_nlopt()
529#if defined(HAVE_NLOPT)
530 integer :: method, dim, maxiter, ierr
531 real(real64), allocatable :: x(:), xl(:), xu(:)
532 real(real64) :: step, toldr, minimum, f
533 type(opt_control_state_t) :: qcpsi
535
537
538 call opt_control_state_null(qcpsi)
539 call opt_control_state_copy(qcpsi, initial_st)
540 call propagate_forward(sys, td, par, oct_target, qcpsi)
541 f = - target_j1(oct_target, sys%namespace, sys%gr, sys%kpoints, qcpsi, sys%ions) - controlfunction_j2(par)
542 call opt_control_state_end(qcpsi)
543 call iteration_manager_direct(-f, par, iterator, sys)
544 if (oct_iterator_maxiter(iterator) == 0) then
545 ! Nothing to do.
547 return
548 end if
549
550 dim = controlfunction_dof(par)
551 safe_allocate(x(dim))
552 safe_allocate(xl(1:dim))
553 safe_allocate(xu(1:dim))
554 call controlfunction_bounds(par, xl, xu)
555
556 if (oct%random_initial_guess) call controlfunction_randomize(par)
557
558 ! Set the module pointers, so that the calc_point and write_iter_info routines
559 ! can use them.
560 call controlfunction_copy(par_, par)
561 sys_ => sys
562 hm_ => sys%hm
563 td_ => td
564
565 call controlfunction_get_theta(par, x)
566
567 maxiter = oct_iterator_maxiter(iterator)
568 step = oct%direct_step
569 select case (oct%algorithm)
570 case (option__octscheme__oct_nlopt_bobyqa)
572 case (option__octscheme__oct_nlopt_lbfgs)
573 method = minmethod_nlopt_lbfgs
574 end select
575 toldr = oct_iterator_tolerance(iterator)
576
577 call minimize_multidim_nlopt(ierr, method, dim, x, step, toldr, maxiter, opt_control_nlopt_func, minimum, &
578 xl, xu)
579 if (ierr < 1 .or. ierr > 4) then
580 message(1) = "The nlopt minimization procedure did not find convergence, or found an error"
581 write(message(2),'(a,i5)') "Error code =", ierr
582 call messages_info(2, namespace=sys%namespace)
583 end if
584
585 call controlfunction_end(par_)
586 safe_deallocate_a(xl)
587 safe_deallocate_a(xu)
588 safe_deallocate_a(x)
590#endif
591 end subroutine scheme_nlopt
592 ! ---------------------------------------------------------
593
594 end subroutine opt_control_run_legacy
595 ! ---------------------------------------------------------
596
597
598 ! ---------------------------------------------------------
599 subroutine f_zbr98(sys, td, qcpsi, prop_psi, prop_chi, par)
600 type(electrons_t), intent(inout) :: sys
601 type(td_t), intent(inout) :: td
602 type(opt_control_state_t), intent(inout) :: qcpsi
603 type(oct_prop_t), intent(inout) :: prop_psi
604 type(oct_prop_t), intent(inout) :: prop_chi
605 type(controlfunction_t), intent(inout) :: par
606
607 type(states_elec_t) :: chi
608 type(opt_control_state_t) :: qcchi
609 type(controlfunction_t) :: par_chi
610
611 push_sub(f_zbr98)
612
613 call controlfunction_copy(par_chi, par)
614
615 call target_get_state(oct_target, chi)
616 call opt_control_state_init(qcchi, chi, sys%ions)
617 call bwd_step(sys, td, oct_target, par, par_chi, qcchi, prop_chi, prop_psi)
618 call opt_control_state_copy(qcpsi, initial_st)
619 call fwd_step(sys, td, oct_target, par, par_chi, qcpsi, prop_chi, prop_psi)
620
621 call states_elec_end(chi)
622 call opt_control_state_end(qcchi)
624 pop_sub(f_zbr98)
625 end subroutine f_zbr98
626
627
628 ! ---------------------------------------------------------
629 subroutine f_wg05(sys, td, qcpsi, par, prop_psi, prop_chi, j1)
630 type(electrons_t), intent(inout) :: sys
631 type(td_t), intent(inout) :: td
632 type(opt_control_state_t), intent(inout) :: qcpsi
633 type(controlfunction_t), intent(inout) :: par
634 type(oct_prop_t), intent(inout) :: prop_psi
635 type(oct_prop_t), intent(inout) :: prop_chi
636 real(real64), intent(out) :: j1
637
638 real(real64) :: new_penalty
639 type(opt_control_state_t) :: qcchi
640 type(controlfunction_t) :: parp
641
642 push_sub(f_wg05)
643
644 if (oct_iterator_current(iterator) == 0) then
645 call opt_control_state_copy(qcpsi, initial_st)
646 call propagate_forward(sys, td, par, oct_target, qcpsi, prop_psi)
647 j1 = target_j1(oct_target, sys%namespace, sys%gr, sys%kpoints, qcpsi)
648 pop_sub(f_wg05)
649 return
650 end if
651
652 call controlfunction_copy(parp, par)
653
654 call opt_control_state_null(qcchi)
655 call opt_control_state_copy(qcchi, qcpsi)
656 call target_chi(oct_target, sys%namespace, sys%gr, sys%kpoints, qcpsi, qcchi, sys%ions)
657 call bwd_step(sys, td, oct_target, par, parp, qcchi, prop_chi, prop_psi)
658
659 call controlfunction_filter(parp, filter)
660
661 ! recalc field
662 if (oct%mode_fixed_fluence) then
664 call controlfunction_set_alpha(parp, new_penalty)
666 end if
667
668 call controlfunction_copy(par, parp)
670
671 call opt_control_state_copy(qcpsi, initial_st)
672 call propagate_forward(sys, td, par, oct_target, qcpsi, prop_psi)
673
674 j1 = target_j1(oct_target, sys%namespace, sys%gr, sys%kpoints, qcpsi)
675
676 call opt_control_state_end(qcchi)
677 call controlfunction_end(parp)
678 pop_sub(f_wg05)
679 end subroutine f_wg05
680 ! ---------------------------------------------------------
681
682
683 ! ---------------------------------------------------------
684 subroutine f_striter(sys, td, par, j1)
685 type(electrons_t), intent(inout) :: sys
686 type(td_t), intent(inout) :: td
687 type(controlfunction_t), intent(inout) :: par
688 real(real64), intent(out) :: j1
689
690 type(opt_control_state_t) :: qcpsi
691 type(opt_control_state_t) :: qcchi
692 type(controlfunction_t) :: par_chi
693 type(oct_prop_t) :: prop_chi, prop_psi
694
695 push_sub(f_striter)
696
697 call oct_prop_init(prop_chi, sys%namespace, "chi", sys%gr, sys%mc)
698 call oct_prop_init(prop_psi, sys%namespace, "psi", sys%gr, sys%mc)
699
701
702 call controlfunction_copy(par_chi, par)
703
704 ! First, a forward propagation with the input field.
705 call opt_control_state_null(qcpsi)
706 call opt_control_state_copy(qcpsi, initial_st)
707 call propagate_forward(sys, td, par, oct_target, qcpsi, prop_psi)
708
709 ! Check the performance.
710 j1 = target_j1(oct_target, sys%namespace, sys%gr, sys%kpoints, qcpsi, sys%ions)
711
712 ! Set the boundary condition for the backward propagation.
713 call opt_control_state_null(qcchi)
714 call opt_control_state_copy(qcchi, qcpsi)
715 call target_chi(oct_target, sys%namespace, sys%gr, sys%kpoints, qcpsi, qcchi, sys%ions)
716
717 ! Backward propagation, while at the same time finding the output field,
718 ! which is placed at par_chi
719 call bwd_step_2(sys, td, oct_target, par, par_chi, qcchi, prop_chi, prop_psi)
720 !if (oct%mode_fixed_fluence) call controlfunction_set_fluence(par_chi)
721
722 ! Copy par_chi to par
723 call controlfunction_copy(par, par_chi)
724
725 call opt_control_state_end(qcpsi)
726 call opt_control_state_end(qcchi)
727 call controlfunction_end(par_chi)
728 call oct_prop_end(prop_chi)
729 call oct_prop_end(prop_psi)
730
731 pop_sub(f_striter)
732 end subroutine f_striter
733 ! ---------------------------------------------------------
734
735
736 ! ---------------------------------------------------------
737 subroutine f_iter(sys, td, qcpsi, par, prop_psi, prop_chi, j1)
738 type(electrons_t), intent(inout) :: sys
739 type(td_t), intent(inout) :: td
740 type(opt_control_state_t), intent(inout) :: qcpsi
741 type(controlfunction_t), intent(inout) :: par
742 type(oct_prop_t), intent(inout) :: prop_psi
743 type(oct_prop_t), intent(inout) :: prop_chi
744 real(real64), intent(out) :: j1
745
746 type(opt_control_state_t) :: qcchi
747 type(controlfunction_t) :: par_chi
748
749 push_sub(f_iter)
750
751 if (oct_iterator_current(iterator) == 0) then
752 call opt_control_state_copy(qcpsi, initial_st)
753 call propagate_forward(sys, td, par, oct_target, qcpsi, prop_psi)
754 j1 = target_j1(oct_target, sys%namespace, sys%gr, sys%kpoints, qcpsi)
755 pop_sub(f_iter)
756 return
757 end if
758
759 call controlfunction_copy(par_chi, par)
760
761 call opt_control_state_null(qcchi)
762 call opt_control_state_copy(qcchi, qcpsi)
763 call target_chi(oct_target, sys%namespace, sys%gr, sys%kpoints, qcpsi, qcchi, sys%ions)
764 call bwd_step(sys, td, oct_target, par, par_chi, qcchi, prop_chi, prop_psi)
765
766 call opt_control_state_copy(qcpsi, initial_st)
767 call fwd_step(sys, td, oct_target, par, par_chi, qcpsi, prop_chi, prop_psi)
768
769 j1 = target_j1(oct_target, sys%namespace, sys%gr, sys%kpoints, qcpsi)
770
772 call controlfunction_end(par_chi)
773 pop_sub(f_iter)
774 end subroutine f_iter
775 ! ---------------------------------------------------------
776
777#include "opt_control_c_inc.F90"
778#include "check_input_inc.F90"
779#include "finalcheck_inc.F90"
780
781
782end module opt_control_oct_m
783
784!! Local Variables:
785!! mode: f90
786!! coding: utf-8
787!! End:
Define which routines can be seen from the outside.
Definition: loct.F90:148
double sqrt(double __x) __attribute__((__nothrow__
This module contains the definition of the data type that holds a "control function" used for OCT run...
subroutine, public controlfunction_filter(par, filter)
subroutine, public controlfunction_apply_envelope(cp)
subroutine, public controlfunction_set_fluence(par)
subroutine, public controlfunction_bounds(par, lower_bounds, upper_bounds)
subroutine, public controlfunction_to_realtime(par)
integer pure function, public controlfunction_dof(par)
real(real64) function, public controlfunction_fluence(par)
subroutine, public controlfunction_set_alpha(par, alpha)
subroutine, public controlfunction_write(filename, cp, namespace)
subroutine, public controlfunction_prepare_initial(par)
"Prepares" the initial guess control field: maybe it has to be normalized to a certain fluence,...
real(real64) pure function, public controlfunction_w0(par)
subroutine, public controlfunction_end(cp)
subroutine, public controlfunction_get_theta(par, theta)
real(real64) function, public controlfunction_j2(par)
subroutine, public controlfunction_randomize(par)
real(real64) pure function, public controlfunction_alpha(par, ipar)
real(real64) pure function, public controlfunction_targetfluence()
subroutine, public controlfunction_copy(cp_out, cp_in)
subroutine, public controlfunction_set_rep(par)
Transforms the control function to frequency space, if this is the space in which the functions are d...
subroutine, public controlfunction_mod_close()
subroutine, public controlfunction_to_h(cp, ext_partners)
subroutine, public controlfunction_init(cp, dt, ntiter)
Before using an controlfunction_t variable, it needs to be initialized, either by calling controlfunc...
subroutine, public controlfunction_mod_init(ext_partners, namespace, dt, max_iter, mode_fixed_fluence)
Initializes the module, should be the first subroutine to be called (the last one should be controlfu...
subroutine, public controlfunction_set(cp, ext_partners)
The external fields defined in epot_t "ep" are transferred to the control functions described in "cp"...
type(lasers_t) function, pointer, public list_get_lasers(partners)
subroutine, public filter_init(steps, namespace, dt, filter)
Definition: filter.F90:156
subroutine, public filter_write(filter, namespace)
Definition: filter.F90:335
subroutine, public filter_end(filter)
Definition: filter.F90:369
real(real64), parameter, public m_pi
some mathematical constants
Definition: global.F90:188
character(len= *), parameter, public oct_dir
Definition: global.F90:263
This module implements the underlying real-space grid.
Definition: grid.F90:119
subroutine, public initial_state_init(sys, qcstate)
Definition: initst.F90:156
Definition: io.F90:116
subroutine, public io_mkdir(fname, namespace, parents)
Definition: io.F90:360
A module to handle KS potential, without the external potential.
integer, parameter, public independent_particles
subroutine, public laser_write_info(lasers, namespace, dt, max_iter, iunit)
Definition: lasers.F90:932
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:117
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:904
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1097
character(len=512), private msg
Definition: messages.F90:167
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:416
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:697
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1069
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:600
integer, parameter, public minmethod_fr_cg
Definition: minimizer.F90:136
integer, parameter, public minmethod_nmsimplex
Definition: minimizer.F90:136
integer, parameter, public minmethod_bfgs2
Definition: minimizer.F90:136
integer, parameter, public minmethod_nlopt_bobyqa
Definition: minimizer.F90:136
integer, parameter, public minmethod_nlopt_lbfgs
Definition: minimizer.F90:136
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:272
This module implements the basic mulsisystem class, a container system for other systems.
This module contains the definition of the oct_t data type, which contains some of the basic informat...
subroutine, public oct_read_inp(oct, namespace)
Reads, from the inp file, some global information about how the QOCT run should be.
logical function, public iteration_manager(namespace, j1, par, par_prev, iterator)
subroutine, public oct_iterator_init(iterator, namespace, par)
integer pure function, public oct_iterator_maxiter(iterator)
subroutine, public oct_iterator_end(iterator, namespace)
integer pure function, public oct_iterator_current(iterator)
subroutine, public iteration_manager_direct(j, par, iterator, sys, dx)
real(real64) pure function, public oct_iterator_tolerance(iterator)
This module contains the main procedure ("opt_control_run") that is used when optimal control runs ar...
subroutine, public opt_control_cg_calc(n, x, f, getgrad, df)
subroutine check_faulty_runmodes(sys, tr)
subroutine, public opt_control_run(system)
subroutine oct_finalcheck(sys, td)
subroutine, public opt_control_cg_write_info(iter, n, val, maxdx, maxdf, x)
interface is required by its being passed as dummy routine to minimize_multidim
subroutine f_striter(sys, td, par, j1)
subroutine, public opt_control_direct_message_info(iter, n, val, maxdx, x)
subroutine f_zbr98(sys, td, qcpsi, prop_psi, prop_chi, par)
subroutine f_iter(sys, td, qcpsi, par, prop_psi, prop_chi, j1)
subroutine opt_control_run_legacy(sys)
This is the main procedure for all types of optimal control runs. It is called from the "run" procedu...
subroutine f_wg05(sys, td, qcpsi, par, prop_psi, prop_chi, j1)
subroutine, public opt_control_function_forward(x, f)
subroutine, public opt_control_direct_calc(n, x, f)
No intents here is unfortunately required because this will be passed to newuoa routines as a dummy f...
This module holds the "opt_control_state_t" datatype, which contains a quantum-classical state.
subroutine, public opt_control_state_end(ocs)
subroutine, public opt_control_state_null(ocs)
subroutine, public opt_control_state_copy(ocsout, ocsin)
subroutine, public opt_control_state_init(ocs, qstate, ions)
subroutine, public opt_control_get_qs(qstate, ocs)
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:1103
subroutine, public propagation_mod_init(niter, eta, delta, number_checkpoints, zbr98, gradients)
This subroutine must be called before any QOCT propagations are done. It simply stores in the module ...
subroutine, public oct_prop_end(prop)
subroutine, public bwd_step(sys, td, tg, par, par_chi, qcchi, prop_chi, prop_psi)
subroutine, public propagate_forward(sys, td, par, tg, qcpsi, prop, write_iter)
subroutine, public fwd_step(sys, td, tg, par, par_chi, qcpsi, prop_chi, prop_psi)
subroutine, public oct_prop_init(prop, namespace, dirname, mesh, mc)
subroutine, public bwd_step_2(sys, td, tg, par, par_chi, qcchi, prop_chi, prop_psi)
subroutine, public propagator_elec_set_scf_prop(tr, threshold)
logical function, public clean_stop(comm)
returns true if a file named stop exists
Definition: restart.F90:335
This module handles spin dimensions of the states and the k-point distribution.
subroutine, public states_elec_end(st)
finalize the states_elec_t object
real(real64) function, public target_j1(tg, namespace, gr, kpoints, qcpsi, ions)
Calculates the J1 functional, i.e.: in the time-independent case, or else in the time-dependent cas...
Definition: target.F90:580
subroutine, public target_init(gr, kpoints, namespace, space, ions, qcs, td, w0, tg, oct, ep, mc)
The target is initialized, mainly by reading from the inp file.
Definition: target.F90:219
subroutine, public target_get_state(tg, st)
This just copies the states_elec_t variable present in target, into st.
Definition: target.F90:205
subroutine, public target_output(tg, namespace, space, gr, dir, ions, hm, outp)
Definition: target.F90:398
subroutine, public target_chi(tg, namespace, gr, kpoints, qcpsi_in, qcchi_out, ions)
Calculate .
Definition: target.F90:632
subroutine, public target_end(tg, oct)
Definition: target.F90:365
Definition: td.F90:116
subroutine, public td_end(td)
Definition: td.F90:633
subroutine, public td_init(td, namespace, space, gr, ions, st, ks, hm, ext_partners, outp)
Definition: td.F90:240
subroutine scheme_zbr98()
subroutine scheme_cg()
subroutine scheme_direct()
subroutine scheme_straight_iteration()
subroutine scheme_mt03()
subroutine scheme_wg05()
subroutine scheme_nlopt()
This is the data type used to hold a control function.
Class describing the electron system.
Definition: electrons.F90:220
Container class for lists of system_oct_m::system_t.
This is the datatype that contains the objects that are propagated: in principle this could be both t...
The states_elec_t class contains all electronic wave functions.