core_build_plan_impl Subroutine

public subroutine core_build_plan_impl(plan, src_pos, options)

FMM 計画と木構造、転送演算子を構築する。

Arguments

Type IntentOptional Attributes Name
type(fmm_plan_type), intent(inout) :: plan

構築対象の FMM 計画。

real(kind=dp), intent(in) :: src_pos(:,:)
type(fmm_options_type), intent(in) :: options

FMM 設定。


Calls

proc~~core_build_plan_impl~~CallsGraph proc~core_build_plan_impl core_build_plan_impl proc~active_tree_child_count active_tree_child_count proc~core_build_plan_impl->proc~active_tree_child_count proc~active_tree_child_idx active_tree_child_idx proc~core_build_plan_impl->proc~active_tree_child_idx proc~active_tree_nnode active_tree_nnode proc~core_build_plan_impl->proc~active_tree_nnode proc~active_tree_node_center active_tree_node_center proc~core_build_plan_impl->proc~active_tree_node_center proc~active_tree_node_radius active_tree_node_radius proc~core_build_plan_impl->proc~active_tree_node_radius proc~append_i32_buffer append_i32_buffer proc~core_build_plan_impl->proc~append_i32_buffer proc~build_axis_powers build_axis_powers proc~core_build_plan_impl->proc~build_axis_powers proc~build_periodic_shift_values build_periodic_shift_values proc~core_build_plan_impl->proc~build_periodic_shift_values proc~compute_laplace_derivatives compute_laplace_derivatives proc~core_build_plan_impl->proc~compute_laplace_derivatives proc~core_destroy_plan_impl core_destroy_plan_impl proc~core_build_plan_impl->proc~core_destroy_plan_impl proc~distance_to_source_bbox distance_to_source_bbox proc~core_build_plan_impl->proc~distance_to_source_bbox proc~distance_to_source_bbox_periodic distance_to_source_bbox_periodic proc~core_build_plan_impl->proc~distance_to_source_bbox_periodic proc~has_valid_target_box has_valid_target_box proc~core_build_plan_impl->proc~has_valid_target_box proc~initialize_basis_tables initialize_basis_tables proc~core_build_plan_impl->proc~initialize_basis_tables proc~nodes_well_separated nodes_well_separated proc~core_build_plan_impl->proc~nodes_well_separated proc~octant_index octant_index proc~core_build_plan_impl->proc~octant_index proc~precompute_periodic2_ewald_data precompute_periodic2_ewald_data proc~core_build_plan_impl->proc~precompute_periodic2_ewald_data proc~precompute_periodic_root_operator precompute_periodic_root_operator proc~core_build_plan_impl->proc~precompute_periodic_root_operator proc~wrap_src_pos_to_primary_cell wrap_src_pos_to_primary_cell proc~core_build_plan_impl->proc~wrap_src_pos_to_primary_cell proc~reset_fmm_plan reset_fmm_plan proc~core_destroy_plan_impl->proc~reset_fmm_plan proc~apply_periodic2_minimum_image apply_periodic2_minimum_image proc~distance_to_source_bbox_periodic->proc~apply_periodic2_minimum_image proc~nodes_well_separated->proc~active_tree_node_center proc~nodes_well_separated->proc~active_tree_node_radius proc~nodes_well_separated->proc~apply_periodic2_minimum_image proc~reset_periodic2_ewald_data reset_periodic2_ewald_data proc~precompute_periodic2_ewald_data->proc~reset_periodic2_ewald_data proc~resolve_periodic2_ewald_alpha resolve_periodic2_ewald_alpha proc~precompute_periodic2_ewald_data->proc~resolve_periodic2_ewald_alpha proc~use_periodic2_m2l_root_oracle use_periodic2_m2l_root_oracle proc~precompute_periodic2_ewald_data->proc~use_periodic2_m2l_root_oracle proc~precompute_periodic_root_operator->proc~active_tree_child_count proc~precompute_periodic_root_operator->proc~active_tree_child_idx proc~precompute_periodic_root_operator->proc~active_tree_nnode proc~precompute_periodic_root_operator->proc~active_tree_node_center proc~precompute_periodic_root_operator->proc~build_axis_powers proc~active_tree_max_depth active_tree_max_depth proc~precompute_periodic_root_operator->proc~active_tree_max_depth proc~active_tree_node_half_size active_tree_node_half_size proc~precompute_periodic_root_operator->proc~active_tree_node_half_size proc~add_periodic2_exact_ewald_correction_single_source add_periodic2_exact_ewald_correction_single_source proc~precompute_periodic_root_operator->proc~add_periodic2_exact_ewald_correction_single_source proc~precompute_periodic_root_operator->proc~use_periodic2_m2l_root_oracle proc~reset_fmm_plan->proc~reset_periodic2_ewald_data

Source Code

  subroutine core_build_plan_impl(plan, src_pos, options)
    type(fmm_plan_type), intent(inout) :: plan
    real(dp), intent(in) :: src_pos(:, :)
    type(fmm_options_type), intent(in) :: options
    integer(i32) :: nsrc

    if (allocated(plan%alpha) .or. allocated(plan%src_pos) .or. allocated(plan%elem_order)) then
      call core_destroy_plan_impl(plan)
    end if
    plan%options = options
    nsrc = int(size(src_pos, 2), i32)
    plan%nsrc = nsrc
    if (size(src_pos, 1) /= 3) error stop 'FMM core expects src_pos(3,n).'
    if (options%leaf_max <= 0_i32) error stop 'FMM leaf_max must be > 0.'
    if (options%order < 0_i32) error stop 'FMM order must be >= 0.'
    if (options%softening < 0.0d0) error stop 'FMM softening must be >= 0.'
    if (options%use_periodic2) then
      if (any(options%periodic_axes < 1_i32) .or. any(options%periodic_axes > 3_i32)) then
        error stop 'periodic2 requires periodic axes in 1..3.'
      end if
      if (options%periodic_axes(1) == options%periodic_axes(2)) then
        error stop 'periodic2 requires two distinct axes.'
      end if
      if (any(options%periodic_len <= 0.0d0)) then
        error stop 'periodic2 requires positive periodic lengths.'
      end if
      if (.not. has_valid_target_box(plan%options)) then
        error stop 'periodic2 requires a valid target box.'
      end if
      select case (trim(plan%options%periodic_far_correction))
      case ('auto')
        plan%options%periodic_far_correction = 'm2l_root_oracle'
        plan%options%periodic_ewald_layers = max(1_i32, plan%options%periodic_ewald_layers)
      case ('none')
        continue
      case ('m2l_root_oracle')
        continue
      case default
        error stop 'Unsupported periodic far correction in FMM core.'
      end select
      if (trim(plan%options%periodic_far_correction) == 'm2l_root_oracle') then
        if (plan%options%periodic_ewald_layers < 1_i32) then
          error stop 'periodic2 root-operator far correction requires periodic_ewald_layers >= 1.'
        end if
      end if
    end if

    allocate (plan%src_pos(3, max(0_i32, nsrc)))
    if (nsrc > 0_i32) plan%src_pos = src_pos

    if (options%use_periodic2 .and. nsrc > 0_i32) call build_canonical_src_pos(plan)

    call initialize_basis_tables(plan, options%order)
    call build_source_tree(plan)
    call precompute_source_p2m_basis(plan)
    call build_target_topology(plan)
    call build_interactions(plan)
    call precompute_translation_operators(plan)
    call precompute_periodic2_ewald_data(plan)
    call precompute_periodic_root_operator(plan)
    call precompute_m2l_derivatives(plan)
    plan%built = .true.
  end subroutine core_build_plan_impl