ソース電荷から FMM state を更新する。
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(fmm_plan_type), | intent(in) | :: | plan |
構築済みの FMM 計画。 |
||
| type(fmm_state_type), | intent(inout) | :: | state |
更新対象の state。 |
||
| real(kind=dp), | intent(in) | :: | src_q(:) |
subroutine core_update_state_impl(plan, state, src_q) type(fmm_plan_type), intent(in) :: plan type(fmm_state_type), intent(inout) :: state real(dp), intent(in) :: src_q(:) integer(i32) :: n_target_nodes, source_idx real(dp) :: total_charge, e_bottom, phi_gauge, z_gauge if (.not. plan%built) error stop 'FMM plan is not built.' if (size(src_q) /= plan%nsrc) error stop 'src_q size does not match plan.' state%ready = .false. call ensure_state_capacity(plan, state) if (plan%periodic_k0_ready) then total_charge = sum(src_q) z_gauge = plan%periodic_k0_plan%break_z(1) e_bottom = -0.5_dp*total_charge/(eps0*plan%periodic_k0_plan%area_xy) phi_gauge = 0.0_dp do source_idx = 1_i32, plan%nsrc phi_gauge = phi_gauge - 0.5_dp*src_q(source_idx)* & (sum(plan%periodic_k0_plan%panel(source_idx)%z)/3.0_dp - z_gauge)/ & (eps0*plan%periodic_k0_plan%area_xy) end do call refresh_periodic_zero_mode_state( & plan%periodic_k0_plan, src_q, e_bottom, z_gauge, phi_gauge, state%periodic_k0_state & ) end if n_target_nodes = merge(plan%target_nnode, plan%nnode, plan%target_tree_ready) !$omp parallel default(none) shared(plan, state, src_q, n_target_nodes) if (associated(state%multipole_active)) then !$omp workshare state%multipole_active = 0_i32 !$omp end workshare end if if (associated(state%local_active)) then !$omp workshare state%local_active = 0_i32 !$omp end workshare end if if (plan%nsrc > 0_i32) then !$omp workshare state%src_q = src_q !$omp end workshare end if if (plan%nsource_leaf <= 0_i32 .and. associated(state%multipole)) then !$omp workshare state%multipole = 0.0d0 !$omp end workshare end if if (plan%m2l_pair_count <= 0_i32 .and. associated(state%local)) then !$omp workshare state%local = 0.0d0 !$omp end workshare end if call p2m_leaf_moments(plan, state) call m2m_upward_pass(plan, state) if (n_target_nodes > 0_i32) then call m2l_accumulate(plan, state) call apply_periodic_target_correction(plan, state) call l2l_downward_pass(plan, state) end if !$omp end parallel state%ready = .true. state%update_count = state%update_count + 1_i32 end subroutine core_update_state_impl