37 use num_types,
only: rp
38 use json_module,
only: json_file
39 use json_utils,
only: json_get_or_default, json_get_or_lookup, json_get
40 use utils,
only: neko_error
49 type continuation_parameter_t
50 character(len=:),
allocatable :: name
51 real(rp),
pointer ::
target => null()
52 real(rp),
allocatable :: values(:)
53 integer :: iterations_per_value = 0
55 procedure :: update => continuation_parameter_update
56 procedure :: free => continuation_parameter_free
57 end type continuation_parameter_t
63 type(continuation_parameter_t),
allocatable :: params(:)
64 integer :: default_iterations = 1
66 procedure :: init => init_scheduler
67 procedure :: free => free_scheduler
68 procedure :: json_get_or_register
69 procedure :: register_parameter
71 procedure :: get_param_name
72 procedure :: get_n_params
83 subroutine init_scheduler(this, json)
85 type(json_file),
intent(inout) :: json
88 call json_get_or_default(json, &
89 'optimization.solver.continuation_iterations', n_default, 1)
91 this%default_iterations = n_default
94 if (
allocated(this%params))
deallocate(this%params)
95 end subroutine init_scheduler
98 subroutine free_scheduler(this)
102 if (.not.
allocated(this%params))
return
104 do i = 1,
size(this%params)
105 call this%params(i)%free()
108 deallocate(this%params)
109 end subroutine free_scheduler
123 subroutine json_get_or_register(this, json, name, target, value, &
126 type(json_file),
intent(inout) :: json
127 character(len=*),
intent(in) :: name
128 real(kind=rp),
target,
intent(inout) ::
target
129 real(kind=rp),
intent(out) ::
value
130 real(kind=rp),
intent(in),
optional :: default_value
131 real(kind=rp),
allocatable :: values(:)
132 real(kind=rp) :: scalar_parameter
134 integer :: var_type, iter
137 call json%info(name, found=found, var_type=var_type)
138 if (.not. found)
then
139 if (
present(default_value))
then
140 value = default_value
142 call neko_error(trim(name)//
" not found and no default provided")
144 else if (var_type == 6)
then
145 if (
present(default_value))
then
146 call json_get_or_default(json, name, scalar_parameter, default_value)
148 call json_get(json, name, scalar_parameter)
150 value = scalar_parameter
151 else if (var_type == 3)
then
152 call json_get_or_lookup(json, name, values)
155 call json_get_or_default(json, trim(name)//
'_iterations', iter, &
156 this%default_iterations)
158 call this%register_parameter(name,
target, values, iter)
160 call neko_error(trim(name)//
" can only be real variable or real array!")
163 end subroutine json_get_or_register
166 subroutine register_parameter(this, name, target, values, iterations)
168 character(len=*),
intent(in) :: name
169 real(rp),
target,
intent(inout) :: target
170 real(rp),
intent(in) :: values(:)
171 integer,
optional,
intent(in) :: iterations
173 integer :: n, old_size
174 type(continuation_parameter_t),
allocatable :: tmp(:)
178 if (
present(iterations))
then
179 iter_val = iterations
181 iter_val = this%default_iterations
185 if (.not.
allocated(this%params))
then
186 allocate(this%params(1))
189 old_size =
size(this%params)
190 allocate(tmp(old_size))
192 deallocate(this%params)
193 allocate(this%params(old_size + 1))
194 this%params(1:old_size) = tmp
199 this%params(n)%name = name
200 this%params(n)%target =>
target
201 allocate(this%params(n)%values(
size(values)))
202 this%params(n)%values = values
203 this%params(n)%iterations_per_value = iter_val
204 end subroutine register_parameter
207 subroutine update(this, iter)
209 integer,
intent(in) :: iter
212 if (.not.
allocated(this%params))
return
214 do i = 1,
size(this%params)
215 call this%params(i)%update(iter)
217 end subroutine update
220 character(len=32) function get_param_name(this, i)
222 integer,
intent(in) :: i
225 if (.not.
allocated(this%params))
return
226 if (i < 1 .or. i >
size(this%params))
return
227 get_param_name = this%params(i)%name
228 end function get_param_name
231 function get_n_params(this)
result(n)
234 if (
allocated(this%params))
then
235 n =
size(this%params)
239 end function get_n_params
242 subroutine continuation_parameter_update(this, iter)
243 class(continuation_parameter_t),
intent(inout) :: this
244 integer,
intent(in) :: iter
247 if (.not.
allocated(this%values))
return
248 if (this%iterations_per_value <= 0)
return
250 idx = (iter - 1) / this%iterations_per_value + 1
251 idx = min(idx,
size(this%values))
253 this%target = this%values(idx)
254 end subroutine continuation_parameter_update
257 subroutine continuation_parameter_free(this)
258 class(continuation_parameter_t),
intent(inout) :: this
259 if (
allocated(this%name))
deallocate(this%name)
260 if (
allocated(this%values))
deallocate(this%values)
262 end subroutine continuation_parameter_free
Continuation scheduler for the optimization loop.