Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_particle_initializers_6d.F90
Go to the documentation of this file.
1 !**************************************************************
2 ! Copyright INRIA
3 ! Authors :
4 ! CALVI project team
5 !
6 ! This code SeLaLib (for Semi-Lagrangian-Library)
7 ! is a parallel library for simulating the plasma turbulence
8 ! in a tokamak.
9 !
10 ! This software is governed by the CeCILL-B license
11 ! under French law and abiding by the rules of distribution
12 ! of free software. You can use, modify and redistribute
13 ! the software under the terms of the CeCILL-B license as
14 ! circulated by CEA, CNRS and INRIA at the following URL
15 ! "http://www.cecill.info".
16 !**************************************************************
19 
21 
23 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24 #include "sll_assert.h"
25 #include "sll_memory.h"
26 #include "sll_working_precision.h"
27 #include "sll_particle_representation.h"
28 
30  use sll_m_constants, only: sll_p_pi
34 
35  implicit none
36 
38 
39  private
40 
41 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
42 
43 contains
44 
51  thermal_speed, &
52  alpha, k, &
53  mesh, &
54  num_particles, &
55  p_group, &
56  rand_seed, &
57  rank, worldsize)
58 
60  sll_real64, intent(in) :: thermal_speed
62  sll_real64, intent(in) :: alpha
64  sll_real64, intent(in) :: k
66  type(sll_t_cartesian_mesh_3d), intent(in) :: mesh
68  sll_int32, intent(in) :: num_particles
70  sll_int32, dimension(:), intent(in), optional :: rand_seed
72  sll_int32, optional :: rank
74  sll_int32, optional :: worldsize
76  type(sll_t_particle_group_6d), intent(inout) :: p_group
77 
78  sll_int32 :: j
79  sll_int32 :: ic_x, ic_y, ic_z
80  sll_int32 :: nc_x, nc_y
81  sll_real64 :: x, y, z
82  sll_real64 :: xmin, ymin, zmin, rdx, rdy, rdz
83  sll_real32 :: weight
84  sll_real64 :: tmp_x, tmp_y, tmp_z
85  sll_real64 :: nu, fdx, phi, theta, rnd
86  sll_real32 :: volume
87 
88  volume = real((mesh%eta1_max - mesh%eta1_min)* &
89  (mesh%eta2_max - mesh%eta2_min)* &
90  (mesh%eta3_max - mesh%eta3_min), f32)
91 
92  if (present(rand_seed)) then
93  call random_seed(put=rand_seed)
94  end if
95 
96  if (present(worldsize)) then
97  weight = volume/(real(worldsize, f32)*real(num_particles, f32))
98  else
99  weight = volume/real(num_particles, f32)
100  end if
101 
102 ! Each MPI node initialize 'num_particles' particles in the phase space
103 
104  rdx = 1._f64/mesh%delta_eta1
105  rdy = 1._f64/mesh%delta_eta2
106  rdz = 1._f64/mesh%delta_eta3
107  xmin = mesh%eta1_min
108  ymin = mesh%eta2_min
109  zmin = mesh%eta3_min
110  nc_x = mesh%num_cells1
111  nc_y = mesh%num_cells2
112 
113  j = 1
114  do while (j <= num_particles)
115  call random_number(x)
116  x = (mesh%eta1_max - xmin)*x + xmin
117  call random_number(fdx)
118  fdx = (1._f64 + alpha)*fdx
119  if (sll_f_eval_landau1d(alpha, k, x) >= fdx) then
120  call random_number(y)
121  y = (mesh%eta2_max - ymin)*y + ymin
122  call random_number(z)
123  z = (mesh%eta3_max - zmin)*z + zmin
124  call random_number(rnd)
125  nu = thermal_speed*sqrt(-2._f64*log(1.0_f64 - rnd))
126  call random_number(theta)
127  call random_number(phi)
128  p_group%p_list(j)%vx = nu*cos(theta*2.0_f64*sll_p_pi)*cos(phi*2.0_f64*sll_p_pi)
129  p_group%p_list(j)%vy = nu*sin(theta*2.0_f64*sll_p_pi)*cos(phi*2.0_f64*sll_p_pi)
130  p_group%p_list(j)%vz = nu*sin(phi*2.0_f64*sll_p_pi)
131  tmp_x = (x - xmin)*rdx
132  tmp_y = (y - ymin)*rdy
133  tmp_z = (z - zmin)*rdz
134  ic_x = int(tmp_x)
135  ic_y = int(tmp_y)
136  ic_z = int(tmp_z)
137  p_group%p_list(j)%dx = real(tmp_x - real(ic_x, f64), f32)
138  p_group%p_list(j)%dy = real(tmp_y - real(ic_y, f64), f32)
139  p_group%p_list(j)%dz = real(tmp_z - real(ic_z, f64), f32)
140  p_group%p_list(j)%ic = 1 + ic_x + ic_y*nc_x + ic_z*(nc_x*nc_y)
141  j = j + 1
142  end if
143  end do
144 
145  return
146  sll_assert(present(rank))
147 
148  end subroutine sll_s_initial_random_particles_6d
149 
150  function sll_f_eval_landau1d(alp, kx, x)
151 
152  sll_real64 :: alp, kx, x
153  sll_real64 :: sll_f_eval_landau1d
154 
155  sll_f_eval_landau1d = 1._f64 + alp*cos(kx*x)
156 
157  end function sll_f_eval_landau1d
158 
Cartesian mesh basic types.
Fortran module where set some physical and mathematical constants.
real(kind=f64), parameter, public sll_p_pi
sll_m_gaussian random generator
subroutine, public sll_s_gaussian_deviate_2d(res)
Returns a value of a random variable in TWO dimensions following the Gaussian probability density wit...
hamm pseudo-random generator
real(kind=f64) function, public sll_f_suite_hamm(n, b)
Initialization of particles in 2d+2v: the Landau damping case.
real(kind=f64) function sll_f_eval_landau1d(alp, kx, x)
subroutine, public sll_s_initial_random_particles_6d(thermal_speed, alpha, k, mesh, num_particles, p_group, rand_seed, rank, worldsize)
Initialize particles in a 3d+3v phase space using random generators.
    Report Typos and Errors