9#define DUMMY_VALUE (-1337.0d0)
11#include "test_macros.inc"
36 DOUBLE PRECISION,
ALLOCATABLE,
PUBLIC :: field_out_data(:,:)
37 DOUBLE PRECISION,
ALLOCATABLE,
PUBLIC :: field_in_data(:,:)
38 INTEGER,
PUBLIC :: field_data_size
39 INTEGER,
PUBLIC :: point_id = huge(0)
40 CHARACTER(LEN=64),
PUBLIC :: config_filename
49 use,
INTRINSIC :: iso_c_binding, only : c_null_char
53 INTEGER :: global_rank, ierror
55 INTEGER,
PARAMETER :: max_opt_arg_len = 1024
56 CHARACTER(max_opt_arg_len) :: grid_dir
61 SUBROUTINE c_unlink ( path ) bind ( c, name='unlink' )
63 use,
INTRINSIC :: iso_c_binding, only : c_char
65 CHARACTER(KIND=c_char),
DIMENSION(*) :: path
67 END SUBROUTINE c_unlink
75 CALL test(command_argument_count() == 1)
76 CALL get_command_argument(1, grid_dir, arg_len)
78 config_filename =
'test_restart_dble.yaml'
83 CALL run_model_config(.false., .false., .false., grid_dir)
84 CALL run_model_config(.false., .false., .true., grid_dir)
86 CALL run_model_config(.true., .false., .false., grid_dir)
87 CALL run_model_config(.true., .false., .true., grid_dir)
89 CALL run_model_config(.false., .true., .false., grid_dir)
90 CALL run_model_config(.false., .true., .true., grid_dir)
92 CALL run_model_config(.true., .true., .false., grid_dir)
93 CALL run_model_config(.true., .true., .true., grid_dir)
95 DEALLOCATE(field_out_data)
96 DEALLOCATE(field_in_data)
98 CALL mpi_comm_rank(mpi_comm_world, global_rank, ierror)
99 IF (global_rank == 0)
CALL c_unlink(trim(config_filename) // c_null_char)
110 USE mpi,
ONLY : mpi_abort, mpi_comm_world
115 CALL test ( .false. )
118 CALL mpi_abort ( mpi_comm_world, 999, ierror )
122 SUBROUTINE run_model_config( &
123 icon_to_cube, cube_to_icon, config_from_file, grid_dir)
129 LOGICAL,
INTENT(IN) :: icon_to_cube
130 LOGICAL,
INTENT(IN) :: cube_to_icon
131 LOGICAL,
INTENT(IN) :: config_from_file
132 CHARACTER (LEN=*) :: grid_dir
134 INTEGER :: ierror, info
135 INTEGER :: global_rank, global_size
136 INTEGER :: local_comm, local_rank, local_size
140 INTEGER :: field_out_id, field_in_id
141 LOGICAL :: receives_data
143 INTEGER :: interp_stack_id
144 INTEGER,
PARAMETER :: collection_size = 1
146 CHARACTER (LEN=:),
ALLOCATABLE :: config
150 INTEGER,
INTENT(IN) :: comm_rank
151 INTEGER,
INTENT(IN) :: comm_size
152 CHARACTER (LEN=*) :: grid_dir
155 INTEGER,
INTENT(IN) :: comm_rank
156 INTEGER,
INTENT(IN) :: comm_size
161 CALL mpi_comm_rank(mpi_comm_world, global_rank, ierror)
162 CALL mpi_comm_size(mpi_comm_world, global_size, ierror)
166 "+1800-01-01T00:00:00.000",
"+2100-01-01T00:00:00.000")
168 IF (global_size < 3)
THEN
169 WRITE ( * , * )
"Wrong number of processes (should be at least 3)"
173 is_icon = global_rank < (global_size / 2)
179 CALL mpi_comm_rank(local_comm, local_rank, ierror)
180 CALL mpi_comm_size(local_comm, local_size, ierror)
181 CALL mpi_comm_free(local_comm, ierror)
184 IF (point_id == huge(point_id))
THEN
194 receives_data = cube_to_icon
196 'icon_to_cube', comp_id, (/point_id/), 1, 1,
"1", &
199 'cube_to_icon', comp_id, (/point_id/), 1, 1,
"1", &
202 receives_data = icon_to_cube
204 'cube_to_icon', comp_id, (/point_id/), 1, 1,
"1", &
207 'icon_to_cube', comp_id, (/point_id/), 1, 1,
"1", &
214 IF (config_from_file)
THEN
224 interp_stack_id, 1, 0, 0, 0)
227 IF (icon_to_cube .AND. .NOT. is_icon)
THEN
229 'icon',
'icon',
'icon_to_cube', &
230 'cube',
'cube',
'icon_to_cube', &
234 IF (cube_to_icon .AND. is_icon)
THEN
236 'cube',
'cube',
'cube_to_icon', &
237 'icon',
'icon',
'cube_to_icon', &
246 IF (global_rank == 0)
THEN
247 open(unit=999, file=config_filename, status=
'replace', &
248 form=
'formatted', action=
'write')
249 write(999,
"(A)") config
259 field_out_id,
SIZE(field_out_data, 1), collection_size, &
260 field_out_data, info, ierror)
262 field_in_data = dummy_value
264 field_in_id,
SIZE(field_in_data, 1), collection_size, &
265 field_in_data, info, ierror)
267 DO i = 1, field_data_size
269 IF (receives_data)
THEN
270 CALL test(abs(field_in_data(i,1) - field_out_data(i,1)) < 0.001)
272 CALL test(field_in_data(i,1) == dummy_value)
279 END SUBROUTINE run_model_config
286 USE field_data,
ONLY: field_out_data, field_in_data, field_data_size, point_id
287 use,
INTRINSIC :: iso_c_binding, only : c_loc
293 SUBROUTINE c_free ( ptr ) bind ( c, NAME='free' )
295 use,
INTRINSIC :: iso_c_binding, only : c_ptr
297 TYPE ( c_ptr ),
INTENT(IN),
VALUE :: ptr
299 END SUBROUTINE c_free
303 INTEGER,
INTENT(IN) :: comm_rank
304 INTEGER,
INTENT(IN) :: comm_size
305 CHARACTER (LEN=*) :: grid_dir
309 INTEGER :: nbr_vertices
311 INTEGER,
POINTER :: num_vertices_per_cell(:)
312 INTEGER,
POINTER :: cell_to_vertex(:)
313 DOUBLE PRECISION,
POINTER :: x_vertices(:)
314 DOUBLE PRECISION,
POINTER :: y_vertices(:)
315 DOUBLE PRECISION,
POINTER :: x_cells(:)
316 DOUBLE PRECISION,
POINTER :: y_cells(:)
318 INTEGER,
POINTER :: cell_mask_int(:)
319 INTEGER,
POINTER :: global_cell_id(:)
320 INTEGER,
POINTER :: cell_core_mask(:)
321 INTEGER,
POINTER :: global_corner_id(:)
322 INTEGER,
POINTER :: corner_core_mask(:)
324 LOGICAL,
ALLOCATABLE :: cell_mask(:)
327 trim(grid_dir) //
'icon_grid_R02B01.nc', nbr_vertices, nbr_cells, &
328 num_vertices_per_cell, cell_to_vertex, x_vertices, y_vertices, &
329 x_cells, y_cells, global_cell_id, cell_mask_int, cell_core_mask, &
330 global_corner_id, corner_core_mask, comm_rank, comm_size)
332 ALLOCATE(cell_mask(nbr_cells))
336 'icon', nbr_vertices, nbr_cells, sum(num_vertices_per_cell), &
337 num_vertices_per_cell, x_vertices, y_vertices, cell_to_vertex, grid_id)
349 ALLOCATE(field_out_data(nbr_cells,1))
350 field_data_size = nbr_cells
351 field_out_data(:,1) = &
352 merge(test_harmonic(x_cells(:), y_cells(:)), &
353 dummy_value, cell_core_mask == 1)
354 ALLOCATE(field_in_data(nbr_cells,1))
356 IF (
ASSOCIATED(num_vertices_per_cell))
CALL c_free(c_loc(num_vertices_per_cell(1)))
357 IF (
ASSOCIATED(cell_to_vertex))
CALL c_free(c_loc(cell_to_vertex(1)))
358 IF (
ASSOCIATED(x_vertices))
CALL c_free(c_loc(x_vertices(1)))
359 IF (
ASSOCIATED(y_vertices))
CALL c_free(c_loc(y_vertices(1)))
360 IF (
ASSOCIATED(x_cells))
CALL c_free(c_loc(x_cells(1)))
361 IF (
ASSOCIATED(y_cells))
CALL c_free(c_loc(y_cells(1)))
363 IF (
ASSOCIATED(cell_mask_int))
CALL c_free(c_loc(cell_mask_int(1)))
364 IF (
ASSOCIATED(global_cell_id))
CALL c_free(c_loc(global_cell_id(1)))
365 IF (
ASSOCIATED(cell_core_mask))
CALL c_free(c_loc(cell_core_mask(1)))
366 IF (
ASSOCIATED(global_corner_id))
CALL c_free(c_loc(global_corner_id(1)))
367 IF (
ASSOCIATED(corner_core_mask))
CALL c_free(c_loc(corner_core_mask(1)))
371 ELEMENTAL DOUBLE PRECISION FUNCTION test_harmonic ( lon, lat )
372 DOUBLE PRECISION,
INTENT(IN) :: lon, lat
374 DOUBLE PRECISION,
PARAMETER :: YAC_RAD = 0.017453292519943
376 2.0 + ((sin(2.0 * lat * yac_rad))**16.0 * cos(16.0 * lon * yac_rad))
377 END FUNCTION test_harmonic
382 num_vertices_per_cell, &
396 USE iso_c_binding,
ONLY: c_int, c_ptr, c_f_pointer, c_null_char
402 SUBROUTINE yac_read_part_icon_grid_information_c ( grid_file, &
405 num_vertices_per_cell, &
407 x_vertices, y_vertices, &
416 bind( c, name=
'yac_read_part_icon_grid_information' )
418 use,
INTRINSIC :: iso_c_binding, only : c_int, c_char, c_ptr
420 CHARACTER ( kind=c_char),
DIMENSION(*) :: grid_file
421 INTEGER ( kind=c_int ) :: nbr_vertices
422 INTEGER ( kind=c_int ) :: nbr_cells
423 TYPE (c_ptr ) :: num_vertices_per_cell
424 TYPE (c_ptr ) :: cell_to_vertex
425 TYPE (c_ptr ) :: x_vertices
426 TYPE (c_ptr ) :: y_vertices
427 TYPE (c_ptr ) :: x_cells
428 TYPE (c_ptr ) :: y_cells
429 TYPE (c_ptr ) :: global_cell_ids
430 TYPE (c_ptr ) :: cell_mask
431 TYPE (c_ptr ) :: cell_core_mask
432 TYPE (c_ptr ) :: global_corner_ids
433 TYPE (c_ptr ) :: corner_core_mask
434 INTEGER ( kind=c_int ),
VALUE :: comm_rank
435 INTEGER ( kind=c_int ),
VALUE :: comm_size
437 END SUBROUTINE yac_read_part_icon_grid_information_c
441 CHARACTER (LEN=*) :: grid_file
442 INTEGER ( kind=c_int ) :: nbr_vertices
443 INTEGER ( kind=c_int ) :: nbr_cells
444 INTEGER,
POINTER :: num_vertices_per_cell(:)
445 INTEGER,
POINTER :: cell_to_vertex(:)
446 DOUBLE PRECISION,
POINTER :: x_vertices(:)
447 DOUBLE PRECISION,
POINTER :: y_vertices(:)
448 DOUBLE PRECISION,
POINTER :: x_cells(:)
449 DOUBLE PRECISION,
POINTER :: y_cells(:)
450 INTEGER,
POINTER :: global_cell_ids(:)
451 INTEGER,
POINTER :: cell_mask(:)
452 INTEGER,
POINTER :: cell_core_mask(:)
453 INTEGER,
POINTER :: global_corner_ids(:)
454 INTEGER,
POINTER :: corner_core_mask(:)
455 INTEGER ( kind=c_int ) :: comm_rank
456 INTEGER ( kind=c_int ) :: comm_size
458 TYPE(c_ptr) :: num_vertices_per_cell_
459 TYPE(c_ptr) :: cell_to_vertex_
460 TYPE(c_ptr) :: x_vertices_
461 TYPE(c_ptr) :: y_vertices_
462 TYPE(c_ptr) :: x_cells_
463 TYPE(c_ptr) :: y_cells_
464 TYPE(c_ptr) :: global_cell_ids_
465 TYPE(c_ptr) :: cell_mask_
466 TYPE(c_ptr) :: cell_core_mask_
467 TYPE(c_ptr) :: global_corner_ids_
468 TYPE(c_ptr) :: corner_core_mask_
470 CALL yac_read_part_icon_grid_information_c ( trim(grid_file) // c_null_char, &
473 num_vertices_per_cell_, &
475 x_vertices_, y_vertices_, &
476 x_cells_, y_cells_, &
480 global_corner_ids_, &
485 CALL c_f_pointer(num_vertices_per_cell_, num_vertices_per_cell, (/nbr_cells/))
486 CALL c_f_pointer(cell_to_vertex_, cell_to_vertex, (/sum(num_vertices_per_cell)/))
487 CALL c_f_pointer(x_vertices_, x_vertices, (/nbr_vertices/))
488 CALL c_f_pointer(y_vertices_, y_vertices, (/nbr_vertices/))
489 CALL c_f_pointer(x_cells_, x_cells, (/nbr_cells/))
490 CALL c_f_pointer(y_cells_, y_cells, (/nbr_cells/))
491 CALL c_f_pointer(global_cell_ids_, global_cell_ids, (/nbr_cells/))
492 CALL c_f_pointer(cell_mask_, cell_mask, (/nbr_cells/))
493 CALL c_f_pointer(cell_core_mask_, cell_core_mask, (/nbr_cells/))
494 CALL c_f_pointer(global_corner_ids_, global_corner_ids, (/nbr_vertices/))
495 CALL c_f_pointer(corner_core_mask_, corner_core_mask, (/nbr_vertices/))
497 cell_to_vertex = cell_to_vertex + 1
508 USE field_data,
ONLY: field_out_data, field_in_data, field_data_size, point_id
509 use,
INTRINSIC :: iso_c_binding, only : c_loc
515 SUBROUTINE c_free ( ptr ) bind ( c, NAME='free' )
517 use,
INTRINSIC :: iso_c_binding, only : c_ptr
519 TYPE ( c_ptr ),
INTENT(IN),
VALUE :: ptr
521 END SUBROUTINE c_free
525 INTEGER,
INTENT(IN) :: comm_rank
526 INTEGER,
INTENT(IN) :: comm_size
530 INTEGER,
PARAMETER :: n = 50
532 INTEGER :: nbr_vertices
534 INTEGER,
POINTER :: num_vertices_per_cell(:)
535 INTEGER,
POINTER :: cell_to_vertex(:)
536 DOUBLE PRECISION,
POINTER :: x_vertices(:)
537 DOUBLE PRECISION,
POINTER :: y_vertices(:)
538 DOUBLE PRECISION,
POINTER :: x_cells(:)
539 DOUBLE PRECISION,
POINTER :: y_cells(:)
541 INTEGER,
POINTER :: cell_core_mask(:)
542 INTEGER,
POINTER :: corner_core_mask(:)
543 INTEGER,
POINTER :: global_cell_id(:)
544 INTEGER,
POINTER :: global_corner_id(:)
547 n, nbr_vertices, nbr_cells, num_vertices_per_cell, cell_to_vertex, &
548 x_vertices, y_vertices, x_cells, y_cells, global_cell_id, &
549 cell_core_mask, global_corner_id, corner_core_mask, &
550 comm_rank, comm_size)
553 'cube', nbr_vertices, nbr_cells, sum(num_vertices_per_cell), &
554 num_vertices_per_cell, x_vertices, y_vertices, cell_to_vertex, grid_id)
564 ALLOCATE(field_out_data(nbr_cells,1))
565 field_data_size = nbr_cells
566 field_out_data(:,1) = &
567 merge(test_harmonic(x_cells(:), y_cells(:)), &
568 dummy_value, cell_core_mask == 1)
569 ALLOCATE(field_in_data(nbr_cells,1))
571 IF (
ASSOCIATED(num_vertices_per_cell))
CALL c_free(c_loc(num_vertices_per_cell(1)))
572 IF (
ASSOCIATED(cell_to_vertex))
CALL c_free(c_loc(cell_to_vertex(1)))
573 IF (
ASSOCIATED(x_vertices))
CALL c_free(c_loc(x_vertices(1)))
574 IF (
ASSOCIATED(y_vertices))
CALL c_free(c_loc(y_vertices(1)))
575 IF (
ASSOCIATED(x_cells))
CALL c_free(c_loc(x_cells(1)))
576 IF (
ASSOCIATED(y_cells))
CALL c_free(c_loc(y_cells(1)))
578 IF (
ASSOCIATED(global_cell_id))
CALL c_free(c_loc(global_cell_id(1)))
579 IF (
ASSOCIATED(cell_core_mask))
CALL c_free(c_loc(cell_core_mask(1)))
580 IF (
ASSOCIATED(global_corner_id))
CALL c_free(c_loc(global_corner_id(1)))
581 IF (
ASSOCIATED(corner_core_mask))
CALL c_free(c_loc(corner_core_mask(1)))
585 ELEMENTAL DOUBLE PRECISION FUNCTION test_harmonic ( lon, lat )
586 DOUBLE PRECISION,
INTENT(IN) :: lon, lat
588 DOUBLE PRECISION,
PARAMETER :: YAC_RAD = 0.017453292519943
590 2.0 + ((sin(2.0 * lat * yac_rad))**16.0 * cos(16.0 * lon * yac_rad))
591 END FUNCTION test_harmonic
596 num_vertices_per_cell, &
609 USE iso_c_binding,
ONLY: c_int, c_ptr, c_f_pointer
615 SUBROUTINE yac_generate_part_cube_grid_information_c ( n, &
618 num_vertices_per_cell, &
620 x_vertices, y_vertices, &
628 bind( c, name=
'yac_generate_part_cube_grid_information' )
630 use,
INTRINSIC :: iso_c_binding, only : c_int, c_ptr
632 INTEGER ( kind=c_int ),
VALUE :: n
633 INTEGER ( kind=c_int ) :: nbr_vertices
634 INTEGER ( kind=c_int ) :: nbr_cells
635 TYPE(c_ptr) :: num_vertices_per_cell
636 TYPE(c_ptr) :: cell_to_vertex
637 TYPE(c_ptr) :: x_vertices
638 TYPE(c_ptr) :: y_vertices
639 TYPE(c_ptr) :: x_cells
640 TYPE(c_ptr) :: y_cells
641 TYPE(c_ptr) :: global_cell_ids
642 TYPE(c_ptr) :: cell_core_mask
643 TYPE(c_ptr) :: global_corner_ids
644 TYPE(c_ptr) :: corner_core_mask
645 INTEGER ( kind=c_int ),
VALUE :: comm_rank
646 INTEGER ( kind=c_int ),
VALUE :: comm_size
648 END SUBROUTINE yac_generate_part_cube_grid_information_c
652 INTEGER ( kind=c_int ) :: n
653 INTEGER ( kind=c_int ) :: nbr_vertices
654 INTEGER ( kind=c_int ) :: nbr_cells
655 INTEGER ( kind=c_int ),
POINTER :: num_vertices_per_cell(:)
656 INTEGER ( kind=c_int ),
POINTER :: cell_to_vertex(:)
657 DOUBLE PRECISION,
POINTER :: x_vertices(:)
658 DOUBLE PRECISION,
POINTER :: y_vertices(:)
659 DOUBLE PRECISION,
POINTER :: x_cells(:)
660 DOUBLE PRECISION,
POINTER :: y_cells(:)
661 INTEGER ( kind=c_int ),
POINTER :: global_cell_ids(:)
662 INTEGER ( kind=c_int ),
POINTER :: cell_core_mask(:)
663 INTEGER ( kind=c_int ),
POINTER :: global_corner_ids(:)
664 INTEGER ( kind=c_int ),
POINTER :: corner_core_mask(:)
665 INTEGER ( kind=c_int ) :: comm_rank
666 INTEGER ( kind=c_int ) :: comm_size
668 TYPE(c_ptr) :: num_vertices_per_cell_
669 TYPE(c_ptr) :: cell_to_vertex_
670 TYPE(c_ptr) :: x_vertices_
671 TYPE(c_ptr) :: y_vertices_
672 TYPE(c_ptr) :: x_cells_
673 TYPE(c_ptr) :: y_cells_
674 TYPE(c_ptr) :: global_cell_ids_
675 TYPE(c_ptr) :: cell_core_mask_
676 TYPE(c_ptr) :: global_corner_ids_
677 TYPE(c_ptr) :: corner_core_mask_
679 CALL yac_generate_part_cube_grid_information_c ( n, &
682 num_vertices_per_cell_, &
684 x_vertices_, y_vertices_, &
685 x_cells_, y_cells_, &
688 global_corner_ids_, &
693 CALL c_f_pointer(num_vertices_per_cell_, num_vertices_per_cell, (/nbr_cells/))
694 CALL c_f_pointer(cell_to_vertex_, cell_to_vertex, (/sum(num_vertices_per_cell)/))
695 CALL c_f_pointer(x_vertices_, x_vertices, (/nbr_vertices/))
696 CALL c_f_pointer(y_vertices_, y_vertices, (/nbr_vertices/))
697 CALL c_f_pointer(x_cells_, x_cells, (/nbr_cells/))
698 CALL c_f_pointer(y_cells_, y_cells, (/nbr_cells/))
699 CALL c_f_pointer(global_cell_ids_, global_cell_ids, (/nbr_cells/))
700 CALL c_f_pointer(cell_core_mask_, cell_core_mask, (/nbr_cells/))
701 CALL c_f_pointer(global_corner_ids_, global_corner_ids, (/nbr_vertices/))
702 CALL c_f_pointer(corner_core_mask_, corner_core_mask, (/nbr_vertices/))
704 cell_to_vertex = cell_to_vertex + 1
void yac_generate_part_cube_grid_information(unsigned n, unsigned *nbr_vertices, unsigned *nbr_cells, unsigned **num_vertices_per_cell, unsigned **cell_to_vertex, double **x_vertices, double **y_vertices, double **x_cells, double **y_cells, int **global_cell_id, int **cell_core_mask, int **global_corner_id, int **corner_core_mask, int rank, int size)
Fortran interface for the coupler cleanup before restart.
Fortran interface for definition of a couple.
Fortran interface for the definition of time parameters.
Fortran interface for the definition of coupling fields using default masks.
Fortran interface for the definition of grids.
Fortran interface for the definition of points.
Fortran interface for invoking the end of the definition phase.
Fortran interface for the coupler termination.
Fortran interface for getting back a local MPI communicator.
Fortran interfaces for the definition of an interpolation stack.
Fortran interface for receiving coupling fields.
Fortran interface for sending coupling fields.
Fortran interface for the reading of configuration files.
Fortran interface for the setting of a grid core masks.
Fortran interface for the setting of grid global ids.
Fortran interface for the setting of default pointset masks.
Fortran interface for invoking the end of the definition phase.
static void merge(char *base_a, size_t num_a, int a_ascending, char *base_b, size_t num_b, int b_ascending, size_t size, int(*compar)(const void *, const void *), char *target)
subroutine, public start_test(name)
subroutine, public stop_test()
subroutine, public exit_tests()
@ yac_proleptic_gregorian
integer yac_yaml_emitter_default_f
Flag paramters for emitting of coupling configurations.
@ yac_reduction_time_none
void yac_read_part_icon_grid_information(const char *filename, int *nbr_vertices, int *nbr_cells, int **num_vertices_per_cell, int **cell_to_vertex, double **x_vertices, double **y_vertices, double **x_cells, double **y_cells, int **global_cell_id, int **cell_mask, int **cell_core_mask, int **global_corner_id, int **corner_core_mask, int rank, int size)
subroutine generate_icon_grid(comm_rank, comm_size, grid_dir)
subroutine generate_cube_grid(comm_rank, comm_size)