Neko 1.99.3
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
json_utils.f90
Go to the documentation of this file.
1! Copyright (c) 2019-2024, The Neko Authors
2! All rights reserved.
3!
4! Redistribution and use in source and binary forms, with or without
5! modification, are permitted provided that the following conditions
6! are met:
7!
8! * Redistributions of source code must retain the above copyright
9! notice, this list of conditions and the following disclaimer.
10!
11! * Redistributions in binary form must reproduce the above
12! copyright notice, this list of conditions and the following
13! disclaimer in the documentation and/or other materials provided
14! with the distribution.
15!
16! * Neither the name of the authors nor the names of its
17! contributors may be used to endorse or promote products derived
18! from this software without specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31! POSSIBILITY OF SUCH DAMAGE.
32!
34!
35! These are json-fortran type codes:
36! json_unknown = 0
37! json_null = 1
38! json_object = 2
39! json_array = 3
40! json_logical = 4
41! json_integer = 5
42! json_real = 6
43! json_string = 7
45 use num_types, only : dp, sp
46 use json_module, only : json_file, json_value, json_core
47 use utils, only : neko_error
48 implicit none
49 private
50
53
55 logical :: json_no_defaults = .false.
56
63 end interface json_get
64
71 end interface json_get_or_default
72
74 module procedure json_get_or_lookup_real, json_get_or_lookup_double, &
75 json_get_or_lookup_real_array, json_get_or_lookup_double_array, &
76 json_get_or_lookup_integer, json_get_or_lookup_integer_array
77 end interface json_get_or_lookup
78
80 module procedure json_get_or_lookup_or_default_real, &
81 json_get_or_lookup_or_default_double, &
82 json_get_or_lookup_or_default_integer
84
87 end interface json_extract_item
88
89 interface
90 module subroutine json_get_or_lookup_real(json, name, val)
91 type(json_file), intent(inout) :: json
92 character(len=*), intent(in) :: name
93 real(kind=sp), intent(out) :: val
94 end subroutine json_get_or_lookup_real
95
96 module subroutine json_get_or_lookup_double(json, name, val)
97 type(json_file), intent(inout) :: json
98 character(len=*), intent(in) :: name
99 real(kind=dp), intent(out) :: val
100 end subroutine json_get_or_lookup_double
101
102 module subroutine json_get_or_lookup_integer(json, name, val)
103 type(json_file), intent(inout) :: json
104 character(len=*), intent(in) :: name
105 integer, intent(out) :: val
106 end subroutine json_get_or_lookup_integer
107
108 module subroutine json_get_or_lookup_or_default_real(json, &
109 name, val, default)
110 type(json_file), intent(inout) :: json
111 character(len=*), intent(in) :: name
112 real(kind=sp), intent(out) :: val
113 real(kind=sp), intent(in) :: default
114 end subroutine json_get_or_lookup_or_default_real
115
116 module subroutine json_get_or_lookup_or_default_double(json, &
117 name, val, default)
118 type(json_file), intent(inout) :: json
119 character(len=*), intent(in) :: name
120 real(kind=dp), intent(out) :: val
121 real(kind=dp), intent(in) :: default
122 end subroutine json_get_or_lookup_or_default_double
123
124 module subroutine json_get_or_lookup_or_default_integer(json,&
125 name, val, default)
126 type(json_file), intent(inout) :: json
127 character(len=*), intent(in) :: name
128 integer, intent(out) :: val
129 integer, intent(in) :: default
130 end subroutine json_get_or_lookup_or_default_integer
131
132 module subroutine json_get_or_lookup_real_array(json, name, val)
133 type(json_file), intent(inout) :: json
134 character(len=*), intent(in) :: name
135 real(kind=sp), allocatable, intent(inout) :: val(:)
136 end subroutine json_get_or_lookup_real_array
137
138 module subroutine json_get_or_lookup_double_array(json, name, val)
139 type(json_file), intent(inout) :: json
140 character(len=*), intent(in) :: name
141 real(kind=dp), allocatable, intent(inout) :: val(:)
142 end subroutine json_get_or_lookup_double_array
143
144 module subroutine json_get_or_lookup_integer_array(json, name, val)
145 type(json_file), intent(inout) :: json
146 character(len=*), intent(in) :: name
147 integer, allocatable, intent(inout) :: val(:)
148 end subroutine json_get_or_lookup_integer_array
149
150 end interface
151contains
152
157 subroutine json_get_real(json, name, value)
158 type(json_file), intent(inout) :: json
159 character(len=*), intent(in) :: name
160 real(kind=sp), intent(out) :: value
161 logical :: found
162 integer :: var_type
163
164 call json%info(name, found = found, var_type = var_type)
165 if (.not. found) then
166 call neko_error("Parameter " // name // " missing from the case file")
167 else if (var_type .ne. 6) then
168 call neko_error("Parameter " // name // " is not a real")
169 end if
170
171 call json%get(name, value)
172 end subroutine json_get_real
173
178 subroutine json_get_double(json, name, value)
179 type(json_file), intent(inout) :: json
180 character(len=*), intent(in) :: name
181 real(kind=dp), intent(out) :: value
182 logical :: found
183 integer :: var_type
184
185 call json%info(name, found = found, var_type = var_type)
186 if (.not. found) then
187 call neko_error("Parameter " // name // " missing from the case file")
188 else if (var_type .ne. 6) then
189 call neko_error("Parameter " // name // " is not a real")
190 end if
191
192 call json%get(name, value)
193 end subroutine json_get_double
194
199 subroutine json_get_integer(json, name, value)
200 type(json_file), intent(inout) :: json
201 character(len=*), intent(in) :: name
202 integer, intent(out) :: value
203 logical :: found
204 integer :: var_type
205
206 call json%info(name, found = found, var_type = var_type)
207 if (.not. found) then
208 call neko_error("Parameter " // name // " missing from the case file")
209 else if (var_type .ne. 5) then
210 call neko_error("Parameter " // name // " is not an integer")
211 end if
212
213 call json%get(name, value)
214 end subroutine json_get_integer
215
220 subroutine json_get_logical(json, name, value)
221 type(json_file), intent(inout) :: json
222 character(len=*), intent(in) :: name
223 logical, intent(out) :: value
224 logical :: found
225 integer :: var_type
226
227 call json%info(name, found = found, var_type = var_type)
228 if (.not. found) then
229 call neko_error("Parameter " // name // " missing from the case file")
230 else if (var_type .ne. 4) then
231 call neko_error("Parameter " // name // " is not a logical")
232 end if
233
234 call json%get(name, value)
235 end subroutine json_get_logical
236
241 subroutine json_get_string(json, name, value)
242 type(json_file), intent(inout) :: json
243 character(len=*), intent(in) :: name
244 character(len=:), allocatable, intent(out) :: value
245 logical :: found
246 integer :: var_type
247
248 call json%info(name, found = found, var_type = var_type)
249 if (.not. found) then
250 call neko_error("Parameter " // name // " missing from the case file")
251 else if (var_type .ne. 7) then
252 call neko_error("Parameter " // name // " is not a string")
253 end if
254
255 call json%get(name, value)
256 end subroutine json_get_string
257
264 subroutine json_get_real_array(json, name, value, expected_size)
265 type(json_file), intent(inout) :: json
266 character(len=*), intent(in) :: name
267 real(kind=sp), allocatable, intent(out) :: value(:)
268 integer, optional, intent(in) :: expected_size
269 logical :: found
270 integer :: var_type
271 integer :: actual_size
272
273 call json%info(name, found = found, var_type = var_type, &
274 n_children = actual_size)
275
276 if (.not. found) then
277 call neko_error("Parameter " // name // " missing from the case file")
278 else if (var_type .ne. 3) then
279 call neko_error("Parameter " // name // " is not an array")
280 end if
281
282 if (present(expected_size)) then
283 call check_expected_size(name, actual_size, expected_size)
284 end if
285
286 call json%get(name, value)
287 end subroutine json_get_real_array
288
295 subroutine json_get_double_array(json, name, value, expected_size)
296 type(json_file), intent(inout) :: json
297 character(len=*), intent(in) :: name
298 real(kind=dp), allocatable, intent(out) :: value(:)
299 integer, optional, intent(in) :: expected_size
300 logical :: found
301 integer :: var_type
302 integer :: actual_size
303
304 call json%info(name, found = found, var_type = var_type, &
305 n_children = actual_size)
306
307 if (.not. found) then
308 call neko_error("Parameter " // name // " missing from the case file")
309 else if (var_type .ne. 3) then
310 call neko_error("Parameter " // name // " is not an array")
311 end if
312
313 if (present(expected_size)) then
314 call check_expected_size(name, actual_size, expected_size)
315 end if
316
317 call json%get(name, value)
318 end subroutine json_get_double_array
319
326 subroutine json_get_integer_array(json, name, value, expected_size)
327 type(json_file), intent(inout) :: json
328 character(len=*), intent(in) :: name
329 integer, allocatable, intent(out) :: value(:)
330 integer, optional, intent(in) :: expected_size
331 logical :: found
332 integer :: var_type
333 integer :: actual_size
334
335 call json%info(name, found = found, var_type = var_type, &
336 n_children = actual_size)
337
338 if (.not. found) then
339 call neko_error("Parameter " // name // " missing from the case file")
340 end if
341
342 if (present(expected_size)) then
343 call check_expected_size(name, actual_size, expected_size)
344 end if
345
346 call json%get(name, value)
347 end subroutine json_get_integer_array
348
355 subroutine json_get_logical_array(json, name, value, expected_size)
356 type(json_file), intent(inout) :: json
357 character(len=*), intent(in) :: name
358 logical, allocatable, intent(out) :: value(:)
359 integer, optional, intent(in) :: expected_size
360 logical :: found
361 integer :: var_type
362 integer :: actual_size
363
364 call json%info(name, found = found, var_type = var_type, &
365 n_children = actual_size)
366
367 if (.not. found) then
368 call neko_error("Parameter " // name // " missing from the case file")
369 else if (var_type .ne. 3) then
370 call neko_error("Parameter " // name // " is not a array")
371 end if
372
373 if (present(expected_size)) then
374 call check_expected_size(name, actual_size, expected_size)
375 end if
376
377 call json%get(name, value)
378 end subroutine json_get_logical_array
379
385 subroutine json_get_string_array(json, name, value, filler)
386 type(json_file), intent(inout) :: json
387 character(len=*), intent(in) :: name
388 character(len=*), allocatable, intent(out) :: value(:)
389 character(len=*), optional, intent(in) :: filler
390 logical :: found
391 type(json_value), pointer :: json_val, val_ptr
392 type(json_core) :: core
393 character(len=:), allocatable :: string_value
394 integer :: i, n_children
395 integer :: var_type
396
397 call json%info(name, found = found, var_type = var_type, &
398 n_children = n_children)
399 if (.not. found) then
400 call neko_error("Parameter " // name // " missing from the case file")
401 else if (var_type .ne. 3) then
402 call neko_error("Parameter " // name // " is not an array")
403 end if
404
405 if (.not. allocated(value)) then
406 allocate(value(n_children))
407 else if (len(value) .lt. n_children) then
408 deallocate(value)
409 allocate(value(n_children))
410 end if
411
412 call json%get(name, json_val, found)
413 call json%get_core(core)
414
415 do i = 1, n_children
416 call core%get_child(json_val, i, val_ptr, found)
417 call core%get(val_ptr, string_value)
418
419 if (len(string_value) .gt. 0) then
420 value(i) = string_value
421 else if (present(filler)) then
422 value(i) = filler
423 end if
424 end do
425
426 end subroutine json_get_string_array
427
429 subroutine json_get_subdict(json, key, output)
430 type(json_file), intent(inout) :: json
431 character(len=*), intent(in) :: key
432 type(json_file), intent(inout) :: output
433
434 type(json_value), pointer :: ptr
435 type(json_core) :: core
436 logical :: found
437 character(len=:), allocatable :: buffer
438
439 call json%get_core(core)
440 call json%get(key, ptr, found)
441
442 if (.not. found) then
443 call neko_error("Parameter " // &
444 trim(key) // " missing from the case file")
445 end if
446
447 call core%print_to_string(ptr, buffer)
448 call output%initialize(strict_type_checking = .true.)
449 call output%load_from_string(buffer)
450
451 end subroutine json_get_subdict
452
458 subroutine json_get_or_default_real(json, name, value, default)
459 type(json_file), intent(inout) :: json
460 character(len=*), intent(in) :: name
461 real(kind=sp), intent(out) :: value
462 real(kind=sp), intent(in) :: default
463 logical :: found
464 integer :: var_type
465
466 call json%info(name, found = found, var_type = var_type)
467
468 if (found .and. (var_type .ne. 6)) then
469 call neko_error("Parameter " // name // " present, but is not a real")
470 end if
471
472 call json%get(name, value, found)
473
474 if ((.not. found) .and. (.not. json_no_defaults)) then
475 value = default
476 call json%add(name, value)
477 else if (.not. found) then
478 call neko_error("Parameter " // name // " missing from the case file")
479 end if
480 end subroutine json_get_or_default_real
481
488 subroutine json_get_or_default_double(json, name, value, default)
489 type(json_file), intent(inout) :: json
490 character(len=*), intent(in) :: name
491 real(kind=dp), intent(out) :: value
492 real(kind=dp), intent(in) :: default
493 logical :: found
494 integer :: var_type
495
496 call json%info(name, found = found, var_type = var_type)
497
498 if (found .and. (var_type .ne. 6)) then
499 call neko_error("Parameter " // name // " present, but is not a real")
500 end if
501
502 call json%get(name, value, found)
503
504 if ((.not. found) .and. (.not. json_no_defaults)) then
505 value = default
506 call json%add(name, value)
507 else if (.not. found) then
508 call neko_error("Parameter " // name // " missing from the case file")
509 end if
510 end subroutine json_get_or_default_double
511
517 subroutine json_get_or_default_integer(json, name, value, default)
518 type(json_file), intent(inout) :: json
519 character(len=*), intent(in) :: name
520 integer, intent(out) :: value
521 integer, intent(in) :: default
522 logical :: found
523 integer :: var_type
524
525 call json%info(name, found = found, var_type = var_type)
526
527 if (found .and. (var_type .ne. 5)) then
528 call neko_error("Parameter " // name // " present, but " // &
529 "is not an integer")
530 end if
531
532 call json%get(name, value, found)
533
534 if ((.not. found) .and. (.not. json_no_defaults)) then
535 value = default
536 call json%add(name, value)
537 else if (.not. found) then
538 call neko_error("Parameter " // name // " missing from the case file")
539 end if
540 end subroutine json_get_or_default_integer
541
547 subroutine json_get_or_default_logical(json, name, value, default)
548 type(json_file), intent(inout) :: json
549 character(len=*), intent(in) :: name
550 logical, intent(out) :: value
551 logical, intent(in) :: default
552 logical :: found
553 integer :: var_type
554
555 call json%info(name, found = found, var_type = var_type)
556
557 if ((found) .and. (var_type .ne. 4)) then
558 call neko_error("Parameter " // name // " present, but is not a logical")
559 end if
560
561 call json%get(name, value, found)
562
563 if ((.not. found) .and. (.not. json_no_defaults)) then
564 value = default
565 call json%add(name, value)
566 else if (.not. found) then
567 call neko_error("Parameter " // name // " missing from the case file")
568 end if
569 end subroutine json_get_or_default_logical
570
576 subroutine json_get_or_default_string(json, name, value, default)
577 type(json_file), intent(inout) :: json
578 character(len=*), intent(in) :: name
579 character(len=:), allocatable, intent(out) :: value
580 character(len=*), intent(in) :: default
581 logical :: found
582 integer :: var_type
583
584 call json%info(name, found = found, var_type = var_type)
585
586 if (found .and. (var_type .ne. 7)) then
587 call neko_error("Parameter " // name // &
588 " present, but is not a string")
589 end if
590
591 call json%get(name, value, found)
592
593 if ((.not. found) .and. (.not. json_no_defaults)) then
594 value = default
595 call json%add(name, value)
596 else if (.not. found) then
597 call neko_error("Parameter " // name // " missing from the case file")
598 end if
599 end subroutine json_get_or_default_string
600
606 subroutine json_extract_item_from_array(core, array, i, item)
607 type(json_core), intent(inout) :: core
608 type(json_value), pointer, intent(in) :: array
609 integer, intent(in) :: i
610 type(json_file), intent(inout) :: item
611 type(json_value), pointer :: ptr
612 logical :: found
613 character(len=:), allocatable :: buffer
614
615 call core%get_child(array, i, ptr, found)
616 call core%print_to_string(ptr, buffer)
617 call item%initialize(strict_type_checking = .true.)
618 call item%load_from_string(buffer)
619
620 end subroutine json_extract_item_from_array
621
627 subroutine json_extract_item_from_name(json, name, i, item)
628 type(json_file), intent(inout) :: json
629 character(len=*), intent(in) :: name
630 integer, intent(in) :: i
631 type(json_file), intent(out) :: item
632
633 type(json_core) :: core
634 type(json_value), pointer :: array
635 type(json_value), pointer :: ptr
636 logical :: found
637 character(len=:), allocatable :: buffer
638
639 call json%get_core(core)
640 call json%get(name, array, found)
641
642 if (.not. found) then
643 call neko_error("Parameter " // name // " missing from the case file")
644 end if
645
646 call core%get_child(array, i, ptr, found)
647 call core%print_to_string(ptr, buffer)
648 call item%initialize(strict_type_checking = .true.)
649 call item%load_from_string(buffer)
650
651 end subroutine json_extract_item_from_name
652
657 subroutine check_expected_size(name, actual_size, expected_size)
658 character(len=*), intent(in) :: name
659 integer, intent(in) :: actual_size, expected_size
660 character(len=32) :: str_actual, str_expected
661
662 if (actual_size /= expected_size) then
663 write(str_actual, '(I0)') actual_size
664 write(str_expected, '(I0)') expected_size
665 call neko_error("Parameter '" // trim(name) // &
666 "' has incorrect size: got " // &
667 trim(str_actual) // ", but expected " // trim(str_expected))
668 end if
669 end subroutine check_expected_size
670
671end module json_utils
Retrieves a parameter by name or assigns a provided default value. In the latter case also adds the m...
Retrieves a parameter by name or throws an error.
Generic buffer that is extended with buffers of varying rank.
Definition buffer.F90:34
Utilities for retrieving parameters from the case files.
subroutine json_get_integer_array(json, name, value, expected_size)
Retrieves a integer array parameter by name or throws an error.
subroutine json_extract_item_from_name(json, name, i, item)
Extract ith item from a JSON array as a separate JSON object.
subroutine json_get_real_array(json, name, value, expected_size)
Retrieves a real array parameter by name or throws an error.
subroutine json_get_logical(json, name, value)
Retrieves a logical parameter by name or throws an error.
subroutine json_get_or_default_string(json, name, value, default)
Retrieves a string parameter by name or assigns a provided default value. In the latter case also add...
subroutine json_get_double_array(json, name, value, expected_size)
Retrieves a double precision array parameter by name or throws an error.
subroutine json_get_subdict(json, key, output)
Extract a sub-object from a json object.
subroutine json_extract_item_from_array(core, array, i, item)
Extract ith item from a JSON array as a separate JSON object.
subroutine json_get_string(json, name, value)
Retrieves a string parameter by name or throws an error.
subroutine json_get_or_default_real(json, name, value, default)
Retrieves a real parameter by name or assigns a provided default value. In the latter case also adds ...
subroutine json_get_or_default_double(json, name, value, default)
Retrieves a double precision parameter by name or assigns a provided default value....
subroutine json_get_or_default_logical(json, name, value, default)
Retrieves a logical parameter by name or assigns a provided default value. In the latter case also ad...
subroutine json_get_or_default_integer(json, name, value, default)
Retrieves an integer parameter by name or assigns a provided default value. In the latter case also a...
subroutine json_get_double(json, name, value)
Retrieves a double precision real parameter by name or throws an error.
subroutine json_get_string_array(json, name, value, filler)
Retrieves a string array parameter by name or throws an error.
subroutine json_get_real(json, name, value)
Retrieves a real parameter by name or throws an error.
logical, public json_no_defaults
If true, the json_get_or_default routines will not add missing parameters.
subroutine json_get_integer(json, name, value)
Retrieves an integer parameter by name or throws an error.
subroutine json_get_logical_array(json, name, value, expected_size)
Retrieves a logical array parameter by name or throws an error.
integer, parameter, public dp
Definition num_types.f90:9
integer, parameter, public sp
Definition num_types.f90:8
Defines an output.
Definition output.f90:34
Utilities.
Definition utils.f90:35