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
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
158 subroutine json_get_real(json, name, value)
159 type(json_file), intent(inout) :: json
160 character(len=*), intent(in) :: name
161 real(kind=sp), intent(out) :: value
162 logical :: found
163 integer :: var_type
164
165 call json%info(name, found = found, var_type = var_type)
166 if (.not. found) then
167 call neko_error("Parameter " // name // " missing from the case file")
168 else if (var_type .ne. 6) then
169 call neko_error("Parameter " // name // " is not a real")
170 end if
171
172 call json%get(name, value)
173 end subroutine json_get_real
174
179 subroutine json_get_double(json, name, value)
180 type(json_file), intent(inout) :: json
181 character(len=*), intent(in) :: name
182 real(kind=dp), intent(out) :: value
183 logical :: found
184 integer :: var_type
185
186 call json%info(name, found = found, var_type = var_type)
187 if (.not. found) then
188 call neko_error("Parameter " // name // " missing from the case file")
189 else if (var_type .ne. 6) then
190 call neko_error("Parameter " // name // " is not a real")
191 end if
192
193 call json%get(name, value)
194 end subroutine json_get_double
195
200 subroutine json_get_integer(json, name, value)
201 type(json_file), intent(inout) :: json
202 character(len=*), intent(in) :: name
203 integer, intent(out) :: value
204 logical :: found
205 integer :: var_type
206
207 call json%info(name, found = found, var_type = var_type)
208 if (.not. found) then
209 call neko_error("Parameter " // name // " missing from the case file")
210 else if (var_type .ne. 5) then
211 call neko_error("Parameter " // name // " is not an integer")
212 end if
213
214 call json%get(name, value)
215 end subroutine json_get_integer
216
221 subroutine json_get_logical(json, name, value)
222 type(json_file), intent(inout) :: json
223 character(len=*), intent(in) :: name
224 logical, intent(out) :: value
225 logical :: found
226 integer :: var_type
227
228 call json%info(name, found = found, var_type = var_type)
229 if (.not. found) then
230 call neko_error("Parameter " // name // " missing from the case file")
231 else if (var_type .ne. 4) then
232 call neko_error("Parameter " // name // " is not a logical")
233 end if
234
235 call json%get(name, value)
236 end subroutine json_get_logical
237
242 subroutine json_get_string(json, name, value)
243 type(json_file), intent(inout) :: json
244 character(len=*), intent(in) :: name
245 character(len=:), allocatable, intent(out) :: value
246 logical :: found
247 integer :: var_type
248
249 call json%info(name, found = found, var_type = var_type)
250 if (.not. found) then
251 call neko_error("Parameter " // name // " missing from the case file")
252 else if (var_type .ne. 7) then
253 call neko_error("Parameter " // name // " is not a string")
254 end if
255
256 call json%get(name, value)
257 end subroutine json_get_string
258
265 subroutine json_get_real_array(json, name, value, expected_size)
266 type(json_file), intent(inout) :: json
267 character(len=*), intent(in) :: name
268 real(kind=sp), allocatable, intent(out) :: value(:)
269 integer, optional, intent(in) :: expected_size
270 logical :: found
271 integer :: var_type
272 integer :: actual_size
273
274 call json%info(name, found = found, var_type = var_type, &
275 n_children = actual_size)
276
277 if (.not. found) then
278 call neko_error("Parameter " // name // " missing from the case file")
279 else if (var_type .ne. 3) then
280 call neko_error("Parameter " // name // " is not an array")
281 end if
282
283 if (present(expected_size)) then
284 call check_expected_size(name, actual_size, expected_size)
285 end if
286
287 call json%get(name, value)
288 end subroutine json_get_real_array
289
296 subroutine json_get_double_array(json, name, value, expected_size)
297 type(json_file), intent(inout) :: json
298 character(len=*), intent(in) :: name
299 real(kind=dp), allocatable, intent(out) :: value(:)
300 integer, optional, intent(in) :: expected_size
301 logical :: found
302 integer :: var_type
303 integer :: actual_size
304
305 call json%info(name, found = found, var_type = var_type, &
306 n_children = actual_size)
307
308 if (.not. found) then
309 call neko_error("Parameter " // name // " missing from the case file")
310 else if (var_type .ne. 3) then
311 call neko_error("Parameter " // name // " is not an array")
312 end if
313
314 if (present(expected_size)) then
315 call check_expected_size(name, actual_size, expected_size)
316 end if
317
318 call json%get(name, value)
319 end subroutine json_get_double_array
320
327 subroutine json_get_integer_array(json, name, value, expected_size)
328 type(json_file), intent(inout) :: json
329 character(len=*), intent(in) :: name
330 integer, allocatable, intent(out) :: value(:)
331 integer, optional, intent(in) :: expected_size
332 logical :: found
333 integer :: var_type
334 integer :: actual_size
335
336 call json%info(name, found = found, var_type = var_type, &
337 n_children = actual_size)
338
339 if (.not. found) then
340 call neko_error("Parameter " // name // " missing from the case file")
341 end if
342
343 if (present(expected_size)) then
344 call check_expected_size(name, actual_size, expected_size)
345 end if
346
347 call json%get(name, value)
348 end subroutine json_get_integer_array
349
356 subroutine json_get_logical_array(json, name, value, expected_size)
357 type(json_file), intent(inout) :: json
358 character(len=*), intent(in) :: name
359 logical, allocatable, intent(out) :: value(:)
360 integer, optional, intent(in) :: expected_size
361 logical :: found
362 integer :: var_type
363 integer :: actual_size
364
365 call json%info(name, found = found, var_type = var_type, &
366 n_children = actual_size)
367
368 if (.not. found) then
369 call neko_error("Parameter " // name // " missing from the case file")
370 else if (var_type .ne. 3) then
371 call neko_error("Parameter " // name // " is not a array")
372 end if
373
374 if (present(expected_size)) then
375 call check_expected_size(name, actual_size, expected_size)
376 end if
377
378 call json%get(name, value)
379 end subroutine json_get_logical_array
380
386 subroutine json_get_string_array(json, name, value, filler)
387 type(json_file), intent(inout) :: json
388 character(len=*), intent(in) :: name
389 character(len=*), allocatable, intent(out) :: value(:)
390 character(len=*), optional, intent(in) :: filler
391 logical :: found
392 type(json_value), pointer :: json_val, val_ptr
393 type(json_core) :: core
394 character(len=:), allocatable :: string_value
395 integer :: i, n_children
396 integer :: var_type
397
398 call json%info(name, found = found, var_type = var_type, &
399 n_children = n_children)
400 if (.not. found) then
401 call neko_error("Parameter " // name // " missing from the case file")
402 else if (var_type .ne. 3) then
403 call neko_error("Parameter " // name // " is not an array")
404 end if
405
406 if (.not. allocated(value)) then
407 allocate(value(n_children))
408 else if (len(value) .lt. n_children) then
409 deallocate(value)
410 allocate(value(n_children))
411 end if
412
413 call json%get(name, json_val, found)
414 call json%get_core(core)
415
416 do i = 1, n_children
417 call core%get_child(json_val, i, val_ptr, found)
418 call core%get(val_ptr, string_value)
419
420 if (len(string_value) .gt. 0) then
421 value(i) = string_value
422 else if (present(filler)) then
423 value(i) = filler
424 end if
425 end do
426
427 end subroutine json_get_string_array
428
430 subroutine json_get_subdict(json, key, output)
431 type(json_file), intent(inout) :: json
432 character(len=*), intent(in) :: key
433 type(json_file), intent(inout) :: output
434
435 type(json_value), pointer :: ptr
436 type(json_core) :: core
437 logical :: found
438 character(len=:), allocatable :: buffer
439
440 call json%get_core(core)
441 call json%get(key, ptr, found)
442
443 if (.not. found) then
444 call neko_error("Parameter " // &
445 trim(key) // " missing from the case file")
446 end if
447
448 call core%print_to_string(ptr, buffer)
449 call output%initialize(strict_type_checking = .true.)
450 call output%load_from_string(buffer)
451
452 end subroutine json_get_subdict
453
456 subroutine json_get_subdict_or_empty(json, key, output)
457 type(json_file), intent(inout) :: json
458 character(len=*), intent(in) :: key
459 type(json_file), intent(inout) :: output
460
461 type(json_value), pointer :: ptr
462 type(json_core) :: core
463 logical :: found
464 character(len=:), allocatable :: buffer
465
466 ! Initialize empty object to return
467 call output%initialize(strict_type_checking = .true.)
468
469 call json%get_core(core)
470 call json%get(key, ptr, found)
471
472 ! Load the contents if found, otherwise the object stays empty.
473 if (found) then
474 call core%print_to_string(ptr, buffer)
475 call output%load_from_string(buffer)
476 end if
477
478 end subroutine json_get_subdict_or_empty
479
485 subroutine json_get_or_default_real(json, name, value, default)
486 type(json_file), intent(inout) :: json
487 character(len=*), intent(in) :: name
488 real(kind=sp), intent(out) :: value
489 real(kind=sp), intent(in) :: default
490 logical :: found
491 integer :: var_type
492
493 call json%info(name, found = found, var_type = var_type)
494
495 if (found .and. (var_type .ne. 6)) then
496 call neko_error("Parameter " // name // " present, but is not a real")
497 end if
498
499 call json%get(name, value, found)
500
501 if ((.not. found) .and. (.not. json_no_defaults)) then
502 value = default
503 call json%add(name, value)
504 else if (.not. found) then
505 call neko_error("Parameter " // name // " missing from the case file")
506 end if
507 end subroutine json_get_or_default_real
508
515 subroutine json_get_or_default_double(json, name, value, default)
516 type(json_file), intent(inout) :: json
517 character(len=*), intent(in) :: name
518 real(kind=dp), intent(out) :: value
519 real(kind=dp), intent(in) :: default
520 logical :: found
521 integer :: var_type
522
523 call json%info(name, found = found, var_type = var_type)
524
525 if (found .and. (var_type .ne. 6)) then
526 call neko_error("Parameter " // name // " present, but is not a real")
527 end if
528
529 call json%get(name, value, found)
530
531 if ((.not. found) .and. (.not. json_no_defaults)) then
532 value = default
533 call json%add(name, value)
534 else if (.not. found) then
535 call neko_error("Parameter " // name // " missing from the case file")
536 end if
537 end subroutine json_get_or_default_double
538
544 subroutine json_get_or_default_integer(json, name, value, default)
545 type(json_file), intent(inout) :: json
546 character(len=*), intent(in) :: name
547 integer, intent(out) :: value
548 integer, intent(in) :: default
549 logical :: found
550 integer :: var_type
551
552 call json%info(name, found = found, var_type = var_type)
553
554 if (found .and. (var_type .ne. 5)) then
555 call neko_error("Parameter " // name // " present, but " // &
556 "is not an integer")
557 end if
558
559 call json%get(name, value, found)
560
561 if ((.not. found) .and. (.not. json_no_defaults)) then
562 value = default
563 call json%add(name, value)
564 else if (.not. found) then
565 call neko_error("Parameter " // name // " missing from the case file")
566 end if
567 end subroutine json_get_or_default_integer
568
574 subroutine json_get_or_default_logical(json, name, value, default)
575 type(json_file), intent(inout) :: json
576 character(len=*), intent(in) :: name
577 logical, intent(out) :: value
578 logical, intent(in) :: default
579 logical :: found
580 integer :: var_type
581
582 call json%info(name, found = found, var_type = var_type)
583
584 if ((found) .and. (var_type .ne. 4)) then
585 call neko_error("Parameter " // name // " present, but is not a logical")
586 end if
587
588 call json%get(name, value, found)
589
590 if ((.not. found) .and. (.not. json_no_defaults)) then
591 value = default
592 call json%add(name, value)
593 else if (.not. found) then
594 call neko_error("Parameter " // name // " missing from the case file")
595 end if
596 end subroutine json_get_or_default_logical
597
603 subroutine json_get_or_default_string(json, name, value, default)
604 type(json_file), intent(inout) :: json
605 character(len=*), intent(in) :: name
606 character(len=:), allocatable, intent(out) :: value
607 character(len=*), intent(in) :: default
608 logical :: found
609 integer :: var_type
610
611 call json%info(name, found = found, var_type = var_type)
612
613 if (found .and. (var_type .ne. 7)) then
614 call neko_error("Parameter " // name // &
615 " present, but is not a string")
616 end if
617
618 call json%get(name, value, found)
619
620 if ((.not. found) .and. (.not. json_no_defaults)) then
621 value = default
622 call json%add(name, value)
623 else if (.not. found) then
624 call neko_error("Parameter " // name // " missing from the case file")
625 end if
626 end subroutine json_get_or_default_string
627
633 subroutine json_extract_item_from_array(core, array, i, item)
634 type(json_core), intent(inout) :: core
635 type(json_value), pointer, intent(in) :: array
636 integer, intent(in) :: i
637 type(json_file), intent(inout) :: item
638 type(json_value), pointer :: ptr
639 logical :: found
640 character(len=:), allocatable :: buffer
641
642 call core%get_child(array, i, ptr, found)
643 call core%print_to_string(ptr, buffer)
644 call item%initialize(strict_type_checking = .true.)
645 call item%load_from_string(buffer)
646
647 end subroutine json_extract_item_from_array
648
654 subroutine json_extract_item_from_name(json, name, i, item)
655 type(json_file), intent(inout) :: json
656 character(len=*), intent(in) :: name
657 integer, intent(in) :: i
658 type(json_file), intent(out) :: item
659
660 type(json_core) :: core
661 type(json_value), pointer :: array
662 type(json_value), pointer :: ptr
663 logical :: found
664 character(len=:), allocatable :: buffer
665
666 call json%get_core(core)
667 call json%get(name, array, found)
668
669 if (.not. found) then
670 call neko_error("Parameter " // name // " missing from the case file")
671 end if
672
673 call core%get_child(array, i, ptr, found)
674 call core%print_to_string(ptr, buffer)
675 call item%initialize(strict_type_checking = .true.)
676 call item%load_from_string(buffer)
677
678 end subroutine json_extract_item_from_name
679
684 subroutine check_expected_size(name, actual_size, expected_size)
685 character(len=*), intent(in) :: name
686 integer, intent(in) :: actual_size, expected_size
687 character(len=32) :: str_actual, str_expected
688
689 if (actual_size /= expected_size) then
690 write(str_actual, '(I0)') actual_size
691 write(str_expected, '(I0)') expected_size
692 call neko_error("Parameter '" // trim(name) // &
693 "' has incorrect size: got " // &
694 trim(str_actual) // ", but expected " // trim(str_expected))
695 end if
696 end subroutine check_expected_size
697
698end 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