速度グリッド分布から reservoir_face 粒子をサンプルする。
velocity_grid_pdf_kind="phase_space" では max(v_n,0) f(v) で流入粒子を選び、
"flux_weighted" では入力 f を流入粒子分布として扱う。
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=dp), | intent(in) | :: | box_min(3) | |||
| real(kind=dp), | intent(in) | :: | box_max(3) | |||
| character(len=*), | intent(in) | :: | inject_face | |||
| real(kind=dp), | intent(in) | :: | pos_low(3) | |||
| real(kind=dp), | intent(in) | :: | pos_high(3) | |||
| character(len=*), | intent(in) | :: | velocity_grid_path | |||
| character(len=*), | intent(in) | :: | velocity_grid_pdf_kind | |||
| real(kind=dp), | intent(in) | :: | batch_duration | |||
| real(kind=dp), | intent(out) | :: | x(:,:) | |||
| real(kind=dp), | intent(out) | :: | v(:,:) | |||
| real(kind=dp), | intent(in), | optional | :: | barrier_normal_energy | ||
| real(kind=dp), | intent(in), | optional | :: | vmin_normal | ||
| real(kind=dp), | intent(in), | optional | :: | position_jitter_dt | ||
| logical, | intent(in), | optional | :: | apply_barrier_energy_shift | ||
| character(len=*), | intent(in), | optional | :: | velocity_grid_sampling |
subroutine sample_reservoir_velocity_grid_particles( & box_min, box_max, inject_face, pos_low, pos_high, velocity_grid_path, velocity_grid_pdf_kind, batch_duration, x, v, & barrier_normal_energy, vmin_normal, position_jitter_dt, apply_barrier_energy_shift, velocity_grid_sampling & ) real(dp), intent(in) :: box_min(3), box_max(3) character(len=*), intent(in) :: inject_face real(dp), intent(in) :: pos_low(3), pos_high(3) character(len=*), intent(in) :: velocity_grid_path, velocity_grid_pdf_kind real(dp), intent(in) :: batch_duration real(dp), intent(out) :: x(:, :) real(dp), intent(out) :: v(:, :) real(dp), intent(in), optional :: barrier_normal_energy real(dp), intent(in), optional :: vmin_normal real(dp), intent(in), optional :: position_jitter_dt logical, intent(in), optional :: apply_barrier_energy_shift character(len=*), intent(in), optional :: velocity_grid_sampling integer :: i, axis_n, axis_t1, axis_t2 real(dp) :: boundary_value, inward_normal(3), vn_floor, barrier, jitter_dt, vn_inf, vn_out real(dp), allocatable :: u(:, :), tau(:) logical :: apply_energy_shift character(len=16) :: grid_sampling if (size(x, 1) /= 3 .or. size(v, 1) /= 3) error stop "reservoir particle arrays must have first dimension 3" if (size(x, 2) /= size(v, 2)) error stop "reservoir x/v size mismatch" if (batch_duration < 0.0_dp) error stop "batch_duration must be >= 0" if (present(position_jitter_dt)) then if (position_jitter_dt < 0.0_dp) error stop "position_jitter_dt must be >= 0" jitter_dt = position_jitter_dt else jitter_dt = 0.0_dp end if apply_energy_shift = .true. if (present(apply_barrier_energy_shift)) apply_energy_shift = apply_barrier_energy_shift grid_sampling = 'auto' if (present(velocity_grid_sampling)) grid_sampling = lower_ascii(trim(velocity_grid_sampling)) if (size(x, 2) == 0) return call resolve_face_geometry(box_min, box_max, inject_face, axis_n, boundary_value, inward_normal) call resolve_face_axes(inject_face, axis_t1, axis_t2) barrier = 0.0_dp if (present(barrier_normal_energy)) barrier = barrier_normal_energy vn_floor = 0.0_dp if (barrier > 0.0_dp) vn_floor = sqrt(barrier) if (present(vmin_normal)) vn_floor = max(vn_floor, max(0.0_dp, vmin_normal)) call sample_velocity_grid_distribution(velocity_grid_path, velocity_grid_pdf_kind, grid_sampling, inward_normal, vn_floor, v) if (apply_energy_shift) then do i = 1, size(v, 2) vn_inf = dot_product(v(:, i), inward_normal) vn_out = sqrt(max(0.0_dp, vn_inf*vn_inf - barrier)) v(:, i) = v(:, i) - inward_normal*vn_inf + inward_normal*vn_out end do end if allocate (u(2, size(x, 2))) call random_number(u) if (jitter_dt > 0.0_dp) then allocate (tau(size(x, 2))) call random_number(tau) end if do i = 1, size(x, 2) x(:, i) = 0.0_dp x(axis_n, i) = boundary_value x(axis_t1, i) = pos_low(axis_t1) + (pos_high(axis_t1) - pos_low(axis_t1))*u(1, i) x(axis_t2, i) = pos_low(axis_t2) + (pos_high(axis_t2) - pos_low(axis_t2))*u(2, i) if (jitter_dt > 0.0_dp) x(:, i) = x(:, i) + v(:, i)*(tau(i)*jitter_dt) x(:, i) = x(:, i) + inward_normal*1.0d-12 end do end subroutine sample_reservoir_velocity_grid_particles