FMM 計画と木構造、転送演算子を構築する。
| Type | Intent | Optional | 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 設定。 |
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