grid_storage.F90 Source File


This file depends on

sourcefile~~grid_storage.f90~~EfferentGraph sourcefile~grid_storage.f90 grid_storage.F90 sourcefile~precision.f90 precision.F90 sourcefile~grid_storage.f90->sourcefile~precision.f90

Files dependent on this one

sourcefile~~grid_storage.f90~~AfferentGraph sourcefile~grid_storage.f90 grid_storage.F90 sourcefile~dft.f90 dft.F90 sourcefile~dft.f90->sourcefile~grid_storage.f90 sourcefile~dft_fuzzycell.f90 dft_fuzzycell.F90 sourcefile~dft.f90->sourcefile~dft_fuzzycell.f90 sourcefile~dft_molgrid.f90 dft_molgrid.F90 sourcefile~dft.f90->sourcefile~dft_molgrid.f90 sourcefile~dft_gridint_energy.f90 dft_gridint_energy.F90 sourcefile~dft.f90->sourcefile~dft_gridint_energy.f90 sourcefile~dft_gridint_grad.f90 dft_gridint_grad.F90 sourcefile~dft.f90->sourcefile~dft_gridint_grad.f90 sourcefile~dft_fuzzycell.f90->sourcefile~grid_storage.f90 sourcefile~dft_fuzzycell.f90->sourcefile~dft_molgrid.f90 sourcefile~dft_molgrid.f90->sourcefile~grid_storage.f90 sourcefile~dft_gridint.f90 dft_gridint.F90 sourcefile~dft_gridint.f90->sourcefile~dft_molgrid.f90 sourcefile~dft_gridint_energy.f90->sourcefile~dft_molgrid.f90 sourcefile~dft_gridint_energy.f90->sourcefile~dft_gridint.f90 sourcefile~dft_gridint_fxc.f90 dft_gridint_fxc.F90 sourcefile~dft_gridint_fxc.f90->sourcefile~dft_molgrid.f90 sourcefile~dft_gridint_fxc.f90->sourcefile~dft_gridint.f90 sourcefile~dft_gridint_grad.f90->sourcefile~dft_molgrid.f90 sourcefile~dft_gridint_grad.f90->sourcefile~dft_gridint.f90 sourcefile~dft_gridint_gxc.f90 dft_gridint_gxc.F90 sourcefile~dft_gridint_gxc.f90->sourcefile~dft_molgrid.f90 sourcefile~dft_gridint_gxc.f90->sourcefile~dft_gridint.f90 sourcefile~dft_gridint_gxc.f90->sourcefile~dft_gridint_fxc.f90 sourcefile~dft_gridint_tdxc_grad.f90 dft_gridint_tdxc_grad.F90 sourcefile~dft_gridint_tdxc_grad.f90->sourcefile~dft_molgrid.f90 sourcefile~dft_gridint_tdxc_grad.f90->sourcefile~dft_gridint.f90 sourcefile~grd2.f90 grd2.F90 sourcefile~grd2.f90->sourcefile~dft_molgrid.f90 sourcefile~hf_energy.f90 hf_energy.f90 sourcefile~hf_energy.f90->sourcefile~dft.f90 sourcefile~hf_energy.f90->sourcefile~dft_molgrid.f90 sourcefile~scf.f90 scf.F90 sourcefile~hf_energy.f90->sourcefile~scf.f90 sourcefile~hf_gradient.f90 hf_gradient.F90 sourcefile~hf_gradient.f90->sourcefile~dft.f90 sourcefile~hf_gradient.f90->sourcefile~dft_molgrid.f90 sourcefile~hf_gradient.f90->sourcefile~grd2.f90 sourcefile~scf.f90->sourcefile~dft.f90 sourcefile~scf.f90->sourcefile~dft_molgrid.f90 sourcefile~tdhf_energy.f90 tdhf_energy.F90 sourcefile~tdhf_energy.f90->sourcefile~dft.f90 sourcefile~tdhf_energy.f90->sourcefile~dft_molgrid.f90 sourcefile~tdhf_energy.f90->sourcefile~dft_gridint_fxc.f90 sourcefile~tdhf_gradient.f90 tdhf_gradient.F90 sourcefile~tdhf_gradient.f90->sourcefile~dft.f90 sourcefile~tdhf_gradient.f90->sourcefile~dft_molgrid.f90 sourcefile~tdhf_gradient.f90->sourcefile~dft_gridint_tdxc_grad.f90 sourcefile~tdhf_gradient.f90->sourcefile~grd2.f90 sourcefile~tdhf_z_vector.f90 tdhf_z_vector.F90 sourcefile~tdhf_z_vector.f90->sourcefile~dft.f90 sourcefile~tdhf_z_vector.f90->sourcefile~dft_molgrid.f90 sourcefile~tdhf_z_vector.f90->sourcefile~dft_gridint_fxc.f90 sourcefile~tdhf_z_vector.f90->sourcefile~dft_gridint_gxc.f90

