window.f90 Source File


This file depends on

sourcefile~~window.f90~~EfferentGraph sourcefile~window.f90 window.f90 sourcefile~grid_param.f90 grid_param.f90 sourcefile~window.f90->sourcefile~grid_param.f90 sourcefile~common_param.f90 common_param.f90 sourcefile~window.f90->sourcefile~common_param.f90 sourcefile~pstruct_data.f90 pstruct_data.f90 sourcefile~window.f90->sourcefile~pstruct_data.f90 sourcefile~mpi_field_interface.f90 mpi_field_interface.f90 sourcefile~window.f90->sourcefile~mpi_field_interface.f90 sourcefile~fstruct_data.f90 fstruct_data.f90 sourcefile~window.f90->sourcefile~fstruct_data.f90 sourcefile~run_data_info.f90 run_data_info.f90 sourcefile~window.f90->sourcefile~run_data_info.f90 sourcefile~mpi_part_interface.f90 mpi_part_interface.f90 sourcefile~window.f90->sourcefile~mpi_part_interface.f90 sourcefile~util.f90 util.f90 sourcefile~window.f90->sourcefile~util.f90 sourcefile~struct_def.f90 struct_def.f90 sourcefile~grid_param.f90->sourcefile~struct_def.f90 sourcefile~precision_def.f90 precision_def.F90 sourcefile~grid_param.f90->sourcefile~precision_def.f90 sourcefile~common_param.f90->sourcefile~precision_def.f90 sourcefile~pstruct_data.f90->sourcefile~struct_def.f90 sourcefile~pstruct_data.f90->sourcefile~precision_def.f90 sourcefile~mpi_field_interface.f90->sourcefile~grid_param.f90 sourcefile~mpi_field_interface.f90->sourcefile~pstruct_data.f90 sourcefile~mpi_field_interface.f90->sourcefile~fstruct_data.f90 sourcefile~parallel.f90 parallel.F90 sourcefile~mpi_field_interface.f90->sourcefile~parallel.f90 sourcefile~fstruct_data.f90->sourcefile~precision_def.f90 sourcefile~run_data_info.f90->sourcefile~grid_param.f90 sourcefile~run_data_info.f90->sourcefile~common_param.f90 sourcefile~run_data_info.f90->sourcefile~pstruct_data.f90 sourcefile~run_data_info.f90->sourcefile~fstruct_data.f90 sourcefile~ionz_data.f90 ionz_data.f90 sourcefile~run_data_info.f90->sourcefile~ionz_data.f90 sourcefile~run_data_info.f90->sourcefile~parallel.f90 sourcefile~phys_param.f90 phys_param.f90 sourcefile~run_data_info.f90->sourcefile~phys_param.f90 sourcefile~code_util.f90 code_util.f90 sourcefile~run_data_info.f90->sourcefile~code_util.f90 sourcefile~control_bunch_input.f90 control_bunch_input.f90 sourcefile~run_data_info.f90->sourcefile~control_bunch_input.f90 sourcefile~mpi_part_interface.f90->sourcefile~grid_param.f90 sourcefile~array_alloc.f90 array_alloc.f90 sourcefile~mpi_part_interface.f90->sourcefile~array_alloc.f90 sourcefile~mpi_part_interface.f90->sourcefile~parallel.f90 sourcefile~mpi_part_interface.f90->sourcefile~code_util.f90 sourcefile~util.f90->sourcefile~precision_def.f90 sourcefile~util.f90->sourcefile~code_util.f90 sourcefile~ionz_data.f90->sourcefile~precision_def.f90 sourcefile~array_alloc.f90->sourcefile~pstruct_data.f90 sourcefile~array_alloc.f90->sourcefile~fstruct_data.f90 sourcefile~struct_def.f90->sourcefile~precision_def.f90 sourcefile~parallel.f90->sourcefile~common_param.f90 sourcefile~parallel.f90->sourcefile~util.f90 sourcefile~mpi_var.f90 mpi_var.f90 sourcefile~parallel.f90->sourcefile~mpi_var.f90 sourcefile~phys_param.f90->sourcefile~precision_def.f90 sourcefile~code_util.f90->sourcefile~precision_def.f90 sourcefile~control_bunch_input.f90->sourcefile~precision_def.f90 sourcefile~mpi_var.f90->sourcefile~precision_def.f90

Files dependent on this one

