Octopus
controlfunction.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
28 use filter_oct_m
29 use global_oct_m
31 use io_oct_m
32 use, intrinsic :: iso_fortran_env
34 use lasers_oct_m
35 use math_oct_m
37 use mpi_oct_m
39 use parser_oct_m
41 use space_oct_m
43 use unit_oct_m
46
47 implicit none
48
49 private
50 public :: &
85
86
87 integer, public, parameter :: &
88 ctr_internal = 1, &
93 ctr_rt = 7
94
95
96
97 integer, parameter, public :: &
98 controlfunction_mode_none = 0, &
101
107 private
108 integer :: representation = 0
113 real(real64) :: omegamax = m_zero
116 real(real64) :: targetfluence = m_zero
119 logical :: fix_initial_fluence = .false.
121 integer :: mode = controlfunction_mode_none
126 real(real64) :: w0 = m_zero
128 integer :: no_controlfunctions = 0 !! The number of control functions to be optimized.
129 real(real64), allocatable :: alpha(:)
131 type(tdf_t), allocatable :: td_penalty(:)
133
134
137 private
138 integer :: no_controlfunctions = 0
141 integer :: dim = 0
145 integer :: dof = 0
147 type(tdf_t), allocatable :: f(:)
148 real(real64), allocatable :: alpha(:)
149
150 integer :: current_representation = 0
151
152 real(real64) :: w0 = m_zero
153 real(real64), allocatable :: u(:, :)
154 real(real64), allocatable :: utransf(:, :)
155 real(real64), allocatable :: utransfi(:, :)
156
157 real(real64), allocatable :: theta(:)
158 end type controlfunction_t
159
160 logical :: cf_common_initialized = .false.
161 type(controlfunction_common_t) :: cf_common
162
163contains
164
173 subroutine controlfunction_mod_init(ext_partners, namespace, dt, max_iter, mode_fixed_fluence)
174 type(partner_list_t), intent(in) :: ext_partners
175 type(namespace_t), intent(in) :: namespace
176 real(real64), intent(in) :: dt
177 integer, intent(in) :: max_iter
178 logical, intent(out) :: mode_fixed_fluence
179
180 character(len=1024) :: expression
181 integer :: no_lines, steps, il, idir, ncols, ipar, irow, ierr
182 real(real64) :: octpenalty
183 complex(real64) :: pol(3)
184 type(block_t) :: blk
185 type(lasers_t), pointer :: lasers
186
188
189 if (.not. cf_common_initialized) then
190 cf_common_initialized = .true.
191 else
192 message(1) = "Internal error: Cannot call controlfunction_mod_init twice."
193 call messages_fatal(1, namespace=namespace)
194 end if
195
196 call messages_print_with_emphasis(msg="OCT: Info about control functions", namespace=namespace)
197
198 !%Variable OCTControlFunctionRepresentation
199 !%Type integer
200 !%Section Calculation Modes::Optimal Control
201 !%Default control_fourier_series_h
202 !%Description
203 !% If <tt>OCTControlRepresentation = control_function_parametrized</tt>, one must
204 !% specify the kind of parameters that determine the control function.
205 !% If <tt>OCTControlRepresentation = control_function_real_time</tt>, then this variable
206 !% is ignored, and the control function is handled directly in real time.
207 !%Option control_fourier_series_h 3
208 !% The control function is expanded as a full Fourier series (although it must, of
209 !% course, be a real function). Then, the total fluence is fixed, and a transformation
210 !% to hyperspherical coordinates is done; the parameters to optimize are the hyperspherical
211 !% angles.
212 !%Option control_zero_fourier_series_h 4
213 !% The control function is expanded as a Fourier series, but assuming (1) that the zero
214 !% frequency component is zero, and (2) the control function, integrated in time, adds
215 !% up to zero (this essentially means that the sum of all the cosine coefficients is zero).
216 !% Then, the total fluence is fixed, and a transformation to hyperspherical coordinates is
217 !% done; the parameters to optimize are the hyperspherical angles.
218 !%Option control_fourier_series 5
219 !% The control function is expanded as a full Fourier series (although it must, of
220 !% course, be a real function). The control parameters are the coefficients of this
221 !% basis-set expansion.
222 !%Option control_zero_fourier_series 6
223 !% The control function is expanded as a full Fourier series (although it must, of
224 !% course, be a real function). The control parameters are the coefficients of this
225 !% basis-set expansion. The difference with the option <tt>control_fourier_series</tt> is that
226 !% (1) that the zero-frequency component is zero, and (2) the control function, integrated
227 !% in time, adds up to zero (this essentially means that the sum of all the cosine
228 !% coefficients is zero).
229 !%Option control_rt 7
230 !% (experimental)
231 !%End
232 call parse_variable(namespace, 'OCTControlFunctionRepresentation', ctr_rt, cf_common%representation)
233 if (.not. varinfo_valid_option('OCTControlFunctionRepresentation', cf_common%representation)) then
234 call messages_input_error(namespace, 'OCTControlFunctionRepresentation')
235 end if
236 select case (cf_common%representation)
238 write(message(1), '(a)') 'Info: The OCT control functions will be represented as a Fourier series,'
239 write(message(2), '(a)') ' and then a transformation to hyperspherical coordinates will be made.'
240 call messages_info(2, namespace=namespace)
242 write(message(1), '(a)') 'Info: The OCT control functions will be represented as a Fourier series,'
243 write(message(2), '(a)') ' in which (i) the zero-frequency component is assumed to be zero,'
244 write(message(3), '(a)') ' and (ii) the sum of all the cosine coefficients are zero, so that'
245 write(message(4), '(a)') ' the control function starts and ends at zero.'
246 write(message(5), '(a)') ' Then, a transformation to hyperspherical coordinates will be made.'
247 call messages_info(5, namespace=namespace)
249 write(message(1), '(a)') 'Info: The OCT control functions will be represented as a Fourier series.'
250 call messages_info(1, namespace=namespace)
252 write(message(1), '(a)') 'Info: The OCT control functions will be represented as a Fourier series,'
253 write(message(2), '(a)') ' in which the zero-frequency component is assumed to be zero,'
254 write(message(3), '(a)') ' and (ii) the sum of all the cosine coefficients are zero, so that'
255 write(message(4), '(a)') ' the control function starts and ends at zero.'
256 call messages_info(4, namespace=namespace)
257 case (ctr_rt)
258 write(message(1), '(a)') 'Info: The OCT control functions will be represented in real time.'
259 call messages_info(1, namespace=namespace)
260 call messages_experimental('"OCTControlFunctionRepresentation = ctr_rt"', namespace=namespace)
261 case default
262 write(message(1), '(a)') 'Info: The OCT control functions will be represented in real time.'
263 call messages_info(1, namespace=namespace)
264 call messages_experimental('"OCTControlFunctionRepresentation = ctr_rt"', namespace=namespace)
265 end select
267 !%Variable OCTControlFunctionOmegaMax
268 !%Type float
269 !%Section Calculation Modes::Optimal Control
270 !%Default -1.0
271 !%Description
272 !% The Fourier series that can be used to represent the control functions must be truncated;
273 !% the truncation is given by a cut-off frequency which is determined by this variable.
274 !%End
275 call parse_variable(namespace, 'OCTControlFunctionOmegaMax', -m_one, cf_common%omegamax)
276 if (cf_common%representation /= ctr_rt) then
277 write(message(1), '(a)') 'Info: The representation of the OCT control parameters will be restricted'
278 write(message(2), '(a,f10.5,a)') ' with an energy cut-off of ', &
279 units_from_atomic(units_out%energy, cf_common%omegamax), ' ['//trim(units_abbrev(units_out%energy)) // ']'
280 call messages_info(2, namespace=namespace)
281 end if
282
283 !%Variable OCTFixFluenceTo
284 !%Type float
285 !%Section Calculation Modes::Optimal Control
286 !%Default 0.0
287 !%Description
288 !% The algorithm tries to obtain the specified fluence for the laser field.
289 !% This works only in conjunction with either the WG05 or the straight iteration scheme.
290 !%
291 !% If this variable is not present in the input file, by default the code will not
292 !% attempt a fixed-fluence QOCT run. The same holds if the value given to this
293 !% variable is exactly zero.
294 !%
295 !% If this variable is given a negative value, then the target fluence will be that of
296 !% the initial laser pulse given as guess in the input file. Note, however, that
297 !% first the code applies the envelope provided by the <tt>OCTLaserEnvelope</tt> input
298 !% option, and afterwards it calculates the fluence.
299 !%End
300 call parse_variable(namespace, 'OCTFixFluenceTo', m_zero, cf_common%targetfluence)
301
302 !%Variable OCTFixInitialFluence
303 !%Type logical
304 !%Section Calculation Modes::Optimal Control
305 !%Default yes
306 !%Description
307 !% By default, when asking for a fixed-fluence optimization (<tt>OCTFixFluenceTo = whatever</tt>),
308 !% the initial laser guess provided in the input file is scaled to match this
309 !% fluence. However, you can force the program to use that initial laser as the initial
310 !% guess, no matter the fluence, by setting <tt>OCTFixInitialFluence = no</tt>.
311 !%End
312 call parse_variable(namespace, 'OCTFixInitialFluence', .true., cf_common%fix_initial_fluence)
313
314
315 !%Variable OCTControlFunctionType
316 !%Type integer
317 !%Section Calculation Modes::Optimal Control
318 !%Default controlfunction_mode_epsilon
319 !%Description
320 !% The control function may fully determine the time-dependent form of the
321 !% external field, or only the envelope function of this external field, or its phase.
322 !% Or, we may have two different control functions, one of them providing the phase
323 !% and the other one, the envelope.
324 !%
325 !% Note that, if <tt>OCTControlRepresentation = control_function_real_time</tt>, then the control
326 !% function must <b>always</b> determine the full external field (THIS NEEDS TO BE FIXED).
327 !%Option controlfunction_mode_epsilon 1
328 !% In this case, the control function determines the full control function: namely,
329 !% if we are considering the electric field of a laser, the time-dependent electric field.
330 !%Option controlfunction_mode_f 2
331 !% The optimization process attempts to find the best possible envelope. The full
332 !% control field is this envelope times a cosine function with a "carrier" frequency.
333 !% This carrier frequency is given by the carrier frequency of the <tt>TDExternalFields</tt>
334 !% in the <tt>inp</tt> file.
335 !%End
336 call parse_variable(namespace, 'OCTControlFunctionType', controlfunction_mode_epsilon, cf_common%mode)
337 if (.not. varinfo_valid_option('OCTControlFunctionType', cf_common%mode)) then
338 call messages_input_error(namespace, 'OCTControlFunctionType')
339 end if
340 if (cf_common%representation == ctr_rt .and. (cf_common%mode /= controlfunction_mode_epsilon)) then
341 call messages_input_error(namespace, 'OCTControlFunctionType')
342 end if
343 call messages_print_var_option('OCTControlFunctionType', cf_common%mode, namespace=namespace)
344
345 lasers => list_get_lasers(ext_partners)
346 if(.not. associated(lasers)) then
347 message(1) = "No lasers found. Cannot proceed."
348 call messages_fatal(1, namespace=namespace)
349 end if
350
351 ! Check that there are no complex polarization vectors.
352 do il = 1, lasers%no_lasers
353 pol(:) = laser_polarization(lasers%lasers(il))
354 do idir = 1, 3
355 if (aimag(pol(idir))**2 > 1.0e-20_real64) then
356 write(message(1), '(a)') 'In QOCT runs, the polarization vector cannot be complex. Complex'
357 write(message(2), '(a)') 'polarization vectors are only truly necessary if one wants a'
358 write(message(3), '(a)') 'circularly / elliptically polarized laser. This concepts assumes'
359 write(message(4), '(a)') 'the existence of a well defined carrier frequency (otherwise it'
360 write(message(5), '(a)') 'would not make sense to speak of a fixed phase difference). So in'
361 write(message(6), '(a)') 'QOCT runs it would only make sense for envelope-only optimizations.'
362 write(message(7), '(a)') 'This possibility should be implemented in the future.'
363 call messages_fatal(7, namespace=namespace)
364 end if
365 end do
366 end do
367
368
369 ! The laser field is defined by "td functions", as implemented in module "tdfunction_m". At this point, they
370 ! can be in "non-numerical" representation (i.e. described with a set of parameters, e.g. frequency,
371 ! width, etc). We need them to be in numerical form (i.e. time grid, values at the time grid).
372 ! Here we do the transformation.
373 ! It cannot be done before calling controlfunction_mod_init because we need to pass the omegamax value.
374 do il = 1, lasers%no_lasers
375 select case (cf_common%mode)
377 call laser_to_numerical_all(lasers%lasers(il), dt, max_iter, cf_common%omegamax)
378 case default
379 call laser_to_numerical(lasers%lasers(il), dt, max_iter, cf_common%omegamax)
380 end select
381 end do
382
383 ! Fix the carrier frequency
384 call messages_obsolete_variable(namespace, 'OCTCarrierFrequency')
385 cf_common%w0 = laser_carrier_frequency(lasers%lasers(1))
386
387 ! Fix the number of control functions: if we have "traditional" QOCT (i.e. the control functions
388 ! are represented directly in real time, then the number of control functions can be larger than
389 ! one; it will be the number of lasers found in the input file. Otherwise, if the control function(s)
390 ! are parametrized ("OCTControlRepresentation = control_function_parametrized"), we only have one
391 ! control function. If there is more than one laser field in the input file, the program stops.
392 if (lasers%no_lasers > 1) then
393 write(message(1), '(a)') 'Currently octopus only accepts one control field.'
394 call messages_fatal(1, namespace=namespace)
395 end if
396 cf_common%no_controlfunctions = 1
397
398 mode_fixed_fluence = .false.
399 select case (cf_common%representation)
401 if (abs(cf_common%targetfluence) <= m_epsilon) then
402 write(message(1), '(a)') 'If you set "OCTControlFunctionRepresentation" to either'
403 write(message(2), '(a)') '"control_fourier_series_h", or "control_zero_fourier_series_h", then the run'
404 write(message(3), '(a)') 'must be done in fixed fluence mode.'
405 call messages_fatal(3, namespace=namespace)
406 end if
407 mode_fixed_fluence = .true.
409 if (abs(cf_common%targetfluence) > m_epsilon) then
410 write(message(1), '(a)') 'If you set "OCTControlFunctionRepresentation" to "control_fourier_series",'
411 write(message(2), '(a)') 'then you cannot run in fixed fluence mode.'
412 call messages_fatal(2, namespace=namespace)
413 end if
414 mode_fixed_fluence = .false.
415 case default
416 if (abs(cf_common%targetfluence) > m_epsilon) mode_fixed_fluence = .true.
417 end select
418
419
420 !%Variable OCTPenalty
421 !%Type float
422 !%Section Calculation Modes::Optimal Control
423 !%Default 1.0
424 !%Description
425 !% The variable specifies the value of the penalty factor for the
426 !% integrated field strength (fluence). Large value = small fluence.
427 !% A transient shape can be specified using the block <tt>OCTLaserEnvelope</tt>.
428 !% In this case <tt>OCTPenalty</tt> is multiplied with time-dependent function.
429 !% The value depends on the coupling between the states. A good start might be a
430 !% value from 0.1 (strong fields) to 10 (weak fields).
431 !%
432 !% Note that if there are several control functions, one can specify this
433 !% variable as a one-line code, each column being the penalty factor for each
434 !% of the control functions. Make sure that the number of columns is equal to the
435 !% number of control functions. If it is not a block, all control functions will
436 !% have the same penalty factor.
437 !%
438 !% All penalty factors must be positive.
439 !%End
440 safe_allocate(cf_common%alpha(1:cf_common%no_controlfunctions))
441 cf_common%alpha = m_zero
442 if (parse_block(namespace, 'OCTPenalty', blk) == 0) then
443 ! We have a block
444 ncols = parse_block_cols(blk, 0)
445 if (ncols /= cf_common%no_controlfunctions) then
446 call messages_input_error(namespace, 'OCTPenalty')
447 else
448 do ipar = 1, ncols
449 call parse_block_float(blk, 0, ipar - 1, cf_common%alpha(ipar))
450 if (cf_common%alpha(ipar) <= m_zero) call messages_input_error(namespace, 'OCTPenalty')
451 end do
452 end if
453 else
454 ! We have the same penalty for all the control functions.
455 call parse_variable(namespace, 'OCTPenalty', m_one, octpenalty)
456 cf_common%alpha(1:cf_common%no_controlfunctions) = octpenalty
457 end if
458
459
460 !%Variable OCTLaserEnvelope
461 !%Type block
462 !%Section Calculation Modes::Optimal Control
463 !%Description
464 !% Often a pre-defined time-dependent envelope on the control function is desired.
465 !% This can be achieved by making the penalty factor time-dependent.
466 !% Here, you may specify the required time-dependent envelope.
467 !%
468 !% It is possible to choose different envelopes for different control functions.
469 !% There should be one line for each control function. Each line should
470 !% have only one element: a string with the name of a time-dependent function,
471 !% that should be correspondingly defined in a <tt>TDFunctions</tt> block.
472 !%End
473 steps = max_iter
474 safe_allocate(cf_common%td_penalty(1:cf_common%no_controlfunctions))
475
476 if (parse_block(namespace, 'OCTLaserEnvelope', blk) == 0) then
477
478 ! Cannot have this unless we have the "usual" controlfunction_mode_epsilon.
479 if (cf_common%mode /= controlfunction_mode_epsilon) then
480 write(message(1),'(a)') 'The block "OCTLaserEnvelope" is only compatible with the option'
481 write(message(2),'(a)') '"OCTControlFunctionType = controlfunction_mode_epsilon".'
482 call messages_fatal(2, namespace=namespace)
483 end if
484
485 no_lines = parse_block_n(blk)
486 if (no_lines /= cf_common%no_controlfunctions) call messages_input_error(namespace, 'OCTLaserEnvelope')
487
488 do irow = 1, no_lines
489 call parse_block_string(blk, irow - 1, 0, expression)
490 call parse_block_end(blk)
491 call tdf_read(cf_common%td_penalty(irow), namespace, trim(expression), ierr)
492 if (ierr.ne.0) then
493 message(1) = 'Time-dependent function "'//trim(expression)//'" could not be read from inp file.'
494 call messages_fatal(1, namespace=namespace)
495 end if
496 call tdf_to_numerical(cf_common%td_penalty(irow), steps, dt, cf_common%omegamax)
497 ierr = parse_block(namespace, 'OCTLaserEnvelope', blk)
498 end do
499
500 call parse_block_end(blk)
501 else
502 do ipar = 1, cf_common%no_controlfunctions
503 call tdf_init_numerical(cf_common%td_penalty(ipar), steps, dt, -m_one, initval = m_one)
504 end do
505 end if
506
507 call messages_print_with_emphasis(namespace=namespace)
508
510 end subroutine controlfunction_mod_init
511
512 ! ---------------------------------------------------------
517 subroutine controlfunction_init(cp, dt, ntiter)
518 type(controlfunction_t), intent(inout) :: cp
519 real(real64), intent(in) :: dt
520 integer, intent(in) :: ntiter
521
522 integer :: ipar
523
524 push_sub(controlfunction_init)
525
526 cp%w0 = cf_common%w0
527 cp%no_controlfunctions = cf_common%no_controlfunctions
528 cp%current_representation = ctr_internal
529 safe_allocate_source_a(cp%alpha, cf_common%alpha)
530
531 safe_allocate(cp%f(1:cp%no_controlfunctions))
532 do ipar = 1, cp%no_controlfunctions
533 call tdf_init_numerical(cp%f(ipar), ntiter, dt, cf_common%omegamax)
534 end do
535
536 ! If the control function is represented directly in real time, the "dimension" (cp%dim) is
537 ! the number of values that represent the function on the discretized time-axis.
538 !
539 ! If the control function is parametrized, up to now (in the future this might change), all
540 ! parametrizations are based on a previous basis-set expansion (sine-Fourier series, or "normal"
541 ! Fourier series with or without the zero term). For the representations whose name ends in "_h",
542 ! the parameters are not directly the coefficients of the control function in this basis-set
543 ! expansion, but are constructed from them (e.g. by performing a coordinate transformation to
544 ! hyperspherical coordinates). The "dimension" (cp%dim) is the dimension of this basis set.
545 select case (cf_common%representation)
546 case (ctr_internal)
547 cp%dim = ntiter + 1
549 ! If nf is the number of frequencies, we will have nf-1 non-zero "sines", nf-1 non-zero "cosines",
550 ! and the zero-frequency component. Total, 2*(nf-1)+1
551 cp%dim = 2 * (tdf_nfreqs(cp%f(1)) - 1) + 1
553 ! If nf is the number of frequencies, we will have nf-1 non-zero "sines", nf-1 non-zero "cosines",
554 ! but no zero-frequency component. Total, 2*(nf-1)
555 cp%dim = 2 * (tdf_nfreqs(cp%f(1)) - 1)
556 case (ctr_rt)
557 cp%dim = ntiter + 1
558 case default
559 message(1) = "Internal error: invalid representation."
560 call messages_fatal(1)
561 end select
562
563 ! The "degrees of freedom" cp%dof is the number of parameters that define the control function.
564 ! (if it is represented directly in real time, this would be meaningless, but we put the number of
565 ! control functions, times the "dimension", which in this case is the number of time discretization
566 ! points). This is not equal to the dimension of the basis set employed (cp%dim), because we may
567 ! add further constraints, and do a coordinate transformation to account for them.
568 select case (cf_common%representation)
569 case (ctr_internal)
570 cp%dof = cp%no_controlfunctions * cp%dim
572 ! The number of degrees of freedom is one fewer than the number of basis coefficients, since we
573 ! add the constraint of fixed fluence.
574 cp%dof = cp%dim - 1
576 ! The number of degrees of freedom is one fewer than the number of basis coefficients, since we
577 ! add (1) the constraint of fixed fluence, and (2) the constraint of the field starting and
578 ! ending at zero, which amounts to having all the cosine coefficients summing up to zero.
579 cp%dof = cp%dim - 2
580 case (ctr_fourier_series)
581 ! In this case, we have no constraints: the dof is equal to the dimension of the basis set, since
582 ! the parameters are directly the coefficients of the basis-set expansion.
583 cp%dof = cp%dim
585 ! The number of degrees of freedom is reduced by one, since we add the constraint forcing the
586 ! the field to start and end at zero, which amounts to having all the cosine coefficients
587 ! summing up to zero.
588 cp%dof = cp%dim - 1
589 case (ctr_rt)
590 cp%dof = cp%no_controlfunctions * cp%dim
591 end select
592
593 if (cp%dof <= 0) then
594 write(message(1),'(a)') 'The number of degrees of freedom used to describe the control function'
595 write(message(2),'(a)') 'is less than or equal to zero. This should not happen. Please review your input file.'
596 call messages_fatal(2)
597 else
598 if (cf_common%representation /= ctr_internal) then
599 write(message(1), '(a,i6,a)') 'The parametrization of the control functions makes use of ', cp%dim, ' basis'
600 write(message(2), '(a,i6,a)') 'functions and ', cp%dof, ' degrees of freedom.'
601 call messages_info(2)
602 safe_allocate(cp%theta(1:cp%dof))
603 cp%theta = m_zero
604 end if
605 end if
606
607 ! Construct the transformation matrix, if needed.
609
611 end subroutine controlfunction_init
612 ! ---------------------------------------------------------
613
614
615
619 subroutine controlfunction_set(cp, ext_partners)
620 type(controlfunction_t), intent(inout) :: cp
621 type(partner_list_t), intent(in) :: ext_partners
622
623 integer :: ipar
624 type(lasers_t), pointer :: lasers
625
626 push_sub(controlfunction_set)
627
628 lasers => list_get_lasers(ext_partners)
629 assert(associated(lasers))
630
631 select case (cf_common%mode)
633 do ipar = 1, cp%no_controlfunctions
634 call tdf_end(cp%f(ipar))
635 call laser_get_f(lasers%lasers(ipar), cp%f(ipar))
636 end do
637 end select
638
639 pop_sub(controlfunction_set)
640 end subroutine controlfunction_set
641 ! ---------------------------------------------------------
642
643
645 integer pure function controlfunction_representation()
646 controlfunction_representation = cf_common%representation
648 ! ---------------------------------------------------------
649
650
653 integer pure function controlfunction_mode()
655 end function controlfunction_mode
656 ! ---------------------------------------------------------
657
658
661 subroutine controlfunction_prepare_initial(par)
662 type(controlfunction_t), intent(inout) :: par
663
665
667
668 if (abs(cf_common%targetfluence) > m_epsilon) then
669 if (cf_common%targetfluence < m_zero) then
670 cf_common%targetfluence = controlfunction_fluence(par)
671 write(message(1), '(a)') 'Info: The QOCT run will attempt to find a solution with the same'
672 write(message(2), '(a,f10.5,a)') ' fluence as the input external fields: F = ', &
673 cf_common%targetfluence, ' a.u.'
674 else
675 write(message(1), '(a)') 'Info: The QOCT run will attempt to find a solution with a predefined'
676 write(message(2), '(a,f10.5,a)') ' fluence: F = ', cf_common%targetfluence, ' a.u.'
677 end if
678 call messages_info(2)
679 if (cf_common%fix_initial_fluence) call controlfunction_set_fluence(par)
680 end if
681
682 ! Move to the "native" representation, if necessary.
684
687 ! ---------------------------------------------------------
688
689
696 subroutine controlfunction_set_rep(par)
697 type(controlfunction_t), intent(inout) :: par
698
700
701 if (par%current_representation /= cf_common%representation) then
702 if (cf_common%representation == ctr_internal) then
704 else
706 end if
707 end if
708
710 end subroutine controlfunction_set_rep
711 ! ---------------------------------------------------------
713
714 ! ---------------------------------------------------------
715 subroutine controlfunction_to_basis(par)
716 type(controlfunction_t), intent(inout) :: par
717
718 integer :: ipar
719
721
722 if (par%current_representation == ctr_internal) then
723 select case (cf_common%representation)
724 case (ctr_rt)
725 par%current_representation = ctr_rt
728 do ipar = 1, par%no_controlfunctions
729 call tdf_numerical_to_fourier(par%f(ipar))
730 end do
731 par%current_representation = ctr_fourier_series_h
734 do ipar = 1, par%no_controlfunctions
735 call tdf_numerical_to_zerofourier(par%f(ipar))
736 end do
737 par%current_representation = ctr_zero_fourier_series_h
739 case (ctr_fourier_series)
740 do ipar = 1, par%no_controlfunctions
741 call tdf_numerical_to_fourier(par%f(ipar))
742 end do
743 par%current_representation = ctr_fourier_series
746 do ipar = 1, par%no_controlfunctions
747 call tdf_numerical_to_zerofourier(par%f(ipar))
748 end do
749 par%current_representation = ctr_zero_fourier_series
751 end select
752 end if
753
755 end subroutine controlfunction_to_basis
756 ! ---------------------------------------------------------
757
758
759 ! ---------------------------------------------------------
760 subroutine controlfunction_to_realtime(par)
761 type(controlfunction_t), intent(inout) :: par
762
763 integer :: ipar
764
766
767 select case (par%current_representation)
768 case (ctr_internal)
770 return
773 do ipar = 1, par%no_controlfunctions
774 call tdf_fourier_to_numerical(par%f(ipar))
775 end do
778 do ipar = 1, par%no_controlfunctions
779 call tdf_zerofourier_to_numerical(par%f(ipar))
780 end do
781 case (ctr_fourier_series)
783 do ipar = 1, par%no_controlfunctions
784 call tdf_fourier_to_numerical(par%f(ipar))
785 end do
788 do ipar = 1, par%no_controlfunctions
789 call tdf_zerofourier_to_numerical(par%f(ipar))
790 end do
791 case (ctr_rt)
793 end select
794
795 par%current_representation = ctr_internal
797 end subroutine controlfunction_to_realtime
798 ! ---------------------------------------------------------
799
800
801 ! ---------------------------------------------------------
802 real(real64) function controlfunction_diff(pp, qq) result(res)
803 type(controlfunction_t), intent(in) :: pp, qq
804
805 integer :: ipar
806
807 push_sub(controlfunction_diff)
809 assert(pp%current_representation == qq%current_representation)
810
811 res = m_zero
812 do ipar = 1, pp%no_controlfunctions
813 res = res + tdf_diff(pp%f(ipar), qq%f(ipar))
814 end do
815
816 pop_sub(controlfunction_diff)
817 end function controlfunction_diff
818 ! ---------------------------------------------------------
819
820
821 ! ---------------------------------------------------------
822 subroutine controlfunction_apply_envelope(cp)
823 type(controlfunction_t), intent(inout) :: cp
824 integer :: ipar, iter
825
827
828 ! Do not apply the envelope if the control functions are represented as a sine-Fourier series.
829 if (cf_common%representation == ctr_rt) then
831 do ipar = 1, cp%no_controlfunctions
832 do iter = 1, tdf_niter(cp%f(ipar)) + 1
833 call tdf_set_numerical(cp%f(ipar), iter, tdf(cp%f(ipar), iter) / tdf(cf_common%td_penalty(ipar), iter))
834 end do
835 end do
837 end if
838
840 end subroutine controlfunction_apply_envelope
841 ! ---------------------------------------------------------
842
843
844 ! ---------------------------------------------------------
845 subroutine controlfunction_to_h(cp, ext_partners)
846 type(controlfunction_t), intent(in) :: cp
847 type(partner_list_t), intent(in) :: ext_partners
848
849 integer :: ipar
850 type(controlfunction_t) :: par
851 type(lasers_t), pointer :: lasers
852
854
855 call controlfunction_copy(par, cp)
857
858 lasers => list_get_lasers(ext_partners)
859 assert(associated(lasers))
860
861 select case (cf_common%mode)
863 do ipar = 1, cp%no_controlfunctions
864 call laser_set_f(lasers%lasers(ipar), par%f(ipar))
865 end do
866 end select
867
868 call controlfunction_end(par)
869
870 pop_sub(controlfunction_to_h)
871 end subroutine controlfunction_to_h
872 ! ---------------------------------------------------------
873
874
875 ! ---------------------------------------------------------
876 subroutine controlfunction_to_h_val(cp, ext_partners, val)
877 type(controlfunction_t), intent(in) :: cp
878 type(partner_list_t), intent(in) :: ext_partners
879 integer, intent(in) :: val
880
881 integer :: ipar
882 type(lasers_t), pointer :: lasers
883
885
886 lasers => list_get_lasers(ext_partners)
887 assert(associated(lasers))
888
889 do ipar = 1, cp%no_controlfunctions
890 call laser_set_f_value(lasers%lasers(ipar), val, tdf(cp%f(ipar), val))
891 end do
892
894 end subroutine controlfunction_to_h_val
895 ! ---------------------------------------------------------
896
897
898 ! ---------------------------------------------------------
899 subroutine controlfunction_end(cp)
900 type(controlfunction_t), intent(inout) :: cp
901 integer :: ipar
902
903 push_sub(controlfunction_end)
904
905 if (allocated(cp%f)) then
906 do ipar = 1, cp%no_controlfunctions
907 call tdf_end(cp%f(ipar))
908 end do
909 end if
910 safe_deallocate_a(cp%f)
911 safe_deallocate_a(cp%alpha)
912 safe_deallocate_a(cp%u)
913 safe_deallocate_a(cp%utransf)
914 safe_deallocate_a(cp%utransfi)
915 safe_deallocate_a(cp%theta)
916
917 pop_sub(controlfunction_end)
918 end subroutine controlfunction_end
919 ! ---------------------------------------------------------
920
921
922 ! ---------------------------------------------------------
923 subroutine controlfunction_write(filename, cp, namespace)
924 character(len=*), intent(in) :: filename
925 type(controlfunction_t), intent(in) :: cp
926 type(namespace_t), intent(in) :: namespace
927
928 integer :: iter, ipar, ifreq, iunit, niter, nfreqs, idof
929 real(real64) :: time, wmax, dw, ww, wa, wb, dt
930 real(real64), allocatable :: func(:, :)
931 complex(real64) :: ft, ez, ezdt
932 character(len=2) :: digit
933 type(controlfunction_t) :: par
934
935 if (.not. mpi_grp_is_root(mpi_world)) return
936
937 push_sub(controlfunction_write)
939 call io_mkdir(trim(filename), namespace)
940
941 call controlfunction_copy(par, cp)
943
944 iunit = io_open(trim(filename)//'/Fluence', namespace, action='write')
945 write(iunit, '(a,es20.8e3)') 'Fluence = ', controlfunction_fluence(par)
946 call io_close(iunit)
947
948 niter = tdf_niter(par%f(1))
949 safe_allocate(func(1:niter + 1, 1:cp%no_controlfunctions))
950
951 select case (cf_common%mode)
953
954 do ipar = 1, cp%no_controlfunctions
955 if (cp%no_controlfunctions > 1) then
956 write(digit,'(i2.2)') ipar
957 iunit = io_open(trim(filename)//'/cp-'//digit, namespace, action='write')
958 else
959 iunit = io_open(trim(filename)//'/cp', namespace, action='write')
960 end if
961 write(iunit,'(2a20)') '# t [a.u] ', ' e(t) '
962 do iter = 1, tdf_niter(par%f(ipar)) + 1
963 time = (iter - 1) * tdf_dt(par%f(ipar))
964 write(iunit, '(2es20.8e3)') time, tdf(par%f(ipar), iter)
965 func(iter, ipar) = tdf(par%f(ipar), time)
966 end do
967 call io_close(iunit)
968 end do
971
972 do ipar = 1, cp%no_controlfunctions
973 if (cp%no_controlfunctions > 1) then
974 write(digit,'(i2.2)') ipar
975 iunit = io_open(trim(filename)//'/cp-'//digit, namespace, action='write')
976 else
977 iunit = io_open(trim(filename)//'/cp', namespace, action='write')
978 end if
979 write(iunit,'(3a20)') '# t [a.u] ', ' e(t) ', ' f(t) '
980 do iter = 1, tdf_niter(par%f(ipar)) + 1
981 time = (iter - 1) * tdf_dt(par%f(ipar))
982 write(iunit, '(3es20.8e3)') time, tdf(par%f(ipar), time) * cos(par%w0 * time), tdf(par%f(ipar), time)
983 func(iter, ipar) = tdf(par%f(ipar), time) * cos(par%w0 * time)
984 end do
985 call io_close(iunit)
986 end do
987
988 end select
989
990
991 !Now, the Fourier transforms.
992 select case (cf_common%mode)
994
995 do ipar = 1, cp%no_controlfunctions
996 if (cp%no_controlfunctions > 1) then
997 write(digit,'(i2.2)') ipar
998 iunit = io_open(trim(filename)//'/cpw-'//digit, namespace, action='write')
999 else
1000 iunit = io_open(trim(filename)//'/cpw', namespace, action='write')
1001 end if
1002 write(iunit,'(3a20)') '# w [a.u] ', ' Re[e(w)] ', &
1003 ' Im[e(w)] '
1004
1005 nfreqs = 1000
1006 wa = m_zero
1007 wb = m_three ! hard-coded to three atomic units... this should be improved.
1008 wmax = wb
1009 dw = wmax / (nfreqs - 1)
1010 dt = tdf_dt(par%f(1))
1011
1012 do ifreq = 1, nfreqs
1013 ww = wa + (ifreq - 1) * dw
1014 ft = m_z0
1015 ez = m_z1
1016 ezdt = exp(m_zi * ww * tdf_dt(par%f(ipar)))
1017 do iter = 1, niter + 1
1018 time = (iter - 1) * dt
1019 ft = ft + func(iter, ipar) * ez
1020 ez = ez * ezdt
1021 end do
1022 ft = ft * dt
1023 write(iunit,'(3es20.8e3)') ww, real(ft, real64) , aimag(ft)
1024 end do
1025 call io_close(iunit)
1026 end do
1027
1028
1030 iunit = io_open(trim(filename)//'/cpw', namespace, action='write')
1031 write(iunit,'(3a20)') '# w [a.u] ', ' Re[e(w)] ', &
1032 ' Im[e(w)] '
1033
1034 nfreqs = 1000
1035 wa = cp%w0 - m_three * cf_common%omegamax
1036 wb = cp%w0 + m_three * cf_common%omegamax
1037 wmax = 6.0_real64*cf_common%omegamax
1038 dw = wmax/(nfreqs-1)
1039 dt = tdf_dt(par%f(1))
1040
1041 do ifreq = 1, nfreqs
1042 ww = wa + (ifreq - 1) * dw
1043 ft = m_z0
1044 ez = m_z1
1045 ezdt = exp(m_zi * ww * tdf_dt(par%f(1)))
1046 do iter = 1, niter + 1
1047 time = (iter - 1) * dt
1048 ft = ft + func(iter, 1) * ez
1049 ez = ez * ezdt
1050 end do
1051 ft = ft * dt
1052 write(iunit,'(3es20.8e3)') ww, real(ft, real64) , aimag(ft)
1053 end do
1054
1055 call io_close(iunit)
1056 end select
1057
1058 ! Now, in case of a parametrized control function, the parameters.
1059 if (cf_common%representation /= ctr_rt) then
1060 iunit = io_open(trim(filename)//'/theta', namespace, action='write')
1061 do idof = 1, par%dof
1062 write(iunit,'(i5,es20.8e3)') idof, par%theta(idof)
1063 end do
1064 call io_close(iunit)
1065 end if
1066
1067 call controlfunction_end(par)
1068 pop_sub(controlfunction_write)
1069 end subroutine controlfunction_write
1070 ! ---------------------------------------------------------
1071
1072
1073 ! ---------------------------------------------------------
1074 ! Gets the fluence of the laser field, defined as:
1075 ! controlfunction_fluence = \sum_i^{no_controlfunctions} \integrate_0^T |epsilon(t)|^2
1076 ! ---------------------------------------------------------
1077 real(real64) function controlfunction_fluence(par)
1078 type(controlfunction_t), intent(in) :: par
1079 type(controlfunction_t) :: par_
1080 integer :: ipar
1081 type(tdf_t) :: ff
1082 push_sub(controlfunction_fluence)
1083
1084 call controlfunction_copy(par_, par)
1086
1088
1089 select case (cf_common%mode)
1091 do ipar = 1, par_%no_controlfunctions
1092 controlfunction_fluence = controlfunction_fluence + tdf_dot_product(par_%f(ipar), par_%f(ipar))
1093 end do
1095 do ipar = 1, par%no_controlfunctions
1096 call tdf_init(ff)
1097 call tdf_copy(ff, par_%f(ipar))
1098 call tdf_cosine_multiply(par%w0, ff)
1099 controlfunction_fluence = controlfunction_fluence + tdf_dot_product(ff, ff)
1100 call tdf_end(ff)
1101 end do
1102 end select
1103
1104 call controlfunction_end(par_)
1106 end function controlfunction_fluence
1107 ! ---------------------------------------------------------
1108
1109
1110 ! ---------------------------------------------------------
1111 ! Gets the J2 functional (which is the fluence, but weighted
1112 ! by a penalty function.
1113 ! ---------------------------------------------------------
1114 real(real64) function controlfunction_j2(par) result(j2)
1115 type(controlfunction_t), intent(in) :: par
1116 type(controlfunction_t) :: par_
1117 integer :: iter, ipar
1118 real(real64) :: time, integral, fi, tdp
1119 type(tdf_t) :: ff
1120
1121 push_sub(controlfunction_j2)
1122
1123 assert(par%current_representation == cf_common%representation)
1124
1125 call controlfunction_copy(par_, par)
1127
1128 integral = m_zero
1129 select case (cf_common%mode)
1131 do ipar = 1, par_%no_controlfunctions
1132 call tdf_init(ff)
1133 call tdf_copy(ff, par_%f(ipar))
1134 do iter = 1, tdf_niter(ff) + 1
1135 time = (iter - 1) * tdf_dt(ff)
1136 fi = tdf(par_%f(ipar), iter)
1137 tdp = sqrt(real(tdf(cf_common%td_penalty(ipar), iter), real64))
1138 call tdf_set_numerical(ff, iter, fi * tdp)
1139 end do
1140 integral = integral + tdf_dot_product(ff, ff)
1141 call tdf_end(ff)
1142 end do
1144 do ipar = 1, par_%no_controlfunctions
1145 call tdf_init(ff)
1146 call tdf_copy(ff, par_%f(ipar))
1147 do iter = 1, tdf_niter(ff) + 1
1148 time = (iter - 1) * tdf_dt(ff)
1149 fi = tdf(par_%f(ipar), iter)
1150 tdp = sqrt(real(tdf(cf_common%td_penalty(ipar), iter), real64))
1151 call tdf_set_numerical(ff, iter, fi * tdp * cos(par_%w0 * time))
1152 end do
1153 integral = integral + tdf_dot_product(ff, ff)
1154 call tdf_end(ff)
1155 end do
1156 end select
1157
1158 j2 = - par_%alpha(1) * (integral - cf_common%targetfluence)
1159
1160 call controlfunction_end(par_)
1161 pop_sub(controlfunction_j2)
1162 end function controlfunction_j2
1163 ! ---------------------------------------------------------
1164
1165
1166 ! ---------------------------------------------------------
1167 subroutine controlfunction_set_fluence(par)
1168 type(controlfunction_t), intent(inout) :: par
1169 real(real64) :: old_fluence
1170 integer :: ipar
1171
1173
1175 old_fluence = controlfunction_fluence(par)
1176 do ipar = 1, par%no_controlfunctions
1177 call tdf_scalar_multiply( sqrt(cf_common%targetfluence / old_fluence), par%f(ipar))
1178 end do
1179 call controlfunction_to_basis(par)
1180
1182 end subroutine controlfunction_set_fluence
1183 ! ---------------------------------------------------------
1184
1185
1186 ! ---------------------------------------------------------
1187 subroutine controlfunction_set_alpha(par, alpha)
1188 type(controlfunction_t), intent(inout) :: par
1189
1190 real(real64), intent(in) :: alpha
1191
1193
1194 par%alpha(:) = alpha
1195
1197 end subroutine controlfunction_set_alpha
1198 ! ---------------------------------------------------------
1199
1200
1201 ! ---------------------------------------------------------
1202 subroutine controlfunction_copy(cp_out, cp_in)
1203 type(controlfunction_t), intent(inout) :: cp_out
1204 type(controlfunction_t), intent(in) :: cp_in
1205
1206 integer :: ipar
1208 push_sub(controlfunction_copy)
1209
1210 call controlfunction_end(cp_out)
1211
1212 cp_out%no_controlfunctions = cp_in%no_controlfunctions
1213 cp_out%dim = cp_in%dim
1214 cp_out%dof = cp_in%dof
1215 cp_out%current_representation = cp_in%current_representation
1216 cp_out%w0 = cp_in%w0
1217
1218 safe_allocate_source_a(cp_out%alpha, cp_in%alpha)
1219 safe_allocate(cp_out%f(1:cp_out%no_controlfunctions))
1220
1221 do ipar = 1, cp_in%no_controlfunctions
1222 call tdf_init(cp_out%f(ipar))
1223 call tdf_copy(cp_out%f(ipar), cp_in%f(ipar))
1224 end do
1225
1226 safe_allocate_source_a(cp_out%u, cp_in%u)
1227 safe_allocate_source_a(cp_out%utransf, cp_in%utransf)
1228 safe_allocate_source_a(cp_out%utransfi, cp_in%utransfi)
1229 safe_allocate_source_a(cp_out%theta, cp_in%theta)
1230
1231 pop_sub(controlfunction_copy)
1232 end subroutine controlfunction_copy
1233 ! ---------------------------------------------------------
1234
1235
1236 ! ---------------------------------------------------------
1237 subroutine controlfunction_randomize(par)
1238 type(controlfunction_t), intent(inout) :: par
1239
1240 integer :: ipar
1241
1243
1244 assert(cf_common%representation /= ctr_internal)
1245
1246 call controlfunction_set_rep(par)
1247
1248 do ipar = 1, par%no_controlfunctions
1249 call tdf_set_random(par%f(ipar))
1250 end do
1252
1254 end subroutine controlfunction_randomize
1255 ! ---------------------------------------------------------
1256
1257
1258
1261 subroutine controlfunction_update(cp, cpp, dir, iter, mu, dd, dq)
1262 type(controlfunction_t), intent(inout) :: cp
1263 type(controlfunction_t), intent(in) :: cpp
1264 character(len=1), intent(in) :: dir
1265 integer, intent(in) :: iter
1266 real(real64), intent(in) :: mu
1267 real(real64), intent(in) :: dd(:)
1268 complex(real64), intent(in) :: dq(:)
1269
1270 real(real64) :: val
1271 integer :: ipar
1272
1273 push_sub(controlfunction_update)
1274
1275 select case (dir)
1276 case ('f')
1277 do ipar = 1, cp%no_controlfunctions
1278 val = dd(ipar) / ( tdf(cf_common%td_penalty(ipar), iter) - m_two * aimag(dq(ipar)))
1279 val = (m_one - mu) * tdf(cpp%f(ipar), iter) + mu * val
1280 call tdf_set_numerical(cp%f(ipar), iter, val)
1281 if (iter + 1 <= tdf_niter(cp%f(ipar)) + 1) call tdf_set_numerical(cp%f(ipar), iter+1, val)
1282 if (iter + 2 <= tdf_niter(cp%f(ipar)) + 1) call tdf_set_numerical(cp%f(ipar), iter+2, val)
1283 end do
1284
1285 case ('b')
1286 do ipar = 1, cp%no_controlfunctions
1287 val = dd(ipar) / ( tdf(cf_common%td_penalty(ipar), iter + 1) - m_two * aimag(dq(ipar)))
1288 val = (m_one - mu) * tdf(cpp%f(ipar), iter + 1) + mu * val
1289 call tdf_set_numerical(cp%f(ipar), iter + 1, val)
1290 if (iter > 0) call tdf_set_numerical(cp%f(ipar), iter, val)
1291 if (iter - 1 > 0) call tdf_set_numerical(cp%f(ipar), iter-1, val)
1292 end do
1293 end select
1294
1296 end subroutine controlfunction_update
1297 ! ---------------------------------------------------------
1298
1299
1300 ! ---------------------------------------------------------
1301 real(real64) pure function controlfunction_alpha(par, ipar)
1302 type(controlfunction_t), intent(in) :: par
1303 integer, intent(in) :: ipar
1304 controlfunction_alpha = par%alpha(ipar)
1305 end function controlfunction_alpha
1306 ! ---------------------------------------------------------
1307
1308
1309 ! ---------------------------------------------------------
1310 real(real64) pure function controlfunction_targetfluence()
1313 ! ---------------------------------------------------------
1314
1315
1316 ! ---------------------------------------------------------
1317 integer pure function controlfunction_number(par)
1318 type(controlfunction_t), intent(in) :: par
1319 controlfunction_number = par%no_controlfunctions
1320 end function controlfunction_number
1321 ! ---------------------------------------------------------
1322
1323
1324 ! ---------------------------------------------------------
1325 subroutine controlfunction_bounds(par, lower_bounds, upper_bounds)
1326 type(controlfunction_t), intent(in) :: par
1327 real(real64), intent(out) :: lower_bounds(:)
1328 real(real64), intent(out) :: upper_bounds(:)
1329
1331
1332 select case (cf_common%representation)
1334 lower_bounds(1:par%dof-1) = m_zero
1335 lower_bounds(par%dof) = -m_pi
1336 upper_bounds(1:par%dof) = m_pi
1337 case default
1338 lower_bounds = -huge(m_zero)
1339 lower_bounds = -huge(m_zero)
1340 upper_bounds = huge(m_zero)
1341 upper_bounds = huge(m_zero)
1342 end select
1343
1344 pop_sub(controlfunction_bounds)
1345 end subroutine controlfunction_bounds
1346 ! ---------------------------------------------------------
1347
1348
1349 ! ---------------------------------------------------------
1350 integer pure function controlfunction_dof(par)
1351 type(controlfunction_t), intent(in) :: par
1352 controlfunction_dof = par%dof
1353 end function controlfunction_dof
1354 ! ---------------------------------------------------------
1355
1356
1357 ! ---------------------------------------------------------
1358 real(real64) pure function controlfunction_w0(par)
1359 type(controlfunction_t), intent(in) :: par
1360 controlfunction_w0 = par%w0
1361 end function controlfunction_w0
1362 ! ---------------------------------------------------------
1363
1364
1365 ! ---------------------------------------------------------
1366 subroutine controlfunction_filter(par, filter)
1367 type(controlfunction_t), intent(inout) :: par
1368 type(filter_t), intent(inout) :: filter
1369
1370 integer :: ipar
1371
1372 push_sub(controlfunction_filter)
1373
1375
1376 do ipar = 1, par%no_controlfunctions
1377 call filter_apply(par%f(ipar), filter)
1378 end do
1379
1380 call controlfunction_to_basis(par)
1381
1382 pop_sub(controlfunction_filter)
1383 end subroutine controlfunction_filter
1384 ! ---------------------------------------------------------
1385
1386
1387 ! ---------------------------------------------------------
1388 subroutine controlfunction_mod_close()
1389 integer :: ipar
1390
1392
1393 if (.not. cf_common_initialized) then
1394 message(1) = "Internal error: Cannot call controlfunction_mod_close when not initialized."
1395 call messages_fatal(1)
1396 end if
1397
1398 cf_common_initialized = .false.
1399 safe_deallocate_a(cf_common%alpha)
1400
1401 do ipar = 1, cf_common%no_controlfunctions
1402 call tdf_end(cf_common%td_penalty(ipar))
1403 end do
1404
1405 safe_deallocate_a(cf_common%td_penalty)
1406
1408 end subroutine controlfunction_mod_close
1409 ! ---------------------------------------------------------
1411
1412 ! ---------------------------------------------------------
1413 subroutine controlfunction_deltaedeltau(par, dedu)
1414 type(controlfunction_t), intent(in) :: par
1415 real(real64), intent(inout) :: dedu(:, :)
1416
1417 integer :: i
1418 real(real64) :: rr
1419 real(real64), allocatable :: grad_matrix(:, :), dedv(:, :)
1420
1422
1423 select case (cf_common%representation)
1424
1425 case (ctr_rt)
1426 dedu = diagonal_matrix(par%dim, m_one)
1427
1429 safe_allocate(grad_matrix(1:par%dim - 1, 1:par%dim))
1430 rr = sqrt(cf_common%targetfluence)
1431 call hypersphere_grad_matrix(grad_matrix, rr, par%theta)
1432 dedu = matmul(grad_matrix, transpose(par%utransfi))
1433 safe_deallocate_a(grad_matrix)
1434
1436 safe_allocate(dedv(1:par%dim-1, 1:par%dim))
1437 dedv = m_zero
1438 do i = 1, (par%dim-1)/2
1439 dedv(i, 1) = - m_one
1440 dedv(i, i+1) = m_one
1441 end do
1442 do i = (par%dim-1)/2+1, par%dim-1
1443 dedv(i, i+1) = m_one
1444 end do
1445 safe_allocate(grad_matrix(1:par%dim - 2, 1:par%dim - 1))
1446 rr = sqrt(cf_common%targetfluence)
1447 call hypersphere_grad_matrix(grad_matrix, rr, par%theta)
1448 dedu = matmul(grad_matrix, matmul(transpose(par%utransfi), dedv))
1449 safe_deallocate_a(grad_matrix)
1450 safe_deallocate_a(dedv)
1452 case (ctr_fourier_series)
1453 dedu = diagonal_matrix(par%dim, m_one)
1454
1456 dedu = m_zero
1457 do i = 1, par%dof/2
1458 dedu(i, 1) = - m_one
1459 dedu(i, i+1) = m_one
1460 end do
1461 do i = par%dof/2+1, par%dof
1462 dedu(i, i+1) = m_one
1463 end do
1464
1465 end select
1466
1468 end subroutine controlfunction_deltaedeltau
1469 ! ---------------------------------------------------------
1470
1471
1474 subroutine controlfunction_der(par, depsilon, i)
1475 type(controlfunction_t), intent(in) :: par
1476 type(tdf_t), intent(inout) :: depsilon
1477 integer, intent(in) :: i
1478
1479 real(real64), allocatable :: dedu(:, :)
1480 push_sub(controlfunction_der)
1481 assert( i > 0 .and. i <= par%dof)
1482
1483 safe_allocate(dedu(1:par%dof, 1:par%dim))
1484 call controlfunction_deltaedeltau(par, dedu)
1485 call tdf_set_numerical(depsilon, dedu(i, 1:par%dim))
1486 call tdf_to_numerical(depsilon)
1487 if (controlfunction_mode() == controlfunction_mode_f) call tdf_cosine_multiply(par%w0, depsilon)
1488
1489 safe_deallocate_a(dedu)
1490 pop_sub(controlfunction_der)
1491 end subroutine controlfunction_der
1492
1493
1496 subroutine controlfunction_gradient(par, par_output, grad)
1497 type(controlfunction_t), intent(in) :: par, par_output
1498 real(real64), intent(inout) :: grad(:)
1499
1500 integer :: jj
1501 type(tdf_t) :: depsilon
1502 push_sub(controlfunction_gradient)
1503
1504 select case (par%current_representation)
1505 case (ctr_rt)
1506 do jj = 1, par%dof
1507 ! Probably we could do without par%u, and write explicitly the values it takes.
1508 grad(jj) = m_two * controlfunction_alpha(par, 1) * par%u(jj, 1)*par%theta(jj) &
1509 - par%u(jj, 1) * tdf(par_output%f(1), jj)
1510 end do
1512 do jj = 1, par%dof
1513 call tdf_copy(depsilon, par%f(1))
1514 call controlfunction_der(par, depsilon, jj)
1515 grad(jj) = m_two * controlfunction_alpha(par, 1) * sum(par%u(jj, :)*par%theta(:)) &
1516 - tdf_dot_product(par_output%f(1), depsilon)
1517 call tdf_end(depsilon)
1518 end do
1519
1521 do jj = 1, par%dof
1522 call tdf_copy(depsilon, par%f(1))
1523 call controlfunction_der(par, depsilon, jj)
1524 grad(jj) = - tdf_dot_product(par_output%f(1), depsilon)
1525 call tdf_end(depsilon)
1526 end do
1527
1528 end select
1529
1531 end subroutine controlfunction_gradient
1532 ! ---------------------------------------------------------
1533
1534#include "controlfunction_trans_inc.F90"
1535
1536end module controlfunction_oct_m
1537
1538!! Local Variables:
1539!! mode: f90
1540!! coding: utf-8
1541!! End:
double exp(double __x) __attribute__((__nothrow__
double sqrt(double __x) __attribute__((__nothrow__
double cos(double __x) __attribute__((__nothrow__
real(real64) function func(r1, rn, n, a)
Definition: logrid.F90:355
This module contains the definition of the data type that holds a "control function" used for OCT run...
integer, parameter, public ctr_fourier_series
integer, parameter, public controlfunction_mode_f
subroutine, public controlfunction_filter(par, filter)
real(real64) function, public controlfunction_diff(pp, qq)
subroutine, public controlfunction_gradient(par, par_output, grad)
controlfunction_gradient computes the (minus the) gradient of the J functional with respect to the pa...
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_h_val(cp, ext_partners, val)
subroutine, public controlfunction_to_realtime(par)
subroutine controlfunction_trans_matrix(par)
integer, parameter, public ctr_internal
integer pure function, public controlfunction_dof(par)
real(real64) function, public controlfunction_fluence(par)
subroutine controlfunction_deltaedeltau(par, dedu)
integer, parameter, public ctr_fourier_series_h
subroutine, public controlfunction_set_theta(par, theta)
subroutine controlfunction_basis_to_theta(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,...
integer pure function, public controlfunction_representation()
Returns the representation type for the control functions used in the OCT run.
real(real64) pure function, public controlfunction_w0(par)
integer, parameter, public ctr_rt
subroutine, public controlfunction_update(cp, cpp, dir, iter, mu, dd, dq)
Update the control function(s) given in "cp", according to the formula cp = (1 - mu) * cpp + mu * dd ...
integer, parameter, public ctr_zero_fourier_series_h
subroutine, public controlfunction_end(cp)
integer, parameter, public ctr_zero_fourier_series
integer, parameter, public controlfunction_mode_epsilon
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)
integer pure function, public controlfunction_number(par)
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)
integer pure function, public controlfunction_mode()
Returns the "mode" of the control function, i.e. if it is the full pulse, the envelope,...
subroutine controlfunction_theta_to_basis(par)
subroutine controlfunction_der(par, depsilon, i)
controlfunction_der computes the derivative of a controlfunction with respect to one of its degrees o...
subroutine, public controlfunction_to_basis(par)
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...
type(controlfunction_common_t) cf_common
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)
real(real64), parameter, public m_zero
Definition: global.F90:187
real(real64), parameter, public m_epsilon
Definition: global.F90:203
real(real64), parameter, public m_one
Definition: global.F90:188
This module defines classes and functions for interaction partners.
Definition: io.F90:114
complex(real64) function, dimension(3), public laser_polarization(laser)
Definition: lasers.F90:722
subroutine, public laser_to_numerical_all(laser, dt, max_iter, omegamax)
The td functions that describe the laser field are transformed to a "numerical" representation (i....
Definition: lasers.F90:879
subroutine, public laser_get_f(laser, ff)
Definition: lasers.F90:763
real(real64) function, public laser_carrier_frequency(laser)
Definition: lasers.F90:619
subroutine, public laser_to_numerical(laser, dt, max_iter, omegamax)
The td functions that describe the laser field are transformed to a "numerical" representation (i....
Definition: lasers.F90:910
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:115
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:930
character(len=512), private msg
Definition: messages.F90:165
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:1057
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
Definition: messages.F90:624
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:420
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:723
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1097
integer function, public parse_block(namespace, name, blk, check_varinfo_)
Definition: parser.F90:618
integer pure function, public tdf_nfreqs(f)
Definition: tdfunction.F90:372
subroutine, public tdf_end(f)
Definition: tdfunction.F90:974
subroutine, public tdf_init_numerical(f, niter, dt, omegamax, initval, rep)
Definition: tdfunction.F90:552
subroutine, public tdf_to_numerical(f, niter, dt, omegamax)
Definition: tdfunction.F90:828
subroutine, public tdf_read(f, namespace, function_name, ierr)
This function initializes "f" from the TDFunctions block.
Definition: tdfunction.F90:218
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:132
character(len=20) pure function, public units_abbrev(this)
Definition: unit.F90:223
This module defines the unit system, used for input and output.
type(unit_system_t), public units_out
This data type contains information that is filled when the module is initialized ("controlfunction_m...
This is the data type used to hold a control function.
int true(void)