module procedures_transmutation_visitors use, intrinsic :: iso_fortran_env, only: DP => REAL64 use procedures_visit_condition, only: visit_different use classes_external_field, only: Abstract_External_Field use classes_visitable_walls, only: Abstract_Visitable_Walls use classes_pair_potential, only: Pair_Potential_Wrapper use types_cells_wrapper, only: Cells_Wrapper use types_dipolar_interactions_dynamic_wrapper, only: Dipolar_Interactions_Dynamic_Wrapper use procedures_dipoles_field_interaction, only: dipoles_field_visit_add => visit_add, & dipoles_field_visit_remove => visit_remove use types_particle_wrapper, only: Concrete_Particle implicit none private public :: visit_short, visit_dipolar, i_exclude_particle interface visit_short module procedure :: transmutation_visit_walls module procedure :: transmutation_visit_short end interface visit_short interface visit_dipolar module procedure :: transmutation_visit_field module procedure :: transmutation_visit_dipolar end interface visit_dipolar contains pure subroutine transmutation_visit_walls(overlap, delta_energies, visitable_walls, wall_pairs,& ij_components, particles) logical, intent(out) :: overlap real(DP), intent(out) :: delta_energies(:) class(Abstract_Visitable_Walls), intent(in) :: visitable_walls type(Pair_Potential_Wrapper), intent(in) :: wall_pairs(:) integer, intent(in) :: ij_components(:) type(Concrete_Particle), intent(in) :: particles(:) integer :: i_partner do i_partner = size(particles), 1, -1 call visitable_walls%visit(overlap, delta_energies(i_partner), & particles(i_partner)%position, wall_pairs(ij_components(i_partner))%potential) if (overlap) return end do delta_energies(1) = -delta_energies(1) end subroutine transmutation_visit_walls subroutine transmutation_visit_short(overlap, delta_energies, cells, ij_components, particles) logical, intent(out) :: overlap real(DP), intent(out) :: delta_energies(:, :) type(Cells_Wrapper), intent(in) :: cells integer, intent(in) :: ij_components(:) type(Concrete_Particle), intent(in) :: particles(:) integer :: k_component, i_partner, i_exclude do i_partner = size(particles), 1, -1 do k_component = 1, size(cells%visitable_cells, 1) i_exclude = i_exclude_particle(k_component, ij_components, particles) call cells%visitable_cells(k_component, ij_components(i_partner))%& visit_energy(overlap, delta_energies(k_component, i_partner), & particles(i_partner), visit_different, i_exclude) if (overlap) return end do end do delta_energies(:, 1) = -delta_energies(:, 1) end subroutine transmutation_visit_short pure subroutine transmutation_visit_field(delta_energies, external_field, particles) real(DP), intent(out) :: delta_energies(:) class(Abstract_External_Field), intent(in) :: external_field type(Concrete_Particle), intent(in) :: particles(:) delta_energies = & [dipoles_field_visit_remove(external_field, particles(1)), & dipoles_field_visit_add(external_field, particles(2))] end subroutine transmutation_visit_field pure subroutine transmutation_visit_dipolar(delta_energies, delta_shared_energy, & dipolar_interactions_dynamic, ij_components, particles) real(DP), intent(out) :: delta_energies(:, :) real(DP), intent(out) :: delta_shared_energy type(Dipolar_Interactions_Dynamic_Wrapper), intent(in) :: dipolar_interactions_dynamic integer, intent(in) :: ij_components(:) type(Concrete_Particle), intent(in) :: particles(:) integer :: k_component, i_partner, i_exclude do i_partner = 1, size(particles) do k_component = 1, size(dipolar_interactions_dynamic%real_components, 1) i_exclude = i_exclude_particle(k_component, ij_components, particles) call dipolar_interactions_dynamic%& real_components(k_component, ij_components(i_partner))%component%& visit(delta_energies(k_component, i_partner), particles(i_partner), & visit_different, i_exclude) end do delta_energies(ij_components(i_partner), i_partner) = & delta_energies(ij_components(i_partner), i_partner) - & dipolar_interactions_dynamic%self_components(ij_components(i_partner))%& component%meet(particles(i_partner)%dipole_moment) end do delta_energies(:, 1) = -delta_energies(:, 1) delta_shared_energy = & dipolar_interactions_dynamic%reci_visitor%& visit_transmutation(ij_components, particles(2)%dipole_moment, particles(1)) + & dipolar_interactions_dynamic%surf_mixture%& visit_transmutation(ij_components, particles(2)%dipole_moment, particles(1)%& dipole_moment) - & dipolar_interactions_dynamic%dlc_visitor%& visit_transmutation(ij_components, particles(2)%dipole_moment, particles(1)) end subroutine transmutation_visit_dipolar !> @note The i_actor <-> j_actor term is ignored. pure integer function i_exclude_particle(k_component, ij_components, particles) & result(i_exclude) integer, intent(in) :: k_component, ij_components(:) type(Concrete_Particle), intent(in) :: particles(:) if (k_component == ij_components(1)) then i_exclude = particles(1)%i else if (k_component == ij_components(2)) then i_exclude = particles(2)%i else i_exclude = 0 end if end function i_exclude_particle end module procedures_transmutation_visitors