module procedures_des_real_pair_factory use, intrinsic :: iso_fortran_env, only: DP => REAL64 use json_module, only: json_file use procedures_checks, only: check_data_found use types_potential_domain, only: Concrete_Potential_Domain use classes_box_size_memento, only: Abstract_Box_Size_Memento use classes_permittivity, only: Abstract_Permittivity use classes_min_distance, only: Min_Distance_Line use classes_des_convergence_parameter, only: Abstract_DES_Convergence_Parameter use classes_des_real_pair, only: Abstract_DES_Real_Pair, Tabulated_DES_Real_Pair, & Raw_DES_Real_Pair, Null_DES_Real_Pair implicit none private public :: create, destroy contains subroutine create(pair, box_size_memento, permittivity, min_distances, dipoles_exist, alpha, & generating_data, prefix) class(Abstract_DES_Real_Pair), allocatable, intent(out) :: pair class(Abstract_Box_Size_Memento), intent(in) :: box_size_memento class(Abstract_Permittivity), intent(in) :: permittivity type(Min_Distance_Line), intent(in) :: min_distances(:) logical, intent(in) :: dipoles_exist class(Abstract_DES_Convergence_Parameter), intent(in) :: alpha type(json_file), intent(inout) :: generating_data character(len=*), intent(in) :: prefix real(DP) :: min_distance integer :: i_component, j_component min_distance = min_distances(1)%line(1)%distance%get() do j_component = 1, size(min_distances) do i_component = 1, size(min_distances(j_component)%line) associate(min_distance_ij => min_distances(j_component)%line(i_component)%distance%& get()) if (min_distance > min_distance_ij) min_distance = min_distance_ij end associate end do end do call allocate(pair, dipoles_exist, generating_data, prefix) call construct(pair, box_size_memento, permittivity, min_distance, dipoles_exist, alpha, & generating_data, prefix) end subroutine create subroutine allocate(pair, dipoles_exist, generating_data, prefix) class(Abstract_DES_Real_Pair), allocatable, intent(out) :: pair logical, intent(in) :: dipoles_exist type(json_file), intent(inout) :: generating_data character(len=*), intent(in) :: prefix character(len=:), allocatable :: data_field logical :: data_found, tabulated_potential if (dipoles_exist) then data_field = prefix//"tabulated" call generating_data%get(data_field, tabulated_potential, data_found) call check_data_found(data_field, data_found) if(tabulated_potential) then allocate(Tabulated_DES_Real_Pair :: pair) else allocate(Raw_DES_Real_Pair :: pair) end if else allocate(Null_DES_Real_Pair :: pair) end if end subroutine allocate subroutine construct(pair, box_size_memento, permittivity, min_distance, dipoles_exist, alpha, & generating_data, prefix) class(Abstract_DES_Real_Pair), intent(inout) :: pair class(Abstract_Box_Size_Memento), intent(in) :: box_size_memento class(Abstract_Permittivity), intent(in) :: permittivity real(DP), intent(in) :: min_distance logical, intent(in) :: dipoles_exist class(Abstract_DES_Convergence_Parameter), intent(in) :: alpha type(json_file), intent(inout) :: generating_data character(len=*), intent(in) :: prefix character(len=:), allocatable :: data_field logical :: data_found type(Concrete_Potential_Domain) :: domain if (dipoles_exist) then domain%min = min_distance data_field = prefix//"max distance / box edge" call generating_data%get(data_field, domain%max_over_box_edge, data_found) call check_data_found(data_field, data_found) select type (pair) type is (Tabulated_DES_Real_Pair) data_field = prefix//"delta distance" call generating_data%get(data_field, domain%delta, data_found) call check_data_found(data_field, data_found) end select end if call pair%construct(box_size_memento, permittivity, alpha, domain) end subroutine construct subroutine destroy(pair) class(Abstract_DES_Real_Pair), allocatable, intent(inout) :: pair if (allocated(pair)) then call pair%destroy() deallocate(pair) end if end subroutine destroy end module procedures_des_real_pair_factory