sourcefile~~window.f90~~AfferentGraph sourcefile~window.f90 window.f90 sourcefile~pic_evolve_in_time.f90 pic_evolve_in_time.f90 sourcefile~pic_evolve_in_time.f90->sourcefile~window.f90 sourcefile~env_evolve_in_time.f90 env_evolve_in_time.f90 sourcefile~env_evolve_in_time.f90->sourcefile~window.f90 sourcefile~aladyn.f90 ALaDyn.F90 sourcefile~aladyn.f90->sourcefile~pic_evolve_in_time.f90 sourcefile~aladyn.f90->sourcefile~env_evolve_in_time.f90

Contents

Source Code


Source Code

!*****************************************************************************************************!
!                            Copyright 2008-2020  The ALaDyn Collaboration                            !
!*****************************************************************************************************!

!*****************************************************************************************************!
!  This file is part of ALaDyn.                                                                       !
!                                                                                                     !
!  ALaDyn is free software: you can redistribute it and/or modify                                     !
!  it under the terms of the GNU General Public License as published by                               !
!  the Free Software Foundation, either version 3 of the License, or                                  !
!  (at your option) any later version.                                                                !
!                                                                                                     !
!  ALaDyn is distributed in the hope that it will be useful,                                          !
!  but WITHOUT ANY WARRANTY; without even the implied warranty of                                     !
!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                      !
!  GNU General Public License for more details.                                                       !
!                                                                                                     !
!  You should have received a copy of the GNU General Public License                                  !
!  along with ALaDyn.  If not, see <http://www.gnu.org/licenses/>.                                    !
!*****************************************************************************************************!

 module window
  use util, only: init_random_seed, gasdev
  use pstruct_data
  use fstruct_data
  use common_param
  use grid_param
  use mpi_field_interface
  use mpi_part_interface
  use run_data_info, only: part_numbers

  implicit none
  !===============================
  ! MOVING WINDOW SECTION
  !=============================
 contains

  subroutine add_particles(np, i1, i2, ic)
   integer, intent(in) :: np, i1, i2, ic
   integer :: n, ix, j, k, j2, k2
   real(dp) :: u, tmp0, whz

   tmp0 = t0_pl(ic)
   n = np
   charge = int(unit_charge(ic), hp_int)
   part_ind = 0
   k2 = loc_nptz(ic)
   j2 = loc_npty(ic)
   if (curr_ndim > 2) then
    do k = 1, k2
     do j = 1, j2
      do ix = i1, i2
       whz = wghpt(ix, ic)*loc_wghyz(j, k, ic)
       wgh = real(whz, sp)
       n = n + 1
       spec(ic)%part(n, 1) = xpt(ix, ic)
       spec(ic)%part(n, 2) = loc_ypt(j, ic)
       spec(ic)%part(n, 3) = loc_zpt(k, ic)
       spec(ic)%part(n, 4:6) = zero_dp
       spec(ic)%part(n, 7) = wgh_cmp
      end do
     end do
    end do
   else
    do j = 1, j2
     do ix = i1, i2
      wgh = real(loc_wghyz(j, 1, ic)*wghpt(ix, ic), sp)
      n = n + 1
      spec(ic)%part(n, 1) = xpt(ix, ic)
      spec(ic)%part(n, 2) = loc_ypt(j, ic)
      spec(ic)%part(n, 3:4) = zero_dp
      spec(ic)%part(n, 5) = wgh_cmp
     end do
    end do
   end if
   if (tmp0 > 0.0) then
    n = np
    call init_random_seed(mype)
    if (curr_ndim > 2) then
     do k = 1, k2
      do j = 1, j2
       do ix = i1, i2
        n = n + 1
        call gasdev(u)
        spec(ic)%part(n, 4) = tmp0*u
        spec(ic)%part(n, 5) = tmp0*u
        spec(ic)%part(n, 6) = tmp0*u
       end do
      end do
     end do
    else
     do j = 1, j2
      do ix = i1, i2
       n = n + 1
       call gasdev(u)
       spec(ic)%part(n, 3) = tmp0*u
       call gasdev(u)
       spec(ic)%part(n, 4) = tmp0*u
      end do
     end do
    end if
   end if
  end subroutine
  !---------------------------
  subroutine particles_inject(xmx)
   real(dp), intent(in) :: xmx
   integer :: ic, ix, npt_inj(4), np_old, np_new
   integer :: i1, i2, n, q
   integer :: j2, k2, ndv
   integer :: j, k

   !========== inject particles from the right
   !   xmx is the box xmax grid value at current time after window move
   !   in Comoving frame xmax is fixed and particles are left advected
   !=================================
   !  nptx(ic) is the max particle index inside the computational box
   !  nptx(ic) is updated in the same way both for moving window xmax
   !  or for left-advect particles with fixed xmax
   !===============================================

   ndv = nd2 + 1
   do ic = 1, nsp
    i1 = 1 + nptx(ic)
    if (i1 <= sptx_max(ic)) then
     !while particle index is less then the max index
     do ix = i1, sptx_max(ic)
      if (xpt(ix, ic) > xmx) exit
     end do
     i2 = ix - 1
     if (ix == sptx_max(ic)) i2 = ix
    else
     i2 = i1 - 1
    end if
    nptx(ic) = i2
    ! endif
    !==========================
    ! Partcles to be injected have index ix [i1,i2]
    !============================
    if (i2 > i1) then
     !==========================
     npt_inj(ic) = 0
     !=========== injects particles with coordinates index i1<= ix <=i2
     select case (ndim)
     case (1)
      do ix = i1, i2
       npt_inj(ic) = npt_inj(ic) + 1
      end do
     case (2)
      j2 = loc_npty(ic)
      do ix = i1, i2
       do j = 1, j2
        npt_inj(ic) = npt_inj(ic) + 1
       end do
      end do
     case (3)
      k2 = loc_nptz(ic)
      j2 = loc_npty(ic)
      do ix = i1, i2
       do k = 1, k2
        do j = 1, j2
         npt_inj(ic) = npt_inj(ic) + 1
        end do
       end do
      end do
     end select
     np_new = 0
     np_old = loc_npart(imody, imodz, imodx, ic)
     np_new = max(np_old + npt_inj(ic), np_new)
     call v_realloc(ebfp, np_new, ndv)
     !=========================
     if (size(spec(ic)%part, ic) < np_new) then
      ebfp(1:np_old, 1:ndv) = spec(ic)%part(1:np_old, 1:ndv)
      deallocate (spec(ic)%part)
      allocate (spec(ic)%part(np_new, ndv))
      spec(ic)%part(1:np_old, 1:ndv) = ebfp(1:np_old, 1:ndv)
     end if
     q = np_old
     call add_particles(q, i1, i2, ic)
     loc_npart(imody, imodz, imodx, ic) = np_new
    end if
   end do
   !=======================
  end subroutine
  !=======================
  subroutine reset_loc_xgrid
   integer :: p, ip, i, ii, n_loc

   p = 0
   n_loc = loc_xgrid(p)%ng
   loc_xg(0, 1, p) = x(1) - dx
   loc_xg(0, 2, p) = xh(1) - dx
   do i = 1, n_loc + 1
    loc_xg(i, 1, p) = x(i)
    loc_xg(i, 2, p) = xh(i)
   end do
   ip = loc_xgrid(0)%ng
   if (npe_xloc > 2) then
    do p = 1, npe_xloc - 2
     n_loc = loc_xgrid(p - 1)%ng
     loc_xg(0, 1:2, p) = loc_xg(n_loc, 1:2, p - 1)
     n_loc = loc_xgrid(p)%ng
     do i = 1, n_loc + 1
      ii = i + ip
      loc_xg(i, 1, p) = x(ii)
      loc_xg(i, 2, p) = xh(ii)
     end do
     loc_xgrid(p)%gmin = loc_xgrid(p - 1)%gmax
     ip = ip + n_loc
     loc_xgrid(p)%gmax = x(ip + 1)
    end do
   end if
   p = npe_xloc - 1
   n_loc = loc_xgrid(p - 1)%ng
   loc_xg(0, 1:2, p) = loc_xg(n_loc, 1:2, p - 1)
   n_loc = loc_xgrid(p)%ng
   do i = 1, n_loc + 1
    ii = i + ip
    loc_xg(i, 1, p) = x(ii)
    loc_xg(i, 2, p) = xh(ii)
   end do
   loc_xgrid(p)%gmin = loc_xgrid(p - 1)%gmax
   ip = ip + n_loc
   loc_xgrid(p)%gmax = x(ip + 1)
  end subroutine
  !========================================
  subroutine comoving_coordinate(vb, w_nst, loc_it)
   real(dp), intent(in) :: vb
   integer, intent(in) :: w_nst, loc_it
   integer :: i, ic, nshx
   real(dp) :: dt_tot, dt_step
   logical, parameter :: mw = .true.
   !======================
   ! In comoving x-coordinate the
   ! [xmin <= x <= xmax] computational box is stationaty
   ! xi= (x-vb*t) => xw is left-advected
   ! fields are left-advected in the x-grid directely in the maxw. equations
   ! particles are left-advected:
   ! xp=xp-vb*dt inside the computational box is added in the eq. of motion and
   ! for moving coordinates at each w_nst steps
   ! xpt(ix,ic)=xpt(ix,ic)-vb*w_nst*dt outside the computational box
   ! then targ_in=targ_in -vb*w_nst*dt   targ_out=targ_out-vb*w_nst*dt
   !
   !==================
   if (loc_it == 0) return
   dt_step = dt_loc
   dt_tot = 0.0
   do i = 1, w_nst
    dt_tot = dt_tot + dt_step
   end do
   nshx = nint(dx_inv*dt_tot*vb) !the number of grid points x-shift for each w_nst step
   do i = 1, nx + 1
    xw(i) = xw(i) - dx*nshx !moves backwards the grid xw
   end do
   xw_max = xw_max - dx*nshx
   xw_min = xw_min - dx*nshx
   !======================== xw(i) grid used only for diagnostics purposes
   targ_in = targ_in - vb*dt_tot
   targ_end = targ_end - vb*dt_tot
   if (.not. part) return
   !===========================
   do ic = 1, nsp !left-advects all particles of the target outside the computational box
    do i = nptx(ic) + 1, sptx_max(ic)
     xpt(i, ic) = xpt(i, ic) - vb*dt_tot
    end do
   end do
   !======================
   call cell_part_dist(mw) !particles are redistributes along the
   if (pex1) then
    if (targ_in <= xmax .and. targ_end > xmax) then
     call particles_inject(xmax)
    end if
   end if
  end subroutine
  !====================================
  subroutine lp_window_xshift(witr, init_iter)
   integer, intent(in) :: witr, init_iter
   integer :: i1, n1p, nc_env
   integer :: ix, nshx, wi2
   real(dp), save :: xlapse, dt_step
   integer, save :: wi1
   logical, parameter :: mw = .true.

   if (init_iter == 0) then
    xlapse = 0.0
    wi1 = 0
    return
   end if
   dt_step = dt_loc
   !==================
   i1 = loc_xgrid(imodx)%p_ind(1)
   n1p = loc_xgrid(imodx)%p_ind(2)
   !======================
   xlapse = xlapse + w_speed*dt_step*witr
   wi2 = nint(dx_inv*xlapse)
   nshx = wi2 - wi1
   wi1 = wi2
   do ix = 1, nx + 1
    x(ix) = x(ix) + dx*nshx
    xh(ix) = xh(ix) + dx*nshx
   end do
   xmin = xmin + dx*nshx
   xmax = xmax + dx*nshx
   xp0_out = xp0_out + dx*nshx
   xp1_out = xp1_out + dx*nshx
   loc_xgrid(imodx)%gmin = loc_xgrid(imodx)%gmin + dx*nshx
   loc_xgrid(imodx)%gmax = loc_xgrid(imodx)%gmax + dx*nshx
   xmn = xmn + dx*nshx
   wi2 = n1p - nshx
   if (wi2 <= 0) then
    write (6, '(a37,3i6)') 'Error in window shifting for MPI proc', &
     imody, imodz, imodx
    ier = 2
    return
   end if
   !===========================
   call fields_left_xshift(ebf, i1, wi2, 1, nfield, nshx)
   if (hybrid) then
    do ix = 1, nxf - nshx
     fluid_x_profile(ix) = fluid_x_profile(ix + nshx)
    end do
    nxf = nxf - nshx
    call fluid_left_xshift(up, fluid_x_profile, fluid_yz_profile, i1, &
                           wi2, 1, nfcomp, nshx)
    call fields_left_xshift(up0, i1, wi2, 1, nfcomp, nshx)
   end if
   if (envelope) then
    nc_env = size(env, 4)
    call fields_left_xshift(env, i1, wi2, 1, nc_env, nshx)
    if (Two_color) call fields_left_xshift(env1, i1, wi2, 1, nc_env, &
                                           nshx)
   end if
   !shifts fields data and inject right ebf(wi2+1:n1p) x-grid nshx new data
   !===========================
   if (part) then
    call cell_part_dist(mw) !particles are redistributes along the
    ! right-shifted x-coordinate in MPI domains
    if (pex1) then
     if (targ_in <= xmax) then
      if (targ_end > xmax) then
       call particles_inject(xmax)
      end if
     end if
    end if
    call part_numbers
   end if
  end subroutine
  !==============================
 end module