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 fixed_occ=.true.)
140
141 safe_allocate(rotation_matrix(1:tmp_st%nst, 1:tmp_st%nst))
142
143 rotation_matrix = diagonal_matrix(tmp_st%nst, m_z1)
144
145 do ist = 1, tg%st%nst
146 do jst = 1, parse_block_cols(blk, ist - 1)
147 call parse_block_cmplx(blk, ist - 1, jst - 1, rotation_matrix(jst, ist))
148 end do
149 end do
150
151 safe_allocate(psi(1:gr%np, 1:tg%st%d%dim))
152
153 do iqn = tg%st%d%kpt%start, tg%st%d%kpt%end
154
155 if (states_are_real(tg%st)) then
156 call states_elec_rotate(tmp_st, namespace, gr, real(rotation_matrix, real64) , iqn)
157 else
158 call states_elec_rotate(tmp_st, namespace, gr, rotation_matrix, iqn)
159 end if
160
161 do ist = tg%st%st_start, tg%st%st_end
162 call states_elec_get_state(tmp_st, gr, ist, iqn, psi)
163 call states_elec_set_state(tg%st, gr, ist, iqn, psi)
164 end do
165
166 end do
168 safe_deallocate_a(rotation_matrix)
169 safe_deallocate_a(psi)
170 call states_elec_end(tmp_st)
171
172 call density_calc(tg%st, gr, tg%st%rho)
173 do ip = 1, gr%np
174 tg%rho(ip) = sum(tg%st%rho(ip, 1:tg%st%d%spin_channels))
175 end do
176 call parse_block_end(blk)
177 else
178 call messages_variable_is_block(namespace, 'OCTTargetDensityFromState')
179 end if
180
181 else
182
183 call conv_to_c_string(expression)
184 do ip = 1, gr%np
185 call mesh_r(gr, ip, rr, coords = xx)
186 ! parse user-defined expression
187 call parse_expression(psi_re, psi_im, space%dim, xx, rr, m_zero, expression)
188 tg%rho(ip) = psi_re
189 end do
190 ! Normalize
191 rr = dmf_integrate(gr, tg%rho)
192 tg%rho = (-tg%st%val_charge) * tg%rho/rr
193 end if
194
195 else
196 tg%density_weight = m_zero
197 end if
198
199 !%Variable OCTCurrentFunctional
200 !%Type integer
201 !%Section Calculation Modes::Optimal Control
202 !%Default oct_no_curr
203 !%Description
204 !% (Experimental) The variable <tt>OCTCurrentFunctional</tt> describes which kind of
205 !% current target functional <math>J1_c[j]</math> is to be used.
206 !%Option oct_no_curr 0
207 !% No current functional is used, no current calculated.
208 !%Option oct_curr_square 1
209 !% Calculates the square of current <math>j</math>:
210 !% <math>J1_c[j] = {\tt OCTCurrentWeight} \int{\left| j(r) \right|^2 dr}</math>.
211 !% For <tt>OCTCurrentWeight</tt> < 0, the current will be minimized (useful in combination with
212 !% target density in order to obtain stable final target density), while for
213 !% <tt>OCTCurrentWeight</tt> > 0, it will be maximized (useful in combination with a target density
214 !% in order to obtain a high-velocity impact, for instance). It is a static target, to be reached at
215 !% total time.
216 !%Option oct_max_curr_ring 2
217 !% Maximizes the current of a quantum ring in one direction. The functional maximizes the <math>z</math> projection of the
218 !% outer product between the position <math>\vec{r}</math> and the current <math>\vec{j}</math>:
219 !% <math>J1[j] = {\tt OCTCurrentWeight} \int{(\vec{r} \times \vec{j}) \cdot \hat{z} dr}</math>.
220 !% For <tt>OCTCurrentWeight</tt> > 0, the
221 !% current flows in counter-clockwise direction, while for <tt>OCTCurrentWeight</tt> < 0, the current is clockwise.
222 !%Option oct_curr_square_td 3
223 !% The time-dependent version of <tt>oct_curr_square</tt>. In fact, calculates the
224 !% square of current in time interval [<tt>OCTStartTimeCurrTg</tt>,
225 !% total time = <tt>TDMaximumIter</tt> * <tt>TDTimeStep</tt>].
226 !% Set <tt>TDPropagator</tt> = <tt>crank_nicolson</tt>.
227 !%End
228
229 !%Variable OCTCurrentWeight
230 !%Type float
231 !%Section Calculation Modes::Optimal Control
232 !%Default 0.0
233 !%Description
234 !% In the case of simultaneous optimization of density <math>n</math> and current <math>j</math>, one can tune the importance
235 !% of the current functional <math>J1_c[j]</math>, as the respective functionals might not provide results on the
236 !% same scale of magnitude. <math>J1[n,j]= J1_d[n]+ {\tt OCTCurrentWeight}\ J1_c[j]</math>. Be aware that its
237 !% sign is crucial for the chosen <tt>OCTCurrentFunctional</tt> as explained there.
238 !%End
239
240 !%Variable OCTStartIterCurrTg
241 !%Type integer
242 !%Section Calculation Modes::Optimal Control
243 !%Default 0
244 !%Description
245 !% Allows for a time-dependent target for the current without defining it for the total
246 !% time-interval of the simulation.
247 !% Thus it can be switched on at the iteration desired, <tt>OCTStartIterCurrTg</tt> >= 0
248 !% and <tt>OCTStartIterCurrTg</tt> < <tt>TDMaximumIter</tt>.
249 !% Tip: If you would like to specify a real time for switching
250 !% the functional on rather than the number of steps, just use something
251 !% like:
252 !% <tt>OCTStartIterCurrTg</tt> = 100.0 / <tt>TDTimeStep</tt>.
253 !%End
254
255 !%Variable OCTSpatialCurrWeight
256 !%Type block
257 !%Section Calculation Modes::Optimal Control
258 !%Description
259 !% Can be seen as a position-dependent <tt>OCTCurrentWeight</tt>. Consequently, it
260 !% weights contribution of current <math>j</math> to its functional <math>J1_c[j]</math> according to the position in space.
261 !% For example, <tt>oct_curr_square</tt> thus becomes
262 !% <math>J1_c[j] = {\tt OCTCurrentWeight} \int{\left| j(r) \right|^2 {\tt OCTSpatialCurrWeight}(r) dr}</math>.
263 !%
264 !% It is defined as <tt>OCTSpatialCurrWeight</tt><math>(r) = g(x) g(y) g(z)</math>, where
265 !% <math>g(x) = \sum_{i} 1/(1+e^{-{\tt fact} (x-{\tt startpoint}_i)}) - 1/(1+e^{-{\tt fact} (x-{\tt endpoint}_i)})</math>.
266 !% If not specified, <math>g(x) = 1</math>.
267 !%
268 !% Each <math>g(x)</math> is represented by one line of the block that has the following form
269 !%
270 !% <tt>%OCTSpatialCurrWeight
271 !% <br>&nbsp;&nbsp; dimension | fact | startpoint_1 | endpoint_1 | startpoint_2 | endpoint_2 |...
272 !% <br>%</tt>
273 !%
274 !% There are no restrictions on the number of lines, nor on the number of pairs of start- and endpoints.
275 !% Attention: <tt>startpoint</tt> and <tt>endpoint</tt> have to be supplied pairwise
276 !% with <tt>startpoint < endpoint</tt>. <tt>dimension > 0</tt> is integer, <tt>fact</tt> is float.
277 !%End
278
279 call parse_variable(namespace, 'OCTCurrentFunctional', oct_no_curr, tg%curr_functional)
280 select case (tg%curr_functional)
281 case (oct_no_curr)
283 if (.not. allocated(stin%current)) then
284 safe_allocate(stin%current( 1:gr%np_part, 1:space%dim, 1:stin%d%nspin))
285 stin%current= m_zero
286 end if
287 end select
288
289 call parse_variable(namespace, 'OCTCurrentWeight', m_zero, tg%curr_weight)
290 write(message(1), '(a,i3)') 'Info: OCTCurrentFunctional = ', tg%curr_functional
291 write(message(2), '(a,f8.3)') 'Info: OCTCurrentWeight = ', tg%curr_weight
292 call messages_info(2, namespace=namespace)
293
294 if (target_mode(tg) == oct_targetmode_td) then
295 call parse_variable(namespace, 'OCTStartIterCurrTg', 0, tg%strt_iter_curr_tg)
296 if (tg%strt_iter_curr_tg < 0) then
297 call messages_input_error(namespace, 'OCTStartIterCurrTg', 'Must be positive.')
298 elseif (tg%strt_iter_curr_tg >= td%max_iter) then
299 call messages_input_error(namespace, 'OCTStartIterCurrTg', 'Has to be < TDMaximumIter.')
300 end if
301 write(message(1), '(a,i3)') 'Info: TargetMode = ', target_mode(tg)
302 write(message(2), '(a,i8)') 'Info: OCTStartIterCurrTg = ', tg%strt_iter_curr_tg
303 call messages_info(2, namespace=namespace)
304 tg%dt = td%dt
305 safe_allocate(tg%td_fitness(0:td%max_iter))
306 tg%td_fitness = m_zero
307 else
308 tg%strt_iter_curr_tg = 0
309 end if
310
311 if (parse_is_defined(namespace, 'OCTSpatialCurrWeight')) then
312 if (parse_block(namespace, 'OCTSpatialCurrWeight', blk) == 0) then
313 safe_allocate(tg%spatial_curr_wgt(1:gr%np_part))
314 safe_allocate(xp(1:gr%np_part))
315 safe_allocate(tmp_box(1:gr%np_part, 1:space%dim))
316
317 no_constraint = parse_block_n(blk)
318 tmp_box = m_zero
319 cstr_dim = 0
320 do ib = 1, no_constraint
321 call parse_block_integer(blk, ib - 1, 0, idim)
322 if (idim <= 0 .or. idim > space%dim) then
323 write(message(1), '(a,i3)') 'Error in "OCTSpatialCurrWeight" block, line:', ib
324 write(message(2), '(a)' ) '"dimension" has to be positive'
325 write(message(3), '(a)' ) 'and must not exceed dimensions of the system.'
326 call messages_fatal(3, namespace=namespace)
327 end if
328 cstr_dim(idim) = 1
329 xp(1:gr%np_part) = gr%x(1:gr%np_part, idim)
330
331 call parse_block_float(blk, ib - 1, 1, fact)
332
333 no_ptpair = parse_block_cols(blk, ib-1) - 2
334 if (mod(no_ptpair,2) /= 0) then
335 write(message(1), '(a,i3)') 'Error in "OCTSpatialCurrWeight" block, line:', ib
336 write(message(2), '(a)' ) 'Each interval needs start and end point!'
337 call messages_fatal(2, namespace=namespace)
338 end if
339
340 do jj= 2, no_ptpair, 2
341 call parse_block_float(blk, ib - 1, jj, xstart)
342 call parse_block_float(blk, ib - 1, jj+1, xend)
343
344 if (xstart >= xend) then
345 write(message(1), '(a,i3)') 'Error in "OCTSpatialCurrWeight" block, line:', ib
346 write(message(2), '(a)' ) 'Set "startpoint" < "endpoint" '
347 call messages_fatal(2, namespace=namespace)
348 end if
349
350 do ip = 1, gr%np_part
351 tmp_box(ip,idim) = tmp_box(ip,idim) + m_one/(m_one+exp(-fact*(xp(ip)-xstart))) - &
352 m_one/(m_one+exp(-fact*(xp(ip)-xend)))
353 end do
354 end do
355
356 end do
357
358 do idim = 1, space%dim
359 if (cstr_dim(idim) == 0) tmp_box(:,idim) = m_one
360 end do
361 tg%spatial_curr_wgt(1:gr%np_part) = product(tmp_box(1:gr%np_part, 1:space%dim),2)
362 safe_deallocate_a(xp)
363 safe_deallocate_a(tmp_box)
364
365 call parse_block_end(blk)
366 else
367 call messages_input_error(namespace, 'OCTSpatialCurrWeight', 'Has to be specified as a block.')
368 end if
369 end if
370
371 pop_sub(target_init_density)
372 end subroutine target_init_density
373
374
375 ! ----------------------------------------------------------------------
377 subroutine target_end_density(tg)
378 type(target_t), intent(inout) :: tg
379
380 push_sub(target_end_density)
381
382 safe_deallocate_a(tg%rho)
383 safe_deallocate_a(tg%spatial_curr_wgt)
384 select case (tg%curr_functional)
385 case (oct_curr_square_td)
386 safe_deallocate_a(tg%td_fitness)
387 end select
388
389 pop_sub(target_end_density)
390 end subroutine target_end_density
391
392
393 ! ----------------------------------------------------------------------
394 subroutine target_output_density(tg, namespace, space, mesh, dir, ions, outp)
395 type(target_t), intent(in) :: tg
396 type(namespace_t), intent(in) :: namespace
397 class(space_t), intent(in) :: space
398 class(mesh_t), intent(in) :: mesh
399 character(len=*), intent(in) :: dir
400 type(ions_t), intent(in) :: ions
401 type(output_t), intent(in) :: outp
402
403 integer :: ierr
404 push_sub(target_output_density)
405
406 call io_mkdir(trim(dir), namespace)
407
408 if (tg%density_weight > m_zero) then
409 call dio_function_output(outp%how(0), trim(dir), 'density_target', namespace, space, mesh, &
410 tg%rho, units_out%length**(-space%dim), ierr, pos=ions%pos, atoms=ions%atom)
411 end if
412
413
414 pop_sub(target_output_density)
415 end subroutine target_output_density
416 ! ----------------------------------------------------------------------
417
418
419 ! ----------------------------------------------------------------------
421 real(real64) function target_j1_density(gr, kpoints, tg, psi) result(j1)
422 type(grid_t), intent(in) :: gr
423 type(kpoints_t), intent(in) :: kpoints
424 type(target_t), intent(in) :: tg
425 type(states_elec_t), intent(inout) :: psi
426
427 integer :: ip, maxiter
428 real(real64) :: currfunc_tmp
429 real(real64), allocatable :: local_function(:)
430
431 push_sub(target_j1_density)
432
433 if (tg%density_weight > m_zero) then
434 safe_allocate(local_function(1:gr%np))
435 do ip = 1, gr%np
436 local_function(ip) = - ( sqrt(psi%rho(ip, 1)) - sqrt(tg%rho(ip)) )**2
437 end do
438 j1 = tg%density_weight * dmf_integrate(gr, local_function)
439 safe_deallocate_a(local_function)
440 else
441 j1 = m_zero
442 end if
443
444 ! current functionals are conveniently combined with others
445 if (tg%curr_functional /= oct_no_curr) then
446 select case (target_mode(tg))
448 currfunc_tmp = jcurr_functional(tg, gr, kpoints, psi)
449 case (oct_targetmode_td)
450 maxiter = size(tg%td_fitness) - 1
451 currfunc_tmp = m_half * tg%dt * tg%td_fitness(tg%strt_iter_curr_tg) + &
452 m_half * tg%dt * tg%td_fitness(maxiter) + &
453 tg%dt * sum(tg%td_fitness(tg%strt_iter_curr_tg+1:maxiter-1))
454 end select
455 if (conf%devel_version) then
456 write(message(1), '(6x,a,f12.5)') " => Other functional = ", j1
457 write(message(2), '(6x,a,f12.5)') " => Current functional = ", currfunc_tmp
458 call messages_info(2)
459 end if
460 ! accumulating functional values
461 j1 = j1 + currfunc_tmp
462 end if
463
464 pop_sub(target_j1_density)
465 end function target_j1_density
466
467
468 ! ----------------------------------------------------------------------
470 subroutine target_chi_density(tg, gr, kpoints, psi_in, chi_out)
471 type(target_t), intent(in) :: tg
472 type(grid_t), intent(in) :: gr
473 type(kpoints_t), intent(in) :: kpoints
474 type(states_elec_t), intent(inout) :: psi_in
475 type(states_elec_t), intent(inout) :: chi_out
476
477 integer :: no_electrons, ip, ist, ib, ik
478 complex(real64), allocatable :: zpsi(:, :)
479
480 push_sub(target_chi_density)
481
482 do ik = chi_out%d%kpt%start, chi_out%d%kpt%end
483 do ib = chi_out%group%block_start, chi_out%group%block_end
484 call batch_set_zero(chi_out%group%psib(ib, ik))
485 end do
486 end do
488 no_electrons = -nint(psi_in%val_charge)
489
490 if (tg%density_weight > m_zero) then
491
492 select case (psi_in%d%ispin)
493 case (unpolarized)
494 assert(psi_in%nik == 1)
495
496 safe_allocate(zpsi(1:gr%np, 1))
497
498 if (no_electrons == 1) then
499
500 call states_elec_get_state(psi_in, gr, 1, 1, zpsi)
501
502 do ip = 1, gr%np
503 zpsi(ip, 1) = sqrt(tg%rho(ip))*exp(m_zi*atan2(aimag(zpsi(ip, 1)), real(zpsi(ip, 1),real64) ))
504 end do
505
506 call states_elec_set_state(chi_out, gr, 1, 1, zpsi)
507
508 else
509 do ist = psi_in%st_start, psi_in%st_end
510
511 call states_elec_get_state(psi_in, gr, ist, 1, zpsi)
512
513 do ip = 1, gr%np
514 if (psi_in%rho(ip, 1) > 1.0e-8_real64) then
515 zpsi(ip, 1) = psi_in%occ(ist, 1)*sqrt(tg%rho(ip)/psi_in%rho(ip, 1))*zpsi(ip, 1)
516 else
517 zpsi(ip, 1) = m_zero !sqrt(tg%rho(ip))
518 end if
519 end do
520
521 call states_elec_set_state(chi_out, gr, ist, 1, zpsi)
522
523 end do
524 end if
525
526 case (spin_polarized)
527 message(1) = 'Error in target.target_chi_density: spin_polarized.'
528 call messages_fatal(1)
529 case (spinors)
530 message(1) = 'Error in target.target_chi_density: spinors.'
531 call messages_fatal(1)
532 end select
533
534 end if
535
536 if (tg%curr_functional /= oct_no_curr) then
537 if (target_mode(tg) == oct_targetmode_static) then
538 call chi_current(tg, gr, kpoints, m_one, psi_in, chi_out)
539 end if
540 end if
541
542 pop_sub(target_chi_density)
543 end subroutine target_chi_density
544
545
546 ! ---------------------------------------------------------
549 subroutine target_tdcalc_density(tg, gr, kpoints, psi, time)
550 type(target_t), intent(inout) :: tg
551 type(grid_t), intent(in) :: gr
552 type(kpoints_t), intent(in) :: kpoints
553 type(states_elec_t), intent(inout) :: psi
554 integer, intent(in) :: time
555
556 push_sub(target_tdcalc_density)
557
558 if (time >= tg%strt_iter_curr_tg) then
559 tg%td_fitness(time) = jcurr_functional(tg, gr, kpoints, psi)
560 end if
561
562
564 end subroutine target_tdcalc_density
565 ! ----------------------------------------------------------------------
566
567
568 ! ----------------------------------------------------------------------
571 real(real64) function jcurr_functional(tg, gr, kpoints, psi) result(jcurr)
572 type(target_t), intent(in) :: tg
573 type(grid_t), intent(in) :: gr
574 type(kpoints_t), intent(in) :: kpoints
575 type(states_elec_t), intent(inout) :: psi
576
577 integer :: ip
578 real(real64), allocatable :: semilocal_function(:)
579
580 push_sub(jcurr_functional)
581
582 jcurr = m_zero
583 assert(psi%nik == 1)
584 safe_allocate(semilocal_function(1:gr%np))
585 semilocal_function = m_zero
586
587 select case (tg%curr_functional)
588 case (oct_no_curr)
589 semilocal_function = m_zero
590
591 case (oct_curr_square,oct_curr_square_td)
592 call states_elec_calc_quantities(gr, psi, kpoints, .false., paramagnetic_current=psi%current)
593 do ip = 1, gr%np
594 semilocal_function(ip) = sum(psi%current(ip, 1:gr%box%dim, 1)**2)
595 end do
596
597 case (oct_max_curr_ring)
598 call states_elec_calc_quantities(gr, psi, kpoints, .false., paramagnetic_current=psi%current)
599
600 if (gr%box%dim /= 2) then
601 call messages_not_implemented('Target for dimension != 2')
602 end if
603
604 do ip = 1, gr%np
605 ! func = j_y * x - j_x * y
606 semilocal_function(ip) = psi%current(ip, 2, 1) * gr%x(ip,1) - &
607 psi%current(ip, 1, 1) * gr%x(ip,2)
608 end do
609 case default
610 message(1) = 'Error in target.jcurr_functional: chosen target does not exist'
611 call messages_fatal(1)
612 end select
613
614
615 if (is_spatial_curr_wgt(tg)) then
616 do ip = 1, gr%np
617 semilocal_function(ip) = semilocal_function(ip) * tg%spatial_curr_wgt(ip)
618 end do
619 end if
620
621 jcurr = tg%curr_weight * dmf_integrate(gr, semilocal_function)
622
623 safe_deallocate_a(semilocal_function)
624
625 pop_sub(jcurr_functional)
626 end function jcurr_functional
627 !-----------------------------------------------------------------------
628
629 ! ----------------------------------------------------------------------
630 ! Calculates current-specific boundary condition
631 !-----------------------------------------------------------------------
632 subroutine chi_current(tg, gr, kpoints, factor, psi_in, chi)
633 type(target_t), intent(in) :: tg
634 type(grid_t), intent(in) :: gr
635 type(kpoints_t), intent(in) :: kpoints
636 real(real64), intent(in) :: factor
637 type(states_elec_t), intent(inout) :: psi_in
638 type(states_elec_t), intent(inout) :: chi
639
640 complex(real64), allocatable :: grad_psi_in(:,:,:), zpsi(:, :), zchi(:, :)
641 real(real64), allocatable :: div_curr_psi_in(:,:)
642 integer :: ip, ist, idim
643
644 push_sub(chi_current)
645 safe_allocate(grad_psi_in(1:gr%np_part, 1:gr%box%dim, 1))
646
647 if (target_mode(tg) == oct_targetmode_td) then
648 call states_elec_calc_quantities(gr, psi_in, kpoints, .false., paramagnetic_current=psi_in%current)
649 end if
650
651 select case (tg%curr_functional)
652 case (oct_no_curr)
653 !nothing to do
654
655 case (oct_curr_square,oct_curr_square_td)
656 ! components current weighted by its position in the mesh, np_part included,
657 ! since needed for the divergence of current.
658 if (is_spatial_curr_wgt(tg)) then
659 do idim = 1, gr%box%dim
660 do ip = 1, gr%np_part
661 psi_in%current(ip, idim, 1) = psi_in%current(ip, idim, 1) * tg%spatial_curr_wgt(ip)
662 end do
663 end do
664 end if
665
666 safe_allocate(div_curr_psi_in(1:gr%np_part, 1))
667 safe_allocate(zpsi(1:gr%np_part, 1:psi_in%d%dim))
668 safe_allocate(zchi(1:gr%np_part, 1:psi_in%d%dim))
669
670 call dderivatives_div(gr%der, psi_in%current(:, :, 1), div_curr_psi_in(:,1))
671
672 ! the boundary condition
673 do ist = psi_in%st_start, psi_in%st_end
674
675 call states_elec_get_state(psi_in, gr, ist, 1, zpsi)
676 call states_elec_get_state(chi, gr, ist, 1, zchi)
677
678 call zderivatives_grad(gr%der, zpsi(:, 1), grad_psi_in(:, :, 1))
679
680 do idim = 1, psi_in%d%dim
681 do ip = 1, gr%np
682 zchi(ip, idim) = zchi(ip, idim) - factor*m_zi*tg%curr_weight* &
683 (m_two*sum(psi_in%current(ip, 1:gr%box%dim, 1)*grad_psi_in(ip, 1:gr%box%dim, 1)) + &
684 div_curr_psi_in(ip, 1)*zpsi(ip, idim))
685 end do
686 end do
687
688 call states_elec_set_state(chi, gr, ist, 1, zchi)
689
690 end do
691
692 safe_deallocate_a(div_curr_psi_in)
693 safe_deallocate_a(zpsi)
694 safe_deallocate_a(zchi)
695
696 case (oct_max_curr_ring)
697
698 safe_allocate(zpsi(1:gr%np_part, 1:psi_in%d%dim))
699 safe_allocate(zchi(1:gr%np_part, 1:psi_in%d%dim))
700
701 do ist = psi_in%st_start, psi_in%st_end
702
703 call states_elec_get_state(psi_in, gr, ist, 1, zpsi)
704 call states_elec_get_state(chi, gr, ist, 1, zchi)
705
706 call zderivatives_grad(gr%der, zpsi(:, 1), grad_psi_in(:, :, 1))
707
708 if (is_spatial_curr_wgt(tg)) then
709
710 do ip = 1, gr%np
711 zchi(ip, 1) = zchi(ip, 1) + factor*m_zi*tg%curr_weight*tg%spatial_curr_wgt(ip)* &
712 (grad_psi_in(ip, 1, 1)*gr%x(ip,2) - grad_psi_in(ip, 2, 1)*gr%x(ip, 1))
713 end do
714
715 else
716
717 do ip = 1, gr%np
718 zchi(ip, 1) = zchi(ip, 1) + factor*m_zi*tg%curr_weight* &
719 (grad_psi_in(ip, 1, 1)*gr%x(ip,2) - grad_psi_in(ip, 2, 1)*gr%x(ip, 1))
720 end do
721
722 end if
723
724 call states_elec_set_state(chi, gr, ist, 1, zchi)
726 end do
727
728 safe_deallocate_a(zpsi)
729 safe_deallocate_a(zchi)
730
731 case default
732 message(1) = 'Error in target.chi_current: chosen target does not exist'
733 call messages_fatal(1)
734 end select
735
736 safe_deallocate_a(grad_psi_in)
737 pop_sub(chi_current)
738 end subroutine chi_current
739 ! ----------------------------------------------------------------------
740
741end module target_density_oct_m
742
743!! Local Variables:
744!! mode: f90
745!! coding: utf-8
746!! 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:612
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.
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:1070
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:161
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:415
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:714
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:617
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, fixed_occ, is_complex, packed)
subroutine, public conv_to_c_string(str)
converts to c string
Definition: string.F90:229
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.
int true(void)