Module morton2d_mod


Uses:
    module kinds_mod
Types:
    public type morton2d_iter
Variables:
    integer (kind=i_k), private, parameter :: SFC_MAX_LEV = 12
    integer (kind=i_k), private, parameter :: SFC_DIMS = 2
Subroutines and functions:
    public pure subroutine morton2d_c2i (lev, p, idx)
    public pure subroutine morton2d_i2c (lev, idx, p)
    public pure subroutine morton2d_c2i_qsz (lev, qsz, p, idx)
    public pure subroutine morton2d_i2c_qsz (lev, qsz, idx, p, iter)
    public pure subroutine morton2d_iter_init (iter, lev, opt_qsz)
    public pure subroutine morton2d_iter_set (iter, idx)
    public pure subroutine morton2d_iter_next (iter)

Simple 2D Morton curve subroutines.

Uses simple bit-interleaving algorithm as described in M.J. Aftosmis, M.J. Berger and S.M. Murman, "Applications of Space-Filling Curves to Cartesian Methods for CFD", 2004 (except for the subroutines with limited query region size)

Routines accept position and morton-index starting at 1!

Author: Matthias Lieber


Description of Types

morton2d_iter

public type morton2d_iter
    integer (kind=i_k) :: idx = -1
    integer (kind=i_k), dimension (SFC_DIMS) :: p = -1
    integer (kind=i_k) :: lev = -1
    integer (kind=i_k), dimension (SFC_DIMS) :: qsz = -1
    integer (kind=i_k) :: len = -1
    integer (kind=i_k), dimension (SFC_MAX_LEV) :: c = -1
    integer (kind=i_k), dimension (SFC_DIMS,SFC_MAX_LEV) :: p0 = 1
    integer (kind=i_K) :: jump_level = SFC_MAX_LEV + 1
end type morton2d_iter
Iterator to traverse the 2D Morton curve

Description of Subroutines and Functions

morton2d_c2i

public pure subroutine morton2d_c2i (lev, p, idx)
    integer (kind=i_k), intent(in) :: lev
    integer (kind=i_k), intent(in), dimension (2) :: p
    integer (kind=i_k), intent(out) :: idx
end subroutine morton2d_c2i
Parameters:
lev level of the morton curve (1=2x2, 2=4x4, 3=8x8, etc)
p 2D coordinates [1 ... 2^lev]
idx index on the 2D morton curve [1 ... (2^lev)^2]
Get index on Morton curve at given 2D coordinate (coordinates-to-index).

Has logarithmic complexity: number of loop iterations = lev. Due to performance reasons, no checking of arguments is performend!


morton2d_i2c

public pure subroutine morton2d_i2c (lev, idx, p)
    integer (kind=i_k), intent(in) :: lev
    integer (kind=i_k), intent(in) :: idx
    integer (kind=i_k), intent(out), dimension (2) :: p
end subroutine morton2d_i2c
Parameters:
lev level of the morton curve (1=2x2, 2=4x4, 3=8x8, etc)
idx index on the 2D morton curve [1 ... (2^lev)^2]
p 2D coordinates [1 ... 2^lev]
Get 2D coordinate at given index on curve (index-to-coordinates).

Has logarithmic complexity: number of loop iterations = lev. Due to performance reasons, no checking of arguments is performend!


morton2d_c2i_qsz

public pure subroutine morton2d_c2i_qsz (lev, qsz, p, idx)
    integer (kind=i_k), intent(in) :: lev
    integer (kind=i_k), intent(in), dimension (2) :: qsz
    integer (kind=i_k), intent(in), dimension (2) :: p
    integer (kind=i_k), intent(out) :: idx
end subroutine morton2d_c2i_qsz
Parameters:
lev level of the morton curve (1=2x2, 2=4x4, 3=8x8, etc)
qsz query region size
p 2D coordinates [1 ... 2^lev]
idx index on the 2D morton curve [1 ... (2^lev)^2]
Get index on curve at given 2D coordinate (coordinates-to-index).

The size of the query region is restricted by qsz for each dimension. qsz must be <= lev**2 and pos must be <= qsz.

Has logarithmic complexity: number of loop iterations = lev. Due to performance reasons, no checking of arguments is performend!


morton2d_i2c_qsz

public pure subroutine morton2d_i2c_qsz (lev, qsz, idx, p, iter)
    integer (kind=i_k), intent(in) :: lev
    integer (kind=i_k), intent(in), dimension (2) :: qsz
    integer (kind=i_k), intent(in) :: idx
    integer (kind=i_k), intent(out), dimension (2) :: p
    type (morton2d_iter), optional, intent(inout) :: iter
end subroutine morton2d_i2c_qsz
Parameters:
lev level of the morton curve (1=2x2, 2=4x4, 3=8x8, etc)
qsz query region size
idx index on the 2D morton curve [1 ... (2^lev)^2 ]
p 2D coordinates [1 ... 2^lev]
iter for internal use only
Get 2D coordinate at given index on curve (index-to-coordinates).

The size of the query region is restricted by qsz for each dimension. qsz must be <= lev**2 and pos must be <= qsz.

Has logarithmic complexity: number of loop iterations = lev. Due to performance reasons, no checking of arguments is performend!


morton2d_iter_init

public pure subroutine morton2d_iter_init (iter, lev, opt_qsz)
    type (morton2d_iter), intent(inout) :: iter
    integer (kind=i_k), intent(in) :: lev
    integer (kind=i_k), optional, intent(in), dimension (SFC_DIMS) :: opt_qsz
end subroutine morton2d_iter_init
Initialize the iterator.

The current index is iter%idx and the current 2D position iter%p.

  call morton2d_iter_init(iter, lev, qsz)
  do while(iter%idx > 0)
    array(iter%p(1),iter%p(2)) = iter%idx
    call morton2d_iter_next(iter)
  end do
  

morton2d_iter_set

public pure subroutine morton2d_iter_set (iter, idx)
    type (morton2d_iter), intent(inout) :: iter
    integer (kind=i_k), intent(in) :: idx
end subroutine morton2d_iter_set
Set the iterator to given index

morton2d_iter_next

public pure subroutine morton2d_iter_next (iter)
    type (morton2d_iter), intent(inout) :: iter
end subroutine morton2d_iter_next
Iterate to next point on the Morton curve

After reaching the end of the curve, iter%idx is set to 0.