33 use,
intrinsic :: iso_fortran_env
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
84 integer :: ip, ist, jst, cstr_dim(space%dim), ib, idim, jj, no_constraint, no_ptpair, iqn
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
94 message(1) =
'Info: Target is a combination of a density and/or a current functional.'
97 tg%move_ions = td%ions_dyn%ions_move()
102 tg%strt_iter_curr_tg = 0
128 tg%density_weight =
m_one
129 safe_allocate(tg%rho(1:gr%np))
131 call parse_variable(namespace,
'OCTTargetDensity',
"0", expression)
133 if (trim(expression) ==
'OCTTargetDensityFromState')
then
135 if (
parse_block(namespace,
'OCTTargetDensityFromState', blk) == 0)
then
141 safe_allocate(rotation_matrix(1:tmp_st%nst, 1:tmp_st%nst))
145 do ist = 1, tg%st%nst
151 safe_allocate(psi(1:gr%np, 1:tg%st%d%dim))
153 do iqn = tg%st%d%kpt%start, tg%st%d%kpt%end
161 do ist = tg%st%st_start, tg%st%st_end
168 safe_deallocate_a(rotation_matrix)
169 safe_deallocate_a(psi)
174 tg%rho(ip) = sum(tg%st%rho(ip, 1:tg%st%d%spin_channels))
185 call mesh_r(gr, ip, rr, coords = xx)
192 tg%rho = (-tg%st%val_charge) * tg%rho/rr
196 tg%density_weight =
m_zero
280 select case (tg%curr_functional)
283 if (.not.
allocated(stin%current))
then
284 safe_allocate(stin%current( 1:gr%np_part, 1:space%dim, 1:stin%d%nspin))
290 write(
message(1),
'(a,i3)')
'Info: OCTCurrentFunctional = ', tg%curr_functional
291 write(
message(2),
'(a,f8.3)')
'Info: OCTCurrentWeight = ', tg%curr_weight
295 call parse_variable(namespace,
'OCTStartIterCurrTg', 0, tg%strt_iter_curr_tg)
296 if (tg%strt_iter_curr_tg < 0)
then
298 elseif (tg%strt_iter_curr_tg >= td%max_iter)
then
302 write(
message(2),
'(a,i8)')
'Info: OCTStartIterCurrTg = ', tg%strt_iter_curr_tg
305 safe_allocate(tg%td_fitness(0:td%max_iter))
308 tg%strt_iter_curr_tg = 0
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))
320 do ib = 1, no_constraint
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.'
329 xp(1:gr%np_part) = gr%x(1:gr%np_part, idim)
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!'
340 do jj= 2, no_ptpair, 2
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" '
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))) - &
358 do idim = 1, space%dim
359 if (cstr_dim(idim) == 0) tmp_box(:,idim) =
m_one
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)
382 safe_deallocate_a(tg%rho)
383 safe_deallocate_a(tg%spatial_curr_wgt)
384 select case (tg%curr_functional)
386 safe_deallocate_a(tg%td_fitness)
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
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)
422 type(
grid_t),
intent(in) :: gr
427 integer :: ip, maxiter
428 real(real64) :: currfunc_tmp
429 real(real64),
allocatable :: local_function(:)
433 if (tg%density_weight >
m_zero)
then
434 safe_allocate(local_function(1:gr%np))
436 local_function(ip) = - (
sqrt(psi%rho(ip, 1)) -
sqrt(tg%rho(ip)) )**2
439 safe_deallocate_a(local_function)
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))
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
461 j1 = j1 + currfunc_tmp
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
477 integer :: no_electrons, ip, ist, ib, ik
478 complex(real64),
allocatable :: zpsi(:, :)
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))
488 no_electrons = -nint(psi_in%val_charge)
490 if (tg%density_weight > m_zero)
then
492 select case (psi_in%d%ispin)
494 assert(psi_in%nik == 1)
496 safe_allocate(zpsi(1:gr%np, 1))
498 if (no_electrons == 1)
then
500 call states_elec_get_state(psi_in, gr, 1, 1, zpsi)
503 zpsi(ip, 1) =
sqrt(tg%rho(ip))*
exp(m_zi*
atan2(aimag(zpsi(ip, 1)), real(zpsi(ip, 1),real64) ))
506 call states_elec_set_state(chi_out, gr, 1, 1, zpsi)
509 do ist = psi_in%st_start, psi_in%st_end
511 call states_elec_get_state(psi_in, gr, ist, 1, zpsi)
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)
521 call states_elec_set_state(chi_out, gr, ist, 1, zpsi)
526 case (spin_polarized)
527 message(1) =
'Error in target.target_chi_density: spin_polarized.'
528 call messages_fatal(1)
530 message(1) =
'Error in target.target_chi_density: spinors.'
531 call messages_fatal(1)
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)
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
558 if (time >= tg%strt_iter_curr_tg)
then
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
578 real(real64),
allocatable :: semilocal_function(:)
584 safe_allocate(semilocal_function(1:gr%np))
585 semilocal_function = m_zero
587 select case (tg%curr_functional)
589 semilocal_function = m_zero
591 case (oct_curr_square,oct_curr_square_td)
592 call states_elec_calc_quantities(gr, psi, kpoints, .false., paramagnetic_current=psi%current)
594 semilocal_function(ip) = sum(psi%current(ip, 1:gr%box%dim, 1)**2)
597 case (oct_max_curr_ring)
598 call states_elec_calc_quantities(gr, psi, kpoints, .false., paramagnetic_current=psi%current)
600 if (gr%box%dim /= 2)
then
601 call messages_not_implemented(
'Target for dimension != 2')
606 semilocal_function(ip) = psi%current(ip, 2, 1) * gr%x(ip,1) - &
607 psi%current(ip, 1, 1) * gr%x(ip,2)
610 message(1) =
'Error in target.jcurr_functional: chosen target does not exist'
611 call messages_fatal(1)
615 if (is_spatial_curr_wgt(tg))
then
617 semilocal_function(ip) = semilocal_function(ip) * tg%spatial_curr_wgt(ip)
621 jcurr = tg%curr_weight * dmf_integrate(gr, semilocal_function)
623 safe_deallocate_a(semilocal_function)
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
640 complex(real64),
allocatable :: grad_psi_in(:,:,:), zpsi(:, :), zchi(:, :)
641 real(real64),
allocatable :: div_curr_psi_in(:,:)
642 integer :: ip, ist, idim
645 safe_allocate(grad_psi_in(1:gr%np_part, 1:gr%box%dim, 1))
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)
651 select case (tg%curr_functional)
655 case (oct_curr_square,oct_curr_square_td)
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)
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))
670 call dderivatives_div(gr%der, psi_in%current(:, :, 1), div_curr_psi_in(:,1))
673 do ist = psi_in%st_start, psi_in%st_end
675 call states_elec_get_state(psi_in, gr, ist, 1, zpsi)
676 call states_elec_get_state(chi, gr, ist, 1, zchi)
678 call zderivatives_grad(gr%der, zpsi(:, 1), grad_psi_in(:, :, 1))
680 do idim = 1, psi_in%d%dim
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))
688 call states_elec_set_state(chi, gr, ist, 1, zchi)
692 safe_deallocate_a(div_curr_psi_in)
693 safe_deallocate_a(zpsi)
694 safe_deallocate_a(zchi)
696 case (oct_max_curr_ring)
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))
701 do ist = psi_in%st_start, psi_in%st_end
703 call states_elec_get_state(psi_in, gr, ist, 1, zpsi)
704 call states_elec_get_state(chi, gr, ist, 1, zchi)
706 call zderivatives_grad(gr%der, zpsi(:, 1), grad_psi_in(:, :, 1))
708 if (is_spatial_curr_wgt(tg))
then
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))
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))
724 call states_elec_set_state(chi, gr, ist, 1, zchi)
728 safe_deallocate_a(zpsi)
729 safe_deallocate_a(zchi)
732 message(1) =
'Error in target.chi_current: chosen target does not exist'
733 call messages_fatal(1)
736 safe_deallocate_a(grad_psi_in)
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.
This module implements a calculator for the density and defines related functions.
subroutine, public density_calc(st, gr, density, istin)
Computes the density from the orbitals in st.
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
real(real64), parameter, public m_zero
type(conf_t), public conf
Global instance of Octopus configuration.
complex(real64), parameter, public m_z1
real(real64), parameter, public m_half
real(real64), parameter, public m_one
This module implements the underlying real-space grid.
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.
subroutine, public io_mkdir(fname, namespace, parents)
This module is intended to contain "only mathematical" functions and procedures.
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
pure subroutine, public mesh_r(mesh, ip, rr, origin, coords)
return the distance to the origin for a given grid point
subroutine, public messages_variable_is_block(namespace, name)
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
subroutine, public messages_input_error(namespace, var, details, row, column)
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
this module contains the low-level part of the output system
logical function, public parse_is_defined(namespace, name)
integer function, public parse_block(namespace, name, blk, check_varinfo_)
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
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
integer, parameter, public oct_targetmode_td
integer, parameter, public oct_targetmode_static
integer, parameter, public oct_no_curr
integer pure function, public target_mode(tg)
integer, parameter, public oct_curr_square
integer, parameter, public oct_max_curr_ring
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
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.
Describes mesh distribution to nodes.
The states_elec_t class contains all electronic wave functions.