Neko 1.99.7
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
54
56 logical :: json_no_defaults = .false.
57
64 end interface json_get
65
72 end interface json_get_or_default
73
75 module procedure json_get_or_lookup_real, json_get_or_lookup_double, &
76 json_get_or_lookup_real_array, json_get_or_lookup_double_array, &
77 json_get_or_lookup_integer, json_get_or_lookup_integer_array
78 end interface json_get_or_lookup
79
81 module procedure json_get_or_lookup_or_default_real, &
82 json_get_or_lookup_or_default_double, &
83 json_get_or_lookup_or_default_integer
85
88 end interface json_extract_item
89
90 interface
91 module subroutine json_get_or_lookup_real(json, name, val)
92 type(json_file), intent(inout) :: json
93 character(len=*), intent(in) :: name
94 real(kind=sp), intent(out) :: val
95 end subroutine json_get_or_lookup_real
96
97 module subroutine json_get_or_lookup_double(json, name, val)
98 type(json_file), intent(inout) :: json
99 character(len=*), intent(in) :: name
100 real(kind=dp), intent(out) :: val
101 end subroutine json_get_or_lookup_double
102
103 module subroutine json_get_or_lookup_integer(json, name, val)
104 type(json_file), intent(inout) :: json
105 character(len=*), intent(in) :: name
106 integer, intent(out) :: val
107 end subroutine json_get_or_lookup_integer
108
109 module subroutine json_get_or_lookup_or_default_real(json, &
110 name, val, default)
111 type(json_file), intent(inout) :: json
112 character(len=*), intent(in) :: name
113 real(kind=sp), intent(out) :: val
114 real(kind=sp), intent(in) :: default
115 end subroutine json_get_or_lookup_or_default_real
116
117 module subroutine json_get_or_lookup_or_default_double(json, &
118 name, val, default)
119 type(json_file), intent(inout) :: json
120 character(len=*), intent(in) :: name
121 real(kind=dp), intent(out) :: val
122 real(kind=dp), intent(in) :: default
123 end subroutine json_get_or_lookup_or_default_double
124
125 module subroutine json_get_or_lookup_or_default_integer(json,&
126 name, val, default)
127 type(json_file), intent(inout) :: json
128 character(len=*), intent(in) :: name
129 integer, intent(out) :: val
130 integer, intent(in) :: default
131 end subroutine json_get_or_lookup_or_default_integer
132
133 module subroutine json_get_or_lookup_real_array(json, name, val)
134 type(json_file), intent(inout) :: json
135 character(len=*), intent(in) :: name
136 real(kind=sp), allocatable, intent(inout) :: val(:)
137 end subroutine json_get_or_lookup_real_array
138
139 module subroutine json_get_or_lookup_double_array(json, name, val)
140 type(json_file), intent(inout) :: json
141 character(len=*), intent(in) :: name
142 real(kind=dp), allocatable, intent(inout) :: val(:)
143 end subroutine json_get_or_lookup_double_array
144
145 module subroutine json_get_or_lookup_integer_array(json, name, val)
146 type(json_file), intent(inout) :: json
147 character(len=*), intent(in) :: name
148 integer, allocatable, intent(inout) :: val(:)
149 end subroutine json_get_or_lookup_integer_array
150
151 end interface
152contains
153
159 subroutine json_get_real(json, name, value)
160 type(json_file), intent(inout) :: json
161 character(len=*), intent(in) :: name
162 real(kind=sp), intent(out) :: value
163 logical :: found
164 integer :: var_type
165
166 call json%info(name, found = found, var_type = var_type)
167 if (.not. found) then
168 call neko_error("Parameter " // name // " missing from the case file")
169 else if (var_type .ne. 6) then
170 call neko_error("Parameter " // name // " is not a real")
171 end if
172
173 call json%get(name, value)
174 end subroutine json_get_real
175
180 subroutine json_get_double(json, name, value)
181 type(json_file), intent(inout) :: json
182 character(len=*), intent(in) :: name
183 real(kind=dp), intent(out) :: value
184 logical :: found
185 integer :: var_type
186
187 call json%info(name, found = found, var_type = var_type)
188 if (.not. found) then
189 call neko_error("Parameter " // name // " missing from the case file")
190 else if (var_type .ne. 6) then
191 call neko_error("Parameter " // name // " is not a real")
192 end if
193
194 call json%get(name, value)
195 end subroutine json_get_double
196
201 subroutine json_get_integer(json, name, value)
202 type(json_file), intent(inout) :: json
203 character(len=*), intent(in) :: name
204 integer, intent(out) :: value
205 logical :: found
206 integer :: var_type
207
208 call json%info(name, found = found, var_type = var_type)
209 if (.not. found) then
210 call neko_error("Parameter " // name // " missing from the case file")
211 else if (var_type .ne. 5) then
212 call neko_error("Parameter " // name // " is not an integer")
213 end if
214
215 call json%get(name, value)
216 end subroutine json_get_integer
217
222 subroutine json_get_logical(json, name, value)
223 type(json_file), intent(inout) :: json
224 character(len=*), intent(in) :: name
225 logical, intent(out) :: value
226 logical :: found
227 integer :: var_type
228
229 call json%info(name, found = found, var_type = var_type)
230 if (.not. found) then
231 call neko_error("Parameter " // name // " missing from the case file")
232 else if (var_type .ne. 4) then
233 call neko_error("Parameter " // name // " is not a logical")
234 end if
235
236 call json%get(name, value)
237 end subroutine json_get_logical
238
243 subroutine json_get_string(json, name, value)
244 type(json_file), intent(inout) :: json
245 character(len=*), intent(in) :: name
246 character(len=:), allocatable, intent(out) :: value
247 logical :: found
248 integer :: var_type
249
250 call json%info(name, found = found, var_type = var_type)
251 if (.not. found) then
252 call neko_error("Parameter " // name // " missing from the case file")
253 else if (var_type .ne. 7) then
254 call neko_error("Parameter " // name // " is not a string")
255 end if
256
257 call json%get(name, value)
258 end subroutine json_get_string
259
266 subroutine json_get_real_array(json, name, value, expected_size)
267 type(json_file), intent(inout) :: json
268 character(len=*), intent(in) :: name
269 real(kind=sp), allocatable, intent(out) :: value(:)
270 integer, optional, intent(in) :: expected_size
271 logical :: found
272 integer :: var_type
273 integer :: actual_size
274
275 call json%info(name, found = found, var_type = var_type, &
276 n_children = actual_size)
277
278 if (.not. found) then
279 call neko_error("Parameter " // name // " missing from the case file")
280 else if (var_type .ne. 3) then
281 call neko_error("Parameter " // name // " is not an array")
282 end if
283
284 if (present(expected_size)) then
285 call check_expected_size(name, actual_size, expected_size)
286 end if
287
288 call json%get(name, value)
289 end subroutine json_get_real_array
290
297 subroutine json_get_double_array(json, name, value, expected_size)
298 type(json_file), intent(inout) :: json
299 character(len=*), intent(in) :: name
300 real(kind=dp), allocatable, intent(out) :: value(:)
301 integer, optional, intent(in) :: expected_size
302 logical :: found
303 integer :: var_type
304 integer :: actual_size
305
306 call json%info(name, found = found, var_type = var_type, &
307 n_children = actual_size)
308
309 if (.not. found) then
310 call neko_error("Parameter " // name // " missing from the case file")
311 else if (var_type .ne. 3) then
312 call neko_error("Parameter " // name // " is not an array")
313 end if
314
315 if (present(expected_size)) then
316 call check_expected_size(name, actual_size, expected_size)
317 end if
318
319 call json%get(name, value)
320 end subroutine json_get_double_array
321
328 subroutine json_get_integer_array(json, name, value, expected_size)
329 type(json_file), intent(inout) :: json
330 character(len=*), intent(in) :: name
331 integer, allocatable, intent(out) :: value(:)
332 integer, optional, intent(in) :: expected_size
333 logical :: found
334 integer :: var_type
335 integer :: actual_size
336
337 call json%info(name, found = found, var_type = var_type, &
338 n_children = actual_size)
339
340 if (.not. found) then
341 call neko_error("Parameter " // name // " missing from the case file")
342 end if
343
344 if (present(expected_size)) then
345 call check_expected_size(name, actual_size, expected_size)
346 end if
347
348 call json%get(name, value)
349 end subroutine json_get_integer_array
350
357 subroutine json_get_logical_array(json, name, value, expected_size)
358 type(json_file), intent(inout) :: json
359 character(len=*), intent(in) :: name
360 logical, allocatable, intent(out) :: value(:)
361 integer, optional, intent(in) :: expected_size
362 logical :: found
363 integer :: var_type
364 integer :: actual_size
365
366 call json%info(name, found = found, var_type = var_type, &
367 n_children = actual_size)
368
369 if (.not. found) then
370 call neko_error("Parameter " // name // " missing from the case file")
371 else if (var_type .ne. 3) then
372 call neko_error("Parameter " // name // " is not a array")
373 end if
374
375 if (present(expected_size)) then
376 call check_expected_size(name, actual_size, expected_size)
377 end if
378
379 call json%get(name, value)
380 end subroutine json_get_logical_array
381
387 subroutine json_get_string_array(json, name, value, filler)
388 type(json_file), intent(inout) :: json
389 character(len=*), intent(in) :: name
390 character(len=*), allocatable, intent(out) :: value(:)
391 character(len=*), optional, intent(in) :: filler
392 logical :: found
393 type(json_value), pointer :: json_val, val_ptr
394 type(json_core) :: core
395 character(len=:), allocatable :: string_value
396 character(len=16) :: len_buf
397 integer :: i, n_children
398 integer :: var_type
399
400 call json%info(name, found = found, var_type = var_type, &
401 n_children = n_children)
402 if (.not. found) then
403 call neko_error("Parameter " // name // " missing from the case file")
404 else if (var_type .ne. 3) then
405 call neko_error("Parameter " // name // " is not an array")
406 end if
407
408 if (.not. allocated(value)) then
409 allocate(value(n_children))
410 else if (size(value) .lt. n_children) then
411 deallocate(value)
412 allocate(value(n_children))
413 end if
414
415 call json%get(name, json_val, found)
416 call json%get_core(core)
417
418 do i = 1, n_children
419 call core%get_child(json_val, i, val_ptr, found)
420 call core%get(val_ptr, string_value)
421
422 ! Assigning into the fixed length elements of `value` would silently
423 ! truncate anything longer, so reject it rather than hand the caller
424 ! a string that is not what the case file says.
425 if (len(string_value) .gt. len(value)) then
426 write (len_buf, '(I0)') len(value)
427 call neko_error("An entry of the array parameter " // name // &
428 " is longer than the " // trim(len_buf) // &
429 " characters available for it")
430 end if
431
432 if (len(string_value) .gt. 0) then
433 value(i) = string_value
434 else if (present(filler)) then
435 value(i) = filler
436 end if
437 end do
438
439 end subroutine json_get_string_array
440
442 subroutine json_get_subdict(json, key, output)
443 type(json_file), intent(inout) :: json
444 character(len=*), intent(in) :: key
445 type(json_file), intent(inout) :: output
446
447 type(json_value), pointer :: ptr
448 type(json_core) :: core
449 logical :: found
450 character(len=:), allocatable :: buffer
451
452 call json%get_core(core)
453 call json%get(key, ptr, found)
454
455 if (.not. found) then
456 call neko_error("Parameter " // &
457 trim(key) // " missing from the case file")
458 end if
459
460 call core%print_to_string(ptr, buffer)
461 call output%initialize(strict_type_checking = .true.)
462 call output%load_from_string(buffer)
463
464 end subroutine json_get_subdict
465
468 subroutine json_get_subdict_or_empty(json, key, output)
469 type(json_file), intent(inout) :: json
470 character(len=*), intent(in) :: key
471 type(json_file), intent(inout) :: output
472
473 type(json_value), pointer :: ptr
474 type(json_core) :: core
475 logical :: found
476 character(len=:), allocatable :: buffer
477
478 ! Initialize empty object to return
479 call output%initialize(strict_type_checking = .true.)
480
481 call json%get_core(core)
482 call json%get(key, ptr, found)
483
484 ! Load the contents if found, otherwise the object stays empty.
485 if (found) then
486 call core%print_to_string(ptr, buffer)
487 call output%load_from_string(buffer)
488 end if
489
490 end subroutine json_get_subdict_or_empty
491
497 subroutine json_get_or_default_real(json, name, value, default)
498 type(json_file), intent(inout) :: json
499 character(len=*), intent(in) :: name
500 real(kind=sp), intent(out) :: value
501 real(kind=sp), intent(in) :: default
502 logical :: found
503 integer :: var_type
504
505 call json%info(name, found = found, var_type = var_type)
506
507 if (found .and. (var_type .ne. 6)) then
508 call neko_error("Parameter " // name // " present, but is not a real")
509 end if
510
511 call json%get(name, value, found)
512
513 if ((.not. found) .and. (.not. json_no_defaults)) then
514 value = default
515 call json%add(name, value)
516 else if (.not. found) then
517 call neko_error("Parameter " // name // " missing from the case file")
518 end if
519 end subroutine json_get_or_default_real
520
527 subroutine json_get_or_default_double(json, name, value, default)
528 type(json_file), intent(inout) :: json
529 character(len=*), intent(in) :: name
530 real(kind=dp), intent(out) :: value
531 real(kind=dp), intent(in) :: default
532 logical :: found
533 integer :: var_type
534
535 call json%info(name, found = found, var_type = var_type)
536
537 if (found .and. (var_type .ne. 6)) then
538 call neko_error("Parameter " // name // " present, but is not a real")
539 end if
540
541 call json%get(name, value, found)
542
543 if ((.not. found) .and. (.not. json_no_defaults)) then
544 value = default
545 call json%add(name, value)
546 else if (.not. found) then
547 call neko_error("Parameter " // name // " missing from the case file")
548 end if
549 end subroutine json_get_or_default_double
550
556 subroutine json_get_or_default_integer(json, name, value, default)
557 type(json_file), intent(inout) :: json
558 character(len=*), intent(in) :: name
559 integer, intent(out) :: value
560 integer, intent(in) :: default
561 logical :: found
562 integer :: var_type
563
564 call json%info(name, found = found, var_type = var_type)
565
566 if (found .and. (var_type .ne. 5)) then
567 call neko_error("Parameter " // name // " present, but " // &
568 "is not an integer")
569 end if
570
571 call json%get(name, value, found)
572
573 if ((.not. found) .and. (.not. json_no_defaults)) then
574 value = default
575 call json%add(name, value)
576 else if (.not. found) then
577 call neko_error("Parameter " // name // " missing from the case file")
578 end if
579 end subroutine json_get_or_default_integer
580
586 subroutine json_get_or_default_logical(json, name, value, default)
587 type(json_file), intent(inout) :: json
588 character(len=*), intent(in) :: name
589 logical, intent(out) :: value
590 logical, intent(in) :: default
591 logical :: found
592 integer :: var_type
593
594 call json%info(name, found = found, var_type = var_type)
595
596 if ((found) .and. (var_type .ne. 4)) then
597 call neko_error("Parameter " // name // " present, but is not a logical")
598 end if
599
600 call json%get(name, value, found)
601
602 if ((.not. found) .and. (.not. json_no_defaults)) then
603 value = default
604 call json%add(name, value)
605 else if (.not. found) then
606 call neko_error("Parameter " // name // " missing from the case file")
607 end if
608 end subroutine json_get_or_default_logical
609
615 subroutine json_get_or_default_string(json, name, value, default)
616 type(json_file), intent(inout) :: json
617 character(len=*), intent(in) :: name
618 character(len=:), allocatable, intent(out) :: value
619 character(len=*), intent(in) :: default
620 logical :: found
621 integer :: var_type
622
623 call json%info(name, found = found, var_type = var_type)
624
625 if (found .and. (var_type .ne. 7)) then
626 call neko_error("Parameter " // name // &
627 " present, but is not a string")
628 end if
629
630 call json%get(name, value, found)
631
632 if ((.not. found) .and. (.not. json_no_defaults)) then
633 value = default
634 call json%add(name, value)
635 else if (.not. found) then
636 call neko_error("Parameter " // name // " missing from the case file")
637 end if
638 end subroutine json_get_or_default_string
639
645 subroutine json_extract_item_from_array(core, array, i, item)
646 type(json_core), intent(inout) :: core
647 type(json_value), pointer, intent(in) :: array
648 integer, intent(in) :: i
649 type(json_file), intent(inout) :: item
650 type(json_value), pointer :: ptr
651 logical :: found
652 character(len=:), allocatable :: buffer
653
654 call core%get_child(array, i, ptr, found)
655 call core%print_to_string(ptr, buffer)
656 call item%initialize(strict_type_checking = .true.)
657 call item%load_from_string(buffer)
658
659 end subroutine json_extract_item_from_array
660
666 subroutine json_extract_item_from_name(json, name, i, item)
667 type(json_file), intent(inout) :: json
668 character(len=*), intent(in) :: name
669 integer, intent(in) :: i
670 type(json_file), intent(out) :: item
671
672 type(json_core) :: core
673 type(json_value), pointer :: array
674 type(json_value), pointer :: ptr
675 logical :: found
676 character(len=:), allocatable :: buffer
677
678 call json%get_core(core)
679 call json%get(name, array, found)
680
681 if (.not. found) then
682 call neko_error("Parameter " // name // " missing from the case file")
683 end if
684
685 call core%get_child(array, i, ptr, found)
686 call core%print_to_string(ptr, buffer)
687 call item%initialize(strict_type_checking = .true.)
688 call item%load_from_string(buffer)
689
690 end subroutine json_extract_item_from_name
691
696 subroutine check_expected_size(name, actual_size, expected_size)
697 character(len=*), intent(in) :: name
698 integer, intent(in) :: actual_size, expected_size
699 character(len=32) :: str_actual, str_expected
700
701 if (actual_size /= expected_size) then
702 write(str_actual, '(I0)') actual_size
703 write(str_expected, '(I0)') expected_size
704 call neko_error("Parameter '" // trim(name) // &
705 "' has incorrect size: got " // &
706 trim(str_actual) // ", but expected " // trim(str_expected))
707 end if
708 end subroutine check_expected_size
709
710end 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, public json_get_subdict_or_empty(json, key, output)
Extract a sub-object from a json object and returns an empty object if the key is missing.
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