Module fd4_util_mod


Uses:
    module fd4_globaldef_mod
    module fd4_vartab_mod
    module fd4_block_mod
    module fd4_domain_mod
    module fd4_iter_mod
    module fd4_mpi_mod
    module fd4_part_sfc_mod
    module fd4_balance_mod
    module fd4_mpitype_mod
    module fd4_comm_mod
    module rbtree_fd4_block_mod
    module stack_mod
Subroutines and functions:
    public subroutine fd4_util_allocate_all_blocks (domain, err)
    public subroutine fd4_util_propagate_facevar (domain, idx, st, uppervalue, err)
    public subroutine fd4_util_check_facevar (domain, idx, st, err)
    public function fd4_util_get_value (domain, idx, st, pos, root) result (value)
    public subroutine fd4_util_get_array (domain, idx, st, abnd, array, err, root, novnull)
    public subroutine fd4_util_put_array (domain, idx, st, abnd, array, err, sbnd, opt_ignore_vthres)
    public subroutine fd4_util_put_array_uv (domain, idx1, st1, abnd1, array1, idx2, st2, abnd2, array2, err)

Simple utilities on top of fd4_domain and fd4_iter. Not optimized for performance.

Author: Matthias Lieber

See also: module fd4_domain_mod, module fd4_iter_mod


Description of Subroutines and Functions

fd4_util_allocate_all_blocks

public subroutine fd4_util_allocate_all_blocks (domain, err)
    type (fd4_domain), intent(inout) :: domain
    integer (kind=i_k), intent(out) :: err
end subroutine fd4_util_allocate_all_blocks
Parameters:
domain the domain
err error status, 0 if ok
Allocate all blocks of the domain and keep them balanced over all processes.

This function is only useful if the domain is not in adaptive block mode, i.e. no variable in the variable table has a threshold value.

Method: Simply mark all blocks for allocation and let fd4_balance_readjust do the work.

TODO:

See also: module fd4_balance_mod


fd4_util_propagate_facevar

public subroutine fd4_util_propagate_facevar (domain, idx, st, uppervalue, err)
    type (fd4_domain), intent(inout), target :: domain
    integer (kind=i_k), intent(in), dimension (:) :: idx
    integer (kind=i_k), intent(in), dimension (:) :: st
    logical, intent(in) :: uppervalue
    integer (kind=i_k), intent(out) :: err
end subroutine fd4_util_propagate_facevar
Parameters:
domain the domain
idx field indexes in vartab, must be of same face type!
st time step indexes
uppervalue propagate upper value to neighbor block's lower value (or reverse?)
err error status, 0 if ok
Enforce consistency of the given face variable.

Copies face values at the boundary of blocks to the corresponding neighbor block to ensure consistency. After calling to this subroutine, fd4_util_check_facevar should report no problems.

Example with 3 blocks:

 
     __    __    __
    |  |  |  |  |  |
    |__|  |__|  |__|
    1  2  3  4  5  6
 
fd4_util_propagate_facevar accepts arrays for idx and st. But all variables must be of the same face type!

fd4_util_check_facevar

public subroutine fd4_util_check_facevar (domain, idx, st, err)
    type (fd4_domain), intent(inout) :: domain
    integer (kind=i_k), intent(in) :: idx
    integer (kind=i_k), intent(in) :: st
    integer (kind=i_k), intent(out) :: err
end subroutine fd4_util_check_facevar
Parameters:
domain the domain
idx field index in vartab
st time step index
Check the given face variable for consistency.

Checks if face values at opposite block boundaries are be equal. Reports to stdout.

Damn stupid implementation: All blocks are migrated to rank 0 which performs the checks, than the blocks are distributed again over all ranks. Use only for small debug runs!


fd4_util_get_value

public function fd4_util_get_value (domain, idx, st, pos, root) result (value)
    type (fd4_domain), intent(in) :: domain
    integer (kind=i_k), intent(in) :: idx
    integer (kind=i_k), intent(in) :: st
    integer (kind=i_k), intent(in), dimension (0:3) :: pos
    integer (kind=i_k), intent(in) :: root
    real (kind=r_k) :: value
end function fd4_util_get_value
Parameters:
domain the domain
idx field index in vartab
st time step index
pos bin and position in global spatial coordinates
root write array in rank root
Get a single value from the domain.

For debug use only! Not optimized.


fd4_util_get_array

