![]() |
RFOF - RF Library for Orbit Following Codes
|
00001 00019 00020 #include "config.h" 00021 00022 subroutine MC_kick_steinbrecher_integrator( & 00023 dt, & 00024 x, & 00025 calc_diffusion_coeff, & 00026 state, & 00027 relative_tolerance_MonteCarlo, & 00028 errorFlag, & 00029 MPI_node_Id) 00030 00031 #ifdef USE_ISO_C_BINDING 00032 use, intrinsic :: ISO_C_BINDING 00033 #endif 00034 00035 use RFOF_types 00036 use RFOF_random_numbers 00037 implicit none 00038 00039 real(8), intent(in) :: dt 00040 real(8), intent(inout) :: x 00041 type(RFOF_state), intent(inout) :: state 00042 real(8) :: relative_tolerance_MonteCarlo 00043 integer, intent(inout) :: errorFlag 00044 integer, intent(in) :: MPI_node_Id 00045 00046 ! Local variables 00047 real(8) :: dx0, dx1, dW, x0, diffusion 00048 00054 interface 00055 subroutine calc_diffusion_coeff(x,state,diffusion,errorFlag) 00056 use RFOF_types 00057 real(8), intent(in) :: x !< Integration variable 00058 type(RFOF_state), intent(inout) :: state !< State of RFOF 00059 integer, intent(out) :: errorFlag !< Error flag 00060 real(8), intent(out) :: diffusion !< diffusion coefficient 00061 end subroutine calc_diffusion_coeff 00062 end interface 00063 00064 !-------------------------------------------------------------------------------- 00065 00066 ! Calculate the diffusion coefficient 00067 call calc_diffusion_coeff(x,state,diffusion,errorFlag) 00068 00069 ! Calculate the length of the kick 00070 ! (here I've just set the random number to one value just; this is only for illustration) 00071 dW = rand_uniform_var0mean1() 00072 dx0 = sqrt(2d0*diffusion*dt)*dW 00073 dx0 = max( 0.1d0*x , min( 2.0d0*x , dx0 )) 00074 x0 = x+dx0 00075 00076 ! Update the diffusion coefficient at the end of the predictor step 00077 call calc_diffusion_coeff(x0,state,diffusion,errorFlag) 00078 00079 ! Update position 00080 dx1 = sqrt(2d0*diffusion*dt)*dW 00081 dx1 = max( -0.9d0*x , min( 0.9d0*x , dx1 )) 00082 x = x+dx1 00083 00084 end subroutine MC_kick_steinbrecher_integrator