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
140 safe_allocate(rotation_matrix(1:tmp_st%nst, 1:tmp_st%nst))
144 do ist = 1, tg%st%nst
150 safe_allocate(psi(1:gr%np, 1:tg%st%d%dim))
152 do iqn = tg%st%d%kpt%start, tg%st%d%kpt%end
160 do ist = tg%st%st_start, tg%st%st_end
167 safe_deallocate_a(rotation_matrix)
168 safe_deallocate_a(psi)
173 tg%rho(ip) = sum(tg%st%rho(ip, 1:tg%st%d%spin_channels))
184 call mesh_r(gr, ip, rr, coords = xx)
191 tg%rho = (-tg%st%val_charge) * tg%rho/rr
195 tg%density_weight =
m_zero
279 select case (tg%curr_functional)
282 if (.not.
allocated(stin%current))
then
283 safe_allocate(stin%current( 1:gr%np_part, 1:space%dim, 1:stin%d%nspin))
289 write(
message(1),
'(a,i3)')
'Info: OCTCurrentFunctional = ', tg%curr_functional
290 write(
message(2),
'(a,f8.3)')
'Info: OCTCurrentWeight = ', tg%curr_weight
294 call parse_variable(namespace,
'OCTStartIterCurrTg', 0, tg%strt_iter_curr_tg)
295 if (tg%strt_iter_curr_tg < 0)
then
297 elseif (tg%strt_iter_curr_tg >= td%max_iter)
then
301 write(
message(2),
'(a,i8)')
'Info: OCTStartIterCurrTg = ', tg%strt_iter_curr_tg
304 safe_allocate(tg%td_fitness(0:td%max_iter))
307 tg%strt_iter_curr_tg = 0
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))
319 do ib = 1, no_constraint
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.'
328 xp(1:gr%np_part) = gr%x(1:gr%np_part, idim)
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!'
339 do jj= 2, no_ptpair, 2
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" '
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))) - &
357 do idim = 1, space%dim
358 if (cstr_dim(idim) == 0) tmp_box(:,idim) =
m_one
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)
381 safe_deallocate_a(tg%rho)
382 safe_deallocate_a(tg%spatial_curr_wgt)
383 select case (tg%curr_functional)
385 safe_deallocate_a(tg%td_fitness)
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
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)
421 type(
grid_t),
intent(in) :: gr
426 integer :: ip, maxiter
427 real(real64) :: currfunc_tmp
428 real(real64),
allocatable :: local_function(:)
432 if (tg%density_weight >
m_zero)
then
433 safe_allocate(local_function(1:gr%np))
435 local_function(ip) = - (
sqrt(psi%rho(ip, 1)) -
sqrt(tg%rho(ip)) )**2
438 safe_deallocate_a(local_function)
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))
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
460 j1 = j1 + currfunc_tmp
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
476 integer :: no_electrons, ip, ist, ib, ik
477 complex(real64),
allocatable :: zpsi(:, :)
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))
487 no_electrons = -nint(psi_in%val_charge)
489 if (tg%density_weight > m_zero)
then
491 select case (psi_in%d%ispin)
493 assert(psi_in%nik == 1)
495 safe_allocate(zpsi(1:gr%np, 1))
497 if (no_electrons == 1)
then
499 call states_elec_get_state(psi_in, gr, 1, 1, zpsi)
502 zpsi(ip, 1) =
sqrt(tg%rho(ip))*
exp(m_zi*
atan2(aimag(zpsi(ip, 1)), real(zpsi(ip, 1),real64) ))
505 call states_elec_set_state(chi_out, gr, 1, 1, zpsi)
508 do ist = psi_in%st_start, psi_in%st_end
510 call states_elec_get_state(psi_in, gr, ist, 1, zpsi)
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)
520 call states_elec_set_state(chi_out, gr, ist, 1, zpsi)
525 case (spin_polarized)
526 message(1) =
'Error in target.target_chi_density: spin_polarized.'
527 call messages_fatal(1)
529 message(1) =
'Error in target.target_chi_density: spinors.'
530 call messages_fatal(1)
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)
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
557 if (time >= tg%strt_iter_curr_tg)
then
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
577 real(real64),
allocatable :: semilocal_function(:)
583 safe_allocate(semilocal_function(1:gr%np))
584 semilocal_function = m_zero
586 select case (tg%curr_functional)
588 semilocal_function = m_zero
590 case (oct_curr_square,oct_curr_square_td)
591 call states_elec_calc_quantities(gr, psi, kpoints, .false., paramagnetic_current=psi%current)
593 semilocal_function(ip) = sum(psi%current(ip, 1:gr%box%dim, 1)**2)
596 case (oct_max_curr_ring)
597 call states_elec_calc_quantities(gr, psi, kpoints, .false., paramagnetic_current=psi%current)
599 if (gr%box%dim /= 2)
then
600 call messages_not_implemented(
'Target for dimension != 2')
605 semilocal_function(ip) = psi%current(ip, 2, 1) * gr%x(ip,1) - &
606 psi%current(ip, 1, 1) * gr%x(ip,2)
609 message(1) =
'Error in target.jcurr_functional: chosen target does not exist'
610 call messages_fatal(1)
614 if (is_spatial_curr_wgt(tg))
then
616 semilocal_function(ip) = semilocal_function(ip) * tg%spatial_curr_wgt(ip)
620 jcurr = tg%curr_weight * dmf_integrate(gr, semilocal_function)
622 safe_deallocate_a(semilocal_function)
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
639 complex(real64),
allocatable :: grad_psi_in(:,:,:), zpsi(:, :), zchi(:, :)
640 real(real64),
allocatable :: div_curr_psi_in(:,:)
641 integer :: ip, ist, idim
644 safe_allocate(grad_psi_in(1:gr%np_part, 1:gr%box%dim, 1))
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)
650 select case (tg%curr_functional)
654 case (oct_curr_square,oct_curr_square_td)
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)
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))
669 call dderivatives_div(gr%der, psi_in%current(:, :, 1), div_curr_psi_in(:,1))
672 do ist = psi_in%st_start, psi_in%st_end
674 call states_elec_get_state(psi_in, gr, ist, 1, zpsi)
675 call states_elec_get_state(chi, gr, ist, 1, zchi)
677 call zderivatives_grad(gr%der, zpsi(:, 1), grad_psi_in(:, :, 1))
679 do idim = 1, psi_in%d%dim
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))
687 call states_elec_set_state(chi, gr, ist, 1, zchi)
691 safe_deallocate_a(div_curr_psi_in)
692 safe_deallocate_a(zpsi)
693 safe_deallocate_a(zchi)
695 case (oct_max_curr_ring)
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))
700 do ist = psi_in%st_start, psi_in%st_end
702 call states_elec_get_state(psi_in, gr, ist, 1, zpsi)
703 call states_elec_get_state(chi, gr, ist, 1, zchi)
705 call zderivatives_grad(gr%der, zpsi(:, 1), grad_psi_in(:, :, 1))
707 if (is_spatial_curr_wgt(tg))
then
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))
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))
723 call states_elec_set_state(chi, gr, ist, 1, zchi)
727 safe_deallocate_a(zpsi)
728 safe_deallocate_a(zchi)
731 message(1) =
'Error in target.chi_current: chosen target does not exist'
732 call messages_fatal(1)
735 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.
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.
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, 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.