97#include "./base/base_uses.f90"
102 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .true.
103 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'generic_function_input'
105 CHARACTER(len=*),
PARAMETER,
PRIVATE :: name_kw_dx =
"DX", &
106 name_kw_error =
"ERROR_LIMIT", &
107 name_kw_parameters =
"PARAMETERS", &
108 name_kw_units =
"UNITS", &
109 name_kw_values =
"VALUES", &
110 name_kw_variables =
"VARIABLES"
129 repeats, do_deriv, input_variables)
131 CHARACTER(LEN=*),
INTENT(IN) :: section_name, func_name, description
132 LOGICAL,
INTENT(IN),
OPTIONAL :: repeats, do_deriv
133 CHARACTER(LEN=*),
DIMENSION(:),
INTENT(IN), &
134 OPTIONAL :: input_variables
136 CHARACTER(LEN=*),
PARAMETER :: default_values_unit_str =
"internal_cp2k"
138 CHARACTER(LEN=:),
ALLOCATABLE :: input_variables_info, my_description
139 CHARACTER(LEN=default_string_length) :: length, my_size_default, my_size_var
141 LOGICAL :: has_kw_variables, my_do_deriv, my_repeats
145 IF (
PRESENT(repeats)) my_repeats = repeats
146 my_do_deriv = .false.
147 IF (
PRESENT(do_deriv)) my_do_deriv = do_deriv
148 has_kw_variables = .false.
149 my_description = trim(description)
154 IF (
PRESENT(input_variables))
THEN
155 has_kw_variables = .true.
156 mydim =
SIZE(input_variables)
158 input_variables_info =
"The following "//trim(my_size_var)//
" symbol(s) will be reserved "// &
159 "as the variable(s) to be substituted for internal evaluation: "
160 DO i = 1,
SIZE(input_variables)
161 input_variables_info = input_variables_info//
"`"//trim(input_variables(i))//
"`"
162 IF (i <
SIZE(input_variables))
THEN
163 input_variables_info = input_variables_info//
", "
165 input_variables_info = input_variables_info//
". "
168 input_variables_info = input_variables_info//
"They cannot be used as parameters."
169 my_description = my_description//
newline//
newline//input_variables_info
173 cpassert(.NOT.
ASSOCIATED(gen_section))
175 CALL section_create(gen_section, __location__, name=trim(section_name), &
176 description=my_description, &
177 n_keywords=0, n_subsections=0, repeats=my_repeats)
179 CALL keyword_create(keyword, __location__, name=trim(func_name), &
180 description=
"Specifies a functional form. The maximum length "// &
181 "is "//trim(adjustl(length))//
" characters. "//
docf(), &
182 usage=trim(func_name)//
" A*X+B*(2/(1+EXP(-0.001*Y))-1)", &
187 CALL keyword_create(keyword, __location__, name=name_kw_parameters, &
188 description=
"Defines the symbols for the parameter(s) in the functional "// &
189 "form, delimited by whitespaces. Symbols are case sensitive and each is "// &
190 "at most "//trim(my_size_default)//
" characters long.", &
191 usage=name_kw_parameters//
" A B", type_of_var=
char_t, &
192 n_var=-1, repeats=.true.)
197 description=
"Optionally, defines CP2K unit string for each of the given "// &
198 "parameter value(s). A valid CP2K unit string is one of the strings that "// &
199 "is listed under the References/Units section of the CP2K manual, or a "// &
200 "combination of multiple of these strings with `*`, `/` and `^`. It is "// &
201 "assumed that the corresponding parameter value is specified in this unit "// &
202 "which needs to be converted first to the internal unit during input parsing. "// &
203 "Note that the meaningfulness of the unit is not checked. If omitted, all "// &
204 "values will be treated as already in the internal unit and used literally.", &
205 usage=name_kw_units//
" eV*angstrom^-1 angstrom", type_of_var=
char_t, &
206 n_var=-1, repeats=.true.)
211 description=
"Defines the value(s) of the parameter in the functional form.", &
212 usage=name_kw_values//
" 50 1.0E+2", type_of_var=
real_t, &
213 n_var=-1, repeats=.true., unit_str=default_values_unit_str)
217 IF (.NOT. has_kw_variables)
THEN
218 CALL keyword_create(keyword, __location__, name=name_kw_variables, &
219 description=
"Defines the symbols for the variable(s) in the functional "// &
220 "form, delimited by whitespaces. Symbols are case sensitive and each is "// &
221 "at most "//trim(my_size_default)//
" characters long.", &
222 usage=name_kw_variables//
" X Y", type_of_var=
char_t, &
228 IF (my_do_deriv)
THEN
230 description=
"Parameter used for computing the derivative with the Ridders' method.", &
231 usage=name_kw_dx//
" <REAL>", default_r_val=0.1_dp, unit_str=
"bohr")
236 description=
"Checks that the error in computing the derivative is not larger than "// &
237 "the value set; in case error is larger a warning message is printed.", &
238 usage=name_kw_error//
" <REAL>", default_r_val=1.0e-12_dp)
261 var_values, i_rep_sec, input_variables, dx, error_limit)
263 CHARACTER(LEN=*),
INTENT(IN) :: func_name
264 CHARACTER(LEN=default_path_length),
INTENT(OUT) :: xfunction
265 CHARACTER(LEN=default_string_length), &
266 ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: parameters
267 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:), &
268 INTENT(OUT) :: values
269 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN),
OPTIONAL :: var_values
270 INTEGER,
INTENT(IN),
OPTIONAL :: i_rep_sec
271 CHARACTER(LEN=*),
DIMENSION(:),
INTENT(IN), &
272 OPTIONAL :: input_variables
273 REAL(kind=
dp),
INTENT(OUT),
OPTIONAL :: dx, error_limit
275 CHARACTER(LEN=default_string_length), &
276 DIMENSION(:),
POINTER :: my_par, my_par_tmp, my_units, &
278 INTEGER :: i, ind, irep, isize, j, mydim, n_par, &
279 n_units, n_val, nblank
281 REAL(kind=
dp),
DIMENSION(:),
POINTER :: my_val, my_val_tmp
283 NULLIFY (my_var, my_par, my_val, my_par_tmp, my_val_tmp)
285 NULLIFY (my_units_tmp)
287 IF (
PRESENT(i_rep_sec)) irep = i_rep_sec
290 CALL compress(xfunction, full=.true.)
291 IF (
PRESENT(dx))
THEN
294 IF (
PRESENT(error_limit))
THEN
297 IF (
PRESENT(input_variables))
THEN
298 ALLOCATE (my_var(
SIZE(input_variables)))
299 my_var = input_variables
303 IF (
ASSOCIATED(my_var))
THEN
309 check = (n_par > 0) .EQV. (n_val > 0)
318 CALL section_vals_val_get(gen_section, name_kw_parameters, i_rep_section=irep, i_rep_val=i, c_vals=my_par_tmp)
319 nblank = count(my_par_tmp ==
"")
320 CALL reallocate(my_par, 1, isize +
SIZE(my_par_tmp) - nblank)
322 DO j = 1,
SIZE(my_par_tmp)
323 IF (my_par_tmp(j) ==
"") cycle
325 my_par(isize + ind) = my_par_tmp(j)
330 CALL section_vals_val_get(gen_section, name_kw_values, i_rep_section=irep, i_rep_val=i, r_vals=my_val_tmp)
331 CALL reallocate(my_val, 1, isize +
SIZE(my_val_tmp))
332 my_val(isize + 1:isize +
SIZE(my_val_tmp)) = my_val_tmp
334 cpassert(
SIZE(my_par) ==
SIZE(my_val))
336 ALLOCATE (my_units(0))
337 IF (n_units > 0)
THEN
339 isize =
SIZE(my_units)
340 CALL section_vals_val_get(gen_section, name_kw_units, i_rep_section=irep, i_rep_val=i, c_vals=my_units_tmp)
341 nblank = count(my_units_tmp ==
"")
342 CALL reallocate(my_units, 1, isize +
SIZE(my_units_tmp) - nblank)
344 DO j = 1,
SIZE(my_units_tmp)
345 IF (my_units_tmp(j) ==
"") cycle
347 my_units(isize + ind) = my_units_tmp(j)
350 cpassert(
SIZE(my_units) ==
SIZE(my_val))
352 mydim = mydim +
SIZE(my_val)
353 IF (
SIZE(my_val) == 0)
THEN
356 DEALLOCATE (my_units)
360 ALLOCATE (parameters(mydim))
361 ALLOCATE (values(mydim))
363 parameters(1:
SIZE(my_var)) = my_var
364 values(1:
SIZE(my_var)) = 0.0_dp
365 IF (
PRESENT(var_values))
THEN
366 cpassert(
SIZE(var_values) ==
SIZE(my_var))
367 values(1:
SIZE(my_var)) = var_values
369 IF (
ASSOCIATED(my_val))
THEN
370 DO i = 1,
SIZE(my_val)
371 parameters(
SIZE(my_var) + i) = my_par(i)
372 IF (n_units > 0)
THEN
373 values(
SIZE(my_var) + i) =
cp_unit_to_cp2k(my_val(i), trim(adjustl(my_units(i))))
375 values(
SIZE(my_var) + i) = my_val(i)
380 IF (
ASSOCIATED(my_par))
THEN
383 IF (
ASSOCIATED(my_val))
THEN
386 IF (
ASSOCIATED(my_units))
THEN
387 DEALLOCATE (my_units)
389 IF (
PRESENT(input_variables))
THEN
real(kind=dp) function, public cp_unit_to_cp2k(value, unit_str, defaults, power)
converts to the internal cp2k units to the given unit
This public domain function parser module is intended for applications where a set of mathematical ex...
character(len=:) function, allocatable, public docf()
...
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
integer, parameter, public default_path_length
Utility routines for the memory handling.
Utilities for string manipulations.
subroutine, public integer_to_string(inumber, string)
Converts an integer number to a string. The WRITE statement will return an error message,...
subroutine, public compress(string, full)
Eliminate multiple space characters in a string. If full is .TRUE., then all spaces are eliminated.
character(len=1), parameter, public newline
subroutine check(condition, label)
Stops with an error message if a test fails.