Module hilbert2d_mod


Uses:
    module kinds_mod
Types:
    private type hilbert_table
    public type hilbert2d_iter
Variables:
    integer (kind=i_k), private, parameter :: SFC_MAX_LEV = 12
    integer (kind=i_k), private, parameter :: SFC_DIMS = 2
    type (hilbert_table), private, parameter, dimension (0:3) :: tab = (/ hilbert_table ((/ 2, 1, -2 /), (/ 1, 0, 0, 2 /), (/ 0, 2, 3, 1 /), (/ 0, 3, 1, 2 /)), hilbert_table ((/ 1, 2, -1 /), (/ 0, 1, 1, 3 /), (/ 0, 1, 3, 2 /), (/ 0, 1, 3, 2 /)), hilbert_table ((/ -1, -2, 1 /), (/ 3, 2, 2, 0 /), (/ 3, 2, 0, 1 /), (/ 2, 3, 1, 0 /)), hilbert_table ((/ -2, -1, 2 /), (/ 2, 3, 3, 1 /), (/ 3, 1, 0, 2 /), (/ 2, 1, 3, 0 /)) /)
Subroutines and functions:
    public pure subroutine hilbert2d_c2i (lev, p, idx)
    public pure subroutine hilbert2d_i2c (lev, idx, p)
    public pure subroutine hilbert2d_c2i_qsz (lev, qsz, p, idx)
    public pure subroutine hilbert2d_i2c_qsz (lev, qsz, idx, p, iter)
    public pure subroutine hilbert2d_iter_init (iter, lev, opt_qsz)
    public pure subroutine hilbert2d_iter_set (iter, idx)
    public pure subroutine hilbert2d_iter_next (iter)

Simple 2D Hilbert curve subroutines. Based on a table description of the curve.

Routines accept position and hilbert-index starting at 1.

Author: Matthias Lieber


Description of Types

hilbert_table

private type hilbert_table
    integer (kind=i_k), dimension (0:2) :: mv
    integer (kind=i_k), dimension (0:3) :: next
    integer (kind=i_k), dimension (0:3) :: num2ref
    integer (kind=i_k), dimension (0:3) :: ref2num
end type hilbert_table
Components:
mv spatial moves of the curve
next next states when refinining (quadrant is sequence number)
num2ref sequence number on curve primitve to reference (spatial) quadrant
ref2num reference (spatial) quadrant to sequence number on curve primitve
Type for one entry in the 2D Hilbert curve description table.

Values of the mv item are:


hilbert2d_iter

public type hilbert2d_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) :: clev = -1
    integer (kind=i_k), dimension (SFC_MAX_LEV) :: s = -1
    integer (kind=i_k), dimension (SFC_MAX_LEV) :: c = -1
    integer (kind=i_K) :: jump_level = SFC_MAX_LEV + 1
end type hilbert2d_iter
Iterator to traverse the 2D Hilbert curve

Description of Subroutines and Functions

hilbert2d_c2i

public pure subroutine hilbert2d_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 hilbert2d_c2i
Parameters:
lev level of the hilbert curve (1=2x2, 2=4x4, 3=8x8, etc)
p 2D coordinates [1 ... 2^lev]
idx index on the 2D hilbert curve [1 ... (2^lev)^2]
Get index on 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!


hilbert2d_i2c

public pure subroutine hilbert2d_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 hilbert2d_i2c
Parameters:
lev level of the hilbert curve (1=2x2, 2=4x4, 3=8x8, etc)
idx index on the 2D hilbert 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!


hilbert2d_c2i_qsz

public pure subroutine hilbert2d_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 hilbert2d_c2i_qsz
Parameters:
lev level of the hilbert curve (1=2x2, 2=4x4, 3=8x8, etc)
qsz query region size
p 2D coordinates [1 ... 2^lev]
idx index on the 2D hilbert 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!


hilbert2d_i2c_qsz

public pure subroutine hilbert2d_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 (hilbert2d_iter), optional, intent(inout) :: iter
end subroutine hilbert2d_i2c_qsz
Parameters:
lev level of the hilbert curve (1=2x2, 2=4x4, 3=8x8, etc)
qsz query region size
idx index on the 2D hilbert 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!


hilbert2d_iter_init

public pure subroutine hilbert2d_iter_init (iter, lev, opt_qsz)
    type (hilbert2d_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 hilbert2d_iter_init
Initialize the iterator.

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

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

hilbert2d_iter_set

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

hilbert2d_iter_next

public pure subroutine hilbert2d_iter_next (iter)
    type (hilbert2d_iter), intent(inout) :: iter
end subroutine hilbert2d_iter_next
Iterate to next point on the hilbert curve

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