Source Code

!> @brief Module to store data of DFT atomic quadratures
!> @author Vladimir Mironov
module mod_grid_storage

  use precision, only: fp
  implicit none

!*******************************************************************************

!> @brief Type to store 3D quadrature grid
!> @author Vladimir Mironov
  type :: grid_3d_t
    !< X coordinates
    real(KIND=fp), allocatable :: x(:)
    !< Y coordinates
    real(KIND=fp), allocatable :: y(:)
    !< Z coordinates
    real(KIND=fp), allocatable :: z(:)
    !< quadrature weights
    real(KIND=fp), allocatable :: w(:)
    !< number of points
    integer :: nPts = 0
    !< grid array index, used for reverse search
    integer :: idGrid = 0
    !< tesselation data: (number or points per zone, tesselation degree)
    integer(KIND=2), allocatable :: izones(:, :)
  contains
    procedure, pass :: set => setGrid
    procedure, pass :: get => getGrid
    procedure, pass :: check => checkGrid
    procedure, pass :: clear => clearGrid
  end type

!*******************************************************************************

!> @brief Pointer to 3D grid container (to be used in arrays)
!> @author Vladimir Mironov
  type :: grid_3d_pt
    type(grid_3d_t), pointer :: p
  end type

!*******************************************************************************

!> @brief Basic array list type to store 3d grids
!> @note DO not use any method except `p => list%get`
!>  in a performance-critical loop!
!> @author Vladimir Mironov
  type :: list_grid_3d_t
    private
    !< Current number of grids stored
    integer, public :: nGrids = 0
    !< Maximum number of grids
    integer :: maxGrids = 0
    !< Grid data
    type(grid_3d_pt), allocatable :: elem(:)
  contains
    procedure, non_overridable :: get_pts => get_grid_pts
    procedure, non_overridable :: set_pts => set_grid_pts
    procedure, non_overridable :: findID => findIDListGrid
    procedure, non_overridable :: getByID => getByIDListGrid
    procedure, non_overridable :: push => pushListGrid
    procedure, non_overridable :: pop => popListGrid

    procedure :: get => getListGrid
    procedure :: set => setListGrid
    procedure :: init => initListGrid
    procedure :: clear => clearListGrid
    procedure :: delete => deleteListGrid
    procedure, private :: extend => extendListGrid
  end type

  type :: atomic_grid_t
    type(list_grid_3d_t), pointer :: spherical_grids
    integer, allocatable       :: sph_npts(:)
    integer                    :: idAtm
    real(kind=fp)              :: rAtm
    real(KIND=fp), allocatable :: sph_radii(:)
    real(KIND=fp), allocatable :: rad_pts(:)
    real(KIND=fp), allocatable :: rad_wts(:)
  end type

  integer, parameter :: DEFAULT_GRID_CHUNK = 32

!*******************************************************************************
  private

  public grid_3d_t
  public grid_3d_pt
  public list_grid_3d_t
  public atomic_grid_t

contains

!*******************************************************************************

!-------------------------------------------------------------------------------

!> @brief Get angular grid data
!> @param[in]   npts  number of points
!> @param[out]  x        x coordinates
!> @param[out]  y        y coordinates
!> @param[out]  z        z coordinates
!> @param[out]  w        weights
!> @param[out]  izones   tesselation data
!> @param[out]  found    whether the grid was found in the dataset
!> @author Vladimir Mironov
  subroutine get_grid_pts(grids, npts, x, y, z, w, izones, found)
    class(list_grid_3d_t) :: grids
    integer, intent(OUT) :: izones(:, :)
    real(KIND=fp), intent(OUT) :: x(:), y(:), z(:), w(:)
    integer, intent(IN) :: npts
    logical, intent(OUT) :: found
    type(grid_3d_t), pointer :: tmp

    tmp => grids%get(npts)
    found = associated(tmp)

    if (found) then
      x = tmp%x
      y = tmp%y
      z = tmp%z
      w = tmp%w
      izones = tmp%izones
    end if

  end subroutine

!-------------------------------------------------------------------------------

!> @brief Set angular grid data
!> @param[in]  npts  number of points
!> @param[in]  x        x coordinates
!> @param[in]  y        y coordinates
!> @param[in]  z        z coordinates
!> @param[in]  w        weights
!> @param[in]  izones   tesselation data
!> @author Vladimir Mironov
  subroutine set_grid_pts(grids, npts, x, y, z, w, izones)
    class(list_grid_3d_t) :: grids
    real(KIND=fp), intent(IN) :: x(:), y(:), z(:), w(:)
    integer, intent(IN) :: izones(:, :)
    integer, intent(IN) :: npts
    type(grid_3d_t), pointer :: tmp
    !TYPE(grid_3d_t) :: grid
    !CALL grid%set(npts,x,y,z,w,izones)
    !tmp => grids%set(grid)
    tmp => grids%set(grid_3d_t(x=x, y=y, z=z, w=w, &
                                    npts=npts, izones=int(izones,2)))
  end subroutine

!*******************************************************************************

!> @brief Get a pointer to a grid stored in a list
!> @param[in]  npts  number of points
!> @author Vladimir Mironov
  function getListGrid(list, npts) result(res)
    class(list_grid_3d_t), target, intent(IN) :: list
    type(grid_3d_t), pointer :: res

    integer, intent(IN) :: npts
    integer :: i
    logical :: found

    found = .false.

    do i = 1, list%nGrids
      res => list%elem(i)%p
      found = res%check(npts)
      if (found) exit
    end do

    if (.not. found) res => null()

  end function getListGrid

!-------------------------------------------------------------------------------

!> @brief Get index of a grid stored in a list
!> @param[in]  npts  number of points
!> @author Vladimir Mironov
  function findIDListGrid(list, npts) result(id)
    class(list_grid_3d_t), target, intent(IN) :: list
    integer :: id

    integer, intent(IN) :: npts
    logical :: found

    found = .false.

    do id = 1, list%nGrids
      found = list%elem(id)%p%check(npts)
      if (found) exit
    end do

    if (.not. found) id = 0

  end function findIDListGrid

!-------------------------------------------------------------------------------

!> @brief Get a pointer to a grid stored in a list by its index
!> @param[in]  id    grid index
!> @author Vladimir Mironov
  function getByIDListGrid(list, id) result(res)
    class(list_grid_3d_t), target, intent(IN) :: list
    type(grid_3d_t), pointer :: res
    integer, intent(IN) :: id

    res => null()
    if (id >= 1 .and. id <= list%nGrids) res => list%elem(id)%p

  end function getByIDListGrid

!-------------------------------------------------------------------------------

!> @brief Set a grid in the list. Return a pointer to the list entry.
!> @param[in]  grid  grid data
!> @author Vladimir Mironov
  function setListGrid(list, grid) result(ptr)
    class(list_grid_3d_t), intent(INOUT) :: list
    type(grid_3d_t), intent(IN) :: grid
    type(grid_3d_t), pointer :: ptr

    ptr => list%get(grid%npts)

    if (associated(ptr)) then
      ptr = grid
    else
      ptr => list%push(grid)
    end if

  end function setListGrid

!-------------------------------------------------------------------------------

!> @brief Add a new grid to the list. Return a pointer to the list entry.
!> @param[in]  grid  grid data
!> @author Vladimir Mironov
  function pushListGrid(list, grid) result(ptr)
    class(list_grid_3d_t), intent(INOUT) :: list
    type(grid_3d_t), intent(IN) :: grid
    type(grid_3d_t), pointer :: ptr

    if (list%nGrids == list%maxGrids) call list%extend

    list%nGrids = list%nGrids+1
    allocate (list%elem(list%nGrids)%p)!, source=grid)
    list%elem(list%nGrids)%p = grid

    ptr => list%elem(list%nGrids)%p

    ptr%idGrid = list%nGrids

  end function pushListGrid

!-------------------------------------------------------------------------------

!> @brief Pop a grid from the top of the list.
!> @author Vladimir Mironov
  function popListGrid(list) result(grid)
    class(list_grid_3d_t), target, intent(INOUT) :: list
    type(grid_3d_t) :: grid

    if (list%nGrids /= 0) then
      grid = list%elem(list%nGrids)%p
      deallocate (list%elem(list%nGrids)%p)
      list%nGrids = list%nGrids-1
    end if

  end function popListGrid

!-------------------------------------------------------------------------------

!> @brief Initialize grid list, possibly specifying its size
!> @param[in]  iSize   desired list size
!> @author Vladimir Mironov
  subroutine initListGrid(list, iSize)
    class(list_grid_3d_t) :: list
    integer, optional, intent(IN) :: iSize
    integer :: isz

    isz = DEFAULT_GRID_CHUNK
    if (present(iSize)) isz = iSize

    if (allocated(list%elem)) then
      call list%clear
      if (list%maxGrids < isz) then
        deallocate (list%elem)
      end if
    end if

    if (.not. allocated(list%elem)) then
      allocate (list%elem(isz))
    end if

    list%nGrids = 0
    list%maxGrids = max(isz, list%maxGrids)

  end subroutine initListGrid

!-------------------------------------------------------------------------------

!> @brief Clear grid list
!> @author Vladimir Mironov
  subroutine clearListGrid(list)
    class(list_grid_3d_t) :: list
    integer :: i
    do i = 1, list%nGrids
      if (associated(list%elem(i)%p)) deallocate (list%elem(i)%p)
    end do
    list%nGrids = 0
  end subroutine clearListGrid

!-------------------------------------------------------------------------------

!> @brief Destroy grid list
!> @author Vladimir Mironov
  subroutine deleteListGrid(list)
    class(list_grid_3d_t) :: list
    call list%clear
    deallocate (list%elem)
    list%maxGrids = 0
  end subroutine deleteListGrid

!-------------------------------------------------------------------------------

!> @brief Extend grid list to a new size
!> @param[in] iSize  size to extend the list
!> @author Vladimir Mironov
  subroutine extendListGrid(list, iSize)
    class(list_grid_3d_t), intent(INOUT) :: list
    type(grid_3d_pt), allocatable :: elem_new(:)

    integer, optional, intent(IN) :: iSize
    integer :: isz

    isz = DEFAULT_GRID_CHUNK
    if (present(iSize)) isz = iSize

    allocate (elem_new(list%maxGrids+isz), source=list%elem)
    call move_alloc(from=elem_new, to=list%elem)
    list%maxGrids = list%maxGrids+isz

  end subroutine

!*******************************************************************************

!> @brief Set 3D grid data
!> @param[in]  npts  number of points
!> @param[in]  x        x coordinates
!> @param[in]  y        y coordinates
!> @param[in]  z        z coordinates
!> @param[in]  w        weights
!> @param[in]  izones   tesselation data
!> @author Vladimir Mironov
  subroutine setGrid(grid, npts, x, y, z, w, izones)
    class(grid_3d_t), intent(INOUT) :: grid
    real(KIND=fp), intent(IN) :: x(:), y(:), z(:), w(:)
    integer, intent(IN) :: izones(:, :)
    integer, intent(IN) :: npts

    grid%npts = npts
    grid%x = x
    grid%y = y
    grid%z = z
    grid%w = w
    grid%izones = int(izones, kind=2)

  end subroutine setGrid

!-------------------------------------------------------------------------------

!> @brief Get 3D grid data
!> @param[in]   npts  number of points
!> @param[out]  x        x coordinates
!> @param[out]  y        y coordinates
!> @param[out]  z        z coordinates
!> @param[out]  w        weights
!> @param[out]  izones   tesselation data
!> @author Vladimir Mironov
  subroutine getGrid(grid, npts, x, y, z, w, izones)
    class(grid_3d_t), intent(IN) :: grid
    real(KIND=fp), intent(OUT) :: x(:), y(:), z(:), w(:)
    integer, intent(OUT) :: izones(:, :)
    integer, intent(OUT) :: npts

    npts = grid%npts
    x = grid%x
    y = grid%y
    z = grid%z
    w = grid%w
    izones = grid%izones

  end subroutine getGrid

!-------------------------------------------------------------------------------

!> @brief Check if it is the grid you are looking for.
!> @param[in]   npts  number of points
!> @author Vladimir Mironov
  function checkGrid(grid, npts) result(ok)
    class(grid_3d_t) :: grid
    integer, intent(IN) :: npts
    logical :: ok
    ok = .false.
    if (grid%npts == npts) ok = .true.
  end function checkGrid

!-------------------------------------------------------------------------------

!> @brief Destroy grid
!> @author Vladimir Mironov
  subroutine clearGrid(grid)
    class(grid_3d_t), intent(INOUT) :: grid
    grid%npts = 0
    deallocate (grid%x, grid%y, grid%z, grid%w)
    deallocate (grid%izones)
  end subroutine clearGrid

!-------------------------------------------------------------------------------

end module mod_grid_storage