From 3cf8da1e69c2cd22f49e418ea7d46a814001e971 Mon Sep 17 00:00:00 2001 From: Ricky Wong <141156427+mo-rickywong@users.noreply.github.com> Date: Thu, 26 Feb 2026 23:46:56 +0000 Subject: [PATCH] Commit changes to allow control of partition constraints --- .../source/driver/coupled_driver_mod.f90 | 7 +- .../source/driver/io_demo_driver_mod.f90 | 1 + .../driver/simple_diffusion_driver_mod.f90 | 1 + .../source/driver/skeleton_driver_mod.f90 | 7 +- components/driver/source/driver_mesh_mod.f90 | 3 +- .../source/mesh/runtime_partition_mod.f90 | 29 ++- .../unit-test/mesh/create_mesh_mod_test.pf | 4 + .../source/mesh/panel_decomposition_mod.f90 | 234 +++++++++--------- infrastructure/source/mesh/partition_mod.F90 | 63 +++-- .../function_space_chain_mod_test.pf | 28 ++- .../mesh/local_mesh_collection_mod_test.pf | 3 + .../unit-test/mesh/local_mesh_mod_test.pf | 15 +- .../unit-test/mesh/mesh_colouring_mod_test.pf | 56 +++-- .../mesh/mesh_map_collection_mod_test.pf | 7 +- .../unit-test/mesh/mesh_map_mod_test.pf | 3 + .../unit-test/mesh/mesh_mod_test.pf | 35 ++- .../unit-test/mesh/mesh_tiling_mod_test.pf | 19 +- .../unit-test/mesh/partition_mod_test.pf | 71 +++--- .../support/generate_local_objects_mod.f90 | 3 + 19 files changed, 358 insertions(+), 231 deletions(-) diff --git a/applications/coupled/source/driver/coupled_driver_mod.f90 b/applications/coupled/source/driver/coupled_driver_mod.f90 index ba5ded978..a1e8a29e9 100644 --- a/applications/coupled/source/driver/coupled_driver_mod.f90 +++ b/applications/coupled/source/driver/coupled_driver_mod.f90 @@ -78,7 +78,7 @@ subroutine initialise( program_name, modeldb, calendar ) real(r_def) :: domain_bottom real(r_def) :: domain_height real(r_def) :: scaled_radius - logical :: apply_partition_check + logical :: check_partitions integer(i_def) :: i integer(i_def), parameter :: one_layer = 1_i_def @@ -119,12 +119,13 @@ subroutine initialise( program_name, modeldb, calendar ) ! Create the required meshes stencil_depth = 1 - apply_partition_check = .false. + check_partitions = .false. + call init_mesh( modeldb%configuration, & modeldb%mpi%get_comm_rank(), & modeldb%mpi%get_comm_size(), & base_mesh_names, extrusion, & - stencil_depth, apply_partition_check ) + stencil_depth, check_partitions ) allocate( twod_names, source=base_mesh_names ) do i=1, size(twod_names) diff --git a/applications/io_demo/source/driver/io_demo_driver_mod.f90 b/applications/io_demo/source/driver/io_demo_driver_mod.f90 index 6daefdec6..402f5a02f 100644 --- a/applications/io_demo/source/driver/io_demo_driver_mod.f90 +++ b/applications/io_demo/source/driver/io_demo_driver_mod.f90 @@ -155,6 +155,7 @@ subroutine initialise(program_name, modeldb) ! --------------------------------------------------------- stencil_depth = 1 check_partitions = .false. + call init_mesh( modeldb%configuration, & modeldb%mpi%get_comm_rank(), & modeldb%mpi%get_comm_size(), & diff --git a/applications/simple_diffusion/source/driver/simple_diffusion_driver_mod.f90 b/applications/simple_diffusion/source/driver/simple_diffusion_driver_mod.f90 index 13f1b9461..6d9f913eb 100644 --- a/applications/simple_diffusion/source/driver/simple_diffusion_driver_mod.f90 +++ b/applications/simple_diffusion/source/driver/simple_diffusion_driver_mod.f90 @@ -149,6 +149,7 @@ subroutine initialise( program_name, modeldb) ! --------------------------------------------------------- stencil_depth = 1 check_partitions = .false. + call init_mesh( modeldb%configuration, & modeldb%mpi%get_comm_rank(), & modeldb%mpi%get_comm_size(), & diff --git a/applications/skeleton/source/driver/skeleton_driver_mod.f90 b/applications/skeleton/source/driver/skeleton_driver_mod.f90 index 607a48568..24e94664f 100644 --- a/applications/skeleton/source/driver/skeleton_driver_mod.f90 +++ b/applications/skeleton/source/driver/skeleton_driver_mod.f90 @@ -82,7 +82,7 @@ subroutine initialise(program_name, modeldb) real(r_def) :: domain_bottom real(r_def) :: domain_height real(r_def) :: scaled_radius - logical :: apply_partition_check + logical :: check_partitions integer(i_def) :: i integer(i_def), parameter :: one_layer = 1_i_def @@ -140,12 +140,13 @@ subroutine initialise(program_name, modeldb) ! Create the required meshes !----------------------------------------------------------------------- stencil_depth = 1 - apply_partition_check = .false. + check_partitions = .false. + call init_mesh( modeldb%configuration, & modeldb%mpi%get_comm_rank(), & modeldb%mpi%get_comm_size(), & base_mesh_names, extrusion, & - stencil_depth, apply_partition_check ) + stencil_depth, check_partitions ) allocate( twod_names, source=base_mesh_names ) do i=1, size(twod_names) diff --git a/components/driver/source/driver_mesh_mod.f90 b/components/driver/source/driver_mesh_mod.f90 index 74d2d2af0..ea399c04a 100644 --- a/components/driver/source/driver_mesh_mod.f90 +++ b/components/driver/source/driver_mesh_mod.f90 @@ -328,7 +328,8 @@ subroutine init_mesh( configuration, & decomposition, & stencil_depths, & generate_inner_halos, & - partitioner_ptr ) + partitioner_ptr, & + enforce_constraints=check_partitions ) ! 2.2f Read in the global intergrid mesh mappings, diff --git a/components/driver/source/mesh/runtime_partition_mod.f90 b/components/driver/source/mesh/runtime_partition_mod.f90 index eec3ae86e..f0c461317 100644 --- a/components/driver/source/mesh/runtime_partition_mod.f90 +++ b/components/driver/source/mesh/runtime_partition_mod.f90 @@ -119,7 +119,8 @@ subroutine create_local_mesh( mesh_names, & decomposition, & stencil_depths, & generate_inner_halos, & - partitioner_ptr ) + partitioner_ptr, & + enforce_constraints ) implicit none @@ -133,6 +134,8 @@ subroutine create_local_mesh( mesh_names, & logical(l_def), intent(in) :: generate_inner_halos + logical(l_def), intent(in), optional :: enforce_constraints + procedure(partitioner_interface), intent(in), pointer :: partitioner_ptr type(global_mesh_type), pointer :: global_mesh_ptr @@ -142,6 +145,14 @@ subroutine create_local_mesh( mesh_names, & integer(i_def) :: local_mesh_id, i integer(i_def) :: mapping_factor + logical(l_def) :: enforce_constraints_choice + + if (present(enforce_constraints)) then + enforce_constraints_choice = enforce_constraints + else + enforce_constraints_choice = .true. + end if + do i=1, size(mesh_names) global_mesh_ptr => global_mesh_collection%get_global_mesh( mesh_names(i) ) @@ -149,14 +160,16 @@ subroutine create_local_mesh( mesh_names, & mapping_factor = calc_mapping_factor( global_mesh_collection, global_mesh_ptr ) ! Create partition - partition = partition_type( global_mesh_ptr, & - partitioner_ptr, & - decomposition, & - stencil_depths(i), & - generate_inner_halos, & - local_rank, & - total_ranks, & + partition = partition_type( global_mesh_ptr, & + partitioner_ptr, & + decomposition, & + stencil_depths(i), & + generate_inner_halos, & + enforce_constraints_choice, & + local_rank, & + total_ranks, & mapping_factor ) + ! Create local_mesh call local_mesh%initialise( global_mesh_ptr, partition ) diff --git a/components/driver/unit-test/mesh/create_mesh_mod_test.pf b/components/driver/unit-test/mesh/create_mesh_mod_test.pf index fd8fe0108..646c641a1 100644 --- a/components/driver/unit-test/mesh/create_mesh_mod_test.pf +++ b/components/driver/unit-test/mesh/create_mesh_mod_test.pf @@ -97,6 +97,7 @@ contains logical(l_def), intent(in) :: generate_inner_halos integer(i_def), intent(in) :: local_rank integer(i_def), intent(in) :: total_ranks + ! Local variables type(ugrid_mesh_data_type) :: ugrid_mesh_data type(global_mesh_type) :: global_mesh @@ -107,6 +108,8 @@ contains procedure(partitioner_interface), pointer :: partitioner_ptr integer(i_def) :: local_mesh_id + logical(l_def), parameter :: enforce_constraints = .true. + ! Reset in case of repeated initialisation call mesh_collection%clear() call global_mesh_collection%clear() @@ -129,6 +132,7 @@ contains decomposition, & max_stencil_depth, & generate_inner_halos, & + enforce_constraints, & local_rank, & total_ranks ) diff --git a/infrastructure/source/mesh/panel_decomposition_mod.f90 b/infrastructure/source/mesh/panel_decomposition_mod.f90 index 0c0545722..d902de2d9 100644 --- a/infrastructure/source/mesh/panel_decomposition_mod.f90 +++ b/infrastructure/source/mesh/panel_decomposition_mod.f90 @@ -80,16 +80,16 @@ module panel_decomposition_mod ! Interface for routines that generate partition shape and location abstract interface - subroutine get_partition_interface( self, & - relative_rank, & - panel_ranks, & - mapping_factor, & - num_cells_x, & - num_cells_y, & - any_maps, & - partition_width, & - partition_height, & - partition_x_pos, & + subroutine get_partition_interface( self, & + relative_rank, & + panel_ranks, & + mapping_factor, & + num_cells_x, & + num_cells_y, & + check_constraints, & + partition_width, & + partition_height, & + partition_x_pos, & partition_y_pos ) use constants_mod, only: i_def import :: panel_decomposition_type @@ -101,7 +101,7 @@ subroutine get_partition_interface( self, & mapping_factor, & num_cells_x, & num_cells_y - logical, intent(in) :: any_maps + logical, intent(in) :: check_constraints integer(i_def), intent(inout) :: partition_width, & partition_height, & @@ -134,22 +134,21 @@ end function get_nprocs_interface !> @param[in] mapping_factor The ratio between this and coarsest mesh !> @param[in] num_cells_x The panel's size in the x direction !> @param[in] num_cells_y The panel's size in the y direction - !> @param[in] any_maps Whether there exist maps between meshes that - !> must having aligning partitions + !> @param[in] check_constaints Check meshes have aligned partitions !> @param[inout] partition_width The partition's size in the x direction !> @param[inout] partition_height The partition's size in the y direction !> @param[inout] partition_x_pos The x index of the partition !> @param[inout] partition_y_pos The y index of the partition - subroutine get_custom_partition( self, & - relative_rank, & - panel_ranks, & - mapping_factor, & - num_cells_x, & - num_cells_y, & - any_maps, & - partition_width, & - partition_height, & - partition_x_pos, & + subroutine get_custom_partition( self, & + relative_rank, & + panel_ranks, & + mapping_factor, & + num_cells_x, & + num_cells_y, & + check_constraints, & + partition_width, & + partition_height, & + partition_x_pos, & partition_y_pos ) implicit none @@ -159,7 +158,7 @@ subroutine get_custom_partition( self, & mapping_factor, & num_cells_x, & num_cells_y - logical, intent(in) :: any_maps + logical, intent(in) :: check_constraints integer(i_def), intent(inout) :: partition_width, & partition_height, & partition_x_pos, & @@ -173,7 +172,10 @@ subroutine get_custom_partition( self, & num_yprocs = self%num_yprocs if ( panel_ranks /= num_xprocs * num_yprocs ) then - write( log_scratch_space, "(a,i0,a,i0,a,i0)" ) "Total ranks per panel ", panel_ranks, " must be the product of xprocs ", self%num_xprocs, " and yprocs ", self%num_yprocs + write( log_scratch_space, "(3(A,I0))" ) & + "Total ranks per panel ", panel_ranks, & + " must be the product of xprocs ", self%num_xprocs, & + " and yprocs ", self%num_yprocs call log_event( log_scratch_space, LOG_LEVEL_ERROR ) end if @@ -183,7 +185,7 @@ subroutine get_custom_partition( self, & num_xprocs, & num_yprocs, & panel_ranks, & - any_maps ) + check_constraints ) call xy_decomposition( relative_rank, & num_cells_x, & @@ -240,22 +242,21 @@ end function get_custom_nprocs !> @param[in] mapping_factor The ratio between this and coarsest mesh !> @param[in] num_cells_x The panel's size in the x direction !> @param[in] num_cells_y The panel's size in the y direction - !> @param[in] any_maps Whether there exist maps between meshes that - !> must having aligning partitions + !> @param[in] check_constaints Check meshes have aligned partitions !> @param[inout] partition_width The partition's size in the x direction !> @param[inout] partition_height The partition's size in the y direction !> @param[inout] partition_x_pos The x index of the partition !> @param[inout] partition_y_pos The y index of the partition - subroutine get_auto_partition( self, & - relative_rank, & - panel_ranks, & - mapping_factor, & - num_cells_x, & - num_cells_y, & - any_maps, & - partition_width, & - partition_height, & - partition_x_pos, & + subroutine get_auto_partition( self, & + relative_rank, & + panel_ranks, & + mapping_factor, & + num_cells_x, & + num_cells_y, & + check_constraints, & + partition_width, & + partition_height, & + partition_x_pos, & partition_y_pos ) implicit none @@ -265,7 +266,7 @@ subroutine get_auto_partition( self, & mapping_factor, & num_cells_x, & num_cells_y - logical, intent(in) :: any_maps + logical, intent(in) :: check_constraints integer(i_def), intent(inout) :: partition_width, & partition_height, & partition_x_pos, & @@ -303,7 +304,7 @@ subroutine get_auto_partition( self, & num_yprocs = panel_ranks / num_xprocs ! If we have any maps then x and y procs must divide the coarsest panel - if ( (.not. any_maps) .or. & + if ( (.not. check_constraints) .or. & ( mod( mp_num_cells_x, num_xprocs ) == 0 .and. & mod( mp_num_cells_y, num_yprocs ) == 0 ) & ) then @@ -321,7 +322,7 @@ subroutine get_auto_partition( self, & num_yprocs = panel_ranks / num_xprocs ! If we have any maps then x and y procs must divide the coarsest panel - if ( (.not. any_maps) .or. & + if ( (.not. check_constraints) .or. & ( mod( mp_num_cells_x, num_xprocs ) == 0 .and. & mod( mp_num_cells_y, num_yprocs ) == 0 ) & ) then @@ -341,7 +342,7 @@ subroutine get_auto_partition( self, & num_xprocs, & num_yprocs, & panel_ranks, & - any_maps ) + check_constraints ) call xy_decomposition( relative_rank, & num_cells_x, & @@ -388,22 +389,21 @@ end function get_auto_nprocs !> @param[in] mapping_factor The ratio between this and coarsest mesh !> @param[in] num_cells_x The panel's size in the x direction !> @param[in] num_cells_y The panel's size in the y direction - !> @param[in] any_maps Whether there exist maps between meshes that - !> must having aligning partitions + !> @param[in] check_constaints Check meshes have aligned partitions !> @param[inout] partition_width The partition's size in the x direction !> @param[inout] partition_height The partition's size in the y direction !> @param[inout] partition_x_pos The x index of the partition !> @param[inout] partition_y_pos The y index of the partition - subroutine get_row_partition( self, & - relative_rank, & - panel_ranks, & - mapping_factor, & - num_cells_x, & - num_cells_y, & - any_maps, & - partition_width, & - partition_height, & - partition_x_pos, & + subroutine get_row_partition( self, & + relative_rank, & + panel_ranks, & + mapping_factor, & + num_cells_x, & + num_cells_y, & + check_constraints, & + partition_width, & + partition_height, & + partition_x_pos, & partition_y_pos ) implicit none @@ -413,7 +413,7 @@ subroutine get_row_partition( self, & mapping_factor, & num_cells_x, & num_cells_y - logical, intent(in) :: any_maps + logical, intent(in) :: check_constraints integer(i_def), intent(inout) :: partition_width, & partition_height, & partition_x_pos, & @@ -431,7 +431,7 @@ subroutine get_row_partition( self, & num_xprocs, & num_yprocs, & panel_ranks, & - any_maps ) + check_constraints ) call xy_decomposition( relative_rank, & num_cells_x, & @@ -478,22 +478,21 @@ end function get_row_nprocs !> @param[in] mapping_factor The ratio between this and coarsest mesh !> @param[in] num_cells_x The panel's size in the x direction !> @param[in] num_cells_y The panel's size in the y direction - !> @param[in] any_maps Whether there exist maps between meshes that - !> must having aligning partitions + !> @param[in] check_constaints Check meshes have aligned partitions !> @param[inout] partition_width The partition's size in the x direction !> @param[inout] partition_height The partition's size in the y direction !> @param[inout] partition_x_pos The x index of the partition !> @param[inout] partition_y_pos The y index of the partition - subroutine get_column_partition( self, & - relative_rank, & - panel_ranks, & - mapping_factor, & - num_cells_x, & - num_cells_y, & - any_maps, & - partition_width, & - partition_height, & - partition_x_pos, & + subroutine get_column_partition( self, & + relative_rank, & + panel_ranks, & + mapping_factor, & + num_cells_x, & + num_cells_y, & + check_constraints, & + partition_width, & + partition_height, & + partition_x_pos, & partition_y_pos ) implicit none @@ -503,7 +502,7 @@ subroutine get_column_partition( self, & mapping_factor, & num_cells_x, & num_cells_y - logical, intent(in) :: any_maps + logical, intent(in) :: check_constraints integer(i_def), intent(inout) :: partition_width, & partition_height, & partition_x_pos, & @@ -521,7 +520,7 @@ subroutine get_column_partition( self, & num_xprocs, & num_yprocs, & panel_ranks, & - any_maps ) + check_constraints ) call xy_decomposition( relative_rank, & num_cells_x, & @@ -568,20 +567,21 @@ end function get_column_nprocs !> @param[in] mapping_factor The ratio between this and coarsest mesh !> @param[in] num_cells_x The panel's size in the x direction !> @param[in] num_cells_y The panel's size in the y direction + !> @param[in] check_constaints Check meshes have aligned partitions !> @param[inout] partition_width The partition's size in the x direction !> @param[inout] partition_height The partition's size in the y direction !> @param[inout] partition_x_pos The x index of the partition !> @param[inout] partition_y_pos The y index of the partition - subroutine get_auto_nonuniform_partition( self, & - relative_rank, & - panel_ranks, & - mapping_factor, & - num_cells_x, & - num_cells_y, & - any_maps, & - partition_width, & - partition_height, & - partition_x_pos, & + subroutine get_auto_nonuniform_partition( self, & + relative_rank, & + panel_ranks, & + mapping_factor, & + num_cells_x, & + num_cells_y, & + check_constraints, & + partition_width, & + partition_height, & + partition_x_pos, & partition_y_pos ) implicit none @@ -591,7 +591,7 @@ subroutine get_auto_nonuniform_partition( self, & mapping_factor, & num_cells_x, & num_cells_y - logical, intent(in) :: any_maps + logical, intent(in) :: check_constraints integer(i_def), intent(inout) :: partition_width, & partition_height, & partition_x_pos, & @@ -620,7 +620,7 @@ subroutine get_auto_nonuniform_partition( self, & num_xprocs = start_xprocs - i ! If there are any intermesh maps then xprocs must also divide the domain. - if ( ( mod(mp_num_cells_x, num_xprocs) == 0 ) .or. .not. any_maps ) then + if ( ( mod(mp_num_cells_x, num_xprocs) == 0 ) .or. .not. check_constraints ) then found_factors = .true. exit end if @@ -628,7 +628,7 @@ subroutine get_auto_nonuniform_partition( self, & num_xprocs = start_xprocs + i ! If there are any intermesh maps then xprocs must also divide the domain. - if ( ( mod(mp_num_cells_x, num_xprocs) == 0 ) .or. .not. any_maps ) then + if ( ( mod(mp_num_cells_x, num_xprocs) == 0 ) .or. .not. check_constraints ) then found_factors = .true. exit end if @@ -684,20 +684,21 @@ end function get_auto_nonuniform_nprocs !> @param[in] mapping_factor The ratio between this and coarsest mesh !> @param[in] num_cells_x The panel's size in the x direction !> @param[in] num_cells_y The panel's size in the y direction + !> @param[in] check_constaints Check meshes have aligned partitions !> @param[inout] partition_width The partition's size in the x direction !> @param[inout] partition_height The partition's size in the y direction !> @param[inout] partition_x_pos The x index of the partition !> @param[inout] partition_y_pos The y index of the partition - subroutine get_guided_nonuniform_partition( self, & - relative_rank, & - panel_ranks, & - mapping_factor, & - num_cells_x, & - num_cells_y, & - any_maps, & - partition_width, & - partition_height, & - partition_x_pos, & + subroutine get_guided_nonuniform_partition( self, & + relative_rank, & + panel_ranks, & + mapping_factor, & + num_cells_x, & + num_cells_y, & + check_constraints, & + partition_width, & + partition_height, & + partition_x_pos, & partition_y_pos ) implicit none @@ -707,7 +708,7 @@ subroutine get_guided_nonuniform_partition( self, & mapping_factor, & num_cells_x, & num_cells_y - logical, intent(in) :: any_maps + logical, intent(in) :: check_constraints integer(i_def), intent(inout) :: partition_width, & partition_height, & partition_x_pos, & @@ -721,17 +722,20 @@ subroutine get_guided_nonuniform_partition( self, & ! Defensive checks if ( num_xprocs <= 0 ) then - call log_event("Number of x processes must be strictly positive.", LOG_LEVEL_ERROR) + call log_event( "Number of x processes must be strictly positive.", & + LOG_LEVEL_ERROR ) end if if ( num_cells_x < num_xprocs ) then - write(log_scratch_space, "(a,i0,a,i0)") "Must have more cells than partitions in x direction." + write(log_scratch_space, '(A)') & + "Must have more cells than partitions in x direction." call log_event(log_scratch_space, LOG_LEVEL_ERROR) end if - if ( any_maps .and. ( mod(num_cells_x, num_xprocs) /= 0 ) ) then - write(log_scratch_space, "(a,i0,a,i0)") "Requested number of ranks in x direction ", num_xprocs, & - " must divide panel x dimension ", num_cells_x + if ( check_constraints .and. ( mod(num_cells_x, num_xprocs) /= 0 ) ) then + write(log_scratch_space, '(2(A,I0))') & + "Requested number of ranks in x direction ", num_xprocs, & + " must divide panel x dimension ", num_cells_x call log_event(log_scratch_space, LOG_LEVEL_ERROR) end if @@ -839,14 +843,15 @@ end subroutine xy_decomposition !> @param[in] num_cells_y The panel's size in the y direction !> @param[in] num_xprocs The number of partitions in the x direction !> @param[in] num_yprocs The number of partitions in the y direction - !> @param[in] panel_ranks The number of ranks the panel is to be split into - !> @param[in] any_maps Whether any mesh maps exist for this mesh + !> @param[in] panel_ranks The number of ranks the panel is to be + !> split into + !> @param[in] check_constaints Check meshes have aligned partitions subroutine xy_defensive_checks( num_cells_x, & num_cells_y, & num_xprocs, & num_yprocs, & panel_ranks, & - any_maps ) + check_constraints ) implicit none integer(i_def), intent(in) :: num_cells_x, & @@ -854,7 +859,8 @@ subroutine xy_defensive_checks( num_cells_x, & num_xprocs, & num_yprocs, & panel_ranks - logical , intent(in) :: any_maps + + logical(l_def), intent(in) :: check_constraints if ( num_xprocs <=0 .or. num_yprocs <= 0 ) then write(log_scratch_space, "(a,i0,a,i0,a)") & @@ -878,23 +884,27 @@ subroutine xy_defensive_checks( num_cells_x, & end if ! Equal divisions are only required if there are maps between meshes - if (any_maps) then + if (check_constraints) then + call log_event("Performing partition constraints.", log_level_debug) if ( mod(num_cells_x, num_xprocs) /= 0 ) then - write(log_scratch_space, "(a,i0,a,i0)") "Requested number of ranks in x direction ", num_xprocs, & + write(log_scratch_space, "(2(A,I0))") & + "Requested number of ranks in x direction ", num_xprocs, & " must divide panel x dimension ", num_cells_x call log_event(log_scratch_space, LOG_LEVEL_ERROR) end if if ( mod(num_cells_y, num_yprocs) /= 0 ) then - write(log_scratch_space, "(a,i0,a,i0)") "Requested number of ranks in y direction ", num_yprocs, & - " must divide panel y dimension ", num_cells_y + write(log_scratch_space, "(2(A,I0))") & + "Requested number of ranks in y direction ", num_yprocs, & + " must divide panel y dimension ", num_cells_y call log_event(log_scratch_space, LOG_LEVEL_ERROR) end if end if if ( num_xprocs * num_yprocs /= panel_ranks ) then - write(log_scratch_space, "(a,i0,a,i0)") "Requested number of partitions ", num_xprocs * num_yprocs, & - " must equal available number of ranks per panel ", panel_ranks + write(log_scratch_space, "(2(A,I0))") & + "Requested number of partitions ", num_xprocs * num_yprocs, & + " must equal available number of ranks per panel ", panel_ranks call log_event(log_scratch_space, LOG_LEVEL_ERROR) end if @@ -1020,14 +1030,16 @@ function calc_panel_width( global_mesh ) result(panel_edge_ncells_x) type(global_mesh_type), intent(in), pointer :: global_mesh - integer(i_def) :: void_cell ! Cell id that marks the cell as a cell outside of the partition. + integer(i_def) :: void_cell ! Cell id that marks the cell as a cell + ! outside of the partition. integer(i_def) :: w_cell ! The id of a cell on the western edge of the domain integer(i_def) :: cell_next(4) ! The cells around the cell being queried integer(i_def) :: cell_next_e ! The cell to the east of the cell being queried logical :: periodic_xy(2) ! Is mesh periodic in the x/y-axes logical :: valid_for_global_model - integer(i_def) :: panel_edge_ncells_x ! number of cells across a panel of the input mesh in x-direction + integer(i_def) :: panel_edge_ncells_x ! Number of cells across a panel of + ! the input mesh in x-direction integer(i_def) :: npanels valid_for_global_model = ( global_mesh%is_topology_periodic() .and. & diff --git a/infrastructure/source/mesh/partition_mod.F90 b/infrastructure/source/mesh/partition_mod.F90 index a9ff9097e..fb4f9f35d 100644 --- a/infrastructure/source/mesh/partition_mod.F90 +++ b/infrastructure/source/mesh/partition_mod.F90 @@ -154,6 +154,7 @@ subroutine partitioner_interface( global_mesh, & max_stencil_depth, & mapping_factor, & generate_inner_halos, & + enforce_constraints, & global_cell_id, & num_inner, & num_edge, & @@ -170,12 +171,15 @@ subroutine partitioner_interface( global_mesh, & total_ranks integer(i_def), intent(in) :: max_stencil_depth integer(i_def), intent(in) :: mapping_factor - logical(l_def), intent(in) :: generate_inner_halos integer(i_def), intent(inout), allocatable :: global_cell_id(:) integer(i_def), intent(out) :: num_inner(:), & num_edge, & num_halo(:), & num_ghost + + logical(l_def), intent(in) :: generate_inner_halos + logical(l_def), intent(in) :: enforce_constraints + end subroutine partitioner_interface end interface @@ -204,6 +208,7 @@ function partition_constructor( global_mesh, & decomposition, & max_stencil_depth, & generate_inner_halos, & + enforce_constraints, & local_rank, & total_ranks, & mapping_factor ) result(self) @@ -216,9 +221,11 @@ function partition_constructor( global_mesh, & integer(i_def), intent(in) :: max_stencil_depth integer(i_def), intent(in) :: local_rank integer(i_def), intent(in) :: total_ranks - logical(l_def), intent(in) :: generate_inner_halos integer(i_def), optional, intent(in) :: mapping_factor + logical(l_def), intent(in) :: generate_inner_halos + logical(l_def), intent(in) :: enforce_constraints + type(partition_type), target :: self integer(i_def) :: i @@ -250,6 +257,7 @@ function partition_constructor( global_mesh, & self%max_stencil_depth, & mf_actual, & generate_inner_halos, & + enforce_constraints, & self%global_cell_id, & self%num_inner, & self%num_edge, & @@ -420,6 +428,7 @@ subroutine partitioner_planar( global_mesh, & max_stencil_depth, & mapping_factor, & generate_inner_halos, & + enforce_constraints, & partitioned_cells, & num_inner, & num_edge, & @@ -440,7 +449,9 @@ subroutine partitioner_planar( global_mesh, & integer(i_def), intent(out) :: num_edge integer(i_def), intent(out) :: num_halo( : ) integer(i_def), intent(out) :: num_ghost - logical(l_def), intent(in) :: generate_inner_halos + + logical(l_def), intent(in) :: generate_inner_halos + logical(l_def), intent(in) :: enforce_constraints ! A biperiodic mesh has 1 panel num_panels = 1 @@ -453,6 +464,7 @@ subroutine partitioner_planar( global_mesh, & max_stencil_depth, & mapping_factor, & generate_inner_halos, & + enforce_constraints, & partitioned_cells, & num_inner, & num_edge, & @@ -500,6 +512,7 @@ subroutine partitioner_cubedsphere( global_mesh, & max_stencil_depth, & mapping_factor, & generate_inner_halos, & + enforce_constraints, & partitioned_cells, & num_inner, & num_edge, & @@ -520,7 +533,9 @@ subroutine partitioner_cubedsphere( global_mesh, & integer(i_def), intent(out) :: num_edge integer(i_def), intent(out) :: num_halo( : ) integer(i_def), intent(out) :: num_ghost - logical(l_def), intent(in) :: generate_inner_halos + + logical(l_def), intent(in) :: generate_inner_halos + logical(l_def), intent(in) :: enforce_constraints ! A cubed sphere has 6 panels num_panels = 6 @@ -533,6 +548,7 @@ subroutine partitioner_cubedsphere( global_mesh, & max_stencil_depth, & mapping_factor, & generate_inner_halos, & + enforce_constraints, & partitioned_cells, & num_inner, & num_edge, & @@ -576,6 +592,7 @@ subroutine partitioner_cubedsphere_serial( global_mesh, & max_stencil_depth, & mapping_factor, & generate_inner_halos, & + enforce_constraints, & partitioned_cells, & num_inner, & num_edge, & @@ -586,6 +603,7 @@ subroutine partitioner_cubedsphere_serial( global_mesh, & ! partition per cubed-sphere "face". In order to run the code serially ! a special case for creating a single partition with all points is required. ! So here. we just return one big partition that holds everything + implicit none type(global_mesh_type), pointer, intent(in) :: global_mesh @@ -601,7 +619,9 @@ subroutine partitioner_cubedsphere_serial( global_mesh, & integer(i_def), intent(out) :: num_edge integer(i_def), intent(out) :: num_halo( : ) integer(i_def), intent(out) :: num_ghost - logical(l_def), intent(in) :: generate_inner_halos + + logical(l_def), intent(in) :: generate_inner_halos + logical(l_def), intent(in) :: enforce_constraints integer(i_def) :: i @@ -638,6 +658,7 @@ subroutine partitioner_rectangular_panels( global_mesh, & max_stencil_depth, & mapping_factor, & generate_inner_halos, & + enforce_constraints, & partitioned_cells, & num_inner, & num_edge, & @@ -670,7 +691,9 @@ subroutine partitioner_rectangular_panels( global_mesh, & integer(i_def), intent(out) :: num_halo( : ) ! Number of cells that are halo cells. integer(i_def), intent(out) :: num_ghost ! Number of cells that are ghost cells - surrounding, ! but not in the partitioned domain - logical(l_def), intent(in) :: generate_inner_halos ! Flag to control the generation of inner halos + + logical(l_def), intent(in) :: generate_inner_halos ! Flag to control the generation of inner halos + logical(l_def), intent(in) :: enforce_constraints ! Apply contraints on the partitoner solutions integer(i_def) :: face ! which face of the cube is implied by local_rank (0->5) integer(i_def) :: start_cell ! lowest cell id of the face implaced by local_rank @@ -683,10 +706,12 @@ subroutine partitioner_rectangular_panels( global_mesh, & integer(i_def) :: num_y ! number of cells in the domain on this partition in y-dirn integer(i_def) :: ix, iy ! loop counters over cells on this partition in x- and y-dirns integer(i_def) :: void_cell ! Cell id that marks the cell as a cell outside of the partition. - logical :: any_maps ! Whether there exist maps between meshes, meaning their partitions must align. integer(i_def) :: start1, end1, inc1 ! Loop indices for inserting cells into the partition integer(i_def) :: start2, end2, inc2 ! Loop indices for inserting cells into the partition + logical(l_def) :: any_maps ! Whether there exist maps between meshes, meaning their partitions must align. + logical(l_def) :: check_constraints + ! Create linked lists type(linked_list_type) :: partition ! a list of all cells in the partition @@ -731,6 +756,12 @@ subroutine partitioner_rectangular_panels( global_mesh, & n_cross_panels = 1 any_maps = global_mesh%get_nmaps() > 0 + if (any_maps .and. enforce_constraints) then + check_constraints = .true. + else + check_constraints = .false. + end if + nullify( last ) nullify( start_subsect ) nullify( insert_point ) @@ -881,15 +912,15 @@ subroutine partitioner_rectangular_panels( global_mesh, & ! Work out the start index and number of cells (in x- and y-dirn) for ! the local partition - call decomposition%get_partition( relative_rank, & - panel_ranks, & - mapping_factor, & - num_cells_x, & - num_cells_y, & - any_maps, & - num_x, & - num_y, & - start_x, & + call decomposition%get_partition( relative_rank, & + panel_ranks, & + mapping_factor, & + num_cells_x, & + num_cells_y, & + check_constraints, & + num_x, & + num_y, & + start_x, & start_y ) diff --git a/infrastructure/unit-test/function_space/function_space_chain_mod_test.pf b/infrastructure/unit-test/function_space/function_space_chain_mod_test.pf index 5e85f4193..defeb59e5 100644 --- a/infrastructure/unit-test/function_space/function_space_chain_mod_test.pf +++ b/infrastructure/unit-test/function_space/function_space_chain_mod_test.pf @@ -128,6 +128,8 @@ integer(i_def) :: mesh_id(4) integer(i_def) :: local_mesh_id integer(i_def) :: i, j, n, x, y +logical(l_def), parameter :: enforce_constraints = .true. + procedure (partitioner_interface), pointer :: partitioner_ptr => null() type(custom_decomposition_type) :: decomposition @@ -155,8 +157,9 @@ do i=1, size(mesh_names) global_mesh_ptr => global_mesh_collection % get_global_mesh( mesh_names(i) ) partition = partition_type( global_mesh_ptr, partitioner_ptr, & - decomposition, max_stencil_depth, & - generate_inner_halos, & + decomposition, max_stencil_depth, & + generate_inner_halos, & + enforce_constraints, & local_rank, total_ranks ) call local_mesh%initialise( global_mesh_ptr, partition ) call local_mesh%init_cell_owner() @@ -212,8 +215,9 @@ do i=1, size(mesh_names) global_mesh_ptr => global_mesh_collection % get_global_mesh (mesh_names(i)) source_local_mesh_ptr => local_mesh_collection % get_local_mesh (mesh_names(i)) partition = partition_type( global_mesh_ptr, partitioner_ptr, & - decomposition, max_stencil_depth, & - generate_inner_halos, & + decomposition, max_stencil_depth, & + generate_inner_halos, & + enforce_constraints, & local_rank, total_ranks ) mesh = mesh_type( source_local_mesh_ptr, extrusion ) mesh_id(i) = mesh_collection % add_new_mesh( mesh ) @@ -229,21 +233,21 @@ do i=1, size(mesh_names)-1 end do mesh_ptr => mesh_collection % get_mesh( mesh_id(1) ) -this%function_space1 => function_space_collection%get_fs( mesh_ptr, & - element_order_h, & +this%function_space1 => function_space_collection%get_fs( mesh_ptr, & + element_order_h, & element_order_v, W0 ) mesh_ptr => mesh_collection % get_mesh( mesh_id(2) ) -this%function_space2 => function_space_collection%get_fs( mesh_ptr, & - element_order_h, & +this%function_space2 => function_space_collection%get_fs( mesh_ptr, & + element_order_h, & element_order_v, W0 ) mesh_ptr => mesh_collection % get_mesh( mesh_id(3) ) -this%function_space3 => function_space_collection%get_fs( mesh_ptr, & - element_order_h, & +this%function_space3 => function_space_collection%get_fs( mesh_ptr, & + element_order_h, & element_order_v, W0 ) mesh_ptr => mesh_collection % get_mesh( mesh_id(4) ) -this%function_space4 => function_space_collection%get_fs( mesh_ptr, & - element_order_h, & +this%function_space4 => function_space_collection%get_fs( mesh_ptr, & + element_order_h, & element_order_v, W0 ) nullify(mesh_ptr) diff --git a/infrastructure/unit-test/mesh/local_mesh_collection_mod_test.pf b/infrastructure/unit-test/mesh/local_mesh_collection_mod_test.pf index c3dd0d7f8..fed2bad63 100644 --- a/infrastructure/unit-test/mesh/local_mesh_collection_mod_test.pf +++ b/infrastructure/unit-test/mesh/local_mesh_collection_mod_test.pf @@ -97,7 +97,9 @@ contains type(local_mesh_type), pointer :: local_mesh_ptr1, local_mesh_ptr2 integer(i_def) :: local_mesh_id integer(i_def) :: unit_test_local_mesh_id + logical(l_def) :: generate_inner_halos + logical(l_def), parameter :: enforce_constraints = .false. filename = 'data/mesh_BiP8x8-750x250.nc' mesh_name = 'unit_test' @@ -117,6 +119,7 @@ contains decomposition, & max_stencil_depth, & generate_inner_halos, & + enforce_constraints, & this%getProcessRank(), & this%getNumProcesses() ) diff --git a/infrastructure/unit-test/mesh/local_mesh_mod_test.pf b/infrastructure/unit-test/mesh/local_mesh_mod_test.pf index c0be3dce3..d724e5ed8 100644 --- a/infrastructure/unit-test/mesh/local_mesh_mod_test.pf +++ b/infrastructure/unit-test/mesh/local_mesh_mod_test.pf @@ -141,6 +141,8 @@ contains logical(l_def) :: generate_inner_halos + logical(l_def), parameter :: enforce_constraints = .false. + logical(l_def) :: answer ! Create a local mesh from partitioning a global mesh on 1 and 4 processors @@ -175,6 +177,7 @@ contains decomposition, & max_stencil_depth, & generate_inner_halos, & + enforce_constraints, & this%getProcessRank(), & this%getNumProcesses() ) @@ -461,6 +464,8 @@ contains integer(i_def) :: total_ranks logical(l_def) :: generate_inner_halos + logical(l_def), parameter :: enforce_constraints = .true. + type(global_mesh_type), target :: global_mesh type(global_mesh_type), pointer :: global_mesh_ptr => null() @@ -470,7 +475,7 @@ contains type(local_mesh_type), target :: local_mesh(2) type(local_mesh_map_type), pointer :: local_mesh_map - integer(i_def), allocatable :: mesh_map(:,:,:) + integer(i_def), allocatable :: mesh_map(:,:,:) npanels = 6 filename='data/mesh_C32_MG.nc' @@ -490,10 +495,10 @@ contains global_mesh = global_mesh_type( ugrid_mesh_data ) call ugrid_mesh_data%clear() global_mesh_ptr => global_mesh - partition = partition_type( global_mesh_ptr, partitioner_ptr, & - decomposition, max_stencil_depth, & - generate_inner_halos, local_rank, & - total_ranks ) + partition = partition_type( global_mesh_ptr, partitioner_ptr, & + decomposition, max_stencil_depth, & + generate_inner_halos, enforce_constraints, & + local_rank, total_ranks ) call local_mesh(i)%initialise( global_mesh_ptr, partition ) nullify(global_mesh_ptr) diff --git a/infrastructure/unit-test/mesh/mesh_colouring_mod_test.pf b/infrastructure/unit-test/mesh/mesh_colouring_mod_test.pf index 9ef91840e..4c87b6dec 100644 --- a/infrastructure/unit-test/mesh/mesh_colouring_mod_test.pf +++ b/infrastructure/unit-test/mesh/mesh_colouring_mod_test.pf @@ -130,7 +130,8 @@ subroutine test_compute_colours_cubedsphere(this) integer(i_def) :: err character( 200 ) :: message - logical(l_def), parameter :: generate_inner_halos = .true. + logical(l_def), parameter :: generate_inner_halos = .true. + logical(l_def), parameter :: enforce_constraints = .false. filename = "data/mesh_C4.nc" call ugrid_mesh_data%read_from_file(trim(filename), mesh_name) @@ -140,13 +141,14 @@ subroutine test_compute_colours_cubedsphere(this) decomposition = custom_decomposition_type(this%xproc, this%yproc) partitioner_ptr => partitioner_cubedsphere_serial - partition = partition_type( global_mesh_ptr, & - partitioner_ptr, & - decomposition, & - halo_depth, & - generate_inner_halos, & - this%local_rank, & - this%total_ranks) + partition = partition_type( global_mesh_ptr, & + partitioner_ptr, & + decomposition, & + halo_depth, & + generate_inner_halos, & + enforce_constraints, & + this%local_rank, & + this%total_ranks ) call local_mesh%initialise( global_mesh_ptr, partition ) call local_mesh%init_cell_owner() @@ -254,7 +256,9 @@ subroutine test_compute_colours_biperiodic(this) type(mesh_type) :: mesh integer(i_def) :: err - logical(l_def), parameter :: generate_inner_halos = .true. + logical(l_def), parameter :: generate_inner_halos = .true. + logical(l_def), parameter :: enforce_constraints = .false. + integer(i_def), parameter :: max_stencil_depth = 1 filename = "data/mesh_BiP8x8-750x250.nc" call ugrid_mesh_data%read_from_file(trim(filename), mesh_name) @@ -264,13 +268,14 @@ subroutine test_compute_colours_biperiodic(this) decomposition = custom_decomposition_type(this%xproc, this%yproc) partitioner_ptr => partitioner_planar - partition = partition_type(global_mesh_ptr, & - partitioner_ptr, & - decomposition, & - 1, & - generate_inner_halos, & - this%local_rank, & - this%total_ranks) + partition = partition_type( global_mesh_ptr, & + partitioner_ptr, & + decomposition, & + max_stencil_depth, & + generate_inner_halos, & + enforce_constraints, & + this%local_rank, & + this%total_ranks ) call local_mesh%initialise( global_mesh_ptr, partition ) call local_mesh%init_cell_owner() @@ -354,7 +359,9 @@ subroutine test_compute_colours_generic(this) type(mesh_type) :: mesh integer(i_def) :: err - logical(l_def), parameter :: generate_inner_halos = .true. + logical(l_def), parameter :: generate_inner_halos = .true. + logical(l_def), parameter :: enforce_constraints = .false. + integer(i_def), parameter :: max_stencil_depth = 1 ! Force colour generator to use generic colour routine by not saying ! it's a cubed sphere @@ -366,13 +373,14 @@ subroutine test_compute_colours_generic(this) partitioner_ptr => partitioner_cubedsphere_serial decomposition = custom_decomposition_type(this%xproc, this%yproc) - partition = partition_type( global_mesh_ptr, & - partitioner_ptr, & - decomposition, & - 1, & - generate_inner_halos, & - this%local_rank, & - this%total_ranks) + partition = partition_type( global_mesh_ptr, & + partitioner_ptr, & + decomposition, & + max_stencil_depth, & + generate_inner_halos, & + enforce_constraints, & + this%local_rank, & + this%total_ranks) call local_mesh%initialise( global_mesh_ptr, partition ) call local_mesh%init_cell_owner() diff --git a/infrastructure/unit-test/mesh/mesh_map_collection_mod_test.pf b/infrastructure/unit-test/mesh/mesh_map_collection_mod_test.pf index b4b2c87ca..e3d5c7425 100644 --- a/infrastructure/unit-test/mesh/mesh_map_collection_mod_test.pf +++ b/infrastructure/unit-test/mesh/mesh_map_collection_mod_test.pf @@ -57,6 +57,7 @@ module mesh_map_collection_mod_test real(r_def), parameter :: domain_top = 10000.0_r_def real(r_def), parameter :: radius = 6371229.0_r_def logical(l_def), parameter :: generate_inner_halos = .true. + logical(l_def), parameter :: enforce_constraints = .true. contains @@ -114,7 +115,8 @@ contains partitioner_ptr, & decomposition, & max_stencil_depth, & - generate_inner_halos, & + generate_inner_halos, & + enforce_constraints, & local_rank, total_ranks ) call coarse_local_mesh%initialise( coarse_global_mesh_ptr, & @@ -134,7 +136,8 @@ contains partitioner_ptr, & decomposition, & max_stencil_depth, & - generate_inner_halos, & + generate_inner_halos, & + enforce_constraints, & local_rank, total_ranks ) call fine_local_mesh%initialise( fine_global_mesh_ptr, & diff --git a/infrastructure/unit-test/mesh/mesh_map_mod_test.pf b/infrastructure/unit-test/mesh/mesh_map_mod_test.pf index 1c1be4a66..012cd33fe 100644 --- a/infrastructure/unit-test/mesh/mesh_map_mod_test.pf +++ b/infrastructure/unit-test/mesh/mesh_map_mod_test.pf @@ -58,6 +58,7 @@ module mesh_map_mod_test real(r_def), parameter :: domain_top = 10000.0_r_def real(r_def), parameter :: radius = 6371229.0_r_def logical(l_def), parameter :: generate_inner_halos = .true. + logical(l_def), parameter :: enforce_constraints = .true. integer(i_def), parameter :: CoarseToFineMap(2,2,96) = reshape( & [ 1, 2, 9, 10, 3, 4, 11, 12, & @@ -189,6 +190,7 @@ contains decomposition, & max_stencil_depth, & generate_inner_halos, & + enforce_constraints, & local_rank, total_ranks ) call coarse_local_mesh%initialise( coarse_global_mesh_ptr, & @@ -209,6 +211,7 @@ contains decomposition, & max_stencil_depth, & generate_inner_halos, & + enforce_constraints, & local_rank, total_ranks ) call fine_local_mesh%initialise( fine_global_mesh_ptr, & diff --git a/infrastructure/unit-test/mesh/mesh_mod_test.pf b/infrastructure/unit-test/mesh/mesh_mod_test.pf index 4061998a8..853811920 100644 --- a/infrastructure/unit-test/mesh/mesh_mod_test.pf +++ b/infrastructure/unit-test/mesh/mesh_mod_test.pf @@ -7,7 +7,8 @@ !> module mesh_mod_test - use constants_mod, only: r_def, i_def, PI, str_max_filename, str_def + use constants_mod, only: r_def, i_def, PI, str_max_filename, & + str_def, l_def use coord_transform_mod, only: llr2xyz use extrusion_mod, only: uniform_extrusion_type, PRIME_EXTRUSION use global_mesh_collection_mod, & @@ -188,7 +189,7 @@ contains global_mesh_id = global_mesh_collection%add_unit_test_global_mesh() this%global_mesh => global_mesh_collection%get_global_mesh(global_mesh_id) - partition = partition_type() + partition = partition_type() call this%local_mesh%initialise( this%global_mesh, partition ) call this%local_mesh%init_cell_owner() @@ -741,7 +742,8 @@ contains !============================================================================== @Test( npes=[1] ) subroutine test_mesh_map_retrieval( this) - use ncdf_quad_mod, only: ncdf_quad_type + + use ncdf_quad_mod, only: ncdf_quad_type implicit none @@ -749,7 +751,6 @@ contains type(ugrid_mesh_data_type) :: ugrid_mesh_data - integer(i_def) :: mesh_map_id integer(i_def) :: test_integer @@ -789,6 +790,14 @@ contains integer(i_def) :: ncells character(str_def), allocatable :: target_mesh_names(:) + integer(i_def), parameter :: local_rank = 0 + integer(i_def), parameter :: total_ranks = 1 + integer(i_def), parameter :: xprocs = 1 + integer(i_def), parameter :: yprocs = 1 + integer(i_def), parameter :: max_stencil_depth = 1 + logical(l_def), parameter :: generate_inner_halos = .true. + logical(l_def), parameter :: enforce_constraints = .true. + ! Clear out the global and local mesh collection, as they may contain ! unit test meshes - which is not what we want. call global_mesh_collection%clear() @@ -806,8 +815,12 @@ contains call global_mesh_collection%add_new_global_mesh( global_mesh ) global_mesh_ptr => global_mesh_collection % get_global_mesh( mesh_names(i) ) - partition = partition_type(global_mesh_ptr, partitioner_ptr, & - custom_decomposition_type(1, 1),1,.true.,0,1) + partition = partition_type( global_mesh_ptr, partitioner_ptr, & + custom_decomposition_type(xprocs, yprocs), & + max_stencil_depth, & + generate_inner_halos, & + enforce_constraints, & + local_rank, total_ranks ) call local_mesh%initialise( global_mesh_ptr, partition ) call local_mesh%init_cell_owner() local_mesh_id = local_mesh_collection%add_new_local_mesh( local_mesh ) @@ -860,8 +873,14 @@ contains do i=1, size(mesh_names) global_mesh_ptr => global_mesh_collection % get_global_mesh (mesh_names(i)) source_local_mesh_ptr => local_mesh_collection % get_local_mesh (mesh_names(i)) - partition = partition_type(global_mesh_ptr, partitioner_ptr,& - custom_decomposition_type(1, 1),1,.true.,0,1) + + partition = partition_type( global_mesh_ptr, partitioner_ptr, & + custom_decomposition_type(xprocs, yprocs), & + max_stencil_depth, & + generate_inner_halos, & + enforce_constraints, & + local_rank, total_ranks ) + mesh = mesh_type( source_local_mesh_ptr, extrusion ) mesh_id = mesh_collection % add_new_mesh( mesh ) call mesh%clear() diff --git a/infrastructure/unit-test/mesh/mesh_tiling_mod_test.pf b/infrastructure/unit-test/mesh/mesh_tiling_mod_test.pf index e50df7c47..ef0112604 100644 --- a/infrastructure/unit-test/mesh/mesh_tiling_mod_test.pf +++ b/infrastructure/unit-test/mesh/mesh_tiling_mod_test.pf @@ -122,6 +122,8 @@ contains type(uniform_extrusion_type) :: extrusion procedure(partitioner_interface), pointer :: partitioner_ptr => null() + logical(l_def), parameter :: enforce_constraints = .false. + ! Run through mesh construction process to initialise tiling via ! the mesh_type API call ugrid_mesh_data%read_from_file( trim(filename), mesh_name ) @@ -132,12 +134,13 @@ contains global_mesh_ptr => global_mesh_collection%get_global_mesh( global_mesh_id ) partitioner_ptr => partitioner_planar - partition = partition_type( global_mesh_ptr, & - partitioner_ptr, & - decomposition, & - max_stencil_depth, & - generate_inner_halos, & - local_rank, & + partition = partition_type( global_mesh_ptr, & + partitioner_ptr, & + decomposition, & + max_stencil_depth, & + generate_inner_halos, & + enforce_constraints, & + local_rank, & total_ranks ) call local_mesh%initialise( global_mesh_ptr, partition ) @@ -201,9 +204,9 @@ contains decomposition = custom_decomposition_type(xyprocs(1), xyprocs(2)) ! Initialise mesh, this also initialises tiling - mesh = get_mesh( filename , decomposition, max_stencil_depth, & + mesh = get_mesh( filename , decomposition, max_stencil_depth, & this%getProcessRank(), this%getNumProcesses(), & - this%num_layers, generate_inner_halos, & + this%num_layers, generate_inner_halos, & tile_size, .false. ) ! Retrieve colouring data through mesh_type API and fill comparison arrays diff --git a/infrastructure/unit-test/mesh/partition_mod_test.pf b/infrastructure/unit-test/mesh/partition_mod_test.pf index 1a40b4802..54747c204 100644 --- a/infrastructure/unit-test/mesh/partition_mod_test.pf +++ b/infrastructure/unit-test/mesh/partition_mod_test.pf @@ -122,6 +122,7 @@ contains integer(i_def) :: num_processes logical(l_def) :: generate_inner_halos + logical(l_def), parameter :: enforce_constraints = .false. character(len = str_max_filename) :: filename @@ -161,6 +162,7 @@ contains decomposition, & max_stencil_depth, & generate_inner_halos, & + enforce_constraints, & local_rank, & total_ranks ) @@ -337,6 +339,7 @@ contains integer(i_def) :: num_processes logical(l_def) :: generate_inner_halos + logical(l_def), parameter :: enforce_constraints = .false. character(len = str_max_filename) :: filename @@ -373,12 +376,13 @@ contains decomposition = custom_decomposition_type(xproc, yproc) ! ! Generate the partition - partition = partition_type( global_mesh_ptr, & - partitioner_ptr, & - decomposition, & - max_stencil_depth, & - generate_inner_halos, & - local_rank, & + partition = partition_type( global_mesh_ptr, & + partitioner_ptr, & + decomposition, & + max_stencil_depth, & + generate_inner_halos, & + enforce_constraints, & + local_rank, & total_ranks ) ! Test functionality of the partition object we've just created on 1, 3 ! and 4 processes @@ -582,6 +586,7 @@ contains integer(i_def) :: num_processes logical(l_def) :: generate_inner_halos + logical(l_def), parameter :: enforce_constraints = .false. character(len = str_max_filename) :: filename @@ -618,12 +623,13 @@ contains decomposition = custom_decomposition_type(xproc, yproc) ! ! Generate the partition - partition = partition_type( global_mesh_ptr, & - partitioner_ptr, & - decomposition, & - max_stencil_depth, & - generate_inner_halos, & - local_rank, & + partition = partition_type( global_mesh_ptr, & + partitioner_ptr, & + decomposition, & + max_stencil_depth, & + generate_inner_halos, & + enforce_constraints, & + local_rank, & total_ranks ) ! Test functionality of the partition object we've just created on 1, 3 ! and 4 processes @@ -798,6 +804,7 @@ contains integer(i_def) :: num_processes logical(l_def) :: generate_inner_halos + logical(l_def), parameter :: enforce_constraints =.false. character(len = str_max_filename) :: filename @@ -834,12 +841,13 @@ contains decomposition = custom_decomposition_type(xproc, yproc) ! ! Generate the partition - partition = partition_type( global_mesh_ptr, & - partitioner_ptr, & - decomposition, & - max_stencil_depth, & - generate_inner_halos, & - local_rank, & + partition = partition_type( global_mesh_ptr, & + partitioner_ptr, & + decomposition, & + max_stencil_depth, & + generate_inner_halos, & + enforce_constraints, & + local_rank, & total_ranks ) ! Test functionality of the partition object we've just created on 1, 3 ! and 4 processes @@ -1046,6 +1054,7 @@ contains integer(i_def) :: global_mesh_id logical(l_def) :: generate_inner_halos + logical(l_def), parameter :: enforce_constraints = .false. character(len = str_max_filename) :: filename @@ -1074,12 +1083,13 @@ contains ! Testing over one (4x4x6) partition - no halo/ghost cells partitioner_ptr => partitioner_cubedsphere_serial - partition = partition_type( global_mesh_ptr, & - partitioner_ptr, & - decomposition, & - max_stencil_depth, & - generate_inner_halos, & - local_rank, & + partition = partition_type( global_mesh_ptr, & + partitioner_ptr, & + decomposition, & + max_stencil_depth, & + generate_inner_halos, & + enforce_constraints, & + local_rank, & total_ranks ) ! Test functionality of the single partition object we've just created @@ -1117,12 +1127,13 @@ contains ! Testing over six (4x4) partitions - one per face of the cubedsphere partitioner_ptr => partitioner_cubedsphere - partition = partition_type( global_mesh_ptr, & - partitioner_ptr, & - decomposition, & - max_stencil_depth, & - generate_inner_halos, & - local_rank, & + partition = partition_type( global_mesh_ptr, & + partitioner_ptr, & + decomposition, & + max_stencil_depth, & + generate_inner_halos, & + enforce_constraints, & + local_rank, & total_ranks ) ! Test functionality of the partition objects we've just created diff --git a/mesh_tools/source/support/generate_local_objects_mod.f90 b/mesh_tools/source/support/generate_local_objects_mod.f90 index e24cb579e..0f4018921 100644 --- a/mesh_tools/source/support/generate_local_objects_mod.f90 +++ b/mesh_tools/source/support/generate_local_objects_mod.f90 @@ -109,6 +109,8 @@ subroutine generate_local_objects( local_mesh_bank, & type(local_mesh_type) :: local_lbc_mesh integer(i_def), allocatable :: cell_lbc_lam_map(:) + logical(l_def), parameter :: enforce_constraints = .false. + n_meshes = size(mesh_names) !==================================================================== @@ -133,6 +135,7 @@ subroutine generate_local_objects( local_mesh_bank, & decomposition, & max_stencil_depth, & generate_inner_halos, & + enforce_constraints, & partition_id, & n_partitions, & mapping_factor )