7 #include "sll_working_precision.h"
8 #include "sll_errors.h"
13 use sll_m_prob,
only: &
50 sll_int32 :: n_gaussians
51 sll_real64,
allocatable :: v_thermal(:,:)
52 sll_real64,
allocatable :: v_mean(:,:)
53 sll_real64,
allocatable :: delta(:)
54 sll_real64,
allocatable :: normal(:)
66 sll_real64,
allocatable :: kx(:,:)
67 sll_real64,
allocatable :: modnum(:,:)
68 sll_real64,
allocatable :: alpha(:)
69 sll_real64,
allocatable :: phase_shift(:)
86 sll_int32 :: n_boxes(3)
88 sll_real64,
allocatable :: noise_vector(:,:,:)
126 sll_real64,
optional :: m
138 sll_real64,
optional :: v(:)
150 sll_real64,
optional :: x(:)
151 sll_real64,
optional :: m
166 sll_real64,
optional :: m
182 sll_real64,
optional :: v(:)
195 fval = fval + self%alpha(j) * cos( sum(self%kx(:,j) * x) - self%phase_shift(j)*
sll_p_pi )
208 sll_real64,
optional :: x(:)
209 sll_real64,
optional :: m
215 do j = 1, self%n_gaussians
216 fval = fval + self%normal(j)*self%delta(j)* &
217 exp( -0.5_f64 * sum( ((v-self%v_mean(:,j))/self%v_thermal(:,j))**2 ) )
225 sll_real64,
optional :: x(:)
226 sll_real64,
optional :: m
232 do j=1,self%n_gaussians
233 fval = fval + self%normal(j)*self%delta(j)* &
234 exp( -0.5_f64 * sum( ((v-self%v_mean(:,j))/self%v_thermal(:,j))**2 ) )
243 sll_real64,
optional :: v(:)
247 sll_real64 :: xbox(3)
252 if(self%dims(1) == 1 )
then
253 xbox = xbox - real(box-1,f64)
254 fval = (1.0_f64-xbox(1)) * self%noise_vector(box(1)+1,1,1) + xbox(1)* self%noise_vector(box(1),1,1)
255 else if (self%dims(1) == 3 )
then
256 fval = self%noise_vector(box(1), box(2), box(3) )
258 print*,
'wrong dimension in eval_x_noise'
267 sll_real64,
optional :: m
270 fval = self%eval_x_density( x ) * self%eval_v_density( v )
278 sll_real64,
optional :: m
294 sll_real64,
optional :: v(:)
301 fval = fval + self%alpha(j) * ( cos(
sll_p_twopi*sum(self%modnum(:,j) * x) - self%kx(2,j)*v(1) - self%phase_shift(j)*
sll_p_pi ) - 0.5_f64*cos(
sll_p_twopi*sum(self%modnum(:,j) * x) - self%phase_shift(j)*
sll_p_pi )*exp(-0.5_f64*self%profile%T_i(x(1) + self%kx(1,j)*v(2))*self%kx(2,j)**2 ) ) * self%profile%radial_distrib(x(1))
311 sll_real64,
optional :: x(:)
312 sll_real64,
optional :: m
318 do j=1,self%n_gaussians
319 fexp = fexp + self%profile%rho_0(x(1))/sqrt(
sll_p_twopi*self%profile%T_i(x(1))/m)**3 * &
320 exp( -0.5_f64 * sum( (v-self%v_mean(:,j))**2/(self%profile%T_i(x(1))/m) ) )
329 if (
allocated(self%kx))
deallocate(self%kx)
330 if (
allocated(self%modnum))
deallocate(self%modnum)
331 if (
allocated(self%alpha))
deallocate(self%alpha)
332 if (
allocated(self%phase_shift))
deallocate(self%phase_shift)
333 if (
allocated(self%v_thermal))
deallocate(self%v_thermal)
334 if (
allocated(self%v_mean))
deallocate(self%v_mean)
335 if (
allocated(self%normal))
deallocate(self%normal)
336 if (
allocated(self%delta))
deallocate(self%delta)
343 if (
allocated(self%v_thermal))
deallocate(self%v_thermal)
344 if (
allocated(self%v_mean))
deallocate(self%v_mean)
345 if (
allocated(self%normal))
deallocate(self%normal)
346 if (
allocated(self%delta))
deallocate(self%delta)
347 if (
allocated(self%noise_vector))
deallocate(self%noise_vector)
353 sll_int32,
intent( in ) :: n_gaussians
354 sll_int32,
intent( in ) :: dims(2)
355 sll_int32,
intent( in ) :: file_id
358 if(
present(profile) )
then
359 self%profile = profile
362 self%n_gaussians = n_gaussians
363 select case( self%dims(1) )
373 sll_int32,
intent( in ) :: file_id
375 sll_real64 :: v_thermal_1(self%n_gaussians)
376 sll_real64 :: v_mean_1(self%n_gaussians)
377 sll_real64 :: v_thermal_2(self%n_gaussians)
378 sll_real64 :: v_mean_2(self%n_gaussians)
379 sll_real64 :: delta(self%n_gaussians)
383 sll_int32 :: rnd_seed_size
384 sll_int32,
allocatable :: rnd_seed(:)
387 namelist /noise_multigaussian/ alpha, n_boxes, v_thermal_1, v_mean_1, v_thermal_2, v_mean_2, delta, domain
391 read(file_id, noise_multigaussian)
393 allocate( self%noise_vector(1:n_boxes+1,1,1) )
394 allocate( self%v_thermal(1:self%dims(2), 1:self%n_gaussians) )
395 allocate( self%v_mean(1:self%dims(2), 1:self%n_gaussians) )
396 allocate( self%normal(1:self%n_gaussians) )
397 allocate( self%delta(1:self%n_gaussians) )
402 self%v_thermal(1,:) = v_thermal_1
403 self%v_mean(1,:) = v_mean_1
404 self%v_thermal(2,:) = v_thermal_2
405 self%v_mean(2,:) = v_mean_2
407 self%n_boxes = n_boxes
409 do j=1,self%n_gaussians
410 self%normal(j) = 1.0_f64/(
sll_p_twopi**(0.5_f64*real(self%dims(2),f64))*&
411 product(self%v_thermal(:,j)))
415 call random_seed(size=rnd_seed_size)
416 allocate( rnd_seed(rnd_seed_size) )
417 do i=1, rnd_seed_size
420 call random_seed(put=rnd_seed)
422 call random_number( rnd )
423 call sll_s_normal_cdf_inv( rnd, 1.0_f64, alpha, self%noise_vector(i,1,1) )
427 rnd = sum(self%noise_vector(1:n_boxes,1,1))/real(n_boxes, f64)
429 self%noise_vector(1:n_boxes,1,1) = self%noise_vector(1:n_boxes,1,1) - rnd
432 self%noise_vector(n_boxes+1,1,1) = self%noise_vector(1,1,1)
434 self%rdx = real( self%n_boxes, f64 ) / domain
440 sll_int32,
intent( in ) :: file_id
442 sll_real64 :: v_thermal(3,self%n_gaussians)
443 sll_real64 :: v_mean(3,self%n_gaussians)
444 sll_real64 :: delta(self%n_gaussians)
445 sll_int32 :: n_boxes(3)
446 sll_real64 :: domain(3)
448 sll_int32 :: rnd_seed_size
449 sll_int32,
allocatable :: rnd_seed(:)
452 namelist /noise_multigaussian/ alpha, n_boxes, v_thermal, v_mean, delta, domain
454 read(file_id, noise_multigaussian)
456 allocate( self%noise_vector(1:n_boxes(1)+1, 1:n_boxes(2)+1, 1:n_boxes(3)+1) )
457 allocate( self%v_thermal(1:self%dims(2), 1:self%n_gaussians) )
458 allocate( self%v_mean(1:self%dims(2), 1:self%n_gaussians) )
459 allocate( self%normal(1:self%n_gaussians) )
460 allocate( self%delta(1:self%n_gaussians) )
465 self%v_thermal = v_thermal
468 self%n_boxes = n_boxes
470 do j=1,self%n_gaussians
471 self%normal(j) = 1.0_f64/(
sll_p_twopi**(0.5_f64*real(self%dims(2),f64))*&
472 product(self%v_thermal(:,j)))
476 call random_seed(size=rnd_seed_size)
477 allocate( rnd_seed(rnd_seed_size) )
478 do i=1, rnd_seed_size
481 call random_seed(put=rnd_seed)
485 call random_number( rnd )
486 call sll_s_normal_cdf_inv( rnd, 1.0_f64, alpha, self%noise_vector(i,j,k) )
494 rnd = sum(self%noise_vector(1:n_boxes(1),j,k))/real(n_boxes(1), f64)
496 self%noise_vector(1:n_boxes(1),j,k) = self%noise_vector(1:n_boxes(1),j,k) - rnd
502 self%rdx = real( self%n_boxes, f64 ) / domain
509 sll_int32,
intent( in ) :: descriptor
510 sll_int32,
intent( in ) :: dims(2)
511 sll_int32,
intent( in ) :: file_id
516 if(
present(profile) )
then
517 self%profile = profile
519 print*,
'Error: no profile given'
524 select case( descriptor )
526 select case( self%dims(1) )
528 select case (self%dims(2) )
530 call sumcos_onegaussian_init_1d1v( file_id, self )
532 call sumcos_onegaussian_init_1d2v( file_id, self )
535 select case ( self%dims(2) )
537 call sumcos_onegaussian_init_2d2v( file_id, self )
539 call sumcos_onegaussian_init_2d3v( file_id, self )
542 call sumcos_onegaussian_init_3d3v( file_id, self )
545 select case( self%dims(1) )
547 select case (self%dims(2) )
549 call cossum_onegaussian_init_1d1v( file_id, self )
551 call cossum_onegaussian_init_1d2v( file_id, self )
554 select case ( self%dims(2) )
556 call cossum_onegaussian_init_2d2v( file_id, self )
558 call cossum_onegaussian_init_2d3v( file_id, self )
561 call cossum_onegaussian_init_3d3v( file_id, self )
565 select case( self%dims(1) )
567 select case (self%dims(2) )
569 call cossum_twogaussian_init_1d1v( file_id, self )
571 call cossum_twogaussian_init_1d2v( file_id, self )
574 call cossum_twogaussian_init_2d2v( file_id, self )
576 call cossum_twogaussian_init_3d3v( file_id, self )
579 select case( self%dims(1) )
581 select case (self%dims(2) )
583 call sumcos_twogaussian_init_1d1v( file_id, self )
585 call sumcos_twogaussian_init_1d2v( file_id, self )
588 call sumcos_twogaussian_init_2d2v( file_id, self )
590 call sumcos_twogaussian_init_3d3v( file_id, self )
593 select case (self%dims(1) )
595 select case( self%dims(2) )
601 select case (self%dims(1) )
603 select case( self%dims(2) )
609 select case (self%dims(1) )
611 select case( self%dims(2) )
617 sll_error(
'Initial distribution not implemented.',
'cos_gaussian_init')
629 character(len=*),
intent( in ) :: distribution
630 sll_int32,
intent( in ) :: dims(2)
631 sll_int32,
intent( in ) :: file_id
635 sll_int32 :: descriptor
637 select case( distribution )
638 case(
"sumcos_onegaussian" )
641 case(
"cossum_onegaussian" )
644 case(
"cossum_twogaussian" )
647 case(
"sumcos_twogaussian" )
650 case(
"cossum_multigaussian1" )
653 case(
"cossum_multigaussian2" )
656 case(
"cossum_multigaussian11" )
659 case (
"noise_multigaussian1" )
662 case (
"noise_multigaussian11" )
665 case(
"cossum_onegaussian_screwpinch" )
668 case(
"sumcos_onegaussian_screwpinch" )
671 case(
"cossum_twogaussian_screwpinch" )
674 case(
"sumcos_twogaussian_screwpinch" )
678 sll_error(
'Initial distribution not implemented.',
'sll_s_initial_distribution_new')
681 select type( params )
683 call params%init( descriptor, dims, file_id )
685 select case ( descriptor )
687 call params%init( 1, dims, file_id, profile )
689 call params%init( 11, dims, file_id, profile )
694 call params%init( descriptor, dims, file_id, profile )
706 sll_int32,
intent( in ) :: dims(2)
707 character(*),
intent( in ) :: nml_file
711 character(len=256) ::
type
712 sll_int32 :: descriptor
713 sll_int32 :: file_id, ierr
715 namelist /initial_distribution/
type
718 open(newunit=file_id, file=trim(nml_file), iostat=ierr)
719 if ( ierr /= 0 )
then
720 sll_error(
'NML file could not be opened.',
'sll_s_initial_distribution_file_new')
722 read( file_id, initial_distribution )
725 case(
"sumcos_onegaussian" )
728 case(
"cossum_onegaussian" )
731 case(
"cossum_twogaussian" )
734 case(
"sumcos_twogaussian" )
737 case(
"cossum_multigaussian1" )
740 case(
"cossum_multigaussian2" )
743 case(
"cossum_multigaussian11" )
746 case (
"noise_multigaussian1" )
749 case (
"noise_multigaussian11" )
752 case(
"cossum_onegaussian_screwpinch" )
755 case(
"sumcos_onegaussian_screwpinch" )
758 case(
"cossum_twogaussian_screwpinch" )
761 case(
"sumcos_twogaussian_screwpinch" )
765 sll_error(
'Initial distribution not implemented.',
'sll_s_initial_distribution_file_new')
768 select type( params )
770 call params%init( descriptor, dims, file_id )
772 select case ( descriptor )
774 call params%init( 1, dims, file_id, profile )
776 call params%init( 11, dims, file_id, profile )
781 call params%init( descriptor, dims, file_id, profile )
791 sll_int32,
intent( in ) :: distribution
792 sll_int32,
intent( in ) :: dims(2)
793 sll_int32,
intent( in ) :: file_id
798 select case( distribution )
818 sll_error(
'Initial distribution not implemented.',
'sll_s_initial_distribution_new')
821 select type( params )
823 call params%init( distribution, dims, file_id )
825 select case ( distribution)
827 call params%init( 1, dims, file_id, profile )
829 call params%init( 11, dims, file_id, profile )
832 call params%init( distribution, dims, file_id )
840 #define MAKE_COS_ONEGAUSSIAN_INIT( fname, dimx, dimv, dimalpha )\
841 subroutine fname( file_id, params );\
842 sll_int32,
intent( in ) :: file_id;\
844 sll_real64 :: kx(dimx)= 0.0_f64; \
845 sll_real64 :: modnum(dimx)= 0.0_f64; \
846 sll_real64 :: alpha(dimalpha); \
847 sll_real64 :: phase_shift(dimalpha) = 0.0_f64; \
848 sll_real64 :: v_thermal(dimv); \
849 sll_real64 :: v_mean(dimv)= 0.0_f64; \
851 namelist /cos_onegaussian/ kx, modnum, alpha, phase_shift, v_thermal, v_mean; \
852 params%n_cos = dimalpha;
855 make_cos_onegaussian_init( cossum_onegaussian_init_1d1v, 1, 1, 1 )
856 #include "sll_k_make_cos_onegaussian_init.F90"
858 make_cos_onegaussian_init( cossum_onegaussian_init_1d2v, 1, 2, 1 )
859 #include "sll_k_make_cos_onegaussian_init.F90"
861 make_cos_onegaussian_init( cossum_onegaussian_init_2d2v, 2, 2, 1 )
862 #include "sll_k_make_cos_onegaussian_init.F90"
864 make_cos_onegaussian_init( cossum_onegaussian_init_2d3v, 2, 3, 1 )
865 #include "sll_k_make_cos_onegaussian_init.F90"
867 make_cos_onegaussian_init( cossum_onegaussian_init_3d3v, 3, 3, 1 )
868 #include "sll_k_make_cos_onegaussian_init.F90"
870 make_cos_onegaussian_init( sumcos_onegaussian_init_1d1v, 1, 1, 1 )
871 #include "sll_k_make_cos_onegaussian_init.F90"
873 make_cos_onegaussian_init( sumcos_onegaussian_init_1d2v, 1, 2, 1 )
874 #include "sll_k_make_cos_onegaussian_init.F90"
876 make_cos_onegaussian_init( sumcos_onegaussian_init_2d2v, 2, 2, 2 )
877 #include "sll_k_make_cos_onegaussian_init.F90"
879 make_cos_onegaussian_init( sumcos_onegaussian_init_2d3v, 2, 3, 2 )
880 #include "sll_k_make_cos_onegaussian_init.F90"
882 make_cos_onegaussian_init( sumcos_onegaussian_init_3d3v, 3, 3, 3 )
883 #include "sll_k_make_cos_onegaussian_init.F90"
886 #define MAKE_COS_TWOGAUSSIAN_INIT( fname, dimx, dimv, dimalpha ) \
887 subroutine fname( file_id, params ); \
888 sll_int32,
intent( in ) :: file_id; \
890 sll_real64 :: kx(dimx)= 0.0_f64; \
891 sll_real64 :: modnum(dimx)= 0.0_f64; \
892 sll_real64 :: alpha(dimalpha); \
893 sll_real64 :: phase_shift(dimalpha) = 0.0_f64; \
894 sll_real64 :: v_thermal_1(dimv); \
895 sll_real64 :: v_mean_1(dimv); \
896 sll_real64 :: v_thermal_2(dimv); \
897 sll_real64 :: v_mean_2(dimv); \
898 sll_real64 :: delta; \
900 namelist /cos_twogaussian/ kx, modnum, alpha, phase_shift, v_thermal_1, v_mean_1, v_thermal_2, v_mean_2, delta; \
901 params%n_cos = dimalpha;
904 make_cos_twogaussian_init( cossum_twogaussian_init_1d1v, 1, 1, 1 )
905 #include "sll_k_make_cos_twogaussian_init.F90"
907 make_cos_twogaussian_init( cossum_twogaussian_init_1d2v, 1, 2, 1 )
908 #include "sll_k_make_cos_twogaussian_init.F90"
910 make_cos_twogaussian_init( cossum_twogaussian_init_2d2v, 2, 2, 1 )
911 #include "sll_k_make_cos_twogaussian_init.F90"
913 make_cos_twogaussian_init( cossum_twogaussian_init_3d3v, 3, 3, 1 )
914 #include "sll_k_make_cos_twogaussian_init.F90"
916 make_cos_twogaussian_init( sumcos_twogaussian_init_1d1v, 1, 1, 1 )
917 #include "sll_k_make_cos_twogaussian_init.F90"
919 make_cos_twogaussian_init( sumcos_twogaussian_init_1d2v, 1, 2, 1 )
920 #include "sll_k_make_cos_twogaussian_init.F90"
922 make_cos_twogaussian_init( sumcos_twogaussian_init_2d2v, 2, 2, 2 )
923 #include "sll_k_make_cos_twogaussian_init.F90"
925 make_cos_twogaussian_init( sumcos_twogaussian_init_3d3v, 3, 3, 3 )
926 #include "sll_k_make_cos_twogaussian_init.F90"
932 sll_int32,
intent( in ) :: file_id
934 sll_int32,
intent( in ) :: n_gaussians
936 sll_real64 :: modnum(1)
937 sll_real64 :: alpha(1)
938 sll_real64 :: phase_shift(1) = 0.0_f64
939 sll_real64 :: v_thermal_1(n_gaussians)
940 sll_real64 :: v_mean_1(n_gaussians)
941 sll_real64 :: v_thermal_2(n_gaussians)
942 sll_real64 :: v_mean_2(n_gaussians)
943 sll_real64 :: delta(n_gaussians)
945 namelist /cos_multigaussian/ kx, modnum, alpha, phase_shift, v_thermal_1, v_mean_1, v_thermal_2, v_mean_2, delta
947 params%n_gaussians = n_gaussians
949 read(file_id, cos_multigaussian)
951 allocate( params%alpha(1:params%n_cos) );
952 allocate( params%phase_shift(1:params%n_cos) );
953 allocate( params%kx(1:params%dims(1), 1:params%n_cos) )
954 allocate( params%modnum(1:params%dims(1), 1:params%n_cos) )
955 allocate( params%v_thermal(1:params%dims(2), 1:params%n_gaussians) )
956 allocate( params%v_mean(1:params%dims(2), 1:params%n_gaussians) )
957 allocate( params%normal(1:params%n_gaussians) )
958 allocate( params%delta(1:params%n_gaussians) )
960 if ( params%n_cos == 1 )
then
962 params%modnum(:,1) = modnum
964 params%modnum = 0.0_f64
966 params%modnum(j,j) = modnum(j)
970 params%phase_shift=phase_shift
971 params%v_thermal(1,:) = v_thermal_1
972 params%v_mean(1,:) = v_mean_1
973 params%v_thermal(2,:) = v_thermal_2
974 params%v_mean(2,:) = v_mean_2
977 do j=1,params%n_gaussians
978 params%normal(j) = 1.0_f64/(
sll_p_twopi**(0.5_f64*real(params%dims(2),f64))*&
979 product(params%v_thermal(:,j)))
Fortran module where set some physical and mathematical constants.
real(kind=f64), parameter, public sll_p_pi
real(kind=f64), parameter, public sll_p_twopi
Parameters to define common initial distributions.
subroutine cossum_multigaussian_init_1d2v(file_id, params, n_gaussians)
1d2v subroutine for initialization of sum of arbitrary number of Gaussians. Note that v_thermal_1/2 r...
real(kind=f64) function sll_f_noise_gaussian(self, x, v, m)
integer(kind=i32), parameter, public sll_p_cossum_onegaussian
Descriptor for (1+cos( \sum kx_i * x_i))*exp(-0.5(v-v_mean)**2/v_thermal**2)
integer(kind=i32), parameter, public sll_p_sumcos_twogaussian
as sll_p_sumcos_onegaussian but with sum of two Gaussians
integer(kind=i32), parameter sll_p_noise_multigaussian1
integer(kind=i32), parameter, public sll_p_sumcos_onegaussian
Descriptor for (1+\sum cos( kx * x_i))*exp(-0.5(v-v_mean)**2/v_thermal**2)
real(kind=f64) function sll_f_cos(self, x, v)
subroutine cos_gaussian_init(self, descriptor, dims, file_id, profile)
subroutine, public sll_s_initial_distribution_new_descriptor(distribution, dims, file_id, params, profile)
Factory function for sll_c_distribution_params, parameters read form input file. Version build upon d...
real(kind=f64) function sll_f_gaussian_screwpinch(self, v, x, m)
integer(kind=i32), parameter sll_p_noise_multigaussian11
real(kind=f64) function sll_f_cos_gaussian_screwpinch(self, x, v, m)
real(kind=f64) function sll_f_gaussian(self, v, x, m)
integer(kind=i32), parameter sll_p_cossum_multigaussian2
integer(kind=i32), parameter, public sll_p_cossum_multigaussian1
subroutine noise_gaussian_init_1d2v(self, file_id)
subroutine, public sll_s_initial_distribution_new(distribution, dims, file_id, params, profile)
Factory function for sll_c_distribution_params, parameters read form input file.
subroutine free_cos_gaussian(self)
real(kind=f64) function sll_f_gaussian_pnoise(self, v, x, m)
integer(kind=i32), parameter, public sll_p_cossum_twogaussian
as sll_p_sumcos_onegaussian but with sum of two Gaussians
real(kind=f64) function sll_f_cos_screwpinch(self, x, v)
real(kind=f64) function sll_f_noise(self, x, v)
subroutine free_noise_gaussian(self)
subroutine, public sll_s_initial_distribution_file_new(dims, nml_file, params, profile)
Factory function for sll_c_distribution_params, parameters read form input file.
integer(kind=i32), parameter sll_p_cossum_multigaussian11
subroutine noise_gaussian_init(self, n_gaussians, dims, file_id, profile)
subroutine noise_gaussian_init_3d3v(self, file_id)
real(kind=f64) function sll_f_cos_gaussian(self, x, v, m)
functions for initial profile of the particle distribution function
Module to select the kind parameter.
Abstract data type for parameters of initial distribution.
Data type for distribution function with (multiple) Gaussians in v and one plus cosine perturbations ...