generate_intersections_from_atom_lists Subroutine

private subroutine generate_intersections_from_atom_lists(atom_lists, n_atoms_list, n_sets, max_k_level, intersections, intersection_sets, intersection_levels, n_intersections)

Uses

    • pic_logger
    • pic_io
  • proc~~generate_intersections_from_atom_lists~~UsesGraph proc~generate_intersections_from_atom_lists generate_intersections_from_atom_lists pic_io pic_io proc~generate_intersections_from_atom_lists->pic_io pic_logger pic_logger proc~generate_intersections_from_atom_lists->pic_logger

Generate k-way intersections from arbitrary atom lists (not tied to sys_geom) max_k_level limits the maximum intersection order to prevent combinatorial explosion

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: atom_lists(:,:)

(max_atoms, n_sets)

integer, intent(in) :: n_atoms_list(:)

Number of atoms in each set

integer, intent(in) :: n_sets

Number of sets (polymers)

integer, intent(in) :: max_k_level

Maximum intersection level to compute

integer, intent(out), allocatable :: intersections(:,:)
integer, intent(out), allocatable :: intersection_sets(:,:)
integer, intent(out), allocatable :: intersection_levels(:)
integer, intent(out) :: n_intersections

Calls

proc~~generate_intersections_from_atom_lists~~CallsGraph proc~generate_intersections_from_atom_lists generate_intersections_from_atom_lists info info proc~generate_intersections_from_atom_lists->info proc~generate_k_way_intersections_from_lists generate_k_way_intersections_from_lists proc~generate_intersections_from_atom_lists->proc~generate_k_way_intersections_from_lists to_char to_char proc~generate_intersections_from_atom_lists->to_char proc~next_combination next_combination proc~generate_k_way_intersections_from_lists->proc~next_combination proc~next_combination_init next_combination_init proc~generate_k_way_intersections_from_lists->proc~next_combination_init

Called by

proc~~generate_intersections_from_atom_lists~~CalledByGraph proc~generate_intersections_from_atom_lists generate_intersections_from_atom_lists proc~generate_polymer_intersections generate_polymer_intersections proc~generate_polymer_intersections->proc~generate_intersections_from_atom_lists

Variables

Type Visibility Attributes Name Initial
integer, private :: actual_max_k
integer, private, allocatable :: combination(:)
integer, private :: idx
integer, private :: intersection_count
integer, private :: k
integer, private :: max_atoms
integer, private :: max_intersections
integer, private, allocatable :: temp_intersections(:,:)
integer, private, allocatable :: temp_levels(:)
integer, private, allocatable :: temp_sets(:,:)

Source Code

   subroutine generate_intersections_from_atom_lists(atom_lists, n_atoms_list, n_sets, max_k_level, &
                                                   intersections, intersection_sets, intersection_levels, n_intersections)
      !! Generate k-way intersections from arbitrary atom lists (not tied to sys_geom)
      !! max_k_level limits the maximum intersection order to prevent combinatorial explosion
      use pic_logger, only: logger => global_logger
      use pic_io, only: to_char
      integer, intent(in) :: atom_lists(:, :)  !! (max_atoms, n_sets)
      integer, intent(in) :: n_atoms_list(:)   !! Number of atoms in each set
      integer, intent(in) :: n_sets            !! Number of sets (polymers)
      integer, intent(in) :: max_k_level       !! Maximum intersection level to compute
      integer, allocatable, intent(out) :: intersections(:, :)
      integer, allocatable, intent(out) :: intersection_sets(:, :)
      integer, allocatable, intent(out) :: intersection_levels(:)
      integer, intent(out) :: n_intersections

      integer :: max_intersections, max_atoms
      integer, allocatable :: temp_intersections(:, :), temp_sets(:, :), temp_levels(:)
      integer :: intersection_count, k, idx, actual_max_k
      integer, allocatable :: combination(:)

      if (n_sets < 2) then
         n_intersections = 0
         return
      end if

      ! Limit k-way intersections to min(max_k_level, n_sets)
      actual_max_k = min(max_k_level, n_sets)

      max_intersections = 2**n_sets - n_sets - 1
      max_atoms = maxval(n_atoms_list)

      allocate (temp_intersections(max_atoms, max_intersections))
      allocate (temp_sets(n_sets, max_intersections))
      allocate (temp_levels(max_intersections))
      temp_intersections = 0
      temp_sets = 0
      intersection_count = 0

      call logger%info("Generating k-way intersections (k=2 to "//to_char(actual_max_k)//")")

      ! Loop over intersection levels k from 2 to actual_max_k
      do k = 2, actual_max_k
         allocate (combination(k))
         call generate_k_way_intersections_from_lists(atom_lists, n_atoms_list, n_sets, k, &
                                                      combination, max_atoms, &
                                                      temp_intersections, temp_sets, temp_levels, intersection_count)
         deallocate (combination)
      end do

      n_intersections = intersection_count

      ! Allocate output arrays
      if (n_intersections > 0) then
         allocate (intersections(max_atoms, n_intersections))
         allocate (intersection_sets(n_sets, n_intersections))
         allocate (intersection_levels(n_intersections))
         intersections = temp_intersections(1:max_atoms, 1:n_intersections)
         intersection_sets = temp_sets(1:n_sets, 1:n_intersections)
         intersection_levels = temp_levels(1:n_intersections)

         call logger%info("Generated "//to_char(n_intersections)//" total intersections:")
         do k = 2, actual_max_k
            idx = count(intersection_levels == k)
            if (idx > 0) then
               call logger%info("  "//to_char(idx)//" intersections at level "//to_char(k))
            end if
         end do
      else
         allocate (intersections(1, 0))
         allocate (intersection_sets(1, 0))
         allocate (intersection_levels(0))
         call logger%info("No intersections found")
      end if

      deallocate (temp_intersections, temp_sets, temp_levels)
   end subroutine generate_intersections_from_atom_lists