diff --git a/src/korc_avalanche.f90 b/src/korc_avalanche.f90 index d64030bc..2600d8ff 100755 --- a/src/korc_avalanche.f90 +++ b/src/korc_avalanche.f90 @@ -7,7 +7,8 @@ MODULE korc_avalanche USE korc_profiles USE korc_coords USE korc_input - + USE korc_random + IMPLICIT NONE TYPE, PRIVATE :: AVALANCHE_PDF_PARAMS @@ -71,14 +72,14 @@ MODULE korc_avalanche sample_distribution,& indicator,& PSI_ROT,& - random_norm,& update_avalanche_params,& Avalanche_4D CONTAINS - SUBROUTINE get_avalanche_distribution(params,g,eta,go,etao) + SUBROUTINE get_avalanche_distribution(params,random,g,eta,go,etao) TYPE(KORC_PARAMS), INTENT(IN) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random REAL(rp), DIMENSION(:), ALLOCATABLE, INTENT(INOUT) :: g REAL(rp), DIMENSION(:), ALLOCATABLE, INTENT(INOUT) :: eta REAL(rp), INTENT(OUT) :: go @@ -88,11 +89,12 @@ SUBROUTINE get_avalanche_distribution(params,g,eta,go,etao) call save_avalanche_params(params) - call sample_distribution(params,g,eta,go,etao) + call sample_distribution(params,random,g,eta,go,etao) END SUBROUTINE get_avalanche_distribution - SUBROUTINE get_Avalanche_4D(params,spp,P,F) + SUBROUTINE get_Avalanche_4D(params,random,spp,P,F) TYPE(KORC_PARAMS), INTENT(IN) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp TYPE(PROFILES), INTENT(IN) :: P TYPE(FIELDS), INTENT(IN) :: F @@ -102,7 +104,7 @@ SUBROUTINE get_Avalanche_4D(params,spp,P,F) call save_avalanche_params(params) - call Avalanche_4D(params,spp,P,F) + call Avalanche_4D(params,random,spp,P,F) END SUBROUTINE get_Avalanche_4D @@ -203,8 +205,9 @@ FUNCTION log10fRE(x,p) END FUNCTION log10fRE - SUBROUTINE sample_distribution(params,g,eta,go,etao) + SUBROUTINE sample_distribution(params,random,g,eta,go,etao) TYPE(KORC_PARAMS), INTENT(IN) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random REAL(rp), DIMENSION(:), ALLOCATABLE, INTENT(INOUT) :: g REAL(rp), DIMENSION(:), ALLOCATABLE, INTENT(INOUT) :: eta REAL(rp), INTENT(OUT) :: go @@ -228,6 +231,7 @@ SUBROUTINE sample_distribution(params,g,eta,go,etao) INTEGER :: ii,jj,ppp,nsamples INTEGER :: mpierr + CALL random%uniform%set(0.0_rp,1.0_rp) ppp = SIZE(g) nsamples = ppp*params%mpi_params%nmpi @@ -276,30 +280,27 @@ SUBROUTINE sample_distribution(params,g,eta,go,etao) ALLOCATE(eta_tmp(nsamples)) ! Number of samples to distribute among all MPI processes - ! Transient ! - call RANDOM_SEED() - - call RANDOM_NUMBER(rand_unif) eta_buffer = aval_params%min_pitch_angle + (aval_params%max_pitch_angle & - - aval_params%min_pitch_angle)*rand_unif + - aval_params%min_pitch_angle)*random%uniform%get() - call RANDOM_NUMBER(rand_unif) p_buffer = aval_params%min_p + (aval_params%max_p - aval_params%min_p)* & - rand_unif + random%uniform%get() ii=2_idef do while (ii .LE. 1000_idef) - eta_test = eta_buffer + random_norm(0.0_rp,deta) + CALL random%normal%set(0.0_rp,deta) + eta_test = eta_buffer + random%normal%get() do while ((ABS(eta_test) .GT. aval_params%max_pitch_angle).OR. & (ABS(eta_test) .LT. aval_params%min_pitch_angle)) - eta_test = eta_buffer + random_norm(0.0_rp,deta) + eta_test = eta_buffer + random%normal%get() end do chi_test = COS(deg2rad(eta_test)) chi = COS(deg2rad(eta_buffer)) - p_test = p_buffer + random_norm(0.0_rp,dp) + CALL random%normal%set(0.0_rp,dp) + p_test = p_buffer + random%normal%get() do while ((p_test.LT.aval_params%min_p).OR.(p_test.GT.aval_params%max_p)) - p_test = p_buffer + random_norm(0.0_rp,dp) + p_test = p_buffer + random%normal%get() end do ratio = fRE(chi_test,p_test)/fRE(chi,p_buffer) @@ -308,9 +309,8 @@ SUBROUTINE sample_distribution(params,g,eta,go,etao) p_buffer = p_test eta_buffer = eta_test ii = ii + 1_idef - else - call RANDOM_NUMBER(rand_unif) - if (rand_unif .LT. ratio) then + else + if (random%uniform%get() .LT. ratio) then p_buffer = p_test eta_buffer = eta_test ii = ii + 1_idef @@ -319,10 +319,6 @@ SUBROUTINE sample_distribution(params,g,eta,go,etao) end do ! Transient ! - - call RANDOM_SEED() - call RANDOM_NUMBER(rand_unif) - eta_tmp(1) = eta_buffer p_tmp(1) = p_buffer @@ -330,17 +326,19 @@ SUBROUTINE sample_distribution(params,g,eta,go,etao) do while(num_accepted.LT.nsamples) ii=2_idef do while (ii .LE. nsamples) - eta_test = eta_tmp(ii-1) + random_norm(0.0_rp,deta) + CALL random%normal%set(0.0_rp,deta) + eta_test = eta_tmp(ii-1) + random%normal%get() do while ((ABS(eta_test) .GT. max_pitch_angle).OR.(ABS(eta_test) & .LT. min_pitch_angle)) - eta_test = eta_tmp(ii-1) + random_norm(0.0_rp,deta) + eta_test = eta_tmp(ii-1) + random%normal%get() end do chi_test = COS(deg2rad(eta_test)) chi = COS(deg2rad(eta_tmp(ii-1))) - p_test = p_tmp(ii-1) + random_norm(0.0_rp,dp) + CALL random%normal%set(0.0_rp,dp) + p_test = p_tmp(ii-1) + random%normal%get() do while ((p_test.LT.min_p).OR.(p_test.GT.max_p)) - p_test = p_tmp(ii-1) + random_norm(0.0_rp,dp) + p_test = p_tmp(ii-1) + random%normal%get() end do ratio = fRE(chi_test,p_test)/fRE(chi,p_tmp(ii-1)) @@ -349,9 +347,8 @@ SUBROUTINE sample_distribution(params,g,eta,go,etao) p_tmp(ii) = p_test eta_tmp(ii) = eta_test ii = ii + 1_idef - else - call RANDOM_NUMBER(rand_unif) - if (rand_unif .LT. ratio) then + else + if (random%uniform%get() .LT. ratio) then p_tmp(ii) = p_test eta_tmp(ii) = eta_test ii = ii + 1_idef @@ -448,20 +445,6 @@ FUNCTION indicator(psi,psi_max) END FUNCTION indicator - - FUNCTION random_norm(mean,sigma) - REAL(rp), INTENT(IN) :: mean - REAL(rp), INTENT(IN) :: sigma - REAL(rp) :: random_norm - REAL(rp) :: rand1, rand2 - - call RANDOM_NUMBER(rand1) - call RANDOM_NUMBER(rand2) - - random_norm = mean+sigma*SQRT(-2.0_rp*LOG(rand1))*COS(2.0_rp*C_PI*rand2); - END FUNCTION random_norm - - SUBROUTINE update_avalanche_params(params,prtcls) !! Updates the avalanche parameters aval_params% at each step !! in the MCMC after the profiles are interpolated at the sampled @@ -497,12 +480,13 @@ SUBROUTINE update_avalanche_params(params,prtcls) END SUBROUTINE update_avalanche_params -subroutine Avalanche_4D(params,spp,P,F) - !! @note Subroutine that generates a 2D Gaussian distribution in an +subroutine Avalanche_4D(params,random,spp,P,F) + !! @note Subroutine that generates a 2D Gaussian distribution in an !! elliptic torus as the initial spatial condition of a given particle !! species in the simulation. @endnote TYPE(KORC_PARAMS), INTENT(IN) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp !! An instance of the derived type SPECIES containing all the parameters !! and simulation variables of the different species in the simulation. @@ -572,6 +556,8 @@ subroutine Avalanche_4D(params,spp,P,F) INTEGER :: mpierr !! mpi error indicator + CALL random%uniform%set(0.0_rp, 1.0_rp) + ALLOCATE(mom(spp%ppp)) nsamples = spp%ppp*params%mpi_params%nmpi @@ -633,13 +619,10 @@ subroutine Avalanche_4D(params,spp,P,F) R_buffer = spp%Ro Z_buffer = spp%Zo - - call RANDOM_NUMBER(rand_unif) T_buffer = min_pitch_angle + (max_pitch_angle & - - min_pitch_angle)*rand_unif + - min_pitch_angle)*random%uniform%get() - call RANDOM_NUMBER(rand_unif) - P_buffer = min_p + (max_p - min_p)*rand_unif + P_buffer = min_p + (max_p - min_p)*random%uniform%get() ! write(output_unit_write,'("length norm: ",E17.10)') params%cpp%length @@ -647,22 +630,25 @@ subroutine Avalanche_4D(params,spp,P,F) do while (ii .LE. 1000_idef) ! write(output_unit_write,'("burn:",I15)') ii - - R_test = R_buffer + random_norm(0.0_rp,aval_params%dR) - Z_test = Z_buffer + random_norm(0.0_rp,aval_params%dZ) - P_test = P_buffer + random_norm(0.0_rp,aval_params%dp) - T_test = T_buffer + random_norm(0.0_rp,aval_params%dth) + CALL random%normal%set(0.0_rp, aval_params%dR) + R_test = R_buffer + random%normal%get() + CALL random%normal%set(0.0_rp, aval_params%dZ) + Z_test = Z_buffer + random%normal%get() ! Test that pitch angle and momentum are within chosen boundary + CALL random%normal%set(0.0_rp, aval_params%dth) + T_test = T_buffer + random%normal%get() do while ((T_test .GT. aval_params%max_pitch_angle).OR. & (T_test .LT. aval_params%min_pitch_angle)) - T_test = T_buffer + random_norm(0.0_rp,aval_params%dth) + T_test = T_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp, aval_params%dp) + P_test = P_buffer + random%normal%get() do while ((P_test.LT.aval_params%min_p).OR. & (P_test.GT.aval_params%max_p)) - P_test = P_buffer + random_norm(0.0_rp,aval_params%dp) + P_test = P_buffer + random%normal%get() end do ! initialize 2D gaussian argument and distribution function, or @@ -727,8 +713,7 @@ subroutine Avalanche_4D(params,spp,P,F) T_buffer = T_test ii = ii + 1_idef else - call RANDOM_NUMBER(rand_unif) - if (rand_unif .LT. ratio) then + if (random%uniform%get() .LT. ratio) then R_buffer = R_test Z_buffer = Z_test P_buffer = P_test @@ -747,28 +732,32 @@ subroutine Avalanche_4D(params,spp,P,F) if (modulo(ii,10000).eq.0) then write(output_unit_write,'("Sample: ",I10)') ii end if - - R_test = R_buffer + random_norm(0.0_rp,aval_params%dR) - Z_test = Z_buffer + random_norm(0.0_rp,aval_params%dZ) - P_test = P_buffer + random_norm(0.0_rp,aval_params%dp) - T_test = T_buffer + random_norm(0.0_rp,aval_params%dth) + + CALL random%normal%set(0.0_rp, aval_params%dR) + R_test = R_buffer + random%normal%get() + CALL random%normal%set(0.0_rp, aval_params%dZ) + Z_test = Z_buffer + random%normal%get() ! Selection boundary is set with buffer region + CALL random%normal%set(0.0_rp, aval_params%dth) + T_test = T_buffer + random%normal%get() do while ((T_test .GT. max_pitch_angle).OR. & (T_test .LT. min_pitch_angle)) if (T_test.lt.0) then T_test=abs(T_test) exit end if - T_test = T_buffer + random_norm(0.0_rp,aval_params%dth) + T_test = T_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp, aval_params%dp) + P_test = P_buffer + random%normal%get() do while ((P_test.LT.min_p).OR.(P_test.GT.max_p)) if (P_test.lt.0) then P_test=abs(P_test) exit end if - P_test = P_buffer + random_norm(0.0_rp,aval_params%dp) + P_test = P_buffer + random%normal%get() end do psi0=psi1 @@ -797,8 +786,7 @@ subroutine Avalanche_4D(params,spp,P,F) P_buffer = P_test T_buffer = T_test else - call RANDOM_NUMBER(rand_unif) - if (rand_unif .LT. ratio) then + if (random%uniform%get() .LT. ratio) then R_buffer = R_test Z_buffer = Z_test P_buffer = P_test @@ -819,9 +807,8 @@ subroutine Avalanche_4D(params,spp,P,F) P_samples(ii) = P_buffer T_samples(ii) = T_buffer ! Sample phi location uniformly - call RANDOM_NUMBER(rand_unif) - PHI_samples(ii) = 2.0_rp*C_PI*rand_unif - ii = ii + 1_idef + PHI_samples(ii) = 2.0_rp*C_PI*random%uniform%get() + ii = ii + 1_idef END IF diff --git a/src/korc_c_random.cpp b/src/korc_c_random.cpp index e1e43cdb..b9e51766 100755 --- a/src/korc_c_random.cpp +++ b/src/korc_c_random.cpp @@ -1,86 +1,69 @@ #include #include -class random { +#ifdef DOUBLE_PRECISION +typedef double real_type; +#else +typedef float real_type; +#endif + +template +class random_dist { std::mt19937_64 engine; - std::uniform_real_distribution dist; - + DIST dist; + public: - random(const uint64_t offset) : + random_dist(const uint64_t offset) : engine(static_cast (std::chrono::system_clock::to_time_t( std::chrono::system_clock::now())) + offset), - dist(0.0, 1.0) {}; - void set_dist(const double low, const double high) { - dist = std::uniform_real_distribution (low, high); + dist(0.0, 1.0) {} + + void set_dist(const real_type low, const real_type high) { + dist = DIST(low, high); } double get_number() { return dist(engine); } }; -class random_U { - std::mt19937_64 engine_U; - std::uniform_real_distribution dist_U; - - public: - random_U(uint64_t seed_U) : engine_U(seed_U), dist_U(0.0, 1.0) {}; - double get_number_U() { - return dist_U(engine_U); - } -}; - -class random_N { - std::mt19937_64 engine_N; - std::normal_distribution dist_N; - - public: - random_N(uint64_t seed_N) : engine_N(seed_N), dist_N(0.0, 1.0) {}; - double get_number_N() { - return dist_N(engine_N); - } -}; +typedef random_dist > random_U; +typedef random_dist > random_N; extern "C" { - void *random_construct_U(int seed_N) { - return new class random_U(static_cast (seed_N)); + void *random_construct_U(int seed) { + return new random_U(static_cast (seed)); } - void *random_construct_N(int seed_N) { - return new class random_N(static_cast (seed_N)); + void *random_construct_N(int seed) { + return new random_N(static_cast (seed)); } double random_get_number_U(void *r) { - return static_cast (r)->get_number_U(); + return static_cast (r)->get_number(); } double random_get_number_N(void *r) { - return static_cast (r)->get_number_N(); - } - - void random_destroy_N(void *r) { - delete static_cast (r); + return static_cast (r)->get_number(); } - + void random_destroy_U(void *r) { - delete static_cast (r); + delete static_cast (r); } - void *random_construct(const int seed) { - return new class random(static_cast (seed)); + void random_destroy_N(void *r) { + delete static_cast (r); } - void random_set_dist(void *r, - const double low, - const double high) { - static_cast (r)->set_dist(low, high); + void random_set_dist_U(void *r, + const real_type low, + const real_type high) { + static_cast (r)->set_dist(low, high); } - double random_get_number(void *r) { - return static_cast (r)->get_number(); - } - - void random_destroy(void *r) { - delete static_cast (r); + void random_set_dist_N(void *r, + const real_type low, + const real_type high) { + static_cast (r)->set_dist(low, high); } } diff --git a/src/korc_collisions.f90 b/src/korc_collisions.f90 index 8cb44a1d..05ba3fd7 100755 --- a/src/korc_collisions.f90 +++ b/src/korc_collisions.f90 @@ -11,9 +11,7 @@ module korc_collisions use korc_fio #endif -#ifdef PARALLEL_RANDOM use korc_random -#endif #ifdef __NVCOMPILER use ieee_arithmetic @@ -1850,18 +1848,17 @@ subroutine unitVectors_p(pchunk,b_unit_X,b_unit_Y,b_unit_Z,b1_X,b1_Y,b1_Z, & end subroutine unitVectors_p -subroutine check_collisions_params(spp) +subroutine check_collisions_params(random,spp) + CLASS(random_context), POINTER, INTENT(inout) :: random TYPE(SPECIES), INTENT(IN) :: spp INTEGER aux aux = cparams_ss%rnd_num_count + 2_idef*INT(spp%ppp,idef) + CALL random%uniform%set(0.0_rp, 1.0_rp) + if (aux.GE.cparams_ss%rnd_dim) then -#ifdef PARALLEL_RANDOM - cparams_ss%rnd_num = get_random() -#else - call RANDOM_NUMBER(cparams_ss%rnd_num) -#endif PARALLEL_RANDOM + cparams_ss%rnd_num = random%uniform%get() cparams_ss%rnd_num_count = 1_idef end if end subroutine check_collisions_params @@ -1871,7 +1868,7 @@ end subroutine check_collisions_params ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ! -subroutine include_CoulombCollisions_FO_p(tt,params,X_X,X_Y,X_Z, & +subroutine include_CoulombCollisions_FO_p(tt,params,random,X_X,X_Y,X_Z, & U_X,U_Y,U_Z,B_X,B_Y,B_Z,me,P,F,flagCon,flagCol,PSIp) !! This subroutine performs a Stochastic collision process consistent !! with the Fokker-Planck model for relativitic electron colliding with @@ -1885,6 +1882,7 @@ subroutine include_CoulombCollisions_FO_p(tt,params,X_X,X_Y,X_Z, & TYPE(PROFILES), INTENT(IN) :: P TYPE(FIELDS), INTENT(IN) :: F TYPE(KORC_PARAMS), INTENT(IN) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random REAL(rp), DIMENSION(params%pchunk), INTENT(IN) :: X_X,X_Y,X_Z,PSIp REAL(rp), DIMENSION(params%pchunk) :: Y_R,Y_PHI,Y_Z REAL(rp), DIMENSION(params%pchunk), INTENT(INOUT) :: U_X,U_Y,U_Z @@ -1988,22 +1986,20 @@ subroutine include_CoulombCollisions_FO_p(tt,params,X_X,X_Y,X_Z, & ! write(output_unit_write,'("phi: ",E17.10)') phi + CALL random%uniform%set(0.0_rp, 1.0_rp) + !$OMP SIMD ! !$OMP& aligned(rnd1,dW,CAL,dCAL,CFL,CBL,vm,ne,Te,Zeff,dpm, & ! !$OMP& flagCon,flagCol,dxi,xi,pm,dphi,um,Ub_X,Ub_Y,Ub_Z,U_X,U_Y,U_Z, & ! !$OMP& b1_X,b1_Y,b1_Z,b2_X,b2_Y,b2_Z,b3_X,b3_Y,b3_Z) do cc=1_idef,pchunk -#ifdef PARALLEL_RANDOM ! uses C library to generate normal_distribution random variables, ! preserving parallelization where Fortran random number generator ! does not - rnd1(cc,1) = get_random() - rnd1(cc,2) = get_random() - rnd1(cc,3) = get_random() -#else - call RANDOM_NUMBER(rnd1) -#endif + rnd1(cc,1) = random%uniform%get() + rnd1(cc,2) = random%uniform%get() + rnd1(cc,3) = random%uniform%get() dW(cc,1) = SQRT(3*dt)*(-1+2*rnd1(cc,1)) dW(cc,2) = SQRT(3*dt)*(-1+2*rnd1(cc,2)) @@ -2086,7 +2082,7 @@ end subroutine include_CoulombCollisions_FO_p #ifdef FIO -subroutine include_CoulombCollisions_FOfio_p(tt,params,X_X,X_Y,X_Z, & +subroutine include_CoulombCollisions_FOfio_p(tt,params,random,X_X,X_Y,X_Z, & U_X,U_Y,U_Z,B_X,B_Y,B_Z,me,P,F,flagCon,flagCol,PSIp,hint) !! This subroutine performs a Stochastic collision process consistent !! with the Fokker-Planck model for relativitic electron colliding with @@ -2100,6 +2096,7 @@ subroutine include_CoulombCollisions_FOfio_p(tt,params,X_X,X_Y,X_Z, & TYPE(PROFILES), INTENT(IN) :: P TYPE(FIELDS), INTENT(IN) :: F TYPE(KORC_PARAMS), INTENT(IN) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random REAL(rp), DIMENSION(params%pchunk), INTENT(IN) :: X_X,X_Y,X_Z,PSIp REAL(rp), DIMENSION(params%pchunk) :: Y_R,Y_PHI,Y_Z REAL(rp), DIMENSION(params%pchunk), INTENT(INOUT) :: U_X,U_Y,U_Z @@ -2147,6 +2144,8 @@ subroutine include_CoulombCollisions_FOfio_p(tt,params,X_X,X_Y,X_Z, & pchunk=params%pchunk + CALL random%uniform%set(0.0_rp,1.0_rp) + if (MODULO(params%it+tt,cparams_ss%subcycling_iterations) .EQ. 0_ip) then dt = REAL(cparams_ss%subcycling_iterations,rp)*params%dt time=params%init_time+(params%it-1+tt)*params%dt @@ -2211,16 +2210,12 @@ subroutine include_CoulombCollisions_FOfio_p(tt,params,X_X,X_Y,X_Z, & ! !$OMP& b1_X,b1_Y,b1_Z,b2_X,b2_Y,b2_Z,b3_X,b3_Y,b3_Z) do cc=1_idef,pchunk -#ifdef PARALLEL_RANDOM ! uses C library to generate normal_distribution random variables, ! preserving parallelization where Fortran random number generator ! does not - rnd1(cc,1) = get_random() - rnd1(cc,2) = get_random() - rnd1(cc,3) = get_random() -#else - call RANDOM_NUMBER(rnd1) -#endif PARALLEL_RANDOM + rnd1(cc,1) = random%uniform%get() + rnd1(cc,2) = random%uniform%get() + rnd1(cc,3) = random%uniform%get() dW(cc,1) = SQRT(3*dt)*(-1+2*rnd1(cc,1)) dW(cc,2) = SQRT(3*dt)*(-1+2*rnd1(cc,2)) @@ -2297,12 +2292,13 @@ end subroutine include_CoulombCollisions_FOfio_p #endif FIO -subroutine include_CoulombCollisions_GC_p(tt,params,Y_R,Y_PHI,Y_Z, & +subroutine include_CoulombCollisions_GC_p(tt,params,random,Y_R,Y_PHI,Y_Z, & Ppll,Pmu,me,flagCon,flagCol,F,P,E_PHI,ne,PSIp) TYPE(PROFILES), INTENT(IN) :: P TYPE(FIELDS), INTENT(IN) :: F TYPE(KORC_PARAMS), INTENT(INOUT) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random REAL(rp), DIMENSION(params%pchunk), INTENT(INOUT) :: Ppll REAL(rp), DIMENSION(params%pchunk), INTENT(INOUT) :: Pmu REAL(rp), DIMENSION(params%pchunk) :: Bmag @@ -2417,20 +2413,15 @@ subroutine include_CoulombCollisions_GC_p(tt,params,Y_R,Y_PHI,Y_Z, & ! write(output_unit_write,'("xi: ",E17.10)') xi ! write(output_unit_write,'("size(E_PHI_GC): ",I16)') size(E_PHI) + CALL random%uniform%set(0.0_rp, 1.0_rp) !$OMP SIMD ! !$OMP& aligned(rnd1,dW,CAL,dCAL,CFL,CBL,v,ne,Te,Zeff,dp, & ! !$OMP& flagCon,flagCol,dxi,xi,pm,Ppll,Pmu,Bmag) do cc=1_idef,pchunk -#ifdef PARALLEL_RANDOM - rnd1(cc,1) = get_random() - rnd1(cc,2) = get_random() - ! rnd1(:,1) = get_random_mkl() - ! rnd1(:,2) = get_random_mkl() -#else - call RANDOM_NUMBER(rnd1) -#endif PARALLEL_RANDOM + rnd1(cc,1) = random%uniform%get() + rnd1(cc,2) = random%uniform%get() dW(cc,1) = SQRT(3*dt)*(-1+2*rnd1(cc,1)) dW(cc,2) = SQRT(3*dt)*(-1+2*rnd1(cc,2)) @@ -2579,13 +2570,13 @@ subroutine include_CoulombCollisions_GC_p(tt,params,Y_R,Y_PHI,Y_Z, & end subroutine include_CoulombCollisions_GC_p -subroutine include_CoulombCollisionsLA_GC_p(spp,achunk,tt,params, & +subroutine include_CoulombCollisionsLA_GC_p(spp,achunk,tt,params,random, & Y_R,Y_PHI,Y_Z,Ppll,Pmu,me,flagCon,flagCol,F,P,E_PHI,ne,Te,PSIp) - TYPE(SPECIES), INTENT(INOUT) :: spp TYPE(PROFILES), INTENT(IN) :: P TYPE(FIELDS), INTENT(IN) :: F TYPE(KORC_PARAMS), INTENT(INOUT) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random INTEGER, INTENT(IN) :: achunk REAL(rp), DIMENSION(achunk), INTENT(INOUT) :: Ppll REAL(rp), DIMENSION(achunk), INTENT(INOUT) :: Pmu @@ -2700,20 +2691,15 @@ subroutine include_CoulombCollisionsLA_GC_p(spp,achunk,tt,params, & ! write(output_unit_write,'("xi: ",E17.10)') xi ! write(output_unit_write,'("size(E_PHI_GC): ",I16)') size(E_PHI) + CALL random%uniform%set(0.0_rp, 1.0_rp) !$OMP SIMD ! !$OMP& aligned(rnd1,dW,CAL,dCAL,CFL,CBL,v,ne,Te,Zeff,dp, & ! !$OMP& flagCon,flagCol,dxi,xi,pm,Ppll,Pmu,Bmag) do cc=1_idef,achunk -#ifdef PARALLEL_RANDOM - rnd1(cc,1) = get_random() - rnd1(cc,2) = get_random() - ! rnd1(:,1) = get_random_mkl() - ! rnd1(:,2) = get_random_mkl() -#else - call RANDOM_NUMBER(rnd1) -#endif PARALLEL_RANDOM + rnd1(cc,1) = random%uniform%get() + rnd1(cc,2) = random%uniform%get() dW(cc,1) = SQRT(3*dt)*(-1+2*rnd1(cc,1)) dW(cc,2) = SQRT(3*dt)*(-1+2*rnd1(cc,2)) @@ -2971,7 +2957,7 @@ subroutine include_CoulombCollisionsLA_GC_p(spp,achunk,tt,params, & !write(6,*) 'ntot',ntot*params%cpp%density - call large_angle_source(spp,params,achunk,F,Y_R,Y_PHI,Y_Z, & + call large_angle_source(spp,params,random,achunk,F,Y_R,Y_PHI,Y_Z, & pm,xi,ne,ntot,Te,Bmag,E_PHI_LAC,me,flagCol,flagCon,B_R,B_PHI,B_Z) #if DBG_CHECK @@ -3033,12 +3019,13 @@ subroutine include_CoulombCollisionsLA_GC_p(spp,achunk,tt,params, & end subroutine include_CoulombCollisionsLA_GC_p #ifdef FIO -subroutine include_CoulombCollisions_GCfio_p(tt,params,Y_R,Y_PHI,Y_Z, & +subroutine include_CoulombCollisions_GCfio_p(tt,params,random,Y_R,Y_PHI,Y_Z, & Ppll,Pmu,me,flagCon,flagCol,F,P,E_PHI,ne,ni,Te,Zeff,nimp,PSIp,hint) TYPE(PROFILES), INTENT(IN) :: P TYPE(FIELDS), INTENT(IN) :: F TYPE(KORC_PARAMS), INTENT(INOUT) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random REAL(rp), DIMENSION(params%pchunk), INTENT(INOUT) :: Ppll REAL(rp), DIMENSION(params%pchunk), INTENT(INOUT) :: Pmu REAL(rp), DIMENSION(params%pchunk) :: Bmag @@ -3077,6 +3064,7 @@ subroutine include_CoulombCollisions_GCfio_p(tt,params,Y_R,Y_PHI,Y_Z, & pchunk=params%pchunk + CALL random%uniform%set(0.0_rp,1.0_rp) if (MODULO(params%it+tt,cparams_ss%subcycling_iterations) .EQ. 0_ip) then dt = REAL(cparams_ss%subcycling_iterations,rp)*params%dt @@ -3139,15 +3127,8 @@ subroutine include_CoulombCollisions_GCfio_p(tt,params,Y_R,Y_PHI,Y_Z, & ! !$OMP& aligned(rnd1,dW,CAL,dCAL,CFL,CBL,v,ne,Te,Zeff,dp, & ! !$OMP& flagCon,flagCol,dxi,xi,pm,Ppll,Pmu,Bmag) do cc=1_idef,pchunk - -#ifdef PARALLEL_RANDOM - rnd1(cc,1) = get_random() - rnd1(cc,2) = get_random() - ! rnd1(:,1) = get_random_mkl() - ! rnd1(:,2) = get_random_mkl() -#else - call RANDOM_NUMBER(rnd1) -#endif PARALLEL_RANDOM + rnd1(cc,1) = random%uniform%get() + rnd1(cc,2) = random%uniform%get() dW(cc,1) = SQRT(3*dt)*(-1+2*rnd1(cc,1)) dW(cc,2) = SQRT(3*dt)*(-1+2*rnd1(cc,2)) @@ -3311,10 +3292,11 @@ end subroutine include_CoulombCollisions_GCfio_p #endif -subroutine large_angle_source(spp,params,achunk,F,Y_R,Y_PHI,Y_Z, & +subroutine large_angle_source(spp,params,random,achunk,F,Y_R,Y_PHI,Y_Z, & pm,xi,ne,netot,Te,Bmag,E_PHI,me,flagCol,flagCon,B_R,B_PHI,B_Z) TYPE(SPECIES), INTENT(INOUT) :: spp TYPE(KORC_PARAMS), INTENT(IN) :: params + CLASS(random_context), INTENT(INOUT) :: random TYPE(FIELDS), INTENT(IN) :: F INTEGER, INTENT(IN) :: achunk REAL(rp), INTENT(INOUT), DIMENSION(achunk) :: pm,xi @@ -3343,6 +3325,7 @@ subroutine large_angle_source(spp,params,achunk,F,Y_R,Y_PHI,Y_Z, & ngam1=cparams_ss%ngrid1 neta1=cparams_ss%ngrid1 + CALL random%uniform%set(0.0_rp, 1.0_rp) !$OMP SIMD do cc=1_idef,achunk @@ -3352,11 +3335,7 @@ subroutine large_angle_source(spp,params,achunk,F,Y_R,Y_PHI,Y_Z, & gam(cc) = sqrt(1+pm(cc)*pm(cc)) gam0(cc)=gam(cc) -#ifdef PARALLEL_RANDOM - prob0(cc) = get_random() -#else - call RANDOM_NUMBER(prob0) -#endif + prob0(cc) = random%uniform%get() end do !$OMP END SIMD @@ -3600,7 +3579,7 @@ subroutine large_angle_source(spp,params,achunk,F,Y_R,Y_PHI,Y_Z, & seciter=0 do while (.not.accepted) - ptrial=p_min+(psecmax-p_min)*get_random() + ptrial=p_min+(psecmax-p_min)*random%uniform%get() gamtrial=sqrt(1+ptrial*ptrial) cosgam1=sqrt(((gam(cc)+1)*(gamtrial-1))/((gam(cc)-1)*(gamtrial+1))) @@ -3615,8 +3594,7 @@ subroutine large_angle_source(spp,params,achunk,F,Y_R,Y_PHI,Y_Z, & !xip=cosgam1*xi(cc)+xirad !xim=cosgam1*xi(cc)-xirad - !xitrial=xim+(xip-xim)*get_random() - xitrial=-1+2*get_random() + xitrial=-1+2*random%uniform%get() sinsq1=(1-xi(cc)*xi(cc))*(1-xitrial*xitrial) cossq1=(cosgam1-xi(cc)*xitrial)**2 @@ -3637,7 +3615,7 @@ subroutine large_angle_source(spp,params,achunk,F,Y_R,Y_PHI,Y_Z, & (ptrial/gamtrial)*(pm(cc)/gam(cc))* & pitchprob1*dsigdgam1 - if (S_LA1/S_LAmax.gt.get_random()) accepted=.true. + if (S_LA1/S_LAmax.gt.random%uniform%get()) accepted=.true. seciter=seciter+1 diff --git a/src/korc_experimental_pdf.f90 b/src/korc_experimental_pdf.f90 index 71090f10..4d0dff3c 100755 --- a/src/korc_experimental_pdf.f90 +++ b/src/korc_experimental_pdf.f90 @@ -90,7 +90,6 @@ MODULE korc_experimental_pdf save_params,& deg2rad,& rad2deg,& - random_norm,& fRE_H,& fRE_pitch @@ -150,21 +149,9 @@ FUNCTION rad2deg(x) rad2deg = 180.0_rp*x/C_PI END FUNCTION rad2deg - - FUNCTION random_norm(mean,sigma) - REAL(rp), INTENT(IN) :: mean - REAL(rp), INTENT(IN) :: sigma - REAL(rp) :: random_norm - REAL(rp) :: rand1, rand2 - - call RANDOM_NUMBER(rand1) - call RANDOM_NUMBER(rand2) - - random_norm = mean+sigma*SQRT(-2.0_rp*LOG(rand1))*COS(2.0_rp*C_PI*rand2) - END FUNCTION random_norm - - SUBROUTINE get_Hollmann_distribution(params,spp) + SUBROUTINE get_Hollmann_distribution(params,random,spp) TYPE(KORC_PARAMS), INTENT(IN) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp ! REAL(rp), DIMENSION(:), ALLOCATABLE, INTENT(INOUT) :: g ! REAL(rp), DIMENSION(:), ALLOCATABLE, INTENT(INOUT) :: eta @@ -184,14 +171,15 @@ SUBROUTINE get_Hollmann_distribution(params,spp) call save_Hollmann_params(params) - call sample_Hollmann_distribution(params,spp) + call sample_Hollmann_distribution(params,random,spp) END SUBROUTINE get_Hollmann_distribution - SUBROUTINE get_Hollmann_distribution_3D(params,spp,F) + SUBROUTINE get_Hollmann_distribution_3D(params,random,spp,F) TYPE(FIELDS), INTENT(IN) :: F TYPE(KORC_PARAMS), INTENT(IN) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp INTEGER :: mpierr @@ -209,13 +197,14 @@ SUBROUTINE get_Hollmann_distribution_3D(params,spp,F) call normalize_Hollmann_params(params) - call sample_Hollmann_distribution_3D(params,spp,F) + call sample_Hollmann_distribution_3D(params,random,spp,F) END SUBROUTINE get_Hollmann_distribution_3D - SUBROUTINE get_Hollmann_distribution_3D_psi(params,spp,F) + SUBROUTINE get_Hollmann_distribution_3D_psi(params,random,spp,F) TYPE(FIELDS), INTENT(IN) :: F TYPE(KORC_PARAMS), INTENT(INOUT) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp INTEGER :: mpierr @@ -233,13 +222,14 @@ SUBROUTINE get_Hollmann_distribution_3D_psi(params,spp,F) call normalize_Hollmann_params(params) - call sample_Hollmann_distribution_3D_psi(params,spp,F) + call sample_Hollmann_distribution_3D_psi(params,random,spp,F) END SUBROUTINE get_Hollmann_distribution_3D_psi - SUBROUTINE get_Hollmann_distribution_1Dtransport(params,spp,F) + SUBROUTINE get_Hollmann_distribution_1Dtransport(params,random,spp,F) TYPE(FIELDS), INTENT(IN) :: F TYPE(KORC_PARAMS), INTENT(INOUT) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp INTEGER :: mpierr @@ -258,7 +248,7 @@ SUBROUTINE get_Hollmann_distribution_1Dtransport(params,spp,F) call normalize_Hollmann_params(params) #ifdef PSPLINE - call sample_Hollmann_distribution_1Dtransport(params,spp,F) + call sample_Hollmann_distribution_1Dtransport(params,random,spp,F) #endif END SUBROUTINE get_Hollmann_distribution_1Dtransport @@ -679,8 +669,9 @@ FUNCTION fRE_pitch(g) END FUNCTION fRE_pitch - SUBROUTINE sample_Hollmann_distribution(params,spp) + SUBROUTINE sample_Hollmann_distribution(params,random,spp) TYPE(KORC_PARAMS), INTENT(IN) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp ! REAL(rp), DIMENSION(:), ALLOCATABLE, INTENT(INOUT) :: g ! REAL(rp), DIMENSION(:), ALLOCATABLE, INTENT(INOUT) :: eta @@ -777,38 +768,27 @@ SUBROUTINE sample_Hollmann_distribution(params,spp) !Transient! - if (.not.params%SameRandSeed) then - call init_random_seed(params) - else - call random_seed(put=seed) - end if - - call RANDOM_NUMBER(rand_unif) -! rand_unif=get_random_U() + CALL random%uniform%set(0.0_rp,1.0_rp) eta_buffer = h_params%min_pitch_angle + (h_params%max_pitch_angle & - - h_params%min_pitch_angle)*rand_unif + - h_params%min_pitch_angle)*random%uniform%get() - call RANDOM_NUMBER(rand_unif) -! rand_unif=get_random_U() g_buffer = h_params%min_sampling_g + (h_params%max_sampling_g - & - h_params%min_sampling_g)*rand_unif + h_params%min_sampling_g)*random%uniform%get() ii=2_idef do while (ii .LE. 1000_idef) - eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) -! eta_test = eta_buffer + get_random_N()*spp%dth + CALL random%normal%set(0.0_rp,spp%dth) + eta_test = eta_buffer + random%normal%get() do while ((ABS(eta_test) .GT. h_params%max_pitch_angle).OR. & (ABS(eta_test) .LT. h_params%min_pitch_angle)) - eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) -! eta_test = eta_buffer + get_random_N()*spp%dth + eta_test = eta_buffer + random%normal%get() end do - g_test = g_buffer + random_norm(0.0_rp,spp%dgam) -! g_test = g_buffer + get_random_N()*spp%dgam + CALL random%normal%set(0.0_rp,spp%dgam) + g_test = g_buffer + random%normal%get() do while ((g_test.LT.h_params%min_sampling_g).OR. & (g_test.GT.h_params%max_sampling_g)) - g_test = g_buffer + random_norm(0.0_rp,spp%dgam) -! g_test = g_buffer + get_random_N()*spp%dgam + g_test = g_buffer + random%normal%get() end do ratio = fRE_H(eta_test,g_test)*sin(deg2rad(eta_test))/ & @@ -822,9 +802,7 @@ SUBROUTINE sample_Hollmann_distribution(params,spp) eta_buffer = eta_test ii = ii + 1_idef else - call RANDOM_NUMBER(rand_unif) -! rand_unif=get_random_U() - if (rand_unif .LT. ratio) then + if (random%uniform%get() .LT. ratio) then g_buffer = g_test eta_buffer = eta_test ii = ii + 1_idef @@ -847,25 +825,23 @@ SUBROUTINE sample_Hollmann_distribution(params,spp) end if ! write(output_unit_write,'("iisample",I16)') ii - eta_test = eta_tmp(ii-1) + random_norm(0.0_rp,spp%dth) - !eta_test = eta_tmp(ii-1) + get_random_N()*spp%dth + CALL random%normal%set(0.0_rp,spp%dth) + eta_test = eta_tmp(ii-1) + random%normal%get() ! write(output_unit_write,'("max_pitch_angle: ",E17.10)') max_pitch_angle ! write(output_unit_write,'("min_pitch_angle: ",E17.10)') min_pitch_angle do while ((ABS(eta_test) .GT. max_pitch_angle).OR. & (ABS(eta_test) .LT. min_pitch_angle)) - eta_test = eta_tmp(ii-1) + random_norm(0.0_rp,spp%dth) -! eta_test = eta_tmp(ii-1) + get_random_N()*spp%dth + eta_test = eta_tmp(ii-1) + random%normal%get() ! write(output_unit_write,'("eta_test: ",E17.10)') eta_test end do - g_test = g_tmp(ii-1) + random_norm(0.0_rp,spp%dgam) - !g_test = g_tmp(ii-1) + get_random_N()*spp%dgam + CALL random%normal%set(0.0_rp,spp%dgam) + g_test = g_tmp(ii-1) + random%normal%get() ! write(output_unit_write,'("max_g: ",E17.10)') max_g ! write(output_unit_write,'("min_g: ",E17.10)') min_g do while ((g_test.LT.min_g).OR.(g_test.GT.max_g)) - g_test = g_tmp(ii-1) + random_norm(0.0_rp,spp%dgam) -! g_test = g_tmp(ii-1) + get_random_N()*spp%dgam + g_test = g_tmp(ii-1) + random%normal%get() ! write(output_unit_write,'("g_test: ",E17.10)') g_test end do @@ -881,9 +857,7 @@ SUBROUTINE sample_Hollmann_distribution(params,spp) eta_tmp(ii) = eta_test ii = ii + 1_idef else - call RANDOM_NUMBER(rand_unif) -! rand_unif=get_random_U() - if (rand_unif .LT. ratio) then + if (random%uniform%get() .LT. ratio) then g_tmp(ii) = g_test eta_tmp(ii) = eta_test ii = ii + 1_idef @@ -938,10 +912,6 @@ SUBROUTINE sample_Hollmann_distribution(params,spp) end if ! write(output_unit_write,'("sampled eta: ",E17.10)') eta - - if (.not.params%SameRandSeed) then - call finalize_random_seed - end if END SUBROUTINE sample_Hollmann_distribution FUNCTION PSI_ROT_exp(R,R0,sigR,Z,Z0,sigZ,theta) @@ -984,12 +954,13 @@ FUNCTION indicator_exp(psi,psi_max) END FUNCTION indicator_exp -subroutine sample_Hollmann_distribution_3D(params,spp,F) - !! @note Subroutine that generates a 2D Gaussian distribution in an +subroutine sample_Hollmann_distribution_3D(params,random,spp,F) + !! @note Subroutine that generates a 2D Gaussian distribution in an !! elliptic torus as the initial spatial condition of a given particle !! species in the simulation. @endnote TYPE(KORC_PARAMS), INTENT(IN) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp !! An instance of the derived type SPECIES containing all the parameters !! and simulation variables of the different species in the simulation. @@ -1058,8 +1029,9 @@ subroutine sample_Hollmann_distribution_3D(params,spp,F) REAL(rp) :: dg,deta LOGICAL :: accepted INTEGER,DIMENSION(33) :: seed=(/1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1/) - - + + CALL random%uniform%set(0.0_rp,1.0_rp) + nsamples = spp%ppp*params%mpi_params%nmpi psi_max_buff = spp%psi_max*2._rp @@ -1123,25 +1095,10 @@ subroutine sample_Hollmann_distribution_3D(params,spp,F) R_buffer = spp%Ro Z_buffer = spp%Zo - - if (.not.params%SameRandSeed) then - call init_random_seed(params) - else - call random_seed(put=seed) - end if - -! call RANDOM_NUMBER(rand_unif) -! eta_buffer = min_pitch_angle + (max_pitch_angle & -! - min_pitch_angle)*rand_unif -! eta_buffer = min_pitch_angle + (max_pitch_angle & -! - min_pitch_angle)*get_random_mkl_U() eta_buffer = min_pitch_angle + (max_pitch_angle & - - min_pitch_angle)*get_random_U() - -! call RANDOM_NUMBER(rand_unif) -! G_buffer = min_g + (max_g - min_g)*rand_unif -! G_buffer = min_g + (max_g - min_g)*get_random_mkl_U() - G_buffer = min_g + (max_g - min_g)*get_random_U() + - min_pitch_angle)*random%uniform%get() + + G_buffer = min_g + (max_g - min_g)*random%uniform%get() ! write(output_unit_write,*) 'R_buffer',R_buffer ! write(output_unit_write,*) 'Z_buffer',Z_buffer @@ -1155,36 +1112,25 @@ subroutine sample_Hollmann_distribution_3D(params,spp,F) do while (ii .LE. 1000_idef) ! write(output_unit_write,'("burn:",I15)') ii - - !R_test = R_buffer + random_norm(0.0_rp,spp%dR) - !R_test = R_buffer + get_random_mkl_N(0.0_rp,spp%dR) - R_test = R_buffer + get_random_N()*spp%dR - - !Z_test = Z_buffer + random_norm(0.0_rp,spp%dZ) - !Z_test = Z_buffer + get_random_mkl_N(0.0_rp,spp%dZ) - Z_test = Z_buffer + get_random_N()*spp%dZ - - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - eta_test = eta_buffer + get_random_N()*spp%dth - - !G_test = G_buffer + random_norm(0.0_rp,spp%dgam) - !G_test = G_buffer + get_random_mkl_N(0.0_rp,spp%dgam) - G_test = G_buffer + get_random_N()*spp%dgam + CALL random%normal%set(0.0_rp,spp%dR) + R_test = R_buffer + random%normal%get() + + CALL random%normal%set(0.0_rp,spp%dZ) + Z_test = Z_buffer + random%normal%get() ! Test that pitch angle and momentum are within chosen boundary + CALL random%normal%set(0.0_rp,spp%dth) + eta_test = eta_buffer + random%normal%get() do while ((ABS(eta_test) .GT. max_pitch_angle).OR. & (ABS(eta_test) .LT. min_pitch_angle)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - eta_test = eta_buffer + get_random_N()*spp%dth + eta_test = eta_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp,spp%dgam) + G_test = G_buffer + random%normal%get() do while ((G_test.LT.min_g).OR.(G_test.GT.max_g)) - !G_test = G_buffer + random_norm(0.0_rp,spp%dgam) - !G_test = G_buffer + get_random_mkl_N(0.0_rp,spp%dgam) - G_test = G_buffer + get_random_N()*spp%dgam + G_test = G_buffer + random%normal%get() end do ! initialize 2D gaussian argument and distribution function, or @@ -1240,10 +1186,7 @@ subroutine sample_Hollmann_distribution_3D(params,spp,F) G_buffer = G_test ii = ii + 1_idef else -! call RANDOM_NUMBER(rand_unif) -! if (rand_unif .LT. ratio) then - !if (get_random_mkl_U() .LT. ratio) then - if (get_random_U() .LT. ratio) then + if (random%uniform%get() .LT. ratio) then accepted=.true. R_buffer = R_test Z_buffer = Z_test @@ -1263,36 +1206,25 @@ subroutine sample_Hollmann_distribution_3D(params,spp,F) if (modulo(ii,nsamples/10).eq.0) then write(output_unit_write,'("Sample: ",I10)') ii end if - - !R_test = R_buffer + random_norm(0.0_rp,spp%dR) - !R_test = R_buffer + get_random_mkl_N(0.0_rp,spp%dR) - R_test = R_buffer + get_random_N()*spp%dR - - !Z_test = Z_buffer + random_norm(0.0_rp,spp%dZ) - !Z_test = Z_buffer + get_random_mkl_N(0.0_rp,spp%dZ) - Z_test = Z_buffer + get_random_N()*spp%dZ - - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - eta_test = eta_buffer + get_random_N()*spp%dth - - !G_test = G_buffer + random_norm(0.0_rp,spp%dgam) - !G_test = G_buffer + get_random_mkl_N(0.0_rp,spp%dgam) - G_test = G_buffer + get_random_N()*spp%dgam + CALL random%normal%set(0.0_rp,spp%dR) + R_test = R_buffer + random%normal%get() + + CALL random%normal%set(0.0_rp,spp%dZ) + Z_test = Z_buffer + random%normal%get() ! Test that pitch angle and momentum are within chosen boundary + CALL random%normal%set(0.0_rp,spp%dth) + eta_test = eta_buffer + random%normal%get() do while ((ABS(eta_test) .GT. max_pitch_angle).OR. & (ABS(eta_test) .LT. min_pitch_angle)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - eta_test = eta_buffer + get_random_N()*spp%dth + eta_test = eta_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp,spp%dgam) + G_test = G_buffer + random%normal%get() do while ((G_test.LT.min_g).OR.(G_test.GT.max_g)) - !G_test = G_buffer + random_norm(0.0_rp,spp%dgam) - !G_test = G_buffer + get_random_mkl_N(0.0_rp,spp%dgam) - G_test = G_buffer + get_random_N()*spp%dgam + G_test = G_buffer + random%normal%get() end do if (accepted) then @@ -1334,10 +1266,7 @@ subroutine sample_Hollmann_distribution_3D(params,spp,F) eta_buffer = eta_test G_buffer = G_test else - !call RANDOM_NUMBER(rand_unif) - !if (rand_unif .LT. ratio) then - !if (get_random_mkl_U() .LT. ratio) then - if (get_random_U() .LT. ratio) then + if (random%uniform%get().LT. ratio) then accepted=.true. R_buffer = R_test Z_buffer = Z_test @@ -1366,11 +1295,8 @@ subroutine sample_Hollmann_distribution_3D(params,spp,F) ! write(output_unit_write,*) 'RS',R_buffer ! Sample phi location uniformly - !call RANDOM_NUMBER(rand_unif) - !PHI_samples(ii) = 2.0_rp*C_PI*rand_unif - !PHI_samples(ii) = 2.0_rp*C_PI*get_random_mkl_U() - PHI_samples(ii) = 2.0_rp*C_PI*get_random_U() - ii = ii + 1_idef + PHI_samples(ii) = 2.0_rp*C_PI*random%uniform%get() + ii = ii + 1_idef END IF end do @@ -1386,10 +1312,6 @@ subroutine sample_Hollmann_distribution_3D(params,spp,F) ! write(output_unit_write,*) 'Z_samples',Z_samples ! write(output_unit_write,*) 'G_samples',G_samples ! write(output_unit_write,*) 'eta_samples',eta_samples - - if (.not.params%SameRandSeed) then - call finalize_random_seed - end if end if @@ -1443,12 +1365,13 @@ subroutine sample_Hollmann_distribution_3D(params,spp,F) end subroutine sample_Hollmann_distribution_3D -subroutine sample_Hollmann_distribution_3D_psi(params,spp,F) - !! @note Subroutine that generates a 2D Gaussian distribution in an +subroutine sample_Hollmann_distribution_3D_psi(params,random,spp,F) + !! @note Subroutine that generates a 2D Gaussian distribution in an !! elliptic torus as the initial spatial condition of a given particle !! species in the simulation. @endnote TYPE(KORC_PARAMS), INTENT(INOUT) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp !! An instance of the derived type SPECIES containing all the parameters !! and simulation variables of the different species in the simulation. @@ -1608,26 +1531,12 @@ subroutine sample_Hollmann_distribution_3D_psi(params,spp,F) R_buffer = spp%Ro Z_buffer = spp%Zo - - - if (.not.params%SameRandSeed) then - call init_random_seed(params) - else - call random_seed(put=seed) - end if -! call RANDOM_NUMBER(rand_unif) -! eta_buffer = min_pitch_angle + (max_pitch_angle & -! - min_pitch_angle)*rand_unif -! eta_buffer = min_pitch_angle + (max_pitch_angle & -! - min_pitch_angle)*get_random_mkl_U() + CALL random%uniform%set(0.0_rp,1.0_rp) eta_buffer = min_pitch_angle + (max_pitch_angle & - - min_pitch_angle)*get_random_U() - -! call RANDOM_NUMBER(rand_unif) -! G_buffer = min_g + (max_g - min_g)*rand_unif -! G_buffer = min_g + (max_g - min_g)*get_random_mkl_U() - G_buffer = min_g + (max_g - min_g)*get_random_U() + - min_pitch_angle)*random%uniform%get() + + G_buffer = min_g + (max_g - min_g)*random%uniform%get() ! write(output_unit_write,*) 'R_buffer',R_buffer ! write(output_unit_write,*) 'Z_buffer',Z_buffer @@ -1644,48 +1553,31 @@ subroutine sample_Hollmann_distribution_3D_psi(params,spp,F) write(output_unit_write,'("Burn: ",I10)') ii end if !write(6,*) ii - - !R_test = R_buffer + random_norm(0.0_rp,spp%dR) - !R_test = R_buffer + get_random_mkl_N(0.0_rp,spp%dR) - R_test = R_buffer + get_random_N()*spp%dR - - !Z_test = Z_buffer + random_norm(0.0_rp,spp%dZ) - !Z_test = Z_buffer + get_random_mkl_N(0.0_rp,spp%dZ) - Z_test = Z_buffer + get_random_N()*spp%dZ - - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - eta_test = eta_buffer + get_random_N()*spp%dth - - !G_test = G_buffer + random_norm(0.0_rp,spp%dgam) - !G_test = G_buffer + get_random_mkl_N(0.0_rp,spp%dgam) - G_test = G_buffer + get_random_N()*spp%dgam - ! Test that pitch angle and momentum are within chosen boundary + CALL random%normal%set(0.0_rp,spp%dth) + eta_test = eta_buffer + random%normal%get() do while ((ABS(eta_test) .GT. max_pitch_angle).OR. & (ABS(eta_test) .LT. min_pitch_angle)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - eta_test = eta_buffer + get_random_N()*spp%dth + eta_test = eta_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp,spp%dR) + R_test = R_buffer + random%normal%get() do while ((R_test.GT.max_R).OR.(R_test .LT. min_R)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - R_test = R_buffer + get_random_N()*spp%dR + R_test = R_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp,spp%dZ) + Z_test = Z_buffer + random%normal%get() do while ((Z_test.GT.max_Z).OR.(Z_test .LT. min_Z)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - Z_test = Z_buffer + get_random_N()*spp%dZ + Z_test = Z_buffer + random%normal%get() end do - + + CALL random%normal%set(0.0_rp,spp%dgam) + G_test = G_buffer + random%normal%get() do while ((G_test.LT.min_g).OR.(G_test.GT.max_g)) - !G_test = G_buffer + random_norm(0.0_rp,spp%dgam) - !G_test = G_buffer + get_random_mkl_N(0.0_rp,spp%dgam) - G_test = G_buffer + get_random_N()*spp%dgam + G_test = G_buffer + random%normal%get() end do ! initialize 2D gaussian argument and distribution function, or @@ -1807,10 +1699,7 @@ subroutine sample_Hollmann_distribution_3D_psi(params,spp,F) G_buffer = G_test ii = ii + 1_idef else -! call RANDOM_NUMBER(rand_unif) -! if (rand_unif .LT. ratio) then - !if (get_random_mkl_U() .LT. ratio) then - if (get_random_U() .LT. ratio) then + if (random%uniform%get() .LT. ratio) then accepted=.true. R_buffer = R_test Z_buffer = Z_test @@ -1830,48 +1719,31 @@ subroutine sample_Hollmann_distribution_3D_psi(params,spp,F) if (modulo(ii,nsamples/10).eq.0) then write(output_unit_write,'("Sample: ",I10)') ii end if - - !R_test = R_buffer + random_norm(0.0_rp,spp%dR) - !R_test = R_buffer + get_random_mkl_N(0.0_rp,spp%dR) - R_test = R_buffer + get_random_N()*spp%dR - - !Z_test = Z_buffer + random_norm(0.0_rp,spp%dZ) - !Z_test = Z_buffer + get_random_mkl_N(0.0_rp,spp%dZ) - Z_test = Z_buffer + get_random_N()*spp%dZ - - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - eta_test = eta_buffer + get_random_N()*spp%dth - - !G_test = G_buffer + random_norm(0.0_rp,spp%dgam) - !G_test = G_buffer + get_random_mkl_N(0.0_rp,spp%dgam) - G_test = G_buffer + get_random_N()*spp%dgam - ! Test that pitch angle and momentum are within chosen boundary + CALL random%normal%set(0.0_rp,spp%dth) + eta_test = eta_buffer + random%normal%get() do while ((ABS(eta_test) .GT. max_pitch_angle).OR. & (ABS(eta_test) .LT. min_pitch_angle)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - eta_test = eta_buffer + get_random_N()*spp%dth + eta_test = eta_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp,spp%dgam) + G_test = G_buffer + random%normal%get() do while ((G_test.LT.min_g).OR.(G_test.GT.max_g)) - !G_test = G_buffer + random_norm(0.0_rp,spp%dgam) - !G_test = G_buffer + get_random_mkl_N(0.0_rp,spp%dgam) - G_test = G_buffer + get_random_N()*spp%dgam + G_test = G_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp,spp%dR) + R_test = R_buffer + random%normal%get() do while ((R_test.GT.max_R).OR.(R_test .LT. min_R)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - R_test = R_buffer + get_random_N()*spp%dR + R_test = R_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp,spp%dZ) + Z_test = Z_buffer + random%normal%get() do while ((Z_test.GT.max_Z).OR.(Z_test .LT. min_Z)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - Z_test = Z_buffer + get_random_N()*spp%dZ + Z_test = Z_buffer + random%normal%get() end do if (accepted) then @@ -1921,10 +1793,7 @@ subroutine sample_Hollmann_distribution_3D_psi(params,spp,F) eta_buffer = eta_test G_buffer = G_test else - !call RANDOM_NUMBER(rand_unif) - !if (rand_unif .LT. ratio) then - !if (get_random_mkl_U() .LT. ratio) then - if (get_random_U() .LT. ratio) then + if (random%uniform%get() .LT. ratio) then accepted=.true. R_buffer = R_test Z_buffer = Z_test @@ -1953,10 +1822,7 @@ subroutine sample_Hollmann_distribution_3D_psi(params,spp,F) ! write(output_unit_write,*) 'RS',R_buffer ! Sample phi location uniformly - !call RANDOM_NUMBER(rand_unif) - !PHI_samples(ii) = 2.0_rp*C_PI*rand_unif - !PHI_samples(ii) = 2.0_rp*C_PI*get_random_mkl_U() - PHI_samples(ii) = 2.0_rp*C_PI*get_random_U() + PHI_samples(ii) = 2.0_rp*C_PI*random%uniform%get() ii = ii + 1_idef END IF @@ -1977,10 +1843,6 @@ subroutine sample_Hollmann_distribution_3D_psi(params,spp,F) if (TRIM(h_params%current_direction) .EQ. 'PARALLEL') then eta_samples = 180.0_rp - eta_samples end if - - if (.not.params%SameRandSeed) then - call finalize_random_seed - end if end if params%GC_coords=.FALSE. @@ -2034,12 +1896,13 @@ subroutine sample_Hollmann_distribution_3D_psi(params,spp,F) end subroutine sample_Hollmann_distribution_3D_psi #ifdef PSPLINE -subroutine sample_Hollmann_distribution_1Dtransport(params,spp,F) - !! @note Subroutine that generates a 2D Gaussian distribution in an +subroutine sample_Hollmann_distribution_1Dtransport(params,random,spp,F) + !! @note Subroutine that generates a 2D Gaussian distribution in an !! elliptic torus as the initial spatial condition of a given particle !! species in the simulation. @endnote TYPE(KORC_PARAMS), INTENT(INOUT) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp !! An instance of the derived type SPECIES containing all the parameters !! and simulation variables of the different species in the simulation. @@ -2198,22 +2061,16 @@ subroutine sample_Hollmann_distribution_1Dtransport(params,spp,F) R_buffer = spp%Ro Z_buffer = spp%Zo - - - if (.not.params%SameRandSeed) then - call init_random_seed(params) - else - call random_seed(put=seed) - end if ! initialize 2D gaussian argument and distribution function, or ! copy from previous sample fRE_out=0._rp + CALL random%uniform%set(0.0_rp,1.0_rp) do while (fRE_out.eq.0._rp) eta_buffer = min_pitch_angle + (max_pitch_angle & - - min_pitch_angle)*get_random_U() - G_buffer = min_g + (max_g - min_g)*get_random_U() + - min_pitch_angle)*random%uniform%get() + G_buffer = min_g + (max_g - min_g)*random%uniform%get() !write(6,*) 'R_buffer',R_buffer*params%cpp%length !write(6,*) 'Z_buffer',Z_buffer*params%cpp%length @@ -2248,30 +2105,32 @@ subroutine sample_Hollmann_distribution_1Dtransport(params,spp,F) ! write(output_unit_write,'("Burn: ",I10)') ii ! write(6,'("Burn: ",I10)') ii !end if - - R_test = R_buffer + get_random_N()*spp%dR - Z_test = Z_buffer + get_random_N()*spp%dZ - eta_test = eta_buffer + get_random_N()*spp%dth - G_test = G_buffer + get_random_N()*spp%dgam - ! Test that pitch angle and momentum are within chosen boundary + CALL random%normal%set(0.0_rp,spp%dth) + eta_test = eta_buffer + random%normal%get() do while ((eta_test .GT. max_pitch_angle).OR. & (eta_test .LT. min_pitch_angle)) - eta_test = eta_buffer + get_random_N()*spp%dth + eta_test = eta_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp,spp%dR) + R_test = R_buffer + random%normal%get() do while ((R_test.GT.max_R).OR.(R_test .LT. min_R)) - R_test = R_buffer + get_random_N()*spp%dR + R_test = R_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp,spp%dZ) + Z_test = Z_buffer + random%normal%get() do while ((Z_test.GT.max_Z).OR.(Z_test .LT. min_Z)) - Z_test = Z_buffer + get_random_N()*spp%dZ + Z_test = Z_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp,spp%dgam) + G_test = G_buffer + random%normal%get() do while ((G_test.LT.min_g).OR.(G_test.GT.max_g)) - G_test = G_buffer + get_random_N()*spp%dgam - end do + G_test = G_buffer + random%normal%get() + end do if (accepted) then !psi0=psi1 @@ -2345,10 +2204,7 @@ subroutine sample_Hollmann_distribution_1Dtransport(params,spp,F) ii = ii + 1_idef rr=1_idef else -! call RANDOM_NUMBER(rand_unif) -! if (rand_unif .LT. ratio) then - !if (get_random_mkl_U() .LT. ratio) then - if (get_random_U() .LT. ratio) then + if (random%uniform%get() .LT. ratio) then accepted=.true. R_buffer = R_test Z_buffer = Z_test @@ -2376,29 +2232,31 @@ subroutine sample_Hollmann_distribution_1Dtransport(params,spp,F) write(output_unit_write,'("Sample: ",I10)') ii write(6,'("Sample: ",I10)') ii end if - - R_test = R_buffer + get_random_N()*spp%dR - Z_test = Z_buffer + get_random_N()*spp%dZ - eta_test = eta_buffer + get_random_N()*spp%dth - G_test = G_buffer + get_random_N()*spp%dgam - ! Test that pitch angle and momentum are within chosen boundary + CALL random%normal%set(0.0_rp,spp%dth) + eta_test = eta_buffer + random%normal%get() do while ((eta_test .GT. max_pitch_angle).OR. & (eta_test .LT. min_pitch_angle)) - eta_test = eta_buffer + get_random_N()*spp%dth + eta_test = eta_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp,spp%dgam) + G_test = G_buffer + random%normal%get() do while ((G_test.LT.min_g).OR.(G_test.GT.max_g)) - G_test = G_buffer + get_random_N()*spp%dgam + G_test = G_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp,spp%dR) + R_test = R_buffer + random%normal%get() do while ((R_test.GT.max_R).OR.(R_test.LT. min_R)) - R_test = R_buffer + get_random_N()*spp%dR + R_test = R_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp,spp%dZ) + Z_test = Z_buffer + random%normal%get() do while ((Z_test.GT.max_Z).OR.(Z_test.LT. min_Z)) - Z_test = Z_buffer + get_random_N()*spp%dZ + Z_test = Z_buffer + random%normal%get() end do if (accepted) then @@ -2454,10 +2312,7 @@ subroutine sample_Hollmann_distribution_1Dtransport(params,spp,F) G_buffer = G_test rr=1_idef else - !call RANDOM_NUMBER(rand_unif) - !if (rand_unif .LT. ratio) then - !if (get_random_mkl_U() .LT. ratio) then - if (get_random_U() .LT. ratio) then + if (random%uniform%get() .LT. ratio) then accepted=.true. R_buffer = R_test Z_buffer = Z_test @@ -2489,11 +2344,8 @@ subroutine sample_Hollmann_distribution_1Dtransport(params,spp,F) ! write(output_unit_write,*) 'RS',R_buffer ! Sample phi location uniformly - !call RANDOM_NUMBER(rand_unif) - !PHI_samples(ii) = 2.0_rp*C_PI*rand_unif - !PHI_samples(ii) = 2.0_rp*C_PI*get_random_mkl_U() - PHI_samples(ii) = 2.0_rp*C_PI*get_random_U() - ii = ii + 1_idef + PHI_samples(ii) = 2.0_rp*C_PI*random%uniform%get() + ii = ii + 1_idef END IF @@ -2515,10 +2367,6 @@ subroutine sample_Hollmann_distribution_1Dtransport(params,spp,F) if (TRIM(h_params%current_direction) .EQ. 'PARALLEL') then eta_samples = 180.0_rp - eta_samples end if - - if (.not.params%SameRandSeed) then - call finalize_random_seed - end if end if params%GC_coords=.FALSE. diff --git a/src/korc_fields.f90 b/src/korc_fields.f90 index 66209d90..62e6be1b 100755 --- a/src/korc_fields.f90 +++ b/src/korc_fields.f90 @@ -1096,10 +1096,6 @@ subroutine unitVectors(params,Xo,F,b1,b2,b3,flag,cart,hint,Bo) vars%PSI_P=0._rp vars%cart=.false. - !write(output_unit_write,*) 'before init_random_seed' - - call init_random_seed(params) - ! write(output_unit_write,*) 'before get_fields' !write(6,*) 'before first get fields' @@ -1161,8 +1157,6 @@ subroutine unitVectors(params,Xo,F,b1,b2,b3,flag,cart,hint,Bo) !write(output_unit_write,*) 'out unitVectors' - call finalize_random_seed - end subroutine unitVectors diff --git a/src/korc_initialize.f90 b/src/korc_initialize.f90 index c7ea30f9..0b9b7b79 100755 --- a/src/korc_initialize.f90 +++ b/src/korc_initialize.f90 @@ -351,13 +351,14 @@ end subroutine define_time_step ! * * * SUBROUTINES FOR INITIALIZING PARTICLES * * * ! ! * * * * * * * * * * * * * * * * * * * * * * * * * ! - subroutine initialize_particles(params,F,P,spp) + subroutine initialize_particles(params,random,F,P,spp) !! @note Subroutine that loads the information of the initial condition !! of the different particle species. This subroutine calls !! the subroutine that generates the initial energy and pitch angle !! distribution functions. @endnote TYPE(KORC_PARAMS), INTENT(IN) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(FIELDS), INTENT(IN) :: F !! An instance of KORC's derived type FIELDS containing all the information !! about the fields used in the simulation. See [[korc_types]] @@ -634,7 +635,7 @@ subroutine initialize_particles(params,F,P,spp) P%n_REr0=max(sqrt(spp(1)%psi_max*2*spp(1)%sigmaR**2), & sqrt(spp(1)%psi_max*2*spp(1)%sigmaZ**2)) - call initial_energy_pitch_dist(params,spp) + call initial_energy_pitch_dist(params,random,spp) DEALLOCATE(ppp) @@ -673,13 +674,14 @@ subroutine initialize_particles(params,F,P,spp) end subroutine initialize_particles - subroutine set_up_particles_ic(params,F,spp,P) + subroutine set_up_particles_ic(params,random,F,spp,P) !! @note Subroutine with calls to subroutines to load particles' !! information if it is a restarting simulation, or to initialize the !! spatial and velocity distribution of each species if it is a new !! simulation. @endnote TYPE(KORC_PARAMS), INTENT(INOUT) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(FIELDS), INTENT(INOUT) :: F !! An instance of KORC's derived type FIELDS containing all !! the information about the fields used in the simulation. @@ -714,15 +716,13 @@ subroutine set_up_particles_ic(params,F,spp,P) !write(6,*) 'flagRE',spp(1)%vars%flagRE !write(6,*) 'pRE',spp(1)%pRE - - call init_random_seed(params) else if (params%mpi_params%rank .EQ. 0) then write(output_unit_write,'("* * * * INITIALIZING SPATIAL DISTRIBUTION * * * *")') flush(output_unit_write) end if - call intitial_spatial_distribution(params,spp,P,F) + call intitial_spatial_distribution(params,random,spp,P,F) if (params%mpi_params%rank .EQ. 0) then write(output_unit_write,'("* * * * * * * * * * * * * * * * * * * * * * * *",/)') end if @@ -730,7 +730,7 @@ subroutine set_up_particles_ic(params,F,spp,P) if (params%mpi_params%rank .EQ. 0) then write(output_unit_write,'("* * * * INITIALIZING VELOCITY COMPONENTS * * * *")') end if - call initial_gyro_distribution(params,F,spp) + call initial_gyro_distribution(params,random,F,spp) if (params%mpi_params%rank .EQ. 0) then write(output_unit_write,'("* * * * * * * * * * * * * * * * * * * * * * * *",/)') end if @@ -743,9 +743,5 @@ subroutine take_down_particles_ic(params) TYPE(KORC_PARAMS), INTENT(INOUT) :: params !! Core KORC simulation parameters. - - if (params%restart.OR.params%proceed.or.params%reinit) then - call finalize_random_seed - end if end subroutine end module korc_initialize diff --git a/src/korc_ppusher.f90 b/src/korc_ppusher.f90 index e000d10e..3a2a6151 100755 --- a/src/korc_ppusher.f90 +++ b/src/korc_ppusher.f90 @@ -1099,10 +1099,11 @@ subroutine FO_init_aorsa_ACC(params,F,spp,output,step) end subroutine FO_init_aorsa_ACC #endif -subroutine adv_FOeqn_top(params,F,P,spp) +subroutine adv_FOeqn_top(params,random,F,P,spp) TYPE(KORC_PARAMS), INTENT(INOUT) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(FIELDS), INTENT(IN) :: F !! An instance of the KORC derived type FIELDS. TYPE(PROFILES), INTENT(IN) :: P @@ -1196,7 +1197,7 @@ subroutine adv_FOeqn_top(params,F,P,spp) B_X,B_Y,B_Z,E_X,E_Y,E_Z) end if - call advance_FOeqn_vars(tt,a,q_cache,m_cache,params, & + call advance_FOeqn_vars(tt,a,q_cache,m_cache,params,random, & X_X,X_Y,X_Z,V_X,V_Y,V_Z,B_X,B_Y,B_Z,E_X,E_Y,E_Z, & P,F,g,flagCon,flagCol,PSIp) end do !timestep iterator @@ -1240,7 +1241,7 @@ subroutine adv_FOeqn_top(params,F,P,spp) end do !$OMP END SIMD - call advance_FP3Deqn_vars(params,X_X,X_Y,X_Z,V_X,V_Y,V_Z, & + call advance_FP3Deqn_vars(params,random,X_X,X_Y,X_Z,V_X,V_Y,V_Z, & g,m_cache,B0,lam,R0,q0,EF0,B_X,B_Y,B_Z,E_X,E_Y,E_Z, & P,F,flagCon,flagCol,PSIp) @@ -1523,13 +1524,13 @@ subroutine adv_FOeqn_top_ACC(params,F,P,spp) end subroutine adv_FOeqn_top_ACC -subroutine advance_FOeqn_vars(tt,a,q_cache,m_cache,params,X_X,X_Y,X_Z, & +subroutine advance_FOeqn_vars(tt,a,q_cache,m_cache,params,random,X_X,X_Y,X_Z, & V_X,V_Y,V_Z,B_X,B_Y,B_Z,E_X,E_Y,E_Z,P,F,g,flagCon,flagCol,PSIp) TYPE(PROFILES), INTENT(IN) :: P TYPE(FIELDS), INTENT(IN) :: F TYPE(KORC_PARAMS), INTENT(IN) :: params !! Core KORC simulation parameters. - + CLASS(random_context), POINTER, INTENT(INOUT) :: random INTEGER(ip), INTENT(IN) :: tt !! Time step used in the leapfrog step (\(\Delta t\)). REAL(rp) :: dt @@ -1709,7 +1710,7 @@ subroutine advance_FOeqn_vars(tt,a,q_cache,m_cache,params,X_X,X_Y,X_Z, & if (params%collisions) then - call include_CoulombCollisions_FO_p(tt,params,X_X,X_Y,X_Z, & + call include_CoulombCollisions_FO_p(tt,params,random,X_X,X_Y,X_Z, & U_X,U_Y,U_Z,B_X,B_Y,B_Z,m_cache,P,F,flagCon,flagCol,PSIp) end if @@ -1745,13 +1746,14 @@ subroutine advance_FOeqn_vars(tt,a,q_cache,m_cache,params,X_X,X_Y,X_Z, & end subroutine advance_FOeqn_vars -subroutine advance_FP3Deqn_vars(params,X_X,X_Y,X_Z,V_X,V_Y,V_Z,g, & +subroutine advance_FP3Deqn_vars(params,random,X_X,X_Y,X_Z,V_X,V_Y,V_Z,g, & m_cache,B0,lam,R0,q0,EF0,B_X,B_Y,B_Z,E_X,E_Y,E_Z, & P,F,flagCon,flagCol,PSIp) TYPE(PROFILES), INTENT(IN) :: P TYPE(FIELDS), INTENT(IN) :: F TYPE(KORC_PARAMS), INTENT(INOUT) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random INTEGER :: cc,pchunk !! Chunk iterator. INTEGER(ip) :: tt @@ -1781,7 +1783,7 @@ subroutine advance_FP3Deqn_vars(params,X_X,X_Y,X_Z,V_X,V_Y,V_Z,g, & do tt=1_ip,params%t_skip - call include_CoulombCollisions_FO_p(tt,params,X_X,X_Y,X_Z, & + call include_CoulombCollisions_FO_p(tt,params,random,X_X,X_Y,X_Z, & U_X,U_Y,U_Z,B_X,B_Y,B_Z,m_cache,P,F,flagCon,flagCol,PSIp) end do @@ -2069,9 +2071,10 @@ end subroutine adv_FOfio_top #ifdef PSPLINE -subroutine adv_FOinterp_top(params,F,P,spp) +subroutine adv_FOinterp_top(params,random,F,P,spp) TYPE(KORC_PARAMS), INTENT(INOUT) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(FIELDS), INTENT(IN) :: F !! An instance of the KORC derived type FIELDS. TYPE(PROFILES), INTENT(IN) :: P @@ -2174,7 +2177,7 @@ subroutine adv_FOinterp_top(params,F,P,spp) ! write(output_unit_write,'("B_Y: ",E17.10)') B_Y(1) ! write(output_unit_write,'("B_Z: ",E17.10)') B_Z(1) - call advance_FOinterp_vars(tt,a,q_cache,m_cache,params, & + call advance_FOinterp_vars(tt,a,q_cache,m_cache,params,random, & X_X,X_Y,X_Z,V_X,V_Y,V_Z,B_X,B_Y,B_Z,E_X,E_Y,E_Z, & g,flagCon,flagCol,P,F,PSIp) end do !timestep iterator @@ -2222,7 +2225,7 @@ subroutine adv_FOinterp_top(params,F,P,spp) end do !$OMP END SIMD - call advance_FP3Dinterp_vars(params,X_X,X_Y,X_Z,V_X,V_Y,V_Z, & + call advance_FP3Dinterp_vars(params,random,X_X,X_Y,X_Z,V_X,V_Y,V_Z, & g,m_cache,B_X,B_Y,B_Z,E_X,E_Y,E_Z,flagCon,flagCol,P,F,PSIp) !$OMP SIMD @@ -2316,9 +2319,10 @@ subroutine adv_FOinterp_top(params,F,P,spp) end subroutine adv_FOinterp_top -subroutine adv_FOinterp_mars_top(params,F,P,spp) +subroutine adv_FOinterp_mars_top(params,random,F,P,spp) TYPE(KORC_PARAMS), INTENT(INOUT) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(FIELDS), INTENT(IN) :: F !! An instance of the KORC derived type FIELDS. TYPE(PROFILES), INTENT(IN) :: P @@ -2405,7 +2409,7 @@ subroutine adv_FOinterp_mars_top(params,F,P,spp) call interp_FOfields_mars_p(pchunk,F,Y_R,Y_PHI,Y_Z, & B_X,B_Y,B_Z,PSIp,flagCon) - call advance_FOinterp_vars(tt,a,q_cache,m_cache,params, & + call advance_FOinterp_vars(tt,a,q_cache,m_cache,params,random, & X_X,X_Y,X_Z,V_X,V_Y,V_Z,B_X,B_Y,B_Z,E_X,E_Y,E_Z, & g,flagCon,flagCol,P,F,PSIp) end do !timestep iterator @@ -2715,9 +2719,10 @@ subroutine adv_FOinterp_mars_top_ACC(params,F,P,spp) end subroutine adv_FOinterp_mars_top_ACC #endif -subroutine adv_FOinterp_aorsa_top(params,F,P,spp) +subroutine adv_FOinterp_aorsa_top(params,random,F,P,spp) TYPE(KORC_PARAMS), INTENT(INOUT) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(FIELDS), INTENT(IN) :: F !! An instance of the KORC derived type FIELDS. TYPE(PROFILES), INTENT(IN) :: P @@ -2813,7 +2818,7 @@ subroutine adv_FOinterp_aorsa_top(params,F,P,spp) ! write(output_unit_write,'("B_Y: ",E17.10)') B_Y(1) ! write(output_unit_write,'("B_Z: ",E17.10)') B_Z(1) - call advance_FOinterp_vars(tt,a,q_cache,m_cache,params, & + call advance_FOinterp_vars(tt,a,q_cache,m_cache,params,random, & X_X,X_Y,X_Z,V_X,V_Y,V_Z,B_X,B_Y,B_Z,E_X,E_Y,E_Z, & g,flagCon,flagCol,P,F,PSIp) end do !timestep iterator @@ -3142,10 +3147,11 @@ subroutine adv_FOinterp_aorsa_top_ACC(params,F,P,spp) end subroutine adv_FOinterp_aorsa_top_ACC #endif -subroutine advance_FOinterp_vars(tt,a,q_cache,m_cache,params,X_X,X_Y,X_Z, & +subroutine advance_FOinterp_vars(tt,a,q_cache,m_cache,params,random,X_X,X_Y,X_Z, & V_X,V_Y,V_Z,B_X,B_Y,B_Z,E_X,E_Y,E_Z,g,flagCon,flagCol,P,F,PSIp) TYPE(KORC_PARAMS), INTENT(IN) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(PROFILES), INTENT(IN) :: P TYPE(FIELDS), INTENT(IN) :: F INTEGER(ip), INTENT(IN) :: tt @@ -3320,7 +3326,7 @@ subroutine advance_FOinterp_vars(tt,a,q_cache,m_cache,params,X_X,X_Y,X_Z, & if (params%collisions) then - call include_CoulombCollisions_FO_p(tt,params,X_X,X_Y,X_Z, & + call include_CoulombCollisions_FO_p(tt,params,random,X_X,X_Y,X_Z, & U_X,U_Y,U_Z,B_X,B_Y,B_Z,m_cache,P,F,flagCon,flagCol,PSIp) end if @@ -3750,10 +3756,11 @@ end subroutine advance_FOfio_vars #endif FIO -subroutine advance_FP3Dinterp_vars(params,X_X,X_Y,X_Z,V_X,V_Y,V_Z,g, & +subroutine advance_FP3Dinterp_vars(params,random,X_X,X_Y,X_Z,V_X,V_Y,V_Z,g, & m_cache,B_X,B_Y,B_Z,E_X,E_Y,E_Z,flagCon,flagCol,P,F,PSIp) TYPE(KORC_PARAMS), INTENT(INOUT) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(PROFILES), INTENT(IN) :: P TYPE(FIELDS), INTENT(IN) :: F INTEGER :: cc,pchunk @@ -3784,7 +3791,7 @@ subroutine advance_FP3Dinterp_vars(params,X_X,X_Y,X_Z,V_X,V_Y,V_Z,g, & do tt=1_ip,params%t_skip - call include_CoulombCollisions_FO_p(tt,params,X_X,X_Y,X_Z, & + call include_CoulombCollisions_FO_p(tt,params,random,X_X,X_Y,X_Z, & U_X,U_Y,U_Z,B_X,B_Y,B_Z,m_cache,P,F,flagCon,flagCol,PSIp) end do @@ -4140,10 +4147,11 @@ FUNCTION rad2deg(x) rad2deg = x*180.0_rp/C_PI END FUNCTION rad2deg -subroutine adv_GCeqn_top(params,F,P,spp) +subroutine adv_GCeqn_top(params,random,F,P,spp) TYPE(KORC_PARAMS), INTENT(INOUT) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(FIELDS), INTENT(INOUT) :: F !! An instance of the KORC derived type FIELDS. TYPE(PROFILES), INTENT(IN) :: P @@ -4232,7 +4240,7 @@ subroutine adv_GCeqn_top(params,F,P,spp) if (params%collisions) then call include_CoulombCollisions_GC_p(tt+params%t_skip*(ttt-1),params, & - Y_R,Y_PHI,Y_Z,V_PLL,V_MU,m_cache,flagCon,flagCol, & + random,Y_R,Y_PHI,Y_Z,V_PLL,V_MU,m_cache,flagCon,flagCol, & F,P,E_PHI,ne,PSIp) end if @@ -4274,7 +4282,7 @@ subroutine adv_GCeqn_top(params,F,P,spp) !endif - call include_CoulombCollisions_GC_p(tt,params, & + call include_CoulombCollisions_GC_p(tt,params,random, & Y_R,Y_PHI,Y_Z,V_PLL,V_MU,m_cache,flagCon,flagCol, & F,P,E_PHI,ne,PSIp) @@ -4356,7 +4364,7 @@ subroutine adv_GCeqn_top(params,F,P,spp) !endif call include_CoulombCollisionsLA_GC_p(spp(ii),achunk, & - tt,params,Y_R,Y_PHI,Y_Z,V_PLL,V_MU,m_cache, & + tt,params,random,Y_R,Y_PHI,Y_Z,V_PLL,V_MU,m_cache, & flagCon,flagCol,F,P,E_PHI,ne,Te,PSIp) end if @@ -4470,7 +4478,7 @@ subroutine adv_GCeqn_top(params,F,P,spp) endif call include_CoulombCollisionsLA_GC_p(spp(ii),achunk, & - tt,params,Y_R,Y_PHI,Y_Z,V_PLL,V_MU,m_cache, & + tt,params,random,Y_R,Y_PHI,Y_Z,V_PLL,V_MU,m_cache, & flagCon,flagCol,F,P,E_PHI,ne,Te,PSIp) @@ -4842,13 +4850,14 @@ subroutine advance_GCeqn_vars(vars,pp,tt,params,Y_R,Y_PHI,Y_Z,V_PLL,V_MU, & end subroutine advance_GCeqn_vars -subroutine advance_FPeqn_vars(params,Y_R,Y_PHI,Y_Z,V_PLL,V_MU,flagCon,flagCol, & +subroutine advance_FPeqn_vars(params,random,Y_R,Y_PHI,Y_Z,V_PLL,V_MU,flagCon,flagCol, & m_cache,F,P,PSIp) TYPE(PROFILES), INTENT(IN) :: P TYPE(FIELDS), INTENT(IN) :: F TYPE(KORC_PARAMS), INTENT(INOUT) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random INTEGER(ip) :: tt !! time iterator. REAL(rp),DIMENSION(params%pchunk), INTENT(INOUT) :: Y_R,Y_PHI,Y_Z @@ -4860,7 +4869,7 @@ subroutine advance_FPeqn_vars(params,Y_R,Y_PHI,Y_Z,V_PLL,V_MU,flagCon,flagCol, & do tt=1_ip,params%t_skip - call include_CoulombCollisions_GC_p(tt,params,Y_R,Y_PHI,Y_Z, & + call include_CoulombCollisions_GC_p(tt,params,random,Y_R,Y_PHI,Y_Z, & V_PLL,V_MU,m_cache,flagCon,flagCol,F,P,E_PHI,ne,PSIp) ! write(output_unit_write,'("Collision Loop in FP")') @@ -4871,10 +4880,11 @@ end subroutine advance_FPeqn_vars #ifdef PSPLINE -subroutine adv_GCinterp_psi_top(params,spp,P,F) +subroutine adv_GCinterp_psi_top(params,random,spp,P,F) TYPE(KORC_PARAMS), INTENT(INOUT) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(PROFILES), INTENT(IN) :: P TYPE(FIELDS), INTENT(INOUT) :: F TYPE(SPECIES), DIMENSION(:), ALLOCATABLE, INTENT(INOUT) :: spp @@ -4949,13 +4959,13 @@ subroutine adv_GCinterp_psi_top(params,spp,P,F) if (.not.params%FokPlan) then do tt=1_ip,params%t_skip call advance_GCinterp_psi_vars(pchunk,spp(ii),pp,tt, & - params,Y_R,Y_PHI,Y_Z,V_PLL,V_MU,q_cache,m_cache, & + params,random,Y_R,Y_PHI,Y_Z,V_PLL,V_MU,q_cache,m_cache, & flagCon,flagCol,F,P,B_R,B_PHI,B_Z,E_PHI,PSIp, & curlb_R,curlb_PHI,curlb_Z,gradB_R,gradB_PHI,gradB_Z,ne, & Y_R0,Y_PHI0,Y_Z0) if (params%collisions) then - call include_CoulombCollisions_GC_p(tt,params, & + call include_CoulombCollisions_GC_p(tt,params,random, & Y_R,Y_PHI,Y_Z,V_PLL,V_MU,m_cache,flagCon,flagCol, & F,P,E_PHI,ne,PSIp) end if @@ -5003,7 +5013,7 @@ subroutine adv_GCinterp_psi_top(params,spp,P,F) else if (params%FokPlan.and.params%collisions) then - call advance_FPinterp_vars(params,Y_R,Y_PHI, & + call advance_FPinterp_vars(params,random,Y_R,Y_PHI, & Y_Z,V_PLL,V_MU,m_cache,flagCon,flagCol,F,P,E_PHI,ne,PSIp) !$OMP SIMD @@ -5104,7 +5114,7 @@ subroutine adv_GCinterp_psi_top(params,spp,P,F) do ttt=1_ip,params%orbits_per_coll call advance_GCinterp_psi_vars(achunk,spp(ii),pp,tt, & - params,Y_R,Y_PHI,Y_Z,V_PLL,V_MU,q_cache,m_cache, & + params,random,Y_R,Y_PHI,Y_Z,V_PLL,V_MU,q_cache,m_cache, & flagCon,flagCol, & F,P,B_R,B_PHI,B_Z,E_PHI,PSIp,curlb_R,curlb_PHI, & curlb_Z,gradB_R,gradB_PHI,gradB_Z,ne, & @@ -5112,7 +5122,7 @@ subroutine adv_GCinterp_psi_top(params,spp,P,F) end do call include_CoulombCollisionsLA_GC_p(spp(ii),achunk, & - tt,params,Y_R,Y_PHI,Y_Z,V_PLL,V_MU,m_cache, & + tt,params,random,Y_R,Y_PHI,Y_Z,V_PLL,V_MU,m_cache, & flagCon,flagCol,F,P,E_PHI,ne,Te,PSIp) !$OMP SIMD @@ -5377,12 +5387,13 @@ end subroutine adv_GCinterp_fio_top #ifdef PSPLINE -subroutine adv_GCinterp_psiwE_top(params,spp,P,F) +subroutine adv_GCinterp_psiwE_top(params,random,spp,P,F) IMPLICIT NONE TYPE(KORC_PARAMS), INTENT(INOUT) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(PROFILES), INTENT(IN) :: P TYPE(FIELDS), INTENT(INOUT) :: F TYPE(SPECIES), DIMENSION(:), ALLOCATABLE, INTENT(INOUT) :: spp @@ -5471,7 +5482,7 @@ subroutine adv_GCinterp_psiwE_top(params,spp,P,F) !end if call advance_GCinterp_psiwE_vars(spp(ii),pchunk,pp,tt, & - params, & + params,random, & Y_R,Y_PHI,Y_Z,V_PLL,V_MU,q_cache,m_cache,flagCon,flagCol, & F,P,B_R,B_PHI,B_Z,E_PHI,PSIp,curlb_R,curlb_PHI, & curlb_Z,gradB_R,gradB_PHI,gradB_Z,ne, & @@ -5479,7 +5490,7 @@ subroutine adv_GCinterp_psiwE_top(params,spp,P,F) if (params%collisions) then - call include_CoulombCollisions_GC_p(tt,params, & + call include_CoulombCollisions_GC_p(tt,params,random, & Y_R,Y_PHI,Y_Z, V_PLL,V_MU,m_cache, & flagCon,flagCol,F,P,E_PHI,ne,PSIp) @@ -5529,7 +5540,7 @@ subroutine adv_GCinterp_psiwE_top(params,spp,P,F) else if (params%FokPlan.and.params%collisions) then do tt=1_ip,params%t_skip - call include_CoulombCollisions_GC_p(tt,params,Y_R,Y_PHI,Y_Z, & + call include_CoulombCollisions_GC_p(tt,params,random,Y_R,Y_PHI,Y_Z, & V_PLL,V_MU,m_cache,flagCon,flagCol,F,P,E_PHI,ne,PSIp) end do @@ -5689,7 +5700,7 @@ subroutine adv_GCinterp_psiwE_top(params,spp,P,F) # endif DBG_CHECK call advance_GCinterp_psiwE_vars(spp(ii),achunk, & - pp,tt,params,Y_R,Y_PHI,Y_Z,V_PLL,V_MU, & + pp,tt,params,random,Y_R,Y_PHI,Y_Z,V_PLL,V_MU, & q_cache,m_cache,flagCon,flagCol, & F,P,B_R,B_PHI,B_Z,E_PHI,PSIp,curlb_R,curlb_PHI, & curlb_Z,gradB_R,gradB_PHI,gradB_Z,ne, & @@ -5711,7 +5722,7 @@ subroutine adv_GCinterp_psiwE_top(params,spp,P,F) # endif DBG_CHECK call include_CoulombCollisionsLA_GC_p(spp(ii),achunk, & - tt,params,Y_R,Y_PHI,Y_Z,V_PLL,V_MU,m_cache, & + tt,params,random,Y_R,Y_PHI,Y_Z,V_PLL,V_MU,m_cache, & flagCon,flagCol,F,P,E_PHI,ne,Te,PSIp) #if DBG_CHECK @@ -5832,10 +5843,11 @@ subroutine adv_GCinterp_psiwE_top(params,spp,P,F) end subroutine adv_GCinterp_psiwE_top -subroutine adv_GCinterp_psi2x1t_top(params,spp,P,F) +subroutine adv_GCinterp_psi2x1t_top(params,random,spp,P,F) TYPE(KORC_PARAMS), INTENT(INOUT) :: params !! Core KORC simulation parameters. +CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(PROFILES), INTENT(IN) :: P TYPE(FIELDS), INTENT(INOUT) :: F TYPE(SPECIES), DIMENSION(:), ALLOCATABLE, INTENT(INOUT) :: spp @@ -5903,7 +5915,7 @@ subroutine adv_GCinterp_psi2x1t_top(params,spp,P,F) if (.not.params%FokPlan) then do tt=1_ip,params%t_skip call advance_GCinterp_psi2x1t_vars(spp(ii)%vars,pp,tt, & - params, & + params,random, & Y_R,Y_PHI,Y_Z,V_PLL,V_MU,q_cache,m_cache,flagCon,flagCol, & F,P,B_R,B_PHI,B_Z,E_PHI,PSIp,curlb_R,curlb_PHI, & curlb_Z,gradB_R,gradB_PHI,gradB_Z,ne) @@ -5944,7 +5956,7 @@ subroutine adv_GCinterp_psi2x1t_top(params,spp,P,F) else if (params%FokPlan.and.params%collisions) then - call advance_FPinterp_vars(params,Y_R,Y_PHI, & + call advance_FPinterp_vars(params,random,Y_R,Y_PHI, & Y_Z,V_PLL,V_MU,m_cache,flagCon,flagCol,F,P,E_PHI,ne,PSIp) !$OMP SIMD @@ -6013,7 +6025,7 @@ subroutine adv_GCinterp_psi2x1t_top(params,spp,P,F) end subroutine adv_GCinterp_psi2x1t_top -subroutine advance_GCinterp_psi_vars(pchunk,spp,pp,tt,params,Y_R,Y_PHI,Y_Z, & +subroutine advance_GCinterp_psi_vars(pchunk,spp,pp,tt,params,random,Y_R,Y_PHI,Y_Z, & V_PLL,V_MU,q_cache,m_cache,flagCon,flagCol,F,P,B_R,B_PHI,B_Z,E_PHI,PSIp, & curlb_R,curlb_PHI,curlb_Z,gradB_R,gradB_PHI,gradB_Z,ne, & Y_R0,Y_PHI0,Y_Z0) @@ -6023,6 +6035,7 @@ subroutine advance_GCinterp_psi_vars(pchunk,spp,pp,tt,params,Y_R,Y_PHI,Y_Z, & !! methods, and descriptions of both. INTEGER,intent(in) :: pchunk TYPE(KORC_PARAMS), INTENT(INOUT) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random !! Core KORC simulation parameters. TYPE(SPECIES), INTENT(INOUT) :: spp TYPE(PROFILES), INTENT(IN) :: P @@ -6376,6 +6389,9 @@ subroutine advance_GCinterp_psi_vars(pchunk,spp,pp,tt,params,Y_R,Y_PHI,Y_Z, & end do + + CALL random%uniform%set(0.0_rp,1.0_rp) + !$OMP END SIMD !write(6,*) 'Y',Y_R*params%cpp%length,Y_PHI,Y_Z*params%cpp%length @@ -6393,8 +6409,8 @@ subroutine advance_GCinterp_psi_vars(pchunk,spp,pp,tt,params,Y_R,Y_PHI,Y_Z, & Zmax=maxval(F%X%Z) do while (.not.accepted) - Rtrial=Rmin+(Rmax-Rmin)*get_random() - Ztrial=Zmin+(Zmax-Zmin)*get_random() + Rtrial=Rmin+(Rmax-Rmin)*random%uniform%get() + Ztrial=Zmin+(Zmax-Zmin)*random%uniform%get() rm_trial=sqrt((Rtrial-F%AB%Ro)**2+(Ztrial)**2)/F%AB%a if (rm_trial.gt.1._rp) cycle @@ -6404,12 +6420,12 @@ subroutine advance_GCinterp_psi_vars(pchunk,spp,pp,tt,params,Y_R,Y_PHI,Y_Z, & end do if (Rtrial*fRE_BMC(spp%BMC_Nra,spp%BMC_ra,spp%BMC_nRE,rm_trial)/maxval(RnRE) & - .gt.get_random()) accepted=.true. + .gt.random%uniform%get()) accepted=.true. end do Y_R(cc)=Rtrial Y_Z(cc)=Ztrial - Y_PHI(cc)=2.0_rp*C_PI*get_random_U() + Y_PHI(cc)=2.0_rp*C_PI*random%uniform%get() !write(6,*) 'resampled R,Z',Rtrial*params%cpp%length,Ztrial*params%cpp%length @@ -6873,7 +6889,7 @@ end subroutine advance_GCinterp_fio_vars #ifdef PSPLINE -subroutine advance_GCinterp_psiwE_vars(spp,pchunk,pp,tt,params,Y_R,Y_PHI,Y_Z, & +subroutine advance_GCinterp_psiwE_vars(spp,pchunk,pp,tt,params,random,Y_R,Y_PHI,Y_Z, & V_PLL,V_MU,q_cache,m_cache,flagCon,flagCol,F,P,B_R,B_PHI,B_Z,E_PHI,PSIp, & curlb_R,curlb_PHI,curlb_Z,gradB_R,gradB_PHI,gradB_Z,ne, & Y_R0,Y_PHI0,Y_Z0,Y_R1,Y_PHI1,Y_Z1) @@ -6882,6 +6898,7 @@ subroutine advance_GCinterp_psiwE_vars(spp,pchunk,pp,tt,params,Y_R,Y_PHI,Y_Z, & !! Comment this section further with evolution equations, numerical !! methods, and descriptions of both. TYPE(KORC_PARAMS), INTENT(INOUT) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random !! Core KORC simulation parameters. TYPE(SPECIES), INTENT(INOUT) :: spp TYPE(PROFILES), INTENT(IN) :: P @@ -7208,6 +7225,7 @@ subroutine advance_GCinterp_psiwE_vars(spp,pchunk,pp,tt,params,Y_R,Y_PHI,Y_Z, & !write(6,*) 'flagCon0,flagCon',flagCon0,flagCon if (params%recycle_losses) then + CALL random%uniform%set(0.0_rp,1.0_rp) do cc=1_idef,pchunk if ((flagCon(cc).eq.0_is).and.(pp-1+cc.le.spp%pinit)) then accepted=.false. @@ -7218,8 +7236,8 @@ subroutine advance_GCinterp_psiwE_vars(spp,pchunk,pp,tt,params,Y_R,Y_PHI,Y_Z, & Zmax=maxval(F%X%Z) do while (.not.accepted) - Rtrial=Rmin+(Rmax-Rmin)*get_random() - Ztrial=Zmin+(Zmax-Zmin)*get_random() + Rtrial=Rmin+(Rmax-Rmin)*random%uniform%get() + Ztrial=Zmin+(Zmax-Zmin)*random%uniform%get() rm_trial=sqrt((Rtrial-F%AB%Ro)**2+(Ztrial)**2)/F%AB%a if (rm_trial.gt.1._rp) cycle @@ -7229,12 +7247,12 @@ subroutine advance_GCinterp_psiwE_vars(spp,pchunk,pp,tt,params,Y_R,Y_PHI,Y_Z, & end do if (Rtrial*fRE_BMC(spp%BMC_Nra,spp%BMC_ra,spp%BMC_nRE,rm_trial)/maxval(RnRE) & - .gt.get_random()) accepted=.true. + .gt.random%uniform%get()) accepted=.true. end do Y_R(cc)=Rtrial Y_Z(cc)=Ztrial - Y_PHI(cc)=2.0_rp*C_PI*get_random_U() + Y_PHI(cc)=2.0_rp*C_PI*random%uniform%get() !write(6,*) 'resampled R,Z',Rtrial,Ztrial @@ -7328,7 +7346,7 @@ FUNCTION fRE_BMC(Nr_a,r_a,nRE,rm) END FUNCTION fRE_BMC -subroutine advance_GCinterp_psi2x1t_vars(vars,pp,tt,params,Y_R,Y_PHI,Y_Z, & +subroutine advance_GCinterp_psi2x1t_vars(vars,pp,tt,params,random,Y_R,Y_PHI,Y_Z, & V_PLL,V_MU,q_cache,m_cache,flagCon,flagCol,F,P,B_R,B_PHI,B_Z,E_PHI,PSIp, & curlb_R,curlb_PHI,curlb_Z,gradB_R,gradB_PHI,gradB_Z,ne) !! @note Subroutine to advance GC variables \(({\bf X},p_\parallel)\) @@ -7337,6 +7355,7 @@ subroutine advance_GCinterp_psi2x1t_vars(vars,pp,tt,params,Y_R,Y_PHI,Y_Z, & !! methods, and descriptions of both. TYPE(KORC_PARAMS), INTENT(INOUT) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(PARTICLES), INTENT(INOUT) :: vars TYPE(PROFILES), INTENT(IN) :: P TYPE(FIELDS), INTENT(IN) :: F @@ -7704,7 +7723,7 @@ subroutine advance_GCinterp_psi2x1t_vars(vars,pp,tt,params,Y_R,Y_PHI,Y_Z, & if (params%collisions) then - call include_CoulombCollisions_GC_p(tt,params,Y_R,Y_PHI,Y_Z, & + call include_CoulombCollisions_GC_p(tt,params,random,Y_R,Y_PHI,Y_Z, & V_PLL,V_MU,m_cache,flagCon,flagCol,F,P,E_PHI,ne,PSIp) end if @@ -7713,9 +7732,10 @@ end subroutine advance_GCinterp_psi2x1t_vars #endif PSPLINE -subroutine advance_FPinterp_vars(params,Y_R,Y_PHI,Y_Z,V_PLL,V_MU, & +subroutine advance_FPinterp_vars(params,random,Y_R,Y_PHI,Y_Z,V_PLL,V_MU, & m_cache,flagCon,flagCol,F,P,E_PHI,ne,PSIp) TYPE(KORC_PARAMS), INTENT(INOUT) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random !! Core KORC simulation parameters. TYPE(PROFILES), INTENT(IN) :: P TYPE(FIELDS), INTENT(IN) :: F @@ -7731,7 +7751,7 @@ subroutine advance_FPinterp_vars(params,Y_R,Y_PHI,Y_Z,V_PLL,V_MU, & ! write(output_unit_write,'("E_PHI_FP: ",E17.10)') E_PHI do tt=1_ip,params%t_skip - call include_CoulombCollisions_GC_p(tt,params,Y_R,Y_PHI,Y_Z, & + call include_CoulombCollisions_GC_p(tt,params,random,Y_R,Y_PHI,Y_Z, & V_PLL,V_MU,m_cache,flagCon,flagCol,F,P,E_PHI,ne,PSIp) ! write(output_unit_write,'("Collision Loop in FP")') diff --git a/src/korc_random.f90 b/src/korc_random.f90 index ea75699f..4a5fba20 100755 --- a/src/korc_random.f90 +++ b/src/korc_random.f90 @@ -1,19 +1,14 @@ -!include 'mkl_vsl.f90' - MODULE korc_random USE, INTRINSIC :: iso_c_binding USE korc_types - ! use mkl_vsl_type - ! use mkl_vsl USE korc_hpc, ONLY : get_thread_number, get_max_threads IMPLICIT NONE - TYPE(C_PTR), DIMENSION(:), ALLOCATABLE , PRIVATE :: states - TYPE(C_PTR), PRIVATE :: state_u - TYPE(C_PTR), PRIVATE :: state_n - ! TYPE(VSL_STREAM_STATE), PRIVATE :: stream +!******************************************************************************* +! Interface binding for the c++ random functions. +!******************************************************************************* INTERFACE TYPE (C_PTR) FUNCTION random_construct_U(seed) BIND(C, NAME='random_construct_U') @@ -38,7 +33,8 @@ END FUNCTION random_construct_N END INTERFACE INTERFACE - REAL (C_DOUBLE) FUNCTION random_get_number_U(r) BIND(C, NAME='random_get_number_U') + REAL (rp) FUNCTION random_get_number_U(r) BIND(C, NAME='random_get_number_U') + USE korc_types, ONLY : rp USE, INTRINSIC :: iso_c_binding IMPLICIT NONE @@ -49,7 +45,8 @@ END FUNCTION random_get_number_U END INTERFACE INTERFACE - REAL (C_DOUBLE) FUNCTION random_get_number_N(r) BIND(C, NAME='random_get_number_N') + REAL (rp) FUNCTION random_get_number_N(r) BIND(C, NAME='random_get_number_N') + USE korc_types, ONLY : rp USE, INTRINSIC :: iso_c_binding IMPLICIT NONE @@ -60,252 +57,308 @@ END FUNCTION random_get_number_N END INTERFACE INTERFACE - REAL (C_DOUBLE) FUNCTION random_get_number(r) BIND(C, NAME='random_get_number') + SUBROUTINE random_destroy_U(r) BIND(C, NAME='random_destroy_U') USE, INTRINSIC :: iso_c_binding IMPLICIT NONE TYPE (C_PTR), VALUE :: r - END FUNCTION random_get_number + END SUBROUTINE random_destroy_U END INTERFACE - + INTERFACE - SUBROUTINE random_destroy_U(r) BIND(C, NAME='random_destroy_U') + SUBROUTINE random_destroy_N(r) BIND(C, NAME='random_destroy_N') USE, INTRINSIC :: iso_c_binding IMPLICIT NONE TYPE (C_PTR), VALUE :: r - END SUBROUTINE random_destroy_U + END SUBROUTINE random_destroy_N END INTERFACE - + INTERFACE - SUBROUTINE random_destroy_N(r) BIND(C, NAME='random_destroy_N') + SUBROUTINE random_set_dist_U(r, low, high) BIND(C, NAME='random_set_dist_U') + USE korc_types, ONLY : rp USE, INTRINSIC :: iso_c_binding IMPLICIT NONE TYPE (C_PTR), VALUE :: r - - END SUBROUTINE random_destroy_N + REAL (rp), VALUE :: low + REAL (rp), VALUE :: high + END SUBROUTINE random_set_dist_U END INTERFACE - + INTERFACE - SUBROUTINE random_set_dist(r, low, high) BIND(C, NAME='random_set_dist') + SUBROUTINE random_set_dist_N(r, low, high) BIND(C, NAME='random_set_dist_N') + USE korc_types, ONLY : rp USE, INTRINSIC :: iso_c_binding IMPLICIT NONE - TYPE (C_PTR), VALUE :: r - REAL (C_DOUBLE), VALUE :: low - REAL (C_DOUBLE), VALUE :: high - END SUBROUTINE random_set_dist + TYPE (C_PTR), VALUE :: r + REAL (rp), VALUE :: low + REAL (rp), VALUE :: high + END SUBROUTINE random_set_dist_N END INTERFACE - - PUBLIC :: initialize_random - PUBLIC :: finalize_random + +!******************************************************************************* +! Class Defintions +!******************************************************************************* + + TYPE :: random_base + TYPE(C_PTR), DIMENSION(:), POINTER :: states => null() + END TYPE + + TYPE, EXTENDS(random_base) :: random_U_context + CONTAINS + PROCEDURE :: get => random_U_get_random + PROCEDURE :: get_array => random_U_get_randoms + PROCEDURE :: set => random_U_set_dist + FINAL :: random_U_context_destruct + END TYPE + + TYPE, EXTENDS(random_base) :: random_N_context + CONTAINS + PROCEDURE :: get => random_N_get_random + PROCEDURE :: get_array => random_N_get_randoms + PROCEDURE :: set => random_N_set_dist + FINAL :: random_N_context_destruct + END TYPE + + TYPE :: random_context + CLASS (random_U_context), POINTER :: uniform => null() + CLASS (random_N_context), POINTER :: normal => null() + CONTAINS + FINAL :: random_context_destruct + END TYPE CONTAINS - SUBROUTINE initialize_random(seed) - IMPLICIT NONE +!******************************************************************************* +! Constructors +!******************************************************************************* - INTEGER, INTENT(IN) :: seed - INTEGER :: num_threads - INTEGER :: thread_num + FUNCTION random_U_context_construct(seed, mpi_rank) + IMPLICIT NONE - num_threads = get_max_threads() - IF (.NOT. ALLOCATED(states)) THEN - ALLOCATE(states(0:num_threads - 1)) - END IF +! Arguments + CLASS (random_U_context), POINTER :: random_U_context_construct + INTEGER, INTENT(IN) :: seed + INTEGER, INTENT(IN) :: mpi_rank - !$OMP PARALLEL PRIVATE(thread_num) - thread_num = get_thread_number() - states(thread_num) = random_construct_U(seed + thread_num) - !$OMP END PARALLEL - END SUBROUTINE initialize_random +! Local Variables + INTEGER :: num_threads + INTEGER :: thread_num - SUBROUTINE finalize_random - IMPLICIT NONE +! Start of executable code. + ALLOCATE(random_U_context_construct) - INTEGER :: thread_num + num_threads = get_max_threads() + ALLOCATE(random_U_context_construct%states(0:num_threads)) - !$OMP PARALLEL PRIVATE(thread_num) - thread_num = get_thread_number() - CALL random_destroy_U(states(thread_num)) - !$OMP END PARALLEL +!$OMP PARALLEL DEFAULT(SHARED) PRIVATE(thread_num) + thread_num = get_thread_number() + random_U_context_construct%states(thread_num) = & + random_construct_U(seed + mpi_rank*num_threads + thread_num) +!$OMP END PARALLEL + END FUNCTION - DEALLOCATE (states) - END SUBROUTINE + FUNCTION random_N_context_construct(seed, mpi_rank) + IMPLICIT NONE + +! Arguments + CLASS (random_N_context), POINTER :: random_N_context_construct + INTEGER, INTENT(IN) :: seed + INTEGER, INTENT(IN) :: mpi_rank + +! Local Variables + INTEGER :: num_threads + INTEGER :: thread_num + +! Start of executable code. + ALLOCATE(random_N_context_construct) + + num_threads = get_max_threads() + ALLOCATE(random_N_context_construct%states(0:num_threads)) + +!$OMP PARALLEL DEFAULT(SHARED) PRIVATE(thread_num) + thread_num = get_thread_number() + random_N_context_construct%states(thread_num) = & + random_construct_N(seed + mpi_rank*num_threads + thread_num) +!$OMP END PARALLEL + END FUNCTION + + FUNCTION random_context_construct(seed, mpi_rank) + + IMPLICIT NONE + +! Arguments + CLASS (random_context), POINTER :: random_context_construct + INTEGER, INTENT(IN) :: seed + INTEGER, INTENT(IN) :: mpi_rank + +! Start of executable code. + ALLOCATE(random_context_construct) + + random_context_construct%uniform => random_U_context_construct(seed, mpi_rank) + random_context_construct%normal => random_N_context_construct(seed, mpi_rank) - SUBROUTINE initialize_random_U(seed) - IMPLICIT NONE + END FUNCTION - INTEGER, INTENT(IN) :: seed +!******************************************************************************* +! Destructors +!******************************************************************************* - state_u = random_construct_U(seed) + SUBROUTINE random_U_context_destruct(this) + IMPLICIT NONE - END SUBROUTINE initialize_random_U +! Arguments + TYPE (random_U_context), INTENT(inout) :: this - SUBROUTINE finalize_random_U - IMPLICIT NONE +! Start of executable code + IF (ASSOCIATED(this%states)) THEN +!$OMP PARALLEL DEFAULT(SHARED) PRIVATE(thread_num) + CALL random_destroy_U(this%states(get_thread_number())) +!$OMP END PARALLEL + DEALLOCATE(this%states) + this%states => null() + END IF - CALL random_destroy_U(state_u) END SUBROUTINE - SUBROUTINE initialize_random_N(seed) - IMPLICIT NONE + SUBROUTINE random_N_context_destruct(this) + IMPLICIT NONE - INTEGER, INTENT(IN) :: seed +! Arguments + TYPE (random_N_context), INTENT(inout) :: this - state_n = random_construct_N(seed) +! Start of executable code + IF (ASSOCIATED(this%states)) THEN +!$OMP PARALLEL DEFAULT(SHARED) PRIVATE(thread_num) + CALL random_destroy_N(this%states(get_thread_number())) +!$OMP END PARALLEL + DEALLOCATE(this%states) + this%states => null() + END IF - END SUBROUTINE initialize_random_N + END SUBROUTINE - SUBROUTINE finalize_random_N - IMPLICIT NONE + SUBROUTINE random_context_destruct(this) + IMPLICIT NONE + +! Arguments + TYPE (random_context), INTENT(inout) :: this + +! Start of executable code + IF (ASSOCIATED(this%uniform)) THEN + DEALLOCATE(this%uniform) + this%uniform => null() + END IF + + IF (ASSOCIATED(this%normal)) THEN + DEALLOCATE(this%normal) + this%normal => null() + END IF - CALL random_destroy_N(state_n) END SUBROUTINE - FUNCTION get_random() - IMPLICIT NONE +!******************************************************************************* +! Getters +!******************************************************************************* + FUNCTION random_U_get_random(this) + IMPLICIT NONE - REAL(rp) :: get_random +! Arguments + REAL(rp) :: random_U_get_random + CLASS (random_U_context), INTENT(in) :: this - get_random = random_get_number(states(get_thread_number())) - END FUNCTION get_random +! Start of executable code + random_U_get_random = random_get_number_U(this%states(get_thread_number())) - FUNCTION get_random_U() - IMPLICIT NONE + END FUNCTION - REAL(rp) :: get_random_U + FUNCTION random_N_get_random(this) + IMPLICIT NONE - get_random_U = random_get_number_U(state_u) - END FUNCTION get_random_U +! Arguments + REAL(rp) :: random_N_get_random + CLASS (random_N_context), INTENT(in) :: this - FUNCTION get_random_N() - IMPLICIT NONE +! Start of executable code + random_N_get_random = random_get_number_N(this%states(get_thread_number())) - REAL(rp) :: get_random_N + END FUNCTION - get_random_N = random_get_number_N(state_n) - END FUNCTION get_random_N + SUBROUTINE random_U_get_randoms(this, nums) + IMPLICIT NONE - SUBROUTINE get_randoms(nums) - IMPLICIT NONE +! Arguments + CLASS (random_U_context), INTENT(in) :: this + REAL(rp), DIMENSION(:), INTENT(out) :: nums - REAL(rp), DIMENSION(:), INTENT(OUT) :: nums +! Local Variables + INTEGER :: i - INTEGER :: i +! Start of executable code +!$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(i) + DO i = 1, SIZE(nums) + nums(i) = this%get() + END DO +!$OMP END PARALLEL DO + END SUBROUTINE - !$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(i) - DO i = 1, SIZE(nums) - nums(i) = get_random() - END DO - !$OMP END PARALLEL DO - END SUBROUTINE get_randoms + SUBROUTINE random_N_get_randoms(this, nums) + IMPLICIT NONE - SUBROUTINE set_random_dist(low, high) - IMPLICIT NONE +! Arguments + CLASS (random_N_context), INTENT(in) :: this + REAL(rp), DIMENSION(:), INTENT(out) :: nums - REAL(rp), INTENT(IN) :: low - REAL(rp), INTENT(IN) :: high +! Local Variables + INTEGER :: i - !$OMP PARALLEL DEFAULT(SHARED) - CALL random_set_dist(states(get_thread_number()), low, high) - !$OMP END PARALLEL +! Start of executable code +!$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(i) + DO i = 1, SIZE(nums) + nums(i) = this%get() + END DO +!$OMP END PARALLEL DO + END SUBROUTINE - END SUBROUTINE set_random_dist - - !SUBROUTINE initialize_random_mkl(seed) - ! USE omp_lib - ! IMPLICIT NONE - - ! INTEGER, INTENT(IN) :: seed - ! INTEGER :: num_threads - ! INTEGER :: thread_num - ! INTEGER :: errcode - ! integer :: brng - - ! brng=VSL_BRNG_MT19937 - ! brng=VSL_BRNG_MT2203 - - ! num_threads = OMP_GET_MAX_THREADS() - ! IF (.NOT. ALLOCATED(streams)) THEN - ! ALLOCATE(states(0:num_threads - 1)) - ! END IF - -!!$OMP PARALLEL PRIVATE(thread_num) - ! thread_num = OMP_GET_THREAD_NUM() - ! errcode=vslnewstream(streams(thread_num),brng,seed) - ! errcode=vslnewstream(stream,brng,seed) -!!$OMP END PARALLEL - !END SUBROUTINE - - !FUNCTION get_random_mkl() - ! USE omp_lib - ! IMPLICIT NONE - ! - ! INTEGER, PARAMETER :: n=8_idef - ! REAL(rp),DIMENSION(n) :: get_random_mkl - ! INTEGER :: errcode - ! INTEGER :: method - - ! real(rp) :: mu,sigma - - ! method=VSL_RNG_METHOD_GAUSSIAN_ICDF - - ! mu=0._rp - ! sigma=1._rp - - ! errcode = vdrnggaussian(method,streams(OMP_GET_THREAD_NUM()),n, & - ! get_random_mkl,mu,sigma) - !END FUNCTION - - !FUNCTION get_random_mkl_N(mu,sigma) - ! USE omp_lib - ! IMPLICIT NONE - ! - ! INTEGER, PARAMETER :: n=8_idef - ! REAL(rp) :: get_random_mkl_N - ! REAL(rp),dimension(2) :: buffer - ! INTEGER :: errcode - ! INTEGER :: method - - ! real(rp),intent(in) :: mu,sigma - - ! method=VSL_RNG_METHOD_GAUSSIAN_BOXMULLER - - ! mu=0._rp - ! sigma=1._rp - - ! errcode = vdrnggaussian(method,stream,2_idef, & - ! buffer,mu,sigma) - ! get_random_mkl_N=buffer(1) - !END FUNCTION - - !FUNCTION get_random_mkl_U() - ! USE omp_libvdrnggaussian - ! IMPLICIT NONE - ! - ! INTEGER, PARAMETER :: n=8_idef - ! REAL(rp) :: get_random_mkl_U - ! REAL(rp),dimension(2) :: buffer - ! INTEGER :: errcode - ! INTEGER :: method - - - ! method=VSL_RNG_METHOD_UNIFORM_STD_ACCURATE - - ! mu=0._rp - ! sigma=1._rp - - ! errcode = vdrnguniform(method,stream,2_idef, & - ! buffer,0._rp,1._rp) - ! get_random_mkl_U=buffer(2) - !END FUNCTION +!******************************************************************************* +! Setters +!******************************************************************************* + SUBROUTINE random_U_set_dist(this, low, high) + IMPLICIT NONE + +! Arguments + CLASS (random_U_context), INTENT(in) :: this + REAL(rp), INTENT(IN) :: low + REAL(rp), INTENT(IN) :: high + +! Start of executable code +!$OMP PARALLEL DEFAULT(SHARED) + CALL random_set_dist_U(this%states(get_thread_number()), low, high) +!$OMP END PARALLEL + + END SUBROUTINE + + SUBROUTINE random_N_set_dist(this, low, high) + IMPLICIT NONE + +! Arguments + CLASS (random_N_context), INTENT(in) :: this + REAL(rp), INTENT(IN) :: low + REAL(rp), INTENT(IN) :: high + +! Start of executable code +!$OMP PARALLEL DEFAULT(SHARED) + CALL random_set_dist_N(this%states(get_thread_number()), low, high) +!$OMP END PARALLEL + + END SUBROUTINE END MODULE korc_random diff --git a/src/korc_rnd_numbers.f90 b/src/korc_rnd_numbers.f90 index e0fde1fe..43fcb565 100755 --- a/src/korc_rnd_numbers.f90 +++ b/src/korc_rnd_numbers.f90 @@ -112,7 +112,7 @@ subroutine rand_real(rrand) rrand = rcoeff*REAL(irand64,rp) + 0.5_rp end subroutine rand_real - +! FIXME: This function is now defunct. subroutine init_random_seed(params) #ifdef PARALLEL_RANDOM use korc_random @@ -157,15 +157,6 @@ subroutine init_random_seed(params) seed(i) = lcg(t) end do end if -#ifdef PARALLEL_RANDOM - call initialize_random(seed(1)) - call initialize_random_U(seed(1)) - call initialize_random_N(seed(1)) - -! call initialize_random_mkl(seed(1)) -#else - call random_seed(put=seed) -#endif contains ! This simple PRNG might not be good enough for real work, but is @@ -183,19 +174,4 @@ function lcg(s) end function lcg end subroutine init_random_seed -subroutine finalize_random_seed -#ifdef PARALLEL_RANDOM - use korc_random -#endif - -implicit none - -#ifdef PARALLEL_RANDOM -call finalize_random -call finalize_random_U -call finalize_random_N -#endif - -end subroutine - end module korc_rnd_numbers diff --git a/src/korc_spatial_distribution.f90 b/src/korc_spatial_distribution.f90 index 1ef727c3..06b205f6 100755 --- a/src/korc_spatial_distribution.f90 +++ b/src/korc_spatial_distribution.f90 @@ -55,7 +55,7 @@ subroutine uniform(spp) end subroutine uniform -subroutine disk(params,spp) +subroutine disk(params,random,spp) !! @note Subrotuine for generating a uniform disk/ring as the !! initial spatial condition of a given species of particles !! in the simulation. @endnote @@ -81,6 +81,7 @@ subroutine disk(params,spp) !! - r_{min}^2)U + r_{min}^2}\), where \(U\) is a uniform deviate in \([0,1]\). TYPE(KORC_PARAMS), INTENT(IN) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp !! An instance of the derived type SPECIES containing all !! the parameters and simulation variables of the different @@ -94,21 +95,12 @@ subroutine disk(params,spp) ALLOCATE( theta(spp%ppp) ) ALLOCATE( r(spp%ppp) ) - ! Initial condition of uniformly distributed particles on a disk in the xz-plane - ! A unique velocity direction - call init_u_random(10986546_8) - - call init_random_seed(params) - call RANDOM_NUMBER(theta) - call finalize_random_seed - - theta = 2.0_rp*C_PI*theta + CALL random%uniform%set(0.0_rp, 2.0_rp*C_PI) + CALL random%uniform%get_array(theta) ! Uniform distribution on a disk at a fixed azimuthal theta -! FIXME: Is it really necessary to reset the seed here? - call init_random_seed(params) - call RANDOM_NUMBER(r) - call finalize_random_seed + CALL random%uniform%set(0.0_rp, 1.0_rp) + CALL random%uniform%get_array(r) r = SQRT((spp%r_outter**2 - spp%r_inner**2)*r + spp%r_inner**2) spp%vars%X(:,1) = ( spp%Ro + r*COS(theta) )*COS(spp%PHIo) @@ -119,8 +111,9 @@ subroutine disk(params,spp) DEALLOCATE(r) end subroutine disk -subroutine torus(params,spp) +subroutine torus(params,random,spp) TYPE(KORC_PARAMS), INTENT(IN) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp REAL(rp), DIMENSION(:), ALLOCATABLE :: r REAL(rp), DIMENSION(:), ALLOCATABLE :: theta @@ -132,27 +125,12 @@ subroutine torus(params,spp) ! Initial condition of uniformly distributed particles on a disk in the xz-plane ! A unique velocity direction -! call init_u_random(10986546_8) - - call init_random_seed(params) -! call RANDOM_NUMBER(theta) -! theta = 2.0_rp*C_PI*theta - - call set_random_dist(0.0_rp, 2.0_rp*C_PI) - call get_randoms(theta) - -! call init_random_seed(params) -! call RANDOM_NUMBER(zeta) -! zeta = 2.0_rp*C_PI*zeta - - call get_randoms(zeta) -! - ! Uniform distribution on a disk at a fixed azimuthal theta -! call init_random_seed(params) -! call RANDOM_NUMBER(r) + call random%uniform%set(0.0_rp, 2.0_rp*C_PI) + call random%uniform%get_array(theta) + call random%uniform%get_array(zeta) - call set_random_dist(0.0_rp, 1.0_rp) - call get_randoms(r) + call random%uniform%set(0.0_rp, 1.0_rp) + call random%uniform%get_array(r) r = SQRT((spp%r_outter**2 - spp%r_inner**2)*r + spp%r_inner**2) @@ -165,8 +143,6 @@ subroutine torus(params,spp) DEALLOCATE(theta) DEALLOCATE(zeta) DEALLOCATE(r) - - call finalize_random_seed end subroutine torus !subroutine torus(params,spp) @@ -246,7 +222,7 @@ end subroutine torus !end subroutine torus -subroutine elliptic_torus(params,spp) +subroutine elliptic_torus(params,random,spp) !! @note Subroutine for generating a uniform elliptic torus as the initial !! spatial condition of a given particle species in the simulation. @endnote !! An initial spatial distribution following the uniform distribution of @@ -279,6 +255,7 @@ subroutine elliptic_torus(params,spp) !! parallel to the \(Z\)-axis. TYPE(KORC_PARAMS), INTENT(IN) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp !! An instance of the derived type SPECIES containing all the parameters !! and simulation variables of the different species in the simulation. @@ -301,6 +278,8 @@ subroutine elliptic_torus(params,spp) REAL(rp), DIMENSION(:), ALLOCATABLE :: Y1 !! Auxiliary vector used in the coordinate transformations. + CALL random%uniform%set(0.0_rp, 1.0_rp) + ALLOCATE(X1(spp%ppp)) ALLOCATE(Y1(spp%ppp)) ALLOCATE(X(spp%ppp)) @@ -312,24 +291,14 @@ subroutine elliptic_torus(params,spp) ! Initial condition of uniformly distributed particles on a disk in the xz-plane ! A unique velocity direction - call init_u_random(10986546_8) - - call init_random_seed(params) - call RANDOM_NUMBER(theta) + call random%uniform%get_array(theta) theta = 2.0_rp*C_PI*theta - call finalize_random_seed -! FIXME: Is it really necessary to reset the seed here? - call init_random_seed(params) - call RANDOM_NUMBER(zeta) + call random%uniform%get_array(zeta) zeta = 2.0_rp*C_PI*zeta - call finalize_random_seed ! Uniform distribution on a disk at a fixed azimuthal theta -! FIXME: Is it really necessary to reset the seed here? - call init_random_seed(params) - call RANDOM_NUMBER(r) - call finalize_random_seed + call random%uniform%get_array(r) r = SQRT((spp%r_outter**2 - spp%r_inner**2)*r + spp%r_inner**2) @@ -409,8 +378,9 @@ END FUNCTION fzero !! @param theta Uniform deviates in the range \([0,2\pi]\) representing the uniform poloidal angle \(\theta\) distribution of the particles. !! @param zeta Uniform deviates in the range \([0,2\pi]\) representing the uniform toroidal angle \(\zeta\) distribution of the particles. !! @param pp Particle iterator. -subroutine exponential_torus(params,spp) +subroutine exponential_torus(params, random,spp) TYPE(KORC_PARAMS), INTENT(IN) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp REAL(rp) :: fl REAL(rp) :: fr @@ -431,24 +401,13 @@ subroutine exponential_torus(params,spp) ! Initial condition of uniformly distributed particles on a ! disk in the xz-plane ! A unique velocity direction - call init_u_random(10986546_8) - - call init_random_seed(params) - call RANDOM_NUMBER(theta) - theta = 2.0_rp*C_PI*theta - call finalize_random_seed - - call init_random_seed(params) -! FIXME: Is it really necessary to reset the seed here? - call RANDOM_NUMBER(zeta) - zeta = 2.0_rp*C_PI*zeta - call finalize_random_seed + CALL random%uniform%set(0.0_rp, 2.0_rp*C_PI) + call random%uniform%get_array(theta) + call random%uniform%get_array(zeta) ! Uniform distribution on a disk at a fixed azimuthal theta - call init_random_seed(params) -! FIXME: Is it really necessary to reset the seed here? - call RANDOM_NUMBER(r) - call finalize_random_seed + CALL random%uniform%set(0.0_rp, 1.0_rp) + call random%uniform%get_array(r) ! Newton-Raphson applied here for finding the radial distribution do pp=1_idef,spp%ppp @@ -520,8 +479,9 @@ end subroutine exponential_torus !! @param X1 Auxiliary vector used in the coordinate transformations. !! @param Y1 Auxiliary vector used in the coordinate transformations. !! @param pp Particle iterator. -subroutine exponential_elliptic_torus(params,spp) +subroutine exponential_elliptic_torus(params,random,spp) TYPE(KORC_PARAMS), INTENT(IN) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp REAL(rp) :: fl REAL(rp) :: fr @@ -540,6 +500,8 @@ subroutine exponential_elliptic_torus(params,spp) REAL(rp), DIMENSION(:), ALLOCATABLE :: Y1 INTEGER :: pp + CALL random%uniform%set(0.0_rp, 1.0_rp) + ALLOCATE(X1(spp%ppp)) ALLOCATE(Y1(spp%ppp)) ALLOCATE(X(spp%ppp)) @@ -552,24 +514,14 @@ subroutine exponential_elliptic_torus(params,spp) ! Initial condition of uniformly distributed particles on a ! disk in the xz-plane ! A unique velocity direction - call init_u_random(10986546_8) - - call init_random_seed(params) - call RANDOM_NUMBER(theta) + call random%uniform%get_array(theta) theta = 2.0_rp*C_PI*theta - call finalize_random_seed -! FIXME: Is it really necessary to reset the seed here? - call init_random_seed(params) - call RANDOM_NUMBER(zeta) + call random%uniform%get_array(zeta) zeta = 2.0_rp*C_PI*zeta - call finalize_random_seed ! Uniform distribution on a disk at a fixed azimuthal theta -! FIXME: Is it really necessary to reset the seed here? - call init_random_seed(params) - call RANDOM_NUMBER(r) - call finalize_random_seed + call random%uniform%get_array(r) do pp=1_idef,spp%ppp rl = 0.0_rp @@ -651,8 +603,9 @@ end subroutine exponential_elliptic_torus !! @param Y1 Auxiliary vector used in the coordinate transformations. !! @param sigma Standard deviation \(\sigma\) of the radial distribution function. !! @param pp Particle iterator. -subroutine gaussian_elliptic_torus(params,spp) +subroutine gaussian_elliptic_torus(params,random,spp) TYPE(KORC_PARAMS), INTENT(IN) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp REAL(rp), DIMENSION(:), ALLOCATABLE :: rotation_angle REAL(rp), DIMENSION(:), ALLOCATABLE :: r @@ -677,24 +630,13 @@ subroutine gaussian_elliptic_torus(params,spp) ! Initial condition of uniformly distributed particles on a ! disk in the xz-plane ! A unique velocity direction - call init_u_random(10986546_8) - - call init_random_seed(params) - call RANDOM_NUMBER(theta) - theta = 2.0_rp*C_PI*theta - call finalize_random_seed - -! FIXME: Is it really necessary to reset the seed here? - call init_random_seed(params) - call RANDOM_NUMBER(zeta) - zeta = 2.0_rp*C_PI*zeta - call finalize_random_seed + call random%uniform%set(0.0_rp, 2.0_rp*C_PI) + call random%uniform%get_array(theta) + call random%uniform%get_array(zeta) ! Uniform distribution on a disk at a fixed azimuthal theta -! FIXME: Is it really necessary to reset the seed here? - call init_random_seed(params) - call RANDOM_NUMBER(r) - call finalize_random_seed + call random%uniform%set(0.0_rp, 1.0_rp) + call random%uniform%get_array(r) sigma = 1.0_rp/SQRT(2.0_rp*(spp%falloff_rate/params%cpp%length)) sigma = sigma/params%cpp%length @@ -771,24 +713,13 @@ FUNCTION indicator(psi,psi_max) END FUNCTION indicator -FUNCTION random_norm(mean,sigma) - REAL(rp), INTENT(IN) :: mean - REAL(rp), INTENT(IN) :: sigma - REAL(rp) :: random_norm - REAL(rp) :: rand1, rand2 - - call RANDOM_NUMBER(rand1) - call RANDOM_NUMBER(rand2) - - random_norm = mean+sigma*SQRT(-2.0_rp*LOG(rand1))*COS(2.0_rp*C_PI*rand2); -END FUNCTION random_norm - -subroutine MH_gaussian_elliptic_torus(params,spp) +subroutine MH_gaussian_elliptic_torus(params,random,spp) !! @note Subroutine that generates a 2D Gaussian distribution in an !! elliptic torus as the initial spatial condition of a given particle !! species in the simulation. @endnote TYPE(KORC_PARAMS), INTENT(IN) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp !! An instance of the derived type SPECIES containing all the parameters !! and simulation variables of the different species in the simulation. @@ -825,6 +756,8 @@ subroutine MH_gaussian_elliptic_torus(params,spp) INTEGER :: mpierr LOGICAL :: accepted + CALL random%uniform%set(0.0_rp,1.0_rp) + nsamples = spp%ppp*params%mpi_params%nmpi psi_max_buff = spp%psi_max*1.1_rp @@ -846,8 +779,10 @@ subroutine MH_gaussian_elliptic_torus(params,spp) ii=2_idef do while (ii .LE. 1000_idef) - R_test = R_buffer + random_norm(0.0_rp,spp%sigmaR) - Z_test = Z_buffer + random_norm(0.0_rp,spp%sigmaZ) + CALL random%normal%set(0.0_rp, spp%sigmaR) + R_test = R_buffer + random%normal%get() + CALL random%normal%set(0.0_rp, spp%sigmaZ) + Z_test = Z_buffer + random%normal%get() psi0=PSI_ROT(R_buffer,spp%Ro,spp%sigmaR,Z_buffer,spp%Zo, & spp%sigmaZ,theta_rad) @@ -861,8 +796,7 @@ subroutine MH_gaussian_elliptic_torus(params,spp) Z_buffer = Z_test ii = ii + 1_idef else - call RANDOM_NUMBER(rand_unif) - if (rand_unif .LT. ratio) then + if (random%uniform%get() .LT. ratio) then R_buffer = R_test Z_buffer = Z_test ii = ii + 1_idef @@ -873,9 +807,10 @@ subroutine MH_gaussian_elliptic_torus(params,spp) ii=1_idef do while (ii .LE. nsamples) - - R_test = R_buffer + random_norm(0.0_rp,spp%sigmaR) - Z_test = Z_buffer + random_norm(0.0_rp,spp%sigmaZ) + CALL random%normal%set(0.0_rp, spp%sigmaR) + R_test = R_buffer + random%normal%get() + CALL random%normal%set(0.0_rp, spp%sigmaZ) + Z_test = Z_buffer + random%normal%get() psi0=PSI_ROT(R_buffer,spp%Ro,spp%sigmaR,Z_buffer,spp%Zo, & spp%sigmaZ,theta_rad) @@ -889,8 +824,7 @@ subroutine MH_gaussian_elliptic_torus(params,spp) R_buffer = R_test Z_buffer = Z_test else - call RANDOM_NUMBER(rand_unif) - if (rand_unif .LT. ratio) then + if (random%uniform%get() .LT. ratio) then accepted=.true. R_buffer = R_test Z_buffer = Z_test @@ -957,8 +891,9 @@ end subroutine MH_gaussian_elliptic_torus !! @param theta Uniform deviates in the range \([0,2\pi]\) representing the uniform poloidal angle \(\theta\) distribution of the particles. !! @param zeta Uniform deviates in the range \([0,2\pi]\) representing the uniform toroidal angle \(\zeta\) distribution of the particles. !! @param pp Particle iterator. -subroutine gaussian_torus(params,spp) +subroutine gaussian_torus(params,random,spp) TYPE(KORC_PARAMS), INTENT(IN) :: params + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp REAL(rp), DIMENSION(:), ALLOCATABLE :: theta REAL(rp), DIMENSION(:), ALLOCATABLE :: zeta @@ -971,24 +906,13 @@ subroutine gaussian_torus(params,spp) ! Initial condition of uniformly distributed particles on a disk in the xz-plane ! A unique velocity direction - call init_u_random(10986546_8) - - call init_random_seed(params) - call RANDOM_NUMBER(theta) - theta = 2.0_rp*C_PI*theta - call finalize_random_seed - -! FIXME: Is it really necessary to reset the seed here? - call init_random_seed(params) - call RANDOM_NUMBER(zeta) - zeta = 2.0_rp*C_PI*zeta - call finalize_random_seed + CALL random%uniform%set(0.0_rp, 2.0_rp*C_PI) + call random%uniform%get_array(theta) + call random%uniform%get_array(zeta) ! Uniform distribution on a disk at a fixed azimuthal theta -! FIXME: Is it really necessary to reset the seed here? - call init_random_seed(params) - call RANDOM_NUMBER(r) - call finalize_random_seed + CALL random%uniform%set(0.0_rp, 1.0_rp) + call random%uniform%get_array(r) sigma = 1.0_rp/SQRT(2.0_rp*(spp%falloff_rate/params%cpp%length)) sigma = sigma/params%cpp%length @@ -1025,12 +949,13 @@ function Spong_2D(R0,b,w,dlam,R,Z,T) end function Spong_2D -subroutine Spong_3D(params,spp) +subroutine Spong_3D(params,random,spp) !! @note Subroutine that generates a 2D Gaussian distribution in an !! elliptic torus as the initial spatial condition of a given particle !! species in the simulation. @endnote TYPE(KORC_PARAMS), INTENT(IN) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp !! An instance of the derived type SPECIES containing all the parameters !! and simulation variables of the different species in the simulation. @@ -1092,6 +1017,7 @@ subroutine Spong_3D(params,spp) INTEGER :: mpierr !! mpi error indicator + CALL random%uniform%set(0.0_rp,1.0_rp) nsamples = spp%ppp*params%mpi_params%nmpi @@ -1138,10 +1064,8 @@ subroutine Spong_3D(params,spp) R_buffer = spp%Ro Z_buffer = spp%Zo - - call RANDOM_NUMBER(rand_unif) T_buffer = min_pitch_angle + (max_pitch_angle & - - min_pitch_angle)*rand_unif + - min_pitch_angle)*random%uniform%get() ! write(output_unit_write,'("length norm: ",E17.10)') params%cpp%length @@ -1150,15 +1074,18 @@ subroutine Spong_3D(params,spp) ! write(output_unit_write,'("burn:",I15)') ii - R_test = R_buffer + random_norm(0.0_rp,spp%dR) - Z_test = Z_buffer + random_norm(0.0_rp,spp%dZ) - T_test = T_buffer + random_norm(0.0_rp,spp%dth) + CALL random%normal%set(0.0_rp, spp%dR) + R_test = R_buffer + random%normal%get() + CALL random%normal%set(0.0_rp, spp%dZ) + Z_test = Z_buffer + random%normal%get() ! Test that pitch angle and momentum are within chosen boundary + CALL random%normal%set(0.0_rp, spp%dth) + T_test = T_buffer + random%normal%get() do while ((T_test .GT. spp%etao_lims(2)).OR. & (T_test .LT. spp%etao_lims(1))) - T_test = T_buffer + random_norm(0.0_rp,spp%dth) + T_test = T_buffer + random%normal%get() end do ! initialize 2D gaussian argument and distribution function, or @@ -1202,8 +1129,7 @@ subroutine Spong_3D(params,spp) T_buffer = T_test ii = ii + 1_idef else - call RANDOM_NUMBER(rand_unif) - if (rand_unif .LT. ratio) then + if (random%uniform%get() .LT. ratio) then R_buffer = R_test Z_buffer = Z_test T_buffer = T_test @@ -1222,18 +1148,21 @@ subroutine Spong_3D(params,spp) !write(output_unit_write,'("Sample: ",I10)') ii end if - R_test = R_buffer + random_norm(0.0_rp,spp%dR) - Z_test = Z_buffer + random_norm(0.0_rp,spp%dZ) - T_test = T_buffer + random_norm(0.0_rp,spp%dth) + CALL random%normal%set(0.0_rp, spp%dR) + R_test = R_buffer + random%normal%get() + CALL random%normal%set(0.0_rp, spp%dZ) + Z_test = Z_buffer + random%normal%get() ! Selection boundary is set with buffer region + CALL random%normal%set(0.0_rp, spp%dth) + T_test = T_buffer + random%normal%get() do while ((T_test .GT. max_pitch_angle).OR. & (T_test .LT. min_pitch_angle)) if (T_test.lt.0) then T_test=abs(T_test) exit end if - T_test = T_buffer + random_norm(0.0_rp,spp%dth) + T_test = T_buffer + random%normal%get() end do @@ -1254,8 +1183,7 @@ subroutine Spong_3D(params,spp) Z_buffer = Z_test T_buffer = T_test else - call RANDOM_NUMBER(rand_unif) - if (rand_unif .LT. ratio) then + if (random%uniform%get() .LT. ratio) then R_buffer = R_test Z_buffer = Z_test T_buffer = T_test @@ -1272,8 +1200,7 @@ subroutine Spong_3D(params,spp) Z_samples(ii) = Z_buffer T_samples(ii) = T_buffer ! Sample phi location uniformly - call RANDOM_NUMBER(rand_unif) - PHI_samples(ii) = 2.0_rp*C_PI*rand_unif + PHI_samples(ii) = 2.0_rp*C_PI*random%uniform%get() ii = ii + 1_idef END IF @@ -1317,12 +1244,13 @@ subroutine Spong_3D(params,spp) end subroutine Spong_3D -subroutine MH_psi(params,spp,F) +subroutine MH_psi(params,random,spp,F) !! @note Subroutine that generates a 2D Gaussian distribution in an !! elliptic torus as the initial spatial condition of a given particle !! species in the simulation. @endnote TYPE(KORC_PARAMS), INTENT(INOUT) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(in) :: random TYPE(SPECIES), INTENT(INOUT) :: spp !! An instance of the derived type SPECIES containing all the parameters !! and simulation variables of the different species in the simulation. @@ -1417,27 +1345,12 @@ subroutine MH_psi(params,spp,F) if (params%mpi_params%rank.EQ.0_idef) then ! Transient ! - + CALL random%uniform%set(0.0_rp,1.0_rp) R_buffer = spp%Ro Z_buffer = spp%Zo PHI_buffer = 0._rp - - if (.not.params%SameRandSeed) then - call init_random_seed(params) - else -#ifdef PARALLEL_RANDOM - call initialize_random(seed(1)) - call initialize_random_U(seed(1)) - call initialize_random_N(seed(1)) - - ! call initialize_random_mkl(seed(1)) -#else - call random_seed(put=seed) -#endif - end if - write(output_unit_write,'("Begin burn: ",I10)') accepted=.false. ii=1_idef @@ -1448,26 +1361,18 @@ subroutine MH_psi(params,spp,F) end if !write(6,'("Burn: ",I10)') ii - !R_test = R_buffer + random_norm(0.0_rp,spp%dR) - !R_test = R_buffer + get_random_mkl_N(0.0_rp,spp%dR) - R_test = R_buffer + get_random_N()*spp%dR - - !Z_test = Z_buffer + random_norm(0.0_rp,spp%dZ) - !Z_test = Z_buffer + get_random_mkl_N(0.0_rp,spp%dZ) - Z_test = Z_buffer + get_random_N()*spp%dZ - + CALL random%normal%set(0.0_rp,spp%dR) + R_test = R_buffer + random%normal%get() do while ((R_test.GT.max_R).OR.(R_test .LT. min_R)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - R_test = R_buffer + get_random_N()*spp%dR + R_test = R_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp,spp%dZ) + Z_test = Z_buffer + random%normal%get() do while ((Z_test.GT.max_Z).OR.(Z_test .LT. min_Z)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - Z_test = Z_buffer + get_random_N()*spp%dZ + Z_test = Z_buffer + random%normal%get() end do - PHI_test = 2.0_rp*C_PI*get_random_U() + PHI_test = 2.0_rp*C_PI*random%uniform%get() ! initialize 2D gaussian argument and distribution function, or @@ -1568,10 +1473,7 @@ subroutine MH_psi(params,spp,F) !write(output_unit_write,*) 'PSIN',PSIN1 else -! call RANDOM_NUMBER(rand_unif) -! if (rand_unif .LT. ratio) then - !if (get_random_mkl_U() .LT. ratio) then - if (get_random_U() .LT. ratio) then + if (random%uniform%get() .LT. ratio) then accepted=.true. R_buffer = R_test Z_buffer = Z_test @@ -1596,26 +1498,18 @@ subroutine MH_psi(params,spp,F) end if #endif - !R_test = R_buffer + random_norm(0.0_rp,spp%dR) - !R_test = R_buffer + get_random_mkl_N(0.0_rp,spp%dR) - R_test = R_buffer + get_random_N()*spp%dR - - !Z_test = Z_buffer + random_norm(0.0_rp,spp%dZ) - !Z_test = Z_buffer + get_random_mkl_N(0.0_rp,spp%dZ) - Z_test = Z_buffer + get_random_N()*spp%dZ - - PHI_test = 2.0_rp*C_PI*get_random_U() + PHI_test = 2.0_rp*C_PI*random%uniform%get() + CALL random%normal%set(0.0_rp,spp%dR) + R_test = R_buffer + random%normal%get() do while ((R_test.GT.max_R).OR.(R_test .LT. min_R)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - R_test = R_buffer + get_random_N()*spp%dR + R_test = R_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp,spp%dZ) + Z_test = Z_buffer + random%normal%get() do while ((Z_test.GT.max_Z).OR.(Z_test .LT. min_Z)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - Z_test = Z_buffer + get_random_N()*spp%dZ + Z_test = Z_buffer + random%normal%get() end do if (accepted) then @@ -1673,10 +1567,7 @@ subroutine MH_psi(params,spp,F) Z_buffer = Z_test PHI_buffer = PHI_test else - !call RANDOM_NUMBER(rand_unif) - !if (rand_unif .LT. ratio) then - !if (get_random_mkl_U() .LT. ratio) then - if (get_random_U() .LT. ratio) then + if (random%uniform%get() .LT. ratio) then accepted=.true. R_buffer = R_test Z_buffer = Z_test @@ -1702,10 +1593,6 @@ subroutine MH_psi(params,spp,F) ! write(output_unit_write,*) 'RS',R_buffer - ! Sample phi location uniformly - !call RANDOM_NUMBER(rand_unif) - !PHI_samples(ii) = 2.0_rp*C_PI*rand_unif - !PHI_samples(ii) = 2.0_rp*C_PI*get_random_mkl_U() ii = ii + 1_idef END IF @@ -1722,10 +1609,6 @@ subroutine MH_psi(params,spp,F) ! write(output_unit_write,*) 'Z_samples',Z_samples ! write(output_unit_write,*) 'G_samples',G_samples ! write(output_unit_write,*) 'eta_samples',eta_samples - - if (.not.params%SameRandSeed) then - call init_random_seed(params) - end if end if params%GC_coords=.FALSE. @@ -1756,12 +1639,13 @@ subroutine MH_psi(params,spp,F) end subroutine MH_psi -subroutine FIO_therm(params,spp,F,P) +subroutine FIO_therm(params,random,spp,F,P) !! @note Subroutine that generates a 2D Gaussian distribution in an !! elliptic torus as the initial spatial condition of a given particle !! species in the simulation. @endnote TYPE(KORC_PARAMS), INTENT(INOUT) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp !! An instance of the derived type SPECIES containing all the parameters !! and simulation variables of the different species in the simulation. @@ -1908,12 +1792,6 @@ subroutine FIO_therm(params,spp,F,P) !write(output_unit_write,*) 'PSIN1',PSIN1 !write(6,*) 'PSIN0',PSIN0 - if (.not.params%SameRandSeed) then - call init_random_seed(params) - else - call random_seed(put=seed) - end if - write(output_unit_write,'("Begin burn: ",I10)') accepted=.false. ii=1_idef @@ -1923,39 +1801,27 @@ subroutine FIO_therm(params,spp,F,P) !write(output_unit_write,'("Burn: ",I10)') ii end if - - !R_test = R_buffer + random_norm(0.0_rp,spp%dR) - !R_test = R_buffer + get_random_mkl_N(0.0_rp,spp%dR) - R_test = R_buffer + get_random_N()*spp%dR - - !Z_test = Z_buffer + random_norm(0.0_rp,spp%dZ) - !Z_test = Z_buffer + get_random_mkl_N(0.0_rp,spp%dZ) - Z_test = Z_buffer + get_random_N()*spp%dZ - - V_test=V_buffer+get_random_N()*spp%dgam - - + CALL random%normal%set(0.0_rp,spp%dR) + R_test = R_buffer + random%normal%get() do while ((R_test.GT.max_R).OR.(R_test .LT. min_R)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - R_test = R_buffer + get_random_N()*spp%dR + R_test = R_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp,spp%dZ) + Z_test = Z_buffer + random%normal%get() do while ((Z_test.GT.max_Z).OR.(Z_test .LT. min_Z)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - Z_test = Z_buffer + get_random_N()*spp%dZ + Z_test = Z_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp,spp%dgam) + V_test = V_buffer + random%normal%get() do while ((V_test.GT.max_V).OR.(V_test .LT. min_V)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - V_test = V_buffer + get_random_N()*spp%dgam + V_test = V_buffer + random%normal%get() end do - PHI_test = 2.0_rp*C_PI*get_random_U() + PHI_test = 2.0_rp*C_PI*random%uniform%get() - XI_test = -1+2.0_rp*get_random_U() + XI_test = -1+2.0_rp*random%uniform%get() if (accepted) then @@ -2025,10 +1891,7 @@ subroutine FIO_therm(params,spp,F,P) !write(output_unit_write,*) 'PSIN',PSIN1 else -! call RANDOM_NUMBER(rand_unif) -! if (rand_unif .LT. ratio) then - !if (get_random_mkl_U() .LT. ratio) then - if (get_random_U() .LT. ratio) then + if (random%uniform%get() .LT. ratio) then accepted=.true. R_buffer = R_test Z_buffer = Z_test @@ -2053,37 +1916,27 @@ subroutine FIO_therm(params,spp,F,P) !write(output_unit_write,'("Sample: ",I10)') ii end if - !R_test = R_buffer + random_norm(0.0_rp,spp%dR) - !R_test = R_buffer + get_random_mkl_N(0.0_rp,spp%dR) - R_test = R_buffer + get_random_N()*spp%dR - - !Z_test = Z_buffer + random_norm(0.0_rp,spp%dZ) - !Z_test = Z_buffer + get_random_mkl_N(0.0_rp,spp%dZ) - Z_test = Z_buffer + get_random_N()*spp%dZ - - PHI_test = 2.0_rp*C_PI*get_random_U() + PHI_test = 2.0_rp*C_PI*random%uniform%get() + CALL random%normal%set(0.0_rp,spp%dR) + R_test = R_buffer + random%normal%get() do while ((R_test.GT.max_R).OR.(R_test .LT. min_R)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - R_test = R_buffer + get_random_N()*spp%dR + R_test = R_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp,spp%dZ) + Z_test = Z_buffer + random%normal%get() do while ((Z_test.GT.max_Z).OR.(Z_test .LT. min_Z)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - Z_test = Z_buffer + get_random_N()*spp%dZ + Z_test = Z_buffer + random%normal%get() end do - V_test=V_buffer+get_random_N()*spp%dgam - + CALL random%normal%set(0.0_rp,spp%dgam) + V_test = V_buffer + random%normal%get() do while ((V_test.GT.max_V).OR.(V_test .LT. min_V)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - V_test = V_buffer + get_random_N()*spp%dgam + V_test = V_buffer + random%normal%get() end do - XI_test = -1+2.0_rp*get_random_U() + XI_test = -1+2.0_rp*random%uniform%get() if (accepted) then PSIN0=PSIN1 @@ -2138,10 +1991,7 @@ subroutine FIO_therm(params,spp,F,P) V_buffer = V_test XI_buffer = XI_test else - !call RANDOM_NUMBER(rand_unif) - !if (rand_unif .LT. ratio) then - !if (get_random_mkl_U() .LT. ratio) then - if (get_random_U() .LT. ratio) then + if (random%uniform%get() .LT. ratio) then accepted=.true. R_buffer = R_test Z_buffer = Z_test @@ -2171,9 +2021,6 @@ subroutine FIO_therm(params,spp,F,P) ! write(output_unit_write,*) 'RS',R_buffer ! Sample phi location uniformly - !call RANDOM_NUMBER(rand_unif) - !PHI_samples(ii) = 2.0_rp*C_PI*rand_unif - !PHI_samples(ii) = 2.0_rp*C_PI*get_random_mkl_U() ii = ii + 1_idef END IF @@ -2193,10 +2040,6 @@ subroutine FIO_therm(params,spp,F,P) G_samples=1/sqrt(1-V_samples**2) ETA_samples=acos(XI_samples)*180/C_PI - - if (.not.params%SameRandSeed) then - call init_random_seed(params) - end if end if params%GC_coords=.FALSE. @@ -2335,12 +2178,13 @@ FUNCTION fRE_BMC(Nr_a,r_a,nRE,rm) END FUNCTION fRE_BMC -subroutine BMC_radial(params,spp,F,P) +subroutine BMC_radial(params,random,spp,F,P) !! @note Subroutine that generates a 2D Gaussian distribution in an !! elliptic torus as the initial spatial condition of a given particle !! species in the simulation. @endnote TYPE(KORC_PARAMS), INTENT(INOUT) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp !! An instance of the derived type SPECIES containing all the parameters !! and simulation variables of the different species in the simulation. @@ -2460,12 +2304,6 @@ subroutine BMC_radial(params,spp,F,P) !write(output_unit_write,*) 'PSIN1',PSIN1 !write(6,*) 'PSIN0',PSIN0 - if (.not.params%SameRandSeed) then - call init_random_seed(params) - else - call random_seed(put=seed) - end if - write(output_unit_write,'("Begin burn: ",I10)') flush(output_unit_write) accepted=.false. @@ -2477,28 +2315,19 @@ subroutine BMC_radial(params,spp,F,P) end if !write(6,'("Burn: ",I10)') ii - - !R_test = R_buffer + random_norm(0.0_rp,spp%dR) - !R_test = R_buffer + get_random_mkl_N(0.0_rp,spp%dR) - R_test = R_buffer + get_random_N()*spp%dR - - !Z_test = Z_buffer + random_norm(0.0_rp,spp%dZ) - !Z_test = Z_buffer + get_random_mkl_N(0.0_rp,spp%dZ) - Z_test = Z_buffer + get_random_N()*spp%dZ - + CALL random%normal%set(0.0_rp,spp%dR) + R_test = R_buffer + random%normal%get() do while ((R_test.GT.max_R).OR.(R_test .LT. min_R)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - R_test = R_buffer + get_random_N()*spp%dR + R_test = R_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp,spp%dZ) + Z_test = Z_buffer + random%normal%get() do while ((Z_test.GT.max_Z).OR.(Z_test .LT. min_Z)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - Z_test = Z_buffer + get_random_N()*spp%dZ + Z_test = Z_buffer + random%normal%get() end do - PHI_test = 2.0_rp*C_PI*get_random_U() + PHI_test = 2.0_rp*C_PI*random%uniform%get() rm_buffer=sqrt((R_buffer-F%AB%Ro)**2+(Z_buffer)**2)/F%AB%a rm_test=sqrt((R_test-F%AB%Ro)**2+(Z_test)**2)/F%AB%a @@ -2557,10 +2386,7 @@ subroutine BMC_radial(params,spp,F,P) !write(output_unit_write,*) 'PSIN',PSIN1 !write(6,*) 'accepted' else -! call RANDOM_NUMBER(rand_unif) -! if (rand_unif .LT. ratio) then - !if (get_random_mkl_U() .LT. ratio) then - if (get_random_U() .LT. ratio) then + if (random%uniform%get() .LT. ratio) then accepted=.true. R_buffer = R_test Z_buffer = Z_test @@ -2584,26 +2410,18 @@ subroutine BMC_radial(params,spp,F,P) !write(output_unit_write,'("Sample: ",I10)') ii end if - !R_test = R_buffer + random_norm(0.0_rp,spp%dR) - !R_test = R_buffer + get_random_mkl_N(0.0_rp,spp%dR) - R_test = R_buffer + get_random_N()*spp%dR - - !Z_test = Z_buffer + random_norm(0.0_rp,spp%dZ) - !Z_test = Z_buffer + get_random_mkl_N(0.0_rp,spp%dZ) - Z_test = Z_buffer + get_random_N()*spp%dZ - - PHI_test = 2.0_rp*C_PI*get_random_U() + PHI_test = 2.0_rp*C_PI*random%uniform%get() + CALL random%normal%set(0.0_rp,spp%dR) + R_test = R_buffer + random%normal%get() do while ((R_test.GT.max_R).OR.(R_test .LT. min_R)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - R_test = R_buffer + get_random_N()*spp%dR + R_test = R_buffer + random%normal%get() end do + CALL random%normal%set(0.0_rp,spp%dZ) + Z_test = Z_buffer + random%normal%get() do while ((Z_test.GT.max_Z).OR.(Z_test .LT. min_Z)) - !eta_test = eta_buffer + random_norm(0.0_rp,spp%dth) - !eta_test = eta_buffer + get_random_mkl_N(0.0_rp,spp%dth) - Z_test = Z_buffer + get_random_N()*spp%dZ + Z_test = Z_buffer + random%normal%get() end do @@ -2628,10 +2446,7 @@ subroutine BMC_radial(params,spp,F,P) Z_buffer = Z_test PHI_buffer = PHI_test else - !call RANDOM_NUMBER(rand_unif) - !if (rand_unif .LT. ratio) then - !if (get_random_mkl_U() .LT. ratio) then - if (get_random_U() .LT. ratio) then + if (random%uniform%get() .LT. ratio) then accepted=.true. R_buffer = R_test Z_buffer = Z_test @@ -2656,9 +2471,6 @@ subroutine BMC_radial(params,spp,F,P) ! write(output_unit_write,*) 'RS',R_buffer ! Sample phi location uniformly - !call RANDOM_NUMBER(rand_unif) - !PHI_samples(ii) = 2.0_rp*C_PI*rand_unif - !PHI_samples(ii) = 2.0_rp*C_PI*get_random_mkl_U() ii = ii + 1_idef !write(6,*) 'accepted' END IF @@ -2676,10 +2488,6 @@ subroutine BMC_radial(params,spp,F,P) ! write(output_unit_write,*) 'Z_samples',Z_samples ! write(output_unit_write,*) 'G_samples',G_samples ! write(output_unit_write,*) 'eta_samples',eta_samples - - if (.not.params%SameRandSeed) then - call init_random_seed(params) - end if end if params%GC_coords=.FALSE. @@ -2711,12 +2519,13 @@ subroutine BMC_radial(params,spp,F,P) end subroutine BMC_radial -subroutine intitial_spatial_distribution(params,spp,P,F) +subroutine intitial_spatial_distribution(params,random,spp,P,F) !! @note Subroutine that contains calls to the different subroutines !! for initializing the simulated particles with various !! spatial distribution functions. @endnote TYPE(KORC_PARAMS), INTENT(INOUT) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), DIMENSION(:), ALLOCATABLE, INTENT(INOUT) :: spp !! An instance of the derived type SPECIES containing all the parameters and !! simulation variables of the different species in the simulation. @@ -2733,23 +2542,23 @@ subroutine intitial_spatial_distribution(params,spp,P,F) CASE ('UNIFORM') call uniform(spp(ss)) CASE ('DISK') - call disk(params,spp(ss)) + call disk(params,random,spp(ss)) CASE ('TORUS') - call torus(params,spp(ss)) + call torus(params,random,spp(ss)) CASE ('EXPONENTIAL-TORUS') - call exponential_torus(params,spp(ss)) + call exponential_torus(params,random,spp(ss)) CASE ('GAUSSIAN-TORUS') - call gaussian_torus(params,spp(ss)) + call gaussian_torus(params,random,spp(ss)) CASE ('ELLIPTIC-TORUS') - call elliptic_torus(params,spp(ss)) + call elliptic_torus(params,random,spp(ss)) CASE ('EXPONENTIAL-ELLIPTIC-TORUS') - call exponential_elliptic_torus(params,spp(ss)) + call exponential_elliptic_torus(params,random,spp(ss)) CASE ('GAUSSIAN-ELLIPTIC-TORUS') - call gaussian_elliptic_torus(params,spp(ss)) + call gaussian_elliptic_torus(params,random,spp(ss)) CASE ('2D-GAUSSIAN-ELLIPTIC-TORUS-MH') - call MH_gaussian_elliptic_torus(params,spp(ss)) + call MH_gaussian_elliptic_torus(params,random,spp(ss)) CASE ('AVALANCHE-4D') - call get_Avalanche_4D(params,spp(ss),P,F) + call get_Avalanche_4D(params,random,spp(ss),P,F) !! In addition to spatial distribution function, [[Avalanche_4D]] !! samples the avalanche distribution function used to initialize !! the components of velocity for all particles. @@ -2758,13 +2567,13 @@ subroutine intitial_spatial_distribution(params,spp,P,F) spp(ss)%vars%X(:,2)=spp(ss)%Xtrace(2) spp(ss)%vars%X(:,3)=spp(ss)%Xtrace(3) CASE ('SPONG-3D') - call Spong_3D(params,spp(ss)) + call Spong_3D(params,random,spp(ss)) CASE ('HOLLMANN-3D') - call get_Hollmann_distribution_3D(params,spp(ss),F) + call get_Hollmann_distribution_3D(params,random,spp(ss),F) CASE ('HOLLMANN-3D-PSI') - call get_Hollmann_distribution_3D_psi(params,spp(ss),F) + call get_Hollmann_distribution_3D_psi(params,random,spp(ss),F) CASE ('HOLLMANN-1DTRANSPORT') - call get_Hollmann_distribution_1Dtransport(params,spp(ss),F) + call get_Hollmann_distribution_1Dtransport(params,random,spp(ss),F) CASE('MH_psi') #if DBG_CHECK @@ -2784,7 +2593,7 @@ subroutine intitial_spatial_distribution(params,spp,P,F) spp(ss)%vars%X(:,2)=0._rp spp(ss)%vars%X(:,3)=spp(ss)%Zo - call MH_psi(params,spp(ss),F) + call MH_psi(params,random,spp(ss),F) CASE('FIO_therm') if (spp(ss)%ppp*params%mpi_params%nmpi.lt.10) then @@ -2796,7 +2605,7 @@ subroutine intitial_spatial_distribution(params,spp,P,F) call korc_abort(19) end if - call FIO_therm(params,spp(ss),F,P) + call FIO_therm(params,random,spp(ss),F,P) CASE('BMC_radial') if (spp(ss)%ppp*params%mpi_params%nmpi.lt.10) then @@ -2808,9 +2617,9 @@ subroutine intitial_spatial_distribution(params,spp,P,F) call korc_abort(19) end if - call BMC_radial(params,spp(ss),F,P) + call BMC_radial(params,random,spp(ss),F,P) CASE DEFAULT - call torus(params,spp(ss)) + call torus(params,random,spp(ss)) END SELECT end do end subroutine intitial_spatial_distribution diff --git a/src/korc_types.f90 b/src/korc_types.f90 index 4fcac824..41dfa7f1 100755 --- a/src/korc_types.f90 +++ b/src/korc_types.f90 @@ -1,9 +1,7 @@ module korc_types !! @note Module containing the definition of KORC derived types and !! KORC variables, the building blocks of the code. @endnote -#ifdef FIO USE, INTRINSIC :: iso_c_binding -#endif implicit none ! * * * * * * * * * * * * * * * * * * * * ! @@ -298,7 +296,7 @@ module korc_types INTEGER :: num_impurity_species REAL(rp), DIMENSION(:), ALLOCATABLE :: Zj REAL(rp) :: gam_min - LOGICAL(rp) :: recycle_losses + LOGICAL :: recycle_losses END TYPE KORC_PARAMS diff --git a/src/korc_velocity_distribution.f90 b/src/korc_velocity_distribution.f90 index 1ae28cd5..dc7d6cc9 100755 --- a/src/korc_velocity_distribution.f90 +++ b/src/korc_velocity_distribution.f90 @@ -17,9 +17,7 @@ MODULE korc_velocity_distribution PUBLIC :: initial_gyro_distribution,& thermal_distribution,& initial_energy_pitch_dist - PRIVATE :: fth_3V,& - random_norm,& - gyro_distribution + PRIVATE :: fth_3V, gyro_distribution CONTAINS @@ -41,37 +39,7 @@ FUNCTION fth_3V(Vth,V) fth_3V = EXP(-0.5_rp*DOT_PRODUCT(V,V)/Vth**2.0_rp) END FUNCTION fth_3V - - FUNCTION random_norm(mu,sigma) - !! @note Gaussian random number generator. @endnote - !! This function returns a deviate of a Gaussian distribution - !! $$f_G(x;\mu,\sigma) = - !! \frac{1}{\sigma\sqrt{2\pi}} \exp{\left( -(x-\mu)^2/2\sigma^2 \right)},$$ - !! - !! with mean \(\mu\), and standard deviation \(\sigma\). - !! - !! We use the Inverse Transform Sampling Method for sampling \(x\). - !! With this method we get \(x = \sqrt{-2\log{(1-y)}}\cos(2\pi z)\), - !! where \(y\) and \(z\) are uniform random numbers in the interval \([0,1]\). - REAL(rp), INTENT(IN) :: mu - !! Mean value \(\mu\) of the Gaussian distribution. - REAL(rp), INTENT(IN) :: sigma - !! Standard deviation \(\sigma\) of the Gaussian distribution. - REAL(rp) :: random_norm - !! Sampled number \(x\) from the Gaussian distribution \(f_G(x;\mu,\sigma)\). - REAL(rp) :: rand1 - !! Uniform random number in the interval \([0,1]\). - REAL(rp) :: rand2 - !! Uniform random number in the interval \([0,1]\). - - call RANDOM_NUMBER(rand1) - call RANDOM_NUMBER(rand2) - - random_norm = SQRT(-2.0_rp*LOG(1.0_rp-rand1))*COS(2.0_rp*C_PI*rand2); - END FUNCTION random_norm - - - subroutine thermal_distribution(params,spp) + subroutine thermal_distribution(params,random,spp) !! @note Subroutine that samples a thermal distribution function !! of electrons for generating the initial condition of a set of !! simulated particles. @endnote @@ -83,6 +51,7 @@ subroutine thermal_distribution(params,spp) !! this function. TYPE(KORC_PARAMS), INTENT(IN) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), INTENT(INOUT) :: spp !! An instance of the derived type SPECIES containing all the !! parameters and simulation variables of the different species @@ -113,7 +82,10 @@ subroutine thermal_distribution(params,spp) !! Iterator. INTEGER :: ppp !! Number of particles per species. - + + CALL random%uniform%set(0.0_rp, 1.0_rp) + CALL random%normal%set(0.0_rp, sv) + Vmax = 0.9_rp Vth = SQRT(spp%Eo*ABS(spp%q)/spp%m) ppp = spp%ppp @@ -123,19 +95,19 @@ subroutine thermal_distribution(params,spp) ii=2_idef do while (ii .LE. 1000_idef) - U(1) = V(1) + random_norm(0.0_rp,sv) + U(1) = V(1) + random%normal%get() do while (ABS(U(1)) .GT. Vmax) - U(1) = V(1) + random_norm(0.0_rp,sv) + U(1) = V(1) + random%normal%get() end do - U(2) = V(2) + random_norm(0.0_rp,sv) + U(2) = V(2) + random%normal%get() do while (ABS(U(2)) .GT. Vmax) - U(2) = V(2) + random_norm(0.0_rp,sv) + U(2) = V(2) + random%normal%get() end do - U(3) = V(3) + random_norm(0.0_rp,sv) + U(3) = V(3) + random%normal%get() do while (ABS(U(3)) .GT. Vmax) - U(3) = V(3) + random_norm(0.0_rp,sv) + U(3) = V(3) + random%normal%get() end do ratio = fth_3V(Vth,U)/fth_3V(Vth,V) @@ -144,8 +116,7 @@ subroutine thermal_distribution(params,spp) V = U ii = ii + 1_idef else - call RANDOM_NUMBER(rand_unif) - if (ratio .GT. rand_unif) then + if (ratio .GT. random%uniform%get()) then V = U ii = ii + 1_idef end if @@ -157,17 +128,17 @@ subroutine thermal_distribution(params,spp) spp%vars%V(1,3) = V(3) ii=2_idef do while (ii .LE. ppp) - U(1) = spp%vars%V(ii-1,1) + random_norm(0.0_rp,sv) + U(1) = spp%vars%V(ii-1,1) + random%normal%get() do while (ABS(U(1)) .GT. Vmax) - U(1) = spp%vars%V(ii-1,1) + random_norm(0.0_rp,sv) + U(1) = spp%vars%V(ii-1,1) + random%normal%get() end do - U(2) = spp%vars%V(ii-1,2) + random_norm(0.0_rp,sv) + U(2) = spp%vars%V(ii-1,2) + random%normal%get() do while (ABS(U(2)) .GT. Vmax) - U(2) = spp%vars%V(ii-1,2) + random_norm(0.0_rp,sv) + U(2) = spp%vars%V(ii-1,2) + random%normal%get() end do - U(3) = spp%vars%V(ii-1,3) + random_norm(0.0_rp,sv) + U(3) = spp%vars%V(ii-1,3) + random%normal%get() do while (ABS(U(3)) .GT. Vmax) - U(3) = spp%vars%V(ii-1,3) + random_norm(0.0_rp,sv) + U(3) = spp%vars%V(ii-1,3) + random%normal%get() end do ratio = fth_3V(Vth,U)/fth_3V(Vth,spp%vars%V(ii-1,:)) @@ -178,8 +149,7 @@ subroutine thermal_distribution(params,spp) spp%vars%V(ii,3) = U(3) ii = ii + 1_idef else - call RANDOM_NUMBER(rand_unif) - if (ratio .GT. rand_unif) then + if (ratio .GT. random%uniform%get()) then spp%vars%V(ii,1) = U(1) spp%vars%V(ii,2) = U(2) spp%vars%V(ii,3) = U(3) @@ -201,11 +171,12 @@ subroutine thermal_distribution(params,spp) end subroutine thermal_distribution - subroutine initial_energy_pitch_dist(params,spp) - !! @note Subroutine that calls subroutines of different modules to + subroutine initial_energy_pitch_dist(params,random,spp) + !! @note Subroutine that calls subroutines of different modules to !! initialize the energy and pitch-angle distribution in various ways. @endnote TYPE(KORC_PARAMS), INTENT(IN) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(SPECIES), DIMENSION(:), ALLOCATABLE, INTENT(INOUT) :: spp !! An instance of the derived type SPECIES containing all the parameters and !! simulation variables of the different species in the simulation. @@ -236,20 +207,20 @@ subroutine initial_energy_pitch_dist(params,spp) spp(ii)%Eo_lims = (/spp(ii)%Eo, spp(ii)%Eo /) CASE ('THERMAL') - call thermal_distribution(params,spp(ii)) + call thermal_distribution(params,random,spp(ii)) spp(ii)%Eo_lims = (/spp(ii)%m*C_C**2*MINVAL(spp(ii)%vars%g) - & spp(ii)%m*C_C**2, & spp(ii)%m*C_C**2*MAXVAL(spp(ii)%vars%g) - spp(ii)%m*C_C**2 /) CASE ('AVALANCHE') - call get_avalanche_distribution(params,spp(ii)%vars%g, & + call get_avalanche_distribution(params,random,spp(ii)%vars%g, & spp(ii)%vars%eta,spp(ii)%go,spp(ii)%etao) spp(ii)%Eo = spp(ii)%m*C_C**2*spp(ii)%go - spp(ii)%m*C_C**2 spp(ii)%Eo_lims = (/spp(ii)%m*C_C**2*MINVAL(spp(ii)%vars%g) & - spp(ii)%m*C_C**2, & spp(ii)%m*C_C**2*MAXVAL(spp(ii)%vars%g) - spp(ii)%m*C_C**2 /) CASE ('HOLLMANN') - call get_Hollmann_distribution(params,spp(ii)) + call get_Hollmann_distribution(params,random,spp(ii)) ! spp(ii)%Eo = spp(ii)%m*C_C**2*spp(ii)%go - spp(ii)%m*C_C**2 spp(ii)%go = (spp(ii)%Eo + spp(ii)%m*C_C**2)/(spp(ii)%m*C_C**2) spp(ii)%Eo_lims = (/spp(ii)%m*C_C**2*MINVAL(spp(ii)%vars%g) & @@ -349,7 +320,7 @@ subroutine initial_energy_pitch_dist(params,spp) end subroutine initial_energy_pitch_dist - subroutine gyro_distribution(params,F,spp) + subroutine gyro_distribution(params,random,F,spp) USE, INTRINSIC :: iso_c_binding @@ -365,6 +336,7 @@ subroutine gyro_distribution(params,F,spp) !! here. @endnote TYPE(KORC_PARAMS), INTENT(IN) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(FIELDS), INTENT(IN) :: F !! An instance of the KORC derived type FIELDS. This structure !! has the information of the magnetic field. @@ -413,14 +385,10 @@ subroutine gyro_distribution(params,F,spp) ALLOCATE( theta(spp%ppp) ) ! * * * * INITIALIZE VELOCITY * * * * - if (.not.params%SameRandSeed) then - call init_random_seed(params) - call RANDOM_NUMBER(theta) - call finalize_random_seed - else + CALL random%uniform%set(0.0_rp,1.0_rp) do pp=1_idef,spp%ppp - theta(pp)=get_random_U() + theta(pp)=random%uniform%get() enddo endif theta = 2.0_rp*C_PI*theta @@ -487,8 +455,8 @@ subroutine gyro_distribution(params,F,spp) end subroutine gyro_distribution - subroutine initial_gyro_distribution(params,F,spp) - !! @note Subroutine that works as an interface for initializing various + subroutine initial_gyro_distribution(params,random,F,spp) + !! @note Subroutine that works as an interface for initializing various !! gyro-angle distributions for the different simulated particle !! species. @endnote !! @todo At this moment this subroutine only calls the subroutine @@ -496,6 +464,7 @@ subroutine initial_gyro_distribution(params,F,spp) !! a uniform gyro-angle distribution. This will be modified later. @endtodo TYPE(KORC_PARAMS), INTENT(IN) :: params !! Core KORC simulation parameters. + CLASS(random_context), POINTER, INTENT(INOUT) :: random TYPE(FIELDS), INTENT(IN) :: F !! An instance of the KORC derived type FIELDS. This structure has !! the information of the magnetic field. @@ -511,7 +480,7 @@ subroutine initial_gyro_distribution(params,F,spp) !Nothing, all was done in initialize_particles through !thermal_distribution CASE DEFAULT - call gyro_distribution(params,F,spp(ss)) + call gyro_distribution(params,random,F,spp(ss)) END SELECT end do end subroutine initial_gyro_distribution diff --git a/src/main.f90 b/src/main.f90 index 90bfa8c7..b902a39c 100755 --- a/src/main.f90 +++ b/src/main.f90 @@ -16,6 +16,7 @@ program main use korc_finalize use korc_profiles use korc_input +use korc_random #ifdef FIO use korc_fio #endif @@ -25,6 +26,8 @@ program main TYPE(KORC_PARAMS) :: params !! Contains the parameters that control the core of KORC: !! time steping, output list, etc. +CLASS(random_context), POINTER :: randoms => null() +!! Contain the context for random uniforms and normal distribuitons. TYPE(SPECIES), DIMENSION(:), ALLOCATABLE :: spp !! Contains the initial parameters of each species, which !! can be different electrons with different @@ -52,6 +55,10 @@ program main !! Subroutine [[initialize_communications]] in [[korc_hpc]] that !! initializes MPI and OpenMP communications. +!call initialize_random(params) + +randoms => random_context_construct(0, params%mpi_params%rank) + if (params%mpi_params%rank .EQ. 0) then flush(output_unit_write) end if @@ -116,7 +123,7 @@ program main flush(output_unit_write) end if -call initialize_particles(params,F,P,spp) ! Initialize particles +call initialize_particles(params,randoms,F,P,spp) ! Initialize particles !!