public subroutine fd4_util_get_array (domain, idx, st, abnd, array, err, root, novnull)
    type (fd4_domain), intent(in), target :: domain
    integer (kind=i_k), intent(in) :: idx
    integer (kind=i_k), intent(in) :: st
    integer (kind=i_k), intent(in), dimension (0:3,2) :: abnd
    real (kind=r_k), intent(inout), dimension (abnd(0,1):abnd(0,2),abnd(1,1):abnd(1,2),abnd(2,1):abnd(2,2),abnd(3,1):abnd(3,2)) :: array
    integer (kind=i_k), intent(out) :: err
    integer (kind=i_k), intent(in) :: root
    logical, optional, intent(in) :: novnull
end subroutine fd4_util_get_array
Parameters:
domain the domain
idx field index in vartab
st time step index
abnd bounds of the array: (bins, x, y, z)
array array with the data
err error status: 0...ok
root write array in rank root
novnull will not fill array for non-allocated blocks if set to .true. (faster)
Get array of domain size from domain's data structures.

Optionally not setting array=0 in non-allocated blocks gives huge speed-up (factor 5 measured, due to cache).

TODO


fd4_util_put_array

public subroutine fd4_util_put_array (domain, idx, st, abnd, array, err, sbnd, opt_ignore_vthres)
    type (fd4_domain), intent(inout) :: domain
    integer (kind=i_k), intent(in) :: idx
    integer (kind=i_k), intent(in) :: st
    integer (kind=i_k), intent(in), dimension (0:3,2) :: abnd
    real (kind=r_k), intent(in), dimension (abnd(0,1):abnd(0,2),abnd(1,1):abnd(1,2),abnd(2,1):abnd(2,2),abnd(3,1):abnd(3,2)) :: array
    integer (kind=i_k), intent(out) :: err
    integer (kind=i_k), optional, intent(in), dimension (0:3,2) :: sbnd
    logical, optional, intent(in) :: opt_ignore_vthres
end subroutine fd4_util_put_array
Parameters:
domain the domain
idx field index in vartab
st time step index
abnd bounds of array: (bins, x, y, z)
array array with the data
err error status: 0...ok
sbnd optionally one can specify a subset of array to put into the domain
opt_ignore_vthres ignore if FD4_NOTHRES is set and put everthing to domain
Put array of given size to domain's data structures.

DEPRECATED, DO NOT USE

This suboutine is thought for filling data structures with initial data and not optimized for performance. Allocates new blocks when necessary. Will never allocate a block for a variable with FD4_NOTHRES.

Currently, this is for testing. Maybe this subroutine will disappear in future.

A safer way to put data into the framework are the coupling routines.

See also: module fd4_couple_mod


fd4_util_put_array_uv

public subroutine fd4_util_put_array_uv (domain, idx1, st1, abnd1, array1, idx2, st2, abnd2, array2, err)
    type (fd4_domain), intent(inout) :: domain
    integer (kind=i_k), intent(in) :: idx1
    integer (kind=i_k), intent(in) :: st1
    integer (kind=i_k), intent(in), dimension (0:3,2) :: abnd1
    real (kind=r_k), intent(in), dimension (abnd1(0,1):abnd1(0,2),abnd1(1,1):abnd1(1,2),abnd1(2,1):abnd1(2,2),abnd1(3,1):abnd1(3,2)) :: array1
    integer (kind=i_k), intent(in) :: idx2
    integer (kind=i_k), intent(in) :: st2
    integer (kind=i_k), intent(in), dimension (0:3,2) :: abnd2
    real (kind=r_k), intent(in), dimension (abnd2(0,1):abnd2(0,2),abnd2(1,1):abnd2(1,2),abnd2(2,1):abnd2(2,2),abnd2(3,1):abnd2(3,2)) :: array2
    integer (kind=i_k), intent(out) :: err
end subroutine fd4_util_put_array_uv
Parameters:
domain the domain
idx1 field index in vartab
st1 time step index
abnd1 bounds of the array: (bins, x, y, z)
array1 array with the data
idx2 field index in vartab
st2 time step index
abnd2 bounds of the array: (bins, x, y, z)
array2 array with the data
err error status: 0...ok
Put u and v wind component to domain's data structures.

DEPRECATED, DO NOT USE

The arrays must be in full domain size. Array 1 must be face variable in 1st dimension (u). Array 2 must be face variable in 2nd dimension (v). This is a very specialized version of fd4_util_put_array.