27 use,
intrinsic :: iso_fortran_env
54 integer :: ctr_iter_max
56 integer :: ctr_iter_main
57 real(real64) :: bestJ1
58 real(real64) :: bestJ1_fluence
59 real(real64) :: bestJ1_J
60 integer :: bestJ1_ctr_iter
61 type(controlfunction_t) :: best_par
62 integer :: convergence_iunit
63 integer :: velocities_iunit
64 logical :: dump_intermediate
72 type(oct_iterator_t),
intent(inout) :: iterator
73 type(namespace_t),
intent(in) :: namespace
74 type(controlfunction_t),
intent(in) :: par
98 call parse_variable(namespace,
'OCTEps', 1.0e-6_real64, iterator%eps)
99 if (iterator%eps <
m_zero) iterator%eps = tiny(
m_one)
109 call parse_variable(namespace,
'OCTMaxIter', 10, iterator%ctr_iter_max)
111 if (iterator%ctr_iter_max < 0 .and. iterator%eps <
m_zero)
then
112 message(1) =
"OCTMaxIter and OCTEps cannot be both < 0."
115 if (iterator%ctr_iter_max < 0) iterator%ctr_iter_max = huge(iterator%ctr_iter_max)
125 call parse_variable(namespace,
'OCTDumpIntermediate', .false., iterator%dump_intermediate)
128 iterator%ctr_iter = 0
129 iterator%ctr_iter_main = 0
130 iterator%bestJ1 = -huge(iterator%bestJ1)
131 iterator%bestJ1_fluence =
m_zero
132 iterator%bestJ1_J =
m_zero
133 iterator%bestJ1_ctr_iter = 0
137 iterator%convergence_iunit =
io_open(
oct_dir//
'convergence', namespace, action=
'write')
139 write(iterator%convergence_iunit,
'(91(''#''))')
140 write(iterator%convergence_iunit,
'(5(a))')
'# iteration',
' J[Psi,chi,epsilon]', &
144 write(iterator%convergence_iunit,
'(91(''#''))')
147 iterator%velocities_iunit =
io_open(
oct_dir//
'velocities', namespace, action=
'write')
165 write(iterator%convergence_iunit,
'(91("#"))')
166 call io_close(iterator%convergence_iunit)
169 call io_close(iterator%velocities_iunit)
178 logical function iteration_manager(namespace, j1, par, par_prev, iterator)
result(stoploop)
180 real(real64),
intent(in) :: j1
185 real(real64) :: fluence, jfunctional, j2, delta
190 if (iterator%dump_intermediate)
call iterator_write(namespace, iterator, par)
196 jfunctional = j1 + j2
199 if (iterator%ctr_iter == iterator%ctr_iter_max)
then
200 message(1) =
"Info: Maximum number of iterations reached."
205 if ((iterator%eps >
m_zero) .and. &
206 (delta < iterator%eps) .and. &
207 (iterator%ctr_iter > 0))
then
208 message(1) =
"Info: Convergence threshold reached."
213 write(
message(1),
'(a,i5)')
'Optimal control iteration #', iterator%ctr_iter
216 write(
message(1),
'(6x,a,f12.5)')
" => J1 = ", j1
217 write(
message(2),
'(6x,a,f12.5)')
" => J = ", jfunctional
218 write(
message(3),
'(6x,a,f12.5)')
" => J2 = ", j2
219 write(
message(4),
'(6x,a,f12.5)')
" => Fluence = ", fluence
221 write(
message(6),
'(6x,a,es12.2)')
" => D[e,e'] = ", delta
222 if (iterator%ctr_iter /= 0)
then
229 bestj1 = (j1 > iterator%bestj1)
233 iterator%bestJ1_J = jfunctional
234 iterator%bestJ1_fluence = fluence
235 iterator%bestJ1_ctr_iter = iterator%ctr_iter
239 iterator%best_par, namespace)
242 write(iterator%convergence_iunit,
'(i11,4f20.8)') &
245 iterator%ctr_iter = iterator%ctr_iter + 1
254 real(real64),
intent(in) :: j
258 real(real64),
optional,
intent(in) :: dx
260 real(real64) :: j1, j2, fluence, delta
263 if (iterator%dump_intermediate)
call iterator_write(sys%namespace, iterator, par)
269 if (
present(dx))
then
275 if (iterator%ctr_iter == 0)
then
278 write(
message(1),
'(a,i5)')
'Function evaluation #', iterator%ctr_iter
282 write(
message(1),
'(6x,a,f12.5)')
" => J1 = ", j1
283 write(
message(2),
'(6x,a,f12.5)')
" => J = ", j
284 write(
message(3),
'(6x,a,f12.5)')
" => J2 = ", j2
285 write(
message(4),
'(6x,a,f12.5)')
" => Fluence = ", fluence
287 if (
present(dx))
then
288 write(
message(1),
'(6x,a,f12.5)')
" => Delta = ", dx
294 if (j1 > iterator%bestJ1)
then
296 iterator%bestJ1_J = j
297 iterator%bestJ1_fluence = fluence
298 iterator%bestJ1_ctr_iter = iterator%ctr_iter
302 iterator%best_par, sys%namespace)
305 write(iterator%convergence_iunit,
'(i11,4f20.8)') &
306 iterator%ctr_iter, j, j1, j2, delta
312 iterator%ctr_iter = iterator%ctr_iter + 1
323 real(real64),
intent(in) :: j, j1, j2, delta
327 iterator%ctr_iter_main = iterator%ctr_iter_main + 1
328 write(iterator%convergence_iunit,
'("### MAIN ITERATION")')
329 write(iterator%convergence_iunit,
'(a2,i9,4f20.8)') &
330 '##', iterator%ctr_iter_main, j, j1, j2, delta
331 write(iterator%convergence_iunit,
'("###")')
344 character(len=80) :: filename
348 write(filename,
'(a,i4.4)')
oct_dir//
'laser.', iterator%ctr_iter
362 par => iterator%best_par
396 type(electrons_t),
intent(in) :: sys
398 character (len=100) :: temp_str
399 character (len=2) :: atoms_str
400 character (len=1) :: dim_str
401 integer :: i, j, n_atoms, dim
405 n_atoms = sys%ions%natoms
409 if (iterator%ctr_iter == 0)
then
410 write(iterator%velocities_iunit,
'(100("#"))')
411 write(iterator%velocities_iunit,
'("# iter")',advance=
'no')
413 write(atoms_str,
'(i2.2)') i
415 write(dim_str,
'(i1)') j
416 temp_str =
"v[" // atoms_str //
"," // dim_str //
"]"
417 write(iterator%velocities_iunit,
'(a16)',advance=
'no') trim(temp_str)
420 write(iterator%velocities_iunit,
'("")')
421 write(iterator%velocities_iunit,
'(100("#"))')
425 write(iterator%velocities_iunit,
'(i7)',advance=
'no') iterator%ctr_iter
428 write(iterator%velocities_iunit,
'(4(" "),(f12.10))',advance=
'no') sys%ions%vel(j, i)
431 write(iterator%velocities_iunit,
'("")')
Prints out to iunit a message in the form: ["InputVariable" = value] where "InputVariable" is given b...
This module contains the definition of the data type that holds a "control function" used for OCT run...
real(real64) function, public controlfunction_diff(pp, qq)
real(real64) function, public controlfunction_fluence(par)
subroutine, public controlfunction_write(filename, cp, namespace)
subroutine, public controlfunction_end(cp)
real(real64) function, public controlfunction_j2(par)
real(real64) pure function, public controlfunction_alpha(par, ipar)
subroutine, public controlfunction_copy(cp_out, cp_in)
real(real64), parameter, public m_zero
real(real64), parameter, public m_one
character(len= *), parameter, public oct_dir
This module implements the underlying real-space grid.
subroutine, public io_close(iunit, grp)
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
character(len=512), private msg
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
subroutine, public oct_iterator_bestpar(par, iterator)
logical function, public iteration_manager(namespace, j1, par, par_prev, iterator)
subroutine, public iteration_manager_main(iterator, j, j1, j2, delta)
subroutine, public oct_iterator_init(iterator, namespace, par)
integer pure function, public oct_iterator_maxiter(iterator)
subroutine iterator_write(namespace, iterator, par)
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)
subroutine, public velocities_write(iterator, sys)
logical function, public parse_is_defined(namespace, name)
This is the data type used to hold a control function.
Class describing the electron system.