5\. Initialize Particle Velocity Phase Space

!! !! Subroutine [[initialize_particles]] in [[korc_initialize]] that @@ -272,7 +279,7 @@ program main write(output_unit_write,'("* * * * INITIALIZING INITIAL CONDITIONS * * * *",/)') flush(output_unit_write) end if -call set_up_particles_ic(params,F,spp,P) +call set_up_particles_ic(params,randoms,F,spp,P) if (params%mpi_params%rank .EQ. 0) then write(output_unit_write,'("* * * * * * * * * * * * * * * * * * * * * * * *",/)') @@ -378,7 +385,7 @@ program main #ifdef ACC call adv_FOeqn_top_ACC(params,F,P,spp) #else - call adv_FOeqn_top(params,F,P,spp) + call adv_FOeqn_top(params,randoms,F,P,spp) #endif params%time = params%init_time & @@ -403,7 +410,7 @@ program main ! Initial half-time particle push do it=params%ito,params%t_steps,params%t_skip - call adv_FOinterp_top(params,F,P,spp) + call adv_FOinterp_top(params,randoms,F,P,spp) params%time = params%init_time & +REAL(it-1_ip+params%t_skip,rp)*params%dt @@ -503,7 +510,7 @@ program main #ifdef ACC call adv_FOinterp_mars_top_ACC(params,F,P,spp) #else - call adv_FOinterp_mars_top(params,F,P,spp) + call adv_FOinterp_mars_top(params,randoms,F,P,spp) #endif ACC params%time = params%init_time & @@ -533,8 +540,8 @@ program main #ifdef ACC call adv_FOinterp_aorsa_top_ACC(params,F,P,spp) #else - call adv_FOinterp_aorsa_top(params,F,P,spp) -#endif ACC + call adv_FOinterp_aorsa_top(params,randoms,F,P,spp) +#endif ACC params%time = params%init_time & +REAL(it-1_ip+params%t_skip,rp)*params%dt params%it = it-1_ip+params%t_skip @@ -552,7 +559,7 @@ program main if (params%orbit_model(1:2).eq.'GC'.and.params%field_eval.eq.'eqn'.and..not.params%field_model.eq.'M3D_C1') then do it=params%ito,params%t_steps,params%t_skip*params%t_it_SC - call adv_GCeqn_top(params,F,P,spp) + call adv_GCeqn_top(params,randoms,F,P,spp) params%time = params%init_time & +REAL(it-1_ip+params%t_skip*params%t_it_SC,rp)*params%dt @@ -576,7 +583,7 @@ program main (.not.params%SC_E).and.(.not.F%Dim2x1t).and..not.params%field_model.eq.'M3D_C1') then do it=params%ito,params%t_steps,params%t_skip - call adv_GCinterp_psi_top(params,spp,P,F) + call adv_GCinterp_psi_top(params,randoms,spp,P,F) if (.not.params%LargeCollisions) then params%time = params%init_time & @@ -601,7 +608,7 @@ program main (.not.params%SC_E).and.F%Dim2x1t.and.(.not.F%ReInterp_2x1t).and..not.params%field_model.eq.'M3D_C1') then do it=params%ito,params%t_steps,params%t_skip - call adv_GCinterp_psi2x1t_top(params,spp,P,F) + call adv_GCinterp_psi2x1t_top(params,randoms,spp,P,F) params%time = params%init_time & +REAL(it-1_ip+params%t_skip,rp)*params%dt @@ -628,7 +635,7 @@ program main end if do it=params%ito,params%t_steps,params%t_skip - call adv_GCinterp_psiwE_top(params,spp,P,F) + call adv_GCinterp_psiwE_top(params,randoms,spp,P,F) if (.not.params%LargeCollisions) then params%time = params%init_time & @@ -754,6 +761,7 @@ program main call deallocate_collisions_params(params) + DEALLOCATE(randoms) call finalize_communications(params) ! * * * FINALIZING SIMULATION * * *