module mod_grid_settings
use mod_global_variables, only: dp, n_gauss
implicit none
private
type, public :: grid_settings_t
character(:), private, allocatable :: geometry
integer, private :: gridpts
integer, private :: gauss_gridpts
integer, private :: ef_gridpts
real(dp), private :: grid_start
real(dp), private :: grid_end
logical :: coaxial
logical :: force_r0
logical :: symmetric_grid
contains
procedure, public :: set_geometry
procedure, public :: get_geometry
procedure, public :: set_gridpts
procedure, public :: get_gridpts
procedure, public :: get_gauss_gridpts
procedure, public :: get_ef_gridpts
procedure, public :: set_grid_boundaries
procedure, public :: get_grid_start
procedure, public :: get_grid_end
procedure, public :: delete
procedure, private :: validate_grid_start
end type grid_settings_t
public :: new_grid_settings
contains
function new_grid_settings() result(grid_settings)
type(grid_settings_t) :: grid_settings
call grid_settings%set_geometry("Cartesian")
call grid_settings%set_gridpts(50)
call grid_settings%set_grid_boundaries(0.0_dp, 1.0_dp)
grid_settings%coaxial = .false.
grid_settings%force_r0 = .false.
grid_settings%symmetric_grid = .false.
end function new_grid_settings
pure subroutine set_geometry(this, geometry)
class(grid_settings_t), intent(inout) :: this
character(len=*), intent(in) :: geometry
this%geometry = geometry
end subroutine set_geometry
pure function get_geometry(this) result(geometry)
class(grid_settings_t), intent(in) :: this
character(len=:), allocatable :: geometry
geometry = trim(adjustl(this%geometry))
end function get_geometry
pure subroutine set_gridpts(this, gridpts)
class(grid_settings_t), intent(inout) :: this
integer, intent(in) :: gridpts
this%gridpts = gridpts
this%gauss_gridpts = n_gauss * (gridpts - 1)
this%ef_gridpts = 2 * gridpts - 1
end subroutine set_gridpts
pure integer function get_gridpts(this)
class(grid_settings_t), intent(in) :: this
get_gridpts = this%gridpts
end function get_gridpts
pure integer function get_gauss_gridpts(this)
class(grid_settings_t), intent(in) :: this
get_gauss_gridpts = this%gauss_gridpts
end function get_gauss_gridpts
pure integer function get_ef_gridpts(this)
class(grid_settings_t), intent(in) :: this
get_ef_gridpts = this%ef_gridpts
end function get_ef_gridpts
subroutine set_grid_boundaries(this, grid_start, grid_end)
class(grid_settings_t), intent(inout) :: this
real(dp), intent(in) :: grid_start
real(dp), intent(in) :: grid_end
this%grid_start = grid_start
if (this%get_geometry() == "cylindrical") call this%validate_grid_start()
this%grid_end = grid_end
end subroutine set_grid_boundaries
pure real(dp) function get_grid_start(this)
class(grid_settings_t), intent(in) :: this
get_grid_start = this%grid_start
end function get_grid_start
pure real(dp) function get_grid_end(this)
class(grid_settings_t), intent(in) :: this
get_grid_end = this%grid_end
end function get_grid_end
subroutine validate_grid_start(this)
use mod_check_values, only: is_zero
use mod_logging, only: logger
class(grid_settings_t), intent(inout) :: this
if (this%grid_start < 0.0_dp) then
call logger%error("grid start must be >= 0 in cylindrical geometry")
return
end if
if (this%coaxial .and. is_zero(this%grid_start)) then
call logger%error("grid start must be > 0 to introduce an inner wall boundary")
return
end if
if (this%force_r0) then
this%grid_start = 0.0_dp
call logger%warning( &
"forcing on-axis r in cylindrical geometry, may lead to spurious eigenvalues" &
)
else if (is_zero(this%grid_start)) then
this%grid_start = 0.025_dp
call logger%info( &
"grid start set to 0.025 to avoid on-axis singularity. " // &
"Set 'force_r0 = .true.' to force r=0. " &
)
end if
end subroutine validate_grid_start
pure subroutine delete(this)
class(grid_settings_t), intent(inout) :: this
if (allocated(this%geometry)) deallocate(this%geometry)
end subroutine delete
end module mod_grid_settings