Octopus
target_density.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
23 use debug_oct_m
27 use global_oct_m
28 use grid_oct_m
29 use io_oct_m
31 use ions_oct_m
33 use, intrinsic :: iso_fortran_env
35 use math_oct_m
36 use mesh_oct_m
41 use parser_oct_m
44 use space_oct_m
49 use string_oct_m
50 use td_oct_m
52 use types_oct_m
53 use unit_oct_m
55
56
57 implicit none
58
59 private
60 public :: &
68
69
70contains
71
72 ! ----------------------------------------------------------------------
74 subroutine target_init_density(gr, kpoints, namespace, space, tg, stin, td, restart)
75 type(grid_t), intent(in) :: gr
76 type(kpoints_t), intent(in) :: kpoints
77 type(namespace_t), intent(in) :: namespace
78 class(space_t), intent(in) :: space
79 type(target_t), intent(inout) :: tg
80 type(states_elec_t), intent(inout) :: stin
81 type(td_t), intent(in) :: td
82 type(restart_t), intent(inout) :: restart
83
84 integer :: ip, ist, jst, cstr_dim(space%dim), ib, idim, jj, no_constraint, no_ptpair, iqn
85 type(block_t) :: blk
86 real(real64) :: psi_re, psi_im, xx(space%dim), rr, fact, xend, xstart
87 real(real64), allocatable :: xp(:), tmp_box(:, :)
88 complex(real64), allocatable :: rotation_matrix(:, :), psi(:, :)
89 type(states_elec_t) :: tmp_st
90 character(len=1024) :: expression
91
92 push_sub(target_init_density)
93
94 message(1) = 'Info: Target is a combination of a density and/or a current functional.'
95 call messages_info(1, namespace=namespace)
96
97 tg%move_ions = td%ions_dyn%ions_move()
98 tg%dt = td%dt
99
100 tg%curr_functional = oct_no_curr
101 tg%curr_weight = m_zero
102 tg%strt_iter_curr_tg = 0
103
104 !%Variable OCTTargetDensity
105 !%Type string
106 !%Section Calculation Modes::Optimal Control
107 !%Description
108 !% If <tt>OCTTargetOperator = oct_tg_density</tt>, then one must supply the target density
109 !% that should be searched for. This one can do by supplying a string through
110 !% the variable <tt>OCTTargetDensity</tt>. Alternately, give the special string <tt>"OCTTargetDensityFromState"</tt>
111 !% to specify the expression via the block <tt>OCTTargetDensityFromState</tt>.
112 !%End
113
114 !%Variable OCTTargetDensityFromState
115 !%Type block
116 !%Default no
117 !%Section Calculation Modes::Optimal Control
118 !%Description
119 !% If <tt>OCTTargetOperator = oct_tg_density</tt>, and <tt>OCTTargetDensity = "OCTTargetDensityFromState"</tt>,
120 !% you must specify a <tt>OCTTargetDensityState</tt> block, in order to specify which linear
121 !% combination of the states present in <tt>restart/gs</tt> is used to
122 !% create the target density.
123 !%
124 !% The syntax is the same as the <tt>TransformStates</tt> block.
125 !%End
126
127 if (parse_is_defined(namespace, 'OCTTargetDensity')) then
128 tg%density_weight = m_one
129 safe_allocate(tg%rho(1:gr%np))
130 tg%rho = m_zero
131 call parse_variable(namespace, 'OCTTargetDensity', "0", expression)
132
133 if (trim(expression) == 'OCTTargetDensityFromState') then
134
135 if (parse_block(namespace, 'OCTTargetDensityFromState', blk) == 0) then
136 call states_elec_copy(tmp_st, tg%st)
137 call states_elec_deallocate_wfns(tmp_st)
138 call states_elec_look_and_load(restart, namespace, space, tmp_st, gr, kpoints)
139
140 safe_allocate(rotation_matrix(1:tmp_st%nst, 1:tmp_st%nst))
141
142 rotation_matrix = diagonal_matrix(tmp_st%nst, m_z1)
143
144 do ist = 1, tg%st%nst
145 do jst = 1, parse_block_cols(blk, ist - 1)
146 call parse_block_cmplx(blk, ist - 1, jst - 1, rotation_matrix(jst, ist))
147 end do
148 end do
149
150 safe_allocate(psi(1:gr%np, 1:tg%st%d%dim))
151
152 do iqn = tg%st%d%kpt%start, tg%st%d%kpt%end
153
154 if (states_are_real(tg%st)) then
155 call states_elec_rotate(tmp_st, namespace, gr, real(rotation_matrix, real64) , iqn)
156 else
157 call states_elec_rotate(tmp_st, namespace, gr, rotation_matrix, iqn)
158 end if
159
160 do ist = tg%st%st_start, tg%st%st_end
161 call states_elec_get_state(tmp_st, gr, ist, iqn, psi)
162 call states_elec_set_state(tg%st, gr, ist, iqn, psi)
163 end do
164
165 end do
166
167 safe_deallocate_a(rotation_matrix)
168 safe_deallocate_a(psi)
169 call states_elec_end(tmp_st)
170
171 call density_calc(tg%st, gr, tg%st%rho)
172 do ip = 1, gr%np
173 tg%rho(ip) = sum(tg%st%rho(ip, 1:tg%st%d%spin_channels))
174 end do
175 call parse_block_end(blk)
176 else
177 call messages_variable_is_block(namespace, 'OCTTargetDensityFromState')
178 end if
179
180 else
181
182 call conv_to_c_string(expression)
183 do ip = 1, gr%np
184 call mesh_r(gr, ip, rr, coords = xx)
185 ! parse user-defined expression
186 call parse_expression(psi_re, psi_im, space%dim, xx, rr, m_zero, expression)
187 tg%rho(ip) = psi_re
188 end do
189 ! Normalize
190 rr = dmf_integrate(gr, tg%rho)
191 tg%rho = (-tg%st%val_charge) * tg%rho/rr
192 end if
193
194 else
195 tg%density_weight = m_zero
196 end if
197
198 !%Variable OCTCurrentFunctional
199 !%Type integer
200 !%Section Calculation Modes::Optimal Control
201 !%Default oct_no_curr
202 !%Description
203 !% (Experimental) The variable <tt>OCTCurrentFunctional</tt> describes which kind of
204 !% current target functional <math>J1_c[j]</math> is to be used.
205 !%Option oct_no_curr 0
206 !% No current functional is used, no current calculated.
207 !%Option oct_curr_square 1
208 !% Calculates the square of current <math>j</math>:
209 !% <math>J1_c[j] = {\tt OCTCurrentWeight} \int{\left| j(r) \right|^2 dr}</math>.
210 !% For <tt>OCTCurrentWeight</tt> < 0, the current will be minimized (useful in combination with
211 !% target density in order to obtain stable final target density), while for
212 !% <tt>OCTCurrentWeight</tt> > 0, it will be maximized (useful in combination with a target density
213 !% in order to obtain a high-velocity impact, for instance). It is a static target, to be reached at
214 !% total time.
215 !%Option oct_max_curr_ring 2
216 !% Maximizes the current of a quantum ring in one direction. The functional maximizes the <math>z</math> projection of the
217 !% outer product between the position <math>\vec{r}</math> and the current <math>\vec{j}</math>:
218 !% <math>J1[j] = {\tt OCTCurrentWeight} \int{(\vec{r} \times \vec{j}) \cdot \hat{z} dr}</math>.
219 !% For <tt>OCTCurrentWeight</tt> > 0, the
220 !% current flows in counter-clockwise direction, while for <tt>OCTCurrentWeight</tt> < 0, the current is clockwise.
221 !%Option oct_curr_square_td 3
222 !% The time-dependent version of <tt>oct_curr_square</tt>. In fact, calculates the
223 !% square of current in time interval [<tt>OCTStartTimeCurrTg</tt>,
224 !% total time = <tt>TDMaximumIter</tt> * <tt>TDTimeStep</tt>].
225 !% Set <tt>TDPropagator</tt> = <tt>crank_nicolson</tt>.
226 !%End
227
228 !%Variable OCTCurrentWeight
229 !%Type float
230 !%Section Calculation Modes::Optimal Control
231 !%Default 0.0
232 !%Description
233 !% In the case of simultaneous optimization of density <math>n</math> and current <math>j</math>, one can tune the importance
234 !% of the current functional <math>J1_c[j]</math>, as the respective functionals might not provide results on the
235 !% same scale of magnitude. <math>J1[n,j]= J1_d[n]+ {\tt OCTCurrentWeight}\ J1_c[j]</math>. Be aware that its
236 !% sign is crucial for the chosen <tt>OCTCurrentFunctional</tt> as explained there.
237 !%End
238
239 !%Variable OCTStartIterCurrTg
240 !%Type integer
241 !%Section Calculation Modes::Optimal Control
242 !%Default 0
243 !%Description
244 !% Allows for a time-dependent target for the current without defining it for the total
245 !% time-interval of the simulation.
246 !% Thus it can be switched on at the iteration desired, <tt>OCTStartIterCurrTg</tt> >= 0
247 !% and <tt>OCTStartIterCurrTg</tt> < <tt>TDMaximumIter</tt>.
248 !% Tip: If you would like to specify a real time for switching
249 !% the functional on rather than the number of steps, just use something
250 !% like:
251 !% <tt>OCTStartIterCurrTg</tt> = 100.0 / <tt>TDTimeStep</tt>.
252 !%End
253
254 !%Variable OCTSpatialCurrWeight
255 !%Type block
256 !%Section Calculation Modes::Optimal Control
257 !%Description
258 !% Can be seen as a position-dependent <tt>OCTCurrentWeight</tt>. Consequently, it
259 !% weights contribution of current <math>j</math> to its functional <math>J1_c[j]</math> according to the position in space.
260 !% For example, <tt>oct_curr_square</tt> thus becomes
261 !% <math>J1_c[j] = {\tt OCTCurrentWeight} \int{\left| j(r) \right|^2 {\tt OCTSpatialCurrWeight}(r) dr}</math>.
262 !%
263 !% It is defined as <tt>OCTSpatialCurrWeight</tt><math>(r) = g(x) g(y) g(z)</math>, where
264 !% <math>g(x) = \sum_{i} 1/(1+e^{-{\tt fact} (x-{\tt startpoint}_i)}) - 1/(1+e^{-{\tt fact} (x-{\tt endpoint}_i)})</math>.
265 !% If not specified, <math>g(x) = 1</math>.
266 !%
267 !% Each <math>g(x)</math> is represented by one line of the block that has the following form
268 !%
269 !% <tt>%OCTSpatialCurrWeight
270 !% <br>&nbsp;&nbsp; dimension | fact | startpoint_1 | endpoint_1 | startpoint_2 | endpoint_2 |...
271 !% <br>%</tt>
272 !%
273 !% There are no restrictions on the number of lines, nor on the number of pairs of start- and endpoints.
274 !% Attention: <tt>startpoint</tt> and <tt>endpoint</tt> have to be supplied pairwise
275 !% with <tt>startpoint < endpoint</tt>. <tt>dimension > 0</tt> is integer, <tt>fact</tt> is float.
276 !%End
277
278 call parse_variable(namespace, 'OCTCurrentFunctional', oct_no_curr, tg%curr_functional)
279 select case (tg%curr_functional)
280 case (oct_no_curr)
282 if (.not. allocated(stin%current)) then
283 safe_allocate(stin%current( 1:gr%np_part, 1:space%dim, 1:stin%d%nspin))
284 stin%current= m_zero
285 end if
286 end select
287
288 call parse_variable(namespace, 'OCTCurrentWeight', m_zero, tg%curr_weight)
289 write(message(1), '(a,i3)') 'Info: OCTCurrentFunctional = ', tg%curr_functional
290 write(message(2), '(a,f8.3)') 'Info: OCTCurrentWeight = ', tg%curr_weight
291 call messages_info(2, namespace=namespace)
292
293 if (target_mode(tg) == oct_targetmode_td) then
294 call parse_variable(namespace, 'OCTStartIterCurrTg', 0, tg%strt_iter_curr_tg)
295 if (tg%strt_iter_curr_tg < 0) then
296 call messages_input_error(namespace, 'OCTStartIterCurrTg', 'Must be positive.')
297 elseif (tg%strt_iter_curr_tg >= td%max_iter) then
298 call messages_input_error(namespace, 'OCTStartIterCurrTg', 'Has to be < TDMaximumIter.')
299 end if
300 write(message(1), '(a,i3)') 'Info: TargetMode = ', target_mode(tg)
301 write(message(2), '(a,i8)') 'Info: OCTStartIterCurrTg = ', tg%strt_iter_curr_tg
302 call messages_info(2, namespace=namespace)
303 tg%dt = td%dt
304 safe_allocate(tg%td_fitness(0:td%max_iter))
305 tg%td_fitness = m_zero
306 else
307 tg%strt_iter_curr_tg = 0
308 end if
309
310 if (parse_is_defined(namespace, 'OCTSpatialCurrWeight')) then
311 if (parse_block(namespace, 'OCTSpatialCurrWeight', blk) == 0) then
312 safe_allocate(tg%spatial_curr_wgt(1:gr%np_part))
313 safe_allocate(xp(1:gr%np_part))
314 safe_allocate(tmp_box(1:gr%np_part, 1:space%dim))
315
316 no_constraint = parse_block_n(blk)
317 tmp_box = m_zero
318 cstr_dim = 0
319 do ib = 1, no_constraint
320 call parse_block_integer(blk, ib - 1, 0, idim)
321 if (idim <= 0 .or. idim > space%dim) then
322 write(message(1), '(a,i3)') 'Error in "OCTSpatialCurrWeight" block, line:', ib
323 write(message(2), '(a)' ) '"dimension" has to be positive'
324 write(message(3), '(a)' ) 'and must not exceed dimensions of the system.'
325 call messages_fatal(3, namespace=namespace)
326 end if
327 cstr_dim(idim) = 1
328 xp(1:gr%np_part) = gr%x(1:gr%np_part, idim)
329
330 call parse_block_float(blk, ib - 1, 1, fact)
331
332 no_ptpair = parse_block_cols(blk, ib-1) - 2
333 if (mod(no_ptpair,2) /= 0) then
334 write(message(1), '(a,i3)') 'Error in "OCTSpatialCurrWeight" block, line:', ib
335 write(message(2), '(a)' ) 'Each interval needs start and end point!'
336 call messages_fatal(2, namespace=namespace)
337 end if
338
339 do jj= 2, no_ptpair, 2
340 call parse_block_float(blk, ib - 1, jj, xstart)
341 call parse_block_float(blk, ib - 1, jj+1, xend)
342
343 if (xstart >= xend) then
344 write(message(1), '(a,i3)') 'Error in "OCTSpatialCurrWeight" block, line:', ib
345 write(message(2), '(a)' ) 'Set "startpoint" < "endpoint" '
346 call messages_fatal(2, namespace=namespace)
347 end if
348
349 do ip = 1, gr%np_part
350 tmp_box(ip,idim) = tmp_box(ip,idim) + m_one/(m_one+exp(-fact*(xp(ip)-xstart))) - &
351 m_one/(m_one+exp(-fact*(xp(ip)-xend)))
352 end do
353 end do
354
355 end do
356
357 do idim = 1, space%dim
358 if (cstr_dim(idim) == 0) tmp_box(:,idim) = m_one
359 end do
360 tg%spatial_curr_wgt(1:gr%np_part) = product(tmp_box(1:gr%np_part, 1:space%dim),2)
361 safe_deallocate_a(xp)
362 safe_deallocate_a(tmp_box)
363
364 call parse_block_end(blk)
365 else
366 call messages_input_error(namespace, 'OCTSpatialCurrWeight', 'Has to be specified as a block.')
367 end if
368 end if
369
370 pop_sub(target_init_density)
371 end subroutine target_init_density
372
373
374 ! ----------------------------------------------------------------------
376 subroutine target_end_density(tg)
377 type(target_t), intent(inout) :: tg
378
379 push_sub(target_end_density)
380
381 safe_deallocate_a(tg%rho)
382 safe_deallocate_a(tg%spatial_curr_wgt)
383 select case (tg%curr_functional)
384 case (oct_curr_square_td)
385 safe_deallocate_a(tg%td_fitness)
386 end select
387
388 pop_sub(target_end_density)
389 end subroutine target_end_density
390
391
392 ! ----------------------------------------------------------------------
393 subroutine target_output_density(tg, namespace, space, mesh, dir, ions, outp)
394 type(target_t), intent(in) :: tg
395 type(namespace_t), intent(in) :: namespace
396 class(space_t), intent(in) :: space
397 class(mesh_t), intent(in) :: mesh
398 character(len=*), intent(in) :: dir
399 type(ions_t), intent(in) :: ions
400 type(output_t), intent(in) :: outp
401
402 integer :: ierr
403 push_sub(target_output_density)
404
405 call io_mkdir(trim(dir), namespace)
406
407 if (tg%density_weight > m_zero) then
408 call dio_function_output(outp%how(0), trim(dir), 'density_target', namespace, space, mesh, &
409 tg%rho, units_out%length**(-space%dim), ierr, pos=ions%pos, atoms=ions%atom)
410 end if
411
412
413 pop_sub(target_output_density)
414 end subroutine target_output_density
415 ! ----------------------------------------------------------------------
416
417
418 ! ----------------------------------------------------------------------
420 real(real64) function target_j1_density(gr, kpoints, tg, psi) result(j1)
421 type(grid_t), intent(in) :: gr
422 type(kpoints_t), intent(in) :: kpoints
423 type(target_t), intent(in) :: tg
424 type(states_elec_t), intent(inout) :: psi
425
426 integer :: ip, maxiter
427 real(real64) :: currfunc_tmp
428 real(real64), allocatable :: local_function(:)
429
430 push_sub(target_j1_density)
431
432 if (tg%density_weight > m_zero) then
433 safe_allocate(local_function(1:gr%np))
434 do ip = 1, gr%np
435 local_function(ip) = - ( sqrt(psi%rho(ip, 1)) - sqrt(tg%rho(ip)) )**2
436 end do
437 j1 = tg%density_weight * dmf_integrate(gr, local_function)
438 safe_deallocate_a(local_function)
439 else
440 j1 = m_zero
441 end if
442
443 ! current functionals are conveniently combined with others
444 if (tg%curr_functional /= oct_no_curr) then
445 select case (target_mode(tg))
447 currfunc_tmp = jcurr_functional(tg, gr, kpoints, psi)
448 case (oct_targetmode_td)
449 maxiter = size(tg%td_fitness) - 1
450 currfunc_tmp = m_half * tg%dt * tg%td_fitness(tg%strt_iter_curr_tg) + &
451 m_half * tg%dt * tg%td_fitness(maxiter) + &
452 tg%dt * sum(tg%td_fitness(tg%strt_iter_curr_tg+1:maxiter-1))
453 end select
454 if (conf%devel_version) then
455 write(message(1), '(6x,a,f12.5)') " => Other functional = ", j1
456 write(message(2), '(6x,a,f12.5)') " => Current functional = ", currfunc_tmp
457 call messages_info(2)
458 end if
459 ! accumulating functional values
460 j1 = j1 + currfunc_tmp
461 end if
462
463 pop_sub(target_j1_density)
464 end function target_j1_density
465
466
467 ! ----------------------------------------------------------------------
469 subroutine target_chi_density(tg, gr, kpoints, psi_in, chi_out)
470 type(target_t), intent(in) :: tg
471 type(grid_t), intent(in) :: gr
472 type(kpoints_t), intent(in) :: kpoints
473 type(states_elec_t), intent(inout) :: psi_in
474 type(states_elec_t), intent(inout) :: chi_out
475
476 integer :: no_electrons, ip, ist, ib, ik
477 complex(real64), allocatable :: zpsi(:, :)
478
479 push_sub(target_chi_density)
480
481 do ik = chi_out%d%kpt%start, chi_out%d%kpt%end
482 do ib = chi_out%group%block_start, chi_out%group%block_end
483 call batch_set_zero(chi_out%group%psib(ib, ik))
484 end do
485 end do
487 no_electrons = -nint(psi_in%val_charge)
488
489 if (tg%density_weight > m_zero) then
490
491 select case (psi_in%d%ispin)
492 case (unpolarized)
493 assert(psi_in%nik == 1)
494
495 safe_allocate(zpsi(1:gr%np, 1))
496
497 if (no_electrons == 1) then
498
499 call states_elec_get_state(psi_in, gr, 1, 1, zpsi)
500
501 do ip = 1, gr%np
502 zpsi(ip, 1) = sqrt(tg%rho(ip))*exp(m_zi*atan2(aimag(zpsi(ip, 1)), real(zpsi(ip, 1),real64) ))
503 end do
504
505 call states_elec_set_state(chi_out, gr, 1, 1, zpsi)
506
507 else
508 do ist = psi_in%st_start, psi_in%st_end
509
510 call states_elec_get_state(psi_in, gr, ist, 1, zpsi)
511
512 do ip = 1, gr%np
513 if (psi_in%rho(ip, 1) > 1.0e-8_real64) then
514 zpsi(ip, 1) = psi_in%occ(ist, 1)*sqrt(tg%rho(ip)/psi_in%rho(ip, 1))*zpsi(ip, 1)
515 else
516 zpsi(ip, 1) = m_zero !sqrt(tg%rho(ip))
517 end if
518 end do
519
520 call states_elec_set_state(chi_out, gr, ist, 1, zpsi)
521
522 end do
523 end if
524
525 case (spin_polarized)
526 message(1) = 'Error in target.target_chi_density: spin_polarized.'
527 call messages_fatal(1)
528 case (spinors)
529 message(1) = 'Error in target.target_chi_density: spinors.'
530 call messages_fatal(1)
531 end select
532
533 end if
534
535 if (tg%curr_functional /= oct_no_curr) then
536 if (target_mode(tg) == oct_targetmode_static) then
537 call chi_current(tg, gr, kpoints, m_one, psi_in, chi_out)
538 end if
539 end if
540
541 pop_sub(target_chi_density)
542 end subroutine target_chi_density
543
544
545 ! ---------------------------------------------------------
548 subroutine target_tdcalc_density(tg, gr, kpoints, psi, time)
549 type(target_t), intent(inout) :: tg
550 type(grid_t), intent(in) :: gr
551 type(kpoints_t), intent(in) :: kpoints
552 type(states_elec_t), intent(inout) :: psi
553 integer, intent(in) :: time
554
555 push_sub(target_tdcalc_density)
556
557 if (time >= tg%strt_iter_curr_tg) then
558 tg%td_fitness(time) = jcurr_functional(tg, gr, kpoints, psi)
559 end if
560
561
563 end subroutine target_tdcalc_density
564 ! ----------------------------------------------------------------------
565
566
567 ! ----------------------------------------------------------------------
570 real(real64) function jcurr_functional(tg, gr, kpoints, psi) result(jcurr)
571 type(target_t), intent(in) :: tg
572 type(grid_t), intent(in) :: gr
573 type(kpoints_t), intent(in) :: kpoints
574 type(states_elec_t), intent(inout) :: psi
575
576 integer :: ip
577 real(real64), allocatable :: semilocal_function(:)
578
579 push_sub(jcurr_functional)
580
581 jcurr = m_zero
582 assert(psi%nik == 1)
583 safe_allocate(semilocal_function(1:gr%np))
584 semilocal_function = m_zero
585
586 select case (tg%curr_functional)
587 case (oct_no_curr)
588 semilocal_function = m_zero
589
590 case (oct_curr_square,oct_curr_square_td)
591 call states_elec_calc_quantities(gr, psi, kpoints, .false., paramagnetic_current=psi%current)
592 do ip = 1, gr%np
593 semilocal_function(ip) = sum(psi%current(ip, 1:gr%box%dim, 1)**2)
594 end do
595
596 case (oct_max_curr_ring)
597 call states_elec_calc_quantities(gr, psi, kpoints, .false., paramagnetic_current=psi%current)
598
599 if (gr%box%dim /= 2) then
600 call messages_not_implemented('Target for dimension != 2')
601 end if
602
603 do ip = 1, gr%np
604 ! func = j_y * x - j_x * y
605 semilocal_function(ip) = psi%current(ip, 2, 1) * gr%x(ip,1) - &
606 psi%current(ip, 1, 1) * gr%x(ip,2)
607 end do
608 case default
609 message(1) = 'Error in target.jcurr_functional: chosen target does not exist'
610 call messages_fatal(1)
611 end select
612
613
614 if (is_spatial_curr_wgt(tg)) then
615 do ip = 1, gr%np
616 semilocal_function(ip) = semilocal_function(ip) * tg%spatial_curr_wgt(ip)
617 end do
618 end if
619
620 jcurr = tg%curr_weight * dmf_integrate(gr, semilocal_function)
621
622 safe_deallocate_a(semilocal_function)
623
624 pop_sub(jcurr_functional)
625 end function jcurr_functional
626 !-----------------------------------------------------------------------
627
628 ! ----------------------------------------------------------------------
629 ! Calculates current-specific boundary condition
630 !-----------------------------------------------------------------------
631 subroutine chi_current(tg, gr, kpoints, factor, psi_in, chi)
632 type(target_t), intent(in) :: tg
633 type(grid_t), intent(in) :: gr
634 type(kpoints_t), intent(in) :: kpoints
635 real(real64), intent(in) :: factor
636 type(states_elec_t), intent(inout) :: psi_in
637 type(states_elec_t), intent(inout) :: chi
638
639 complex(real64), allocatable :: grad_psi_in(:,:,:), zpsi(:, :), zchi(:, :)
640 real(real64), allocatable :: div_curr_psi_in(:,:)
641 integer :: ip, ist, idim
642
643 push_sub(chi_current)
644 safe_allocate(grad_psi_in(1:gr%np_part, 1:gr%box%dim, 1))
645
646 if (target_mode(tg) == oct_targetmode_td) then
647 call states_elec_calc_quantities(gr, psi_in, kpoints, .false., paramagnetic_current=psi_in%current)
648 end if
649
650 select case (tg%curr_functional)
651 case (oct_no_curr)
652 !nothing to do
653
654 case (oct_curr_square,oct_curr_square_td)
655 ! components current weighted by its position in the mesh, np_part included,
656 ! since needed for the divergence of current.
657 if (is_spatial_curr_wgt(tg)) then
658 do idim = 1, gr%box%dim
659 do ip = 1, gr%np_part
660 psi_in%current(ip, idim, 1) = psi_in%current(ip, idim, 1) * tg%spatial_curr_wgt(ip)
661 end do
662 end do
663 end if
664
665 safe_allocate(div_curr_psi_in(1:gr%np_part, 1))
666 safe_allocate(zpsi(1:gr%np_part, 1:psi_in%d%dim))
667 safe_allocate(zchi(1:gr%np_part, 1:psi_in%d%dim))
668
669 call dderivatives_div(gr%der, psi_in%current(:, :, 1), div_curr_psi_in(:,1))
670
671 ! the boundary condition
672 do ist = psi_in%st_start, psi_in%st_end
673
674 call states_elec_get_state(psi_in, gr, ist, 1, zpsi)
675 call states_elec_get_state(chi, gr, ist, 1, zchi)
676
677 call zderivatives_grad(gr%der, zpsi(:, 1), grad_psi_in(:, :, 1))
678
679 do idim = 1, psi_in%d%dim
680 do ip = 1, gr%np
681 zchi(ip, idim) = zchi(ip, idim) - factor*m_zi*tg%curr_weight* &
682 (m_two*sum(psi_in%current(ip, 1:gr%box%dim, 1)*grad_psi_in(ip, 1:gr%box%dim, 1)) + &
683 div_curr_psi_in(ip, 1)*zpsi(ip, idim))
684 end do
685 end do
686
687 call states_elec_set_state(chi, gr, ist, 1, zchi)
688
689 end do
690
691 safe_deallocate_a(div_curr_psi_in)
692 safe_deallocate_a(zpsi)
693 safe_deallocate_a(zchi)
694
695 case (oct_max_curr_ring)
696
697 safe_allocate(zpsi(1:gr%np_part, 1:psi_in%d%dim))
698 safe_allocate(zchi(1:gr%np_part, 1:psi_in%d%dim))
699
700 do ist = psi_in%st_start, psi_in%st_end
701
702 call states_elec_get_state(psi_in, gr, ist, 1, zpsi)
703 call states_elec_get_state(chi, gr, ist, 1, zchi)
704
705 call zderivatives_grad(gr%der, zpsi(:, 1), grad_psi_in(:, :, 1))
706
707 if (is_spatial_curr_wgt(tg)) then
708
709 do ip = 1, gr%np
710 zchi(ip, 1) = zchi(ip, 1) + factor*m_zi*tg%curr_weight*tg%spatial_curr_wgt(ip)* &
711 (grad_psi_in(ip, 1, 1)*gr%x(ip,2) - grad_psi_in(ip, 2, 1)*gr%x(ip, 1))
712 end do
713
714 else
715
716 do ip = 1, gr%np
717 zchi(ip, 1) = zchi(ip, 1) + factor*m_zi*tg%curr_weight* &
718 (grad_psi_in(ip, 1, 1)*gr%x(ip,2) - grad_psi_in(ip, 2, 1)*gr%x(ip, 1))
719 end do
720
721 end if
722
723 call states_elec_set_state(chi, gr, ist, 1, zchi)
725 end do
726
727 safe_deallocate_a(zpsi)
728 safe_deallocate_a(zchi)
729
730 case default
731 message(1) = 'Error in target.chi_current: chosen target does not exist'
732 call messages_fatal(1)
733 end select
734
735 safe_deallocate_a(grad_psi_in)
736 pop_sub(chi_current)
737 end subroutine chi_current
738 ! ----------------------------------------------------------------------
739
740end module target_density_oct_m
741
742!! Local Variables:
743!! mode: f90
744!! coding: utf-8
745!! End:
double exp(double __x) __attribute__((__nothrow__
double sqrt(double __x) __attribute__((__nothrow__
double atan2(double __y, double __x) __attribute__((__nothrow__
This module implements common operations on batches of mesh functions.
Definition: batch_ops.F90:116
This module implements a calculator for the density and defines related functions.
Definition: density.F90:120
subroutine, public density_calc(st, gr, density, istin)
Computes the density from the orbitals in st.
Definition: density.F90:609
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
real(real64), parameter, public m_zero
Definition: global.F90:188
type(conf_t), public conf
Global instance of Octopus configuration.
Definition: global.F90:178
complex(real64), parameter, public m_z1
Definition: global.F90:199
real(real64), parameter, public m_half
Definition: global.F90:194
real(real64), parameter, public m_one
Definition: global.F90:189
This module implements the underlying real-space grid.
Definition: grid.F90:117
subroutine, public dio_function_output(how, dir, fname, namespace, space, mesh, ff, unit, ierr, pos, atoms, grp, root)
Top-level IO routine for functions defined on the mesh.
Definition: io.F90:114
subroutine, public io_mkdir(fname, namespace, parents)
Definition: io.F90:311
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:115
This module defines various routines, operating on mesh functions.
real(real64) function, public dmf_integrate(mesh, ff, mask, reduce)
Integrate a function on the mesh.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
pure subroutine, public mesh_r(mesh, ip, rr, origin, coords)
return the distance to the origin for a given grid point
Definition: mesh.F90:336
subroutine, public messages_variable_is_block(namespace, name)
Definition: messages.F90:1069
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:414
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:713
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:616
this module contains the low-level part of the output system
Definition: output_low.F90:115
logical function, public parse_is_defined(namespace, name)
Definition: parser.F90:502
integer function, public parse_block(namespace, name, blk, check_varinfo_)
Definition: parser.F90:618
pure logical function, public states_are_real(st)
subroutine, public states_elec_end(st)
finalize the states_elec_t object
subroutine, public states_elec_deallocate_wfns(st)
Deallocates the KS wavefunctions defined within a states_elec_t structure.
subroutine, public states_elec_copy(stout, stin, exclude_wfns, exclude_eigenval, special)
make a (selective) copy of a states_elec_t object
This module handles reading and writing restart information for the states_elec_t.
subroutine, public states_elec_look_and_load(restart, namespace, space, st, mesh, kpoints, is_complex, packed)
subroutine, public conv_to_c_string(str)
converts to c string
Definition: string.F90:252
subroutine, public chi_current(tg, gr, kpoints, factor, psi_in, chi)
real(real64) function, public target_j1_density(gr, kpoints, tg, psi)
subroutine, public target_end_density(tg)
subroutine, public target_init_density(gr, kpoints, namespace, space, tg, stin, td, restart)
subroutine, public target_output_density(tg, namespace, space, mesh, dir, ions, outp)
subroutine, public target_chi_density(tg, gr, kpoints, psi_in, chi_out)
subroutine, public target_tdcalc_density(tg, gr, kpoints, psi, time)
real(real64) function jcurr_functional(tg, gr, kpoints, psi)
Calculates a current functional that may be combined with other functionals found in function target_...
integer, parameter, public oct_curr_square_td
Definition: target_low.F90:231
integer, parameter, public oct_targetmode_td
Definition: target_low.F90:227
integer, parameter, public oct_targetmode_static
Definition: target_low.F90:227
integer, parameter, public oct_no_curr
Definition: target_low.F90:231
integer pure function, public target_mode(tg)
Definition: target_low.F90:243
integer, parameter, public oct_curr_square
Definition: target_low.F90:231
integer, parameter, public oct_max_curr_ring
Definition: target_low.F90:231
Definition: td.F90:114
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:132
This module defines the unit system, used for input and output.
type(unit_system_t), public units_out
Description of the grid, containing information on derivatives, stencil, and symmetries.
Definition: grid.F90:168
Describes mesh distribution to nodes.
Definition: mesh.F90:186
output handler class
Definition: output_low.F90:164
The states_elec_t class contains all electronic wave functions.