module classes_changed_box_size use, intrinsic :: iso_fortran_env, only: DP => REAL64 use data_constants, only: num_dimensions use procedures_checks, only: check_positive, check_increase_factor use classes_tunable_move, only: Abstract_Tunable_Move use classes_changed_box_size_ratio, only: Abstract_Changed_Box_Size_Ratio use module_move_tuning, only: Concrete_Move_Tuning_Parameters, set_increase_factor implicit none private type, extends(Abstract_Tunable_Move), abstract, public :: Abstract_Changed_Box_Size private real(DP) :: frequency_ratio = 0._DP class(Abstract_Changed_Box_Size_Ratio), allocatable :: ratio type(Concrete_Move_Tuning_Parameters) :: tuning_parameters real(DP) :: current_increase_factor = 1._DP logical :: max_factor_reached = .false. contains procedure :: construct => Abstract_construct procedure :: destroy => Abstract_destroy procedure :: get_frequency_ratio => Abstract_get_frequency_ratio procedure :: get_ratio => Abstract_get_ratio procedure :: increase_delta => Abstract_increase_delta procedure :: decrease_delta => Abstract_decrease_delta end type Abstract_Changed_Box_Size type, extends(Abstract_Changed_Box_Size), public :: Concrete_Changed_Box_Size end type Concrete_Changed_Box_Size type, extends(Abstract_Changed_Box_Size), public :: Null_Changed_Box_Size contains procedure :: construct => Null_construct procedure :: destroy => Null_destroy procedure :: get_frequency_ratio => Null_get_frequency_ratio procedure :: get_ratio => Null_get_ratio procedure :: increase_delta => Null_increase_delta procedure :: decrease_delta => Null_decrease_delta end type Null_Changed_Box_Size contains !implementation Abstract_Changed_Box_Size subroutine Abstract_construct(this, frequency_ratio, ratio, tuning_parameters) class(Abstract_Changed_Box_Size), intent(out) :: this real(DP), intent(in) :: frequency_ratio class(Abstract_Changed_Box_Size_Ratio), intent(in) :: ratio type(Concrete_Move_Tuning_Parameters), intent(in) :: tuning_parameters call check_positive("Abstract_Changed_Box_Size: construct", "frequency_ratio", & frequency_ratio) this%frequency_ratio = frequency_ratio allocate(this%ratio, source=ratio) call check_increase_factor("Abstract_Changed_Box_Size: construct", "increase_factor", & tuning_parameters%increase_factor) this%tuning_parameters%increase_factor = tuning_parameters%increase_factor this%current_increase_factor = this%tuning_parameters%increase_factor call check_increase_factor("Abstract_Changed_Box_Size: construct", & "increase_factor_max", tuning_parameters%increase_factor_max) this%tuning_parameters%increase_factor_max = tuning_parameters%increase_factor_max end subroutine Abstract_construct subroutine Abstract_destroy(this) class(Abstract_Changed_Box_Size), intent(inout) :: this if (allocated(this%ratio)) deallocate(this%ratio) end subroutine Abstract_destroy pure real(DP) function Abstract_get_frequency_ratio(this) result(frequency_ratio) class(Abstract_Changed_Box_Size), intent(in) :: this frequency_ratio = this%frequency_ratio end function Abstract_get_frequency_ratio function Abstract_get_ratio(this) result(ratio) real(DP) :: ratio(num_dimensions) class(Abstract_Changed_Box_Size), intent(in) :: this ratio = this%ratio%get() end function Abstract_get_ratio subroutine Abstract_increase_delta(this) class(Abstract_Changed_Box_Size), intent(inout) :: this if (this%max_factor_reached) return call set_increase_factor("Abstract_Changed_Box_Size", this%current_increase_factor, & this%tuning_parameters, this%max_factor_reached) call this%ratio%set(this%current_increase_factor * this%ratio%get_delta()) end subroutine Abstract_increase_delta subroutine Abstract_decrease_delta(this) class(Abstract_Changed_Box_Size), intent(inout) :: this call this%ratio%set(this%ratio%get_delta() / this%current_increase_factor) end subroutine Abstract_decrease_delta !end implementation Abstract_Changed_Box_Size !implementation Null_Changed_Box_Size subroutine Null_construct(this, frequency_ratio, ratio, tuning_parameters) class(Null_Changed_Box_Size), intent(out) :: this real(DP), intent(in) :: frequency_ratio class(Abstract_Changed_Box_Size_Ratio), intent(in) :: ratio type(Concrete_Move_Tuning_Parameters), intent(in) :: tuning_parameters end subroutine Null_construct subroutine Null_destroy(this) class(Null_Changed_Box_Size), intent(inout) :: this end subroutine Null_destroy pure real(DP) function Null_get_frequency_ratio(this) result(frequency_ratio) class(Null_Changed_Box_Size), intent(in) :: this frequency_ratio = 0._DP end function Null_get_frequency_ratio function Null_get_ratio(this) result(ratio) real(DP) :: ratio(num_dimensions) class(Null_Changed_Box_Size), intent(in) :: this ratio = 1._DP end function Null_get_ratio subroutine Null_increase_delta(this) class(Null_Changed_Box_Size), intent(inout) :: this end subroutine Null_increase_delta subroutine Null_decrease_delta(this) class(Null_Changed_Box_Size), intent(inout) :: this end subroutine Null_decrease_delta !end implementation Null_Changed_Box_Size end module classes_changed_box_size