Neko 1.99.5
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 integer :: i, n_children
397 integer :: var_type
398
399 call json%info(name, found = found, var_type = var_type, &
400 n_children = n_children)
401 if (.not. found) then
402 call neko_error("Parameter " // name // " missing from the case file")
403 else if (var_type .ne. 3) then
404 call neko_error("Parameter " // name // " is not an array")
405 end if
406
407 if (.not. allocated(value)) then
408 allocate(value(n_children))
409 else if (len(value) .lt. n_children) then
410 deallocate(value)
411 allocate(value(n_children))
412 end if
413
414 call json%get(name, json_val, found)
415 call json%get_core(core)
416
417 do i = 1, n_children
418 call core%get_child(json_val, i, val_ptr, found)
419 call core%get(val_ptr, string_value)
420
421 if (len(string_value) .gt. 0) then
422 value(i) = string_value
423 else if (present(filler)) then
424 value(i) = filler
425 end if
426 end do
427
428 end subroutine json_get_string_array
429
431 subroutine json_get_subdict(json, key, output)
432 type(json_file), intent(inout) :: json
433 character(len=*), intent(in) :: key
434 type(json_file), intent(inout) :: output
435
436 type(json_value), pointer :: ptr
437 type(json_core) :: core
438 logical :: found
439 character(len=:), allocatable :: buffer
440
441 call json%get_core(core)
442 call json%get(key, ptr, found)
443
444 if (.not. found) then
445 call neko_error("Parameter " // &
446 trim(key) // " missing from the case file")
447 end if
448
449 call core%print_to_string(ptr, buffer)
450 call output%initialize(strict_type_checking = .true.)
451 call output%load_from_string(buffer)
452
453 end subroutine json_get_subdict
454
457 subroutine json_get_subdict_or_empty(json, key, output)
458 type(json_file), intent(inout) :: json
459 character(len=*), intent(in) :: key
460 type(json_file), intent(inout) :: output
461
462 type(json_value), pointer :: ptr
463 type(json_core) :: core
464 logical :: found
465 character(len=:), allocatable :: buffer
466
467 ! Initialize empty object to return
468 call output%initialize(strict_type_checking = .true.)
469
470 call json%get_core(core)
471 call json%get(key, ptr, found)
472
473 ! Load the contents if found, otherwise the object stays empty.
474 if (found) then
475 call core%print_to_string(ptr, buffer)
476 call output%load_from_string(buffer)
477 end if
478
479 end subroutine json_get_subdict_or_empty
480
486 subroutine json_get_or_default_real(json, name, value, default)
487 type(json_file), intent(inout) :: json
488 character(len=*), intent(in) :: name
489 real(kind=sp), intent(out) :: value
490 real(kind=sp), intent(in) :: default
491 logical :: found
492 integer :: var_type
493
494 call json%info(name, found = found, var_type = var_type)
495
496 if (found .and. (var_type .ne. 6)) then
497 call neko_error("Parameter " // name // " present, but is not a real")
498 end if
499
500 call json%get(name, value, found)
501
502 if ((.not. found) .and. (.not. json_no_defaults)) then
503 value = default
504 call json%add(name, value)
505 else if (.not. found) then
506 call neko_error("Parameter " // name // " missing from the case file")
507 end if
508 end subroutine json_get_or_default_real
509
516 subroutine json_get_or_default_double(json, name, value, default)
517 type(json_file), intent(inout) :: json
518 character(len=*), intent(in) :: name
519 real(kind=dp), intent(out) :: value
520 real(kind=dp), intent(in) :: default
521 logical :: found
522 integer :: var_type
523
524 call json%info(name, found = found, var_type = var_type)
525
526 if (found .and. (var_type .ne. 6)) then
527 call neko_error("Parameter " // name // " present, but is not a real")
528 end if
529
530 call json%get(name, value, found)
531
532 if ((.not. found) .and. (.not. json_no_defaults)) then
533 value = default
534 call json%add(name, value)
535 else if (.not. found) then
536 call neko_error("Parameter " // name // " missing from the case file")
537 end if
538 end subroutine json_get_or_default_double
539
545 subroutine json_get_or_default_integer(json, name, value, default)
546 type(json_file), intent(inout) :: json
547 character(len=*), intent(in) :: name
548 integer, intent(out) :: value
549 integer, intent(in) :: default
550 logical :: found
551 integer :: var_type
552
553 call json%info(name, found = found, var_type = var_type)
554
555 if (found .and. (var_type .ne. 5)) then
556 call neko_error("Parameter " // name // " present, but " // &
557 "is not an integer")
558 end if
559
560 call json%get(name, value, found)
561
562 if ((.not. found) .and. (.not. json_no_defaults)) then
563 value = default
564 call json%add(name, value)
565 else if (.not. found) then
566 call neko_error("Parameter " // name // " missing from the case file")
567 end if
568 end subroutine json_get_or_default_integer
569
575 subroutine json_get_or_default_logical(json, name, value, default)
576 type(json_file), intent(inout) :: json
577 character(len=*), intent(in) :: name
578 logical, intent(out) :: value
579 logical, intent(in) :: default
580 logical :: found
581 integer :: var_type
582
583 call json%info(name, found = found, var_type = var_type)
584
585 if ((found) .and. (var_type .ne. 4)) then
586 call neko_error("Parameter " // name // " present, but is not a logical")
587 end if
588
589 call json%get(name, value, found)
590
591 if ((.not. found) .and. (.not. json_no_defaults)) then
592 value = default
593 call json%add(name, value)
594 else if (.not. found) then
595 call neko_error("Parameter " // name // " missing from the case file")
596 end if
597 end subroutine json_get_or_default_logical
598
604 subroutine json_get_or_default_string(json, name, value, default)
605 type(json_file), intent(inout) :: json
606 character(len=*), intent(in) :: name
607 character(len=:), allocatable, intent(out) :: value
608 character(len=*), intent(in) :: default
609 logical :: found
610 integer :: var_type
611
612 call json%info(name, found = found, var_type = var_type)
613
614 if (found .and. (var_type .ne. 7)) then
615 call neko_error("Parameter " // name // &
616 " present, but is not a string")
617 end if
618
619 call json%get(name, value, found)
620
621 if ((.not. found) .and. (.not. json_no_defaults)) then
622 value = default
623 call json%add(name, value)
624 else if (.not. found) then
625 call neko_error("Parameter " // name // " missing from the case file")
626 end if
627 end subroutine json_get_or_default_string
628
634 subroutine json_extract_item_from_array(core, array, i, item)
635 type(json_core), intent(inout) :: core
636 type(json_value), pointer, intent(in) :: array
637 integer, intent(in) :: i
638 type(json_file), intent(inout) :: item
639 type(json_value), pointer :: ptr
640 logical :: found
641 character(len=:), allocatable :: buffer
642
643 call core%get_child(array, i, ptr, found)
644 call core%print_to_string(ptr, buffer)
645 call item%initialize(strict_type_checking = .true.)
646 call item%load_from_string(buffer)
647
648 end subroutine json_extract_item_from_array
649
655 subroutine json_extract_item_from_name(json, name, i, item)
656 type(json_file), intent(inout) :: json
657 character(len=*), intent(in) :: name
658 integer, intent(in) :: i
659 type(json_file), intent(out) :: item
660
661 type(json_core) :: core
662 type(json_value), pointer :: array
663 type(json_value), pointer :: ptr
664 logical :: found
665 character(len=:), allocatable :: buffer
666
667 call json%get_core(core)
668 call json%get(name, array, found)
669
670 if (.not. found) then
671 call neko_error("Parameter " // name // " missing from the case file")
672 end if
673
674 call core%get_child(array, i, ptr, found)
675 call core%print_to_string(ptr, buffer)
676 call item%initialize(strict_type_checking = .true.)
677 call item%load_from_string(buffer)
678
679 end subroutine json_extract_item_from_name
680
685 subroutine check_expected_size(name, actual_size, expected_size)
686 character(len=*), intent(in) :: name
687 integer, intent(in) :: actual_size, expected_size
688 character(len=32) :: str_actual, str_expected
689
690 if (actual_size /= expected_size) then
691 write(str_actual, '(I0)') actual_size
692 write(str_expected, '(I0)') expected_size
693 call neko_error("Parameter '" // trim(name) // &
694 "' has incorrect size: got " // &
695 trim(str_actual) // ", but expected " // trim(str_expected))
696 end if
697 end subroutine check_expected_size
698
699end 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