Apply distance-based screening to filter out fragments that exceed cutoff distances Modifies polymers array in-place and updates total_fragments count
IMPORTANT: For MBE correctness, if any k-subset of an n-mer exceeds the k-mer cutoff, the entire n-mer must be screened out. Otherwise, compute_mbe will fail when trying to look up the missing subset.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(inout) | :: | polymers(:,:) | |||
| integer(kind=int64), | intent(inout) | :: | total_fragments | |||
| type(system_geometry_t), | intent(in) | :: | sys_geom | |||
| type(driver_config_t), | intent(in) | :: | driver_config | |||
| integer, | intent(in) | :: | max_level |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | fragment_size | ||||
| integer(kind=int64), | private | :: | fragments_kept | ||||
| integer(kind=int64), | private | :: | fragments_screened | ||||
| integer(kind=int64), | private | :: | i | ||||
| logical, | private | :: | should_screen |
subroutine apply_distance_screening(polymers, total_fragments, sys_geom, driver_config, max_level) !! Apply distance-based screening to filter out fragments that exceed cutoff distances !! Modifies polymers array in-place and updates total_fragments count !! !! IMPORTANT: For MBE correctness, if any k-subset of an n-mer exceeds the k-mer cutoff, !! the entire n-mer must be screened out. Otherwise, compute_mbe will fail when trying !! to look up the missing subset. use mqc_physical_fragment, only: calculate_monomer_distance use mqc_config_adapter, only: driver_config_t integer, intent(inout) :: polymers(:, :) integer(int64), intent(inout) :: total_fragments type(system_geometry_t), intent(in) :: sys_geom type(driver_config_t), intent(in) :: driver_config integer, intent(in) :: max_level integer(int64) :: i, fragments_kept integer :: fragment_size integer(int64) :: fragments_screened logical :: should_screen ! Check if we have cutoffs to apply if (.not. allocated(driver_config%fragment_cutoffs)) then return ! No screening needed end if fragments_kept = 0_int64 fragments_screened = 0_int64 ! Loop through all fragments and filter based on distance do i = 1_int64, total_fragments fragment_size = count(polymers(i, :) > 0) ! Monomers are always kept (distance = 0) if (fragment_size == 1) then fragments_kept = fragments_kept + 1_int64 if (fragments_kept /= i) then ! Compact array - move this fragment to the kept position polymers(fragments_kept, :) = polymers(i, :) end if cycle end if ! For n-mers (n >= 2), check if this fragment or any of its subsets should be screened should_screen = fragment_should_be_screened(polymers(i, 1:fragment_size), fragment_size, & sys_geom, driver_config) if (.not. should_screen) then ! Keep this fragment fragments_kept = fragments_kept + 1_int64 if (fragments_kept /= i) then polymers(fragments_kept, :) = polymers(i, :) end if else ! Screen out this fragment fragments_screened = fragments_screened + 1_int64 end if end do ! Update total fragment count if (fragments_screened > 0) then call logger%info("Distance-based screening applied:") call logger%info(" Fragments before screening: "//to_char(total_fragments)) call logger%info(" Fragments screened out: "//to_char(fragments_screened)) call logger%info(" Fragments kept: "//to_char(fragments_kept)) total_fragments = fragments_kept end if end subroutine apply_distance_screening