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.
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.