module procedures_exchange_visitors use, intrinsic :: iso_fortran_env, only: DP => REAL64 use procedures_visit_condition, only: visit_different use types_particle_wrapper, only: Concrete_Particle use types_cells_wrapper, only: Cells_Wrapper use types_dipolar_interactions_dynamic_wrapper, only: Dipolar_Interactions_Dynamic_Wrapper implicit none private public :: visit_add, visit_remove interface visit_add module procedure :: visit_add_short module procedure :: visit_add_dipolar end interface visit_add interface visit_remove module procedure :: visit_remove_dipolar module procedure :: visit_remove_short end interface visit_remove contains subroutine visit_add_short(overlap, delta_energies, i_component, particle, cells) logical, intent(out) :: overlap real(DP), intent(inout) :: delta_energies(:) integer, intent(in) :: i_component type(Concrete_Particle), intent(in) :: particle type(Cells_Wrapper), intent(in) :: cells integer :: j_component, i_exclude do j_component = 1, size(cells%visitable_cells, 1) i_exclude = merge(particle%i, 0, j_component == i_component) call cells%visitable_cells(j_component, i_component)%& visit_energy(overlap, delta_energies(j_component), particle, visit_different, & i_exclude) if (overlap) return end do end subroutine visit_add_short subroutine visit_remove_short(overlap, delta_energies, i_component, particle, cells) logical, intent(out) :: overlap real(DP), intent(inout) :: delta_energies(:) integer, intent(in) :: i_component type(Concrete_Particle), intent(in) :: particle type(Cells_Wrapper), intent(in) :: cells integer :: j_component, i_exclude do j_component = 1, size(cells%visitable_cells, 1) i_exclude = merge(particle%i, 0, j_component == i_component) call cells%visitable_cells(j_component, i_component)%& visit_energy(overlap, delta_energies(j_component), particle, visit_different, & i_exclude) end do delta_energies = -delta_energies end subroutine visit_remove_short pure subroutine visit_add_dipolar(delta_energies, delta_shared_energy, i_component, particle, & dipolar_interactions_dynamic) real(DP), intent(inout) :: delta_energies(:) real(DP), intent(out) :: delta_shared_energy integer, intent(in) :: i_component type(Concrete_Particle), intent(in) :: particle type(Dipolar_Interactions_Dynamic_Wrapper), intent(in) :: dipolar_interactions_dynamic integer :: j_component, i_exclude do j_component = 1, size(dipolar_interactions_dynamic%real_components, 1) i_exclude = merge(particle%i, 0, j_component == i_component) call dipolar_interactions_dynamic%real_components(j_component, i_component)%component%& visit(delta_energies(j_component), particle, visit_different, i_exclude) end do delta_energies(i_component) = delta_energies(i_component) - dipolar_interactions_dynamic%& self_components(i_component)%component%meet(particle%dipole_moment) delta_shared_energy = & dipolar_interactions_dynamic%reci_visitor%visit_add(i_component, particle) + & dipolar_interactions_dynamic%surf_mixture%& visit_add(i_component, particle%dipole_moment) - & dipolar_interactions_dynamic%dlc_visitor%visit_add(i_component, particle) end subroutine visit_add_dipolar pure subroutine visit_remove_dipolar(delta_energies, delta_shared_energy, i_component, & particle, dipolar_interactions_dynamic) real(DP), intent(inout) :: delta_energies(:) real(DP), intent(out) :: delta_shared_energy integer, intent(in) :: i_component type(Concrete_Particle), intent(in) :: particle type(Dipolar_Interactions_Dynamic_Wrapper), intent(in) :: dipolar_interactions_dynamic integer :: j_component, i_exclude do j_component = 1, size(dipolar_interactions_dynamic%real_components, 1) i_exclude = merge(particle%i, 0, j_component == i_component) call dipolar_interactions_dynamic%real_components(j_component, i_component)%component%& visit(delta_energies(j_component), particle, visit_different, i_exclude) end do delta_energies(i_component) = delta_energies(i_component) - dipolar_interactions_dynamic%& self_components(i_component)%component%meet(particle%dipole_moment) delta_energies = -delta_energies delta_shared_energy = & dipolar_interactions_dynamic%reci_visitor%visit_remove(i_component, particle) + & dipolar_interactions_dynamic%surf_mixture%& visit_remove(i_component, particle%dipole_moment) - & dipolar_interactions_dynamic%dlc_visitor%visit_remove(i_component, particle) end subroutine visit_remove_dipolar end module procedures_exchange_visitors