# tem_Sparta_module Module

The implementation is based on the SPartA Algorithm.

Some elements which require further treatment expose higher computational effort. This includes among others the enforcing of boundary conditions, source terms, or the interpolation between levels. Depending on the selected behavior of elements, this result in considerable higher effort on certain elements. When running in parallel, it is important to balance the load between the participating processing units equally in order to achieve a minimal time to solution. It is always desired to minimize the waiting time of processing units. The initial disitribution of the elements among the processes assigns the roughly the same amount of elements to each partition, regardless of their cost. This simple partitioning yields very good results for uniform grid simulations, as the elements with additional behavior is of the order of $\mathcal{O}(n^2)$ while the total number of elements are of order $\mathcal{O}(n^3)$.

Especially when using locally refined grids, the computational cost of elements varies considerably. Besides the increased update interval of the smaller elements, the interpolation routines are very expensive compared to the pure computation of an element.

To account for this variation of the computational cost, a load balancing algorithm (see: [2] at Treelm bibliography) is employed to homogenize the total cost among the partitions. It is based on a space-filling curve, which fits nicely into the TreElm framework. Additionally, each element of the tree is assigned a weight representing the computational cost. The total cost is then possibly equally distributed among the partitions which results in a re-partitioning of the mesh along the space-filling curve.

## Interfaces

• ### private subroutine tem_exchange_long(me, val, nComponents, comm)

#### Arguments

Type IntentOptional AttributesName
type(tem_sparta_type), intent(in) :: me
integer(kind=long_k), intent(inout), allocatable:: val(:)
integer, intent(in) :: nComponents
integer, intent(in) :: comm
• ### private subroutine tem_exchange_double(me, val, nComponents, comm)

#### Arguments

Type IntentOptional AttributesName
type(tem_sparta_type), intent(in) :: me
real(kind=double_k), intent(inout), allocatable:: val(:)
integer, intent(in) :: nComponents
integer, intent(in) :: comm
• ### private subroutine tem_exchange_long2(me, val, nComponents, comm)

#### Arguments

Type IntentOptional AttributesName
type(tem_sparta_type), intent(in) :: me
integer(kind=long_k), intent(inout), allocatable:: val(:,:)
integer, intent(in) :: nComponents
integer, intent(in) :: comm
• ### private subroutine tem_exchange_double2(me, val, nComponents, comm)

#### Arguments

Type IntentOptional AttributesName
type(tem_sparta_type), intent(in) :: me
real(kind=double_k), intent(inout), allocatable:: val(:,:)
integer, intent(in) :: nComponents
integer, intent(in) :: comm

## Derived Types

### type, public :: tem_sparta_type

#### Components

TypeVisibility AttributesNameInitial
integer, public, allocatable:: send_index(:)
integer, public, allocatable:: recv_index(:)
integer, public, allocatable:: send_count(:)
integer, public, allocatable:: recv_count(:)
integer, public :: old_size =0
integer, public :: new_size =0

## Subroutines

### public subroutine tem_balance_sparta(weight, myPart, nParts, comm, myElems, offset, sparta)

Return splitting positions based on the weights provided by each rank.

#### Arguments

Type IntentOptional AttributesName
real(kind=rk), intent(in) :: weight(:)

Sorted list of weights corresponding to treeID order

integer, intent(in) :: myPart
integer, intent(in) :: nParts

Number of procs the distribution should span

integer, intent(in) :: comm

MPI Communicator

integer, intent(inout) :: myElems

number of elements

integer(kind=long_k), intent(out) :: offset

Array of offsets with the size nParts. Offset index starts at 0. This Array needs to be allocate and deallocated outside

type(tem_sparta_type), intent(inout) :: sparta

### public subroutine tem_init_sparta(me, nParts)

#### Arguments

Type IntentOptional AttributesName
type(tem_sparta_type), intent(inout) :: me
integer, intent(in) :: nParts

### public subroutine tem_destroy_sparta(me)

#### Arguments

Type IntentOptional AttributesName
type(tem_sparta_type), intent(inout) :: me

### public subroutine tem_output_sparta(me, outUnit)

#### Arguments

Type IntentOptional AttributesName
type(tem_sparta_type), intent(in) :: me
integer, intent(in) :: outUnit

### public subroutine tem_derive_sparta(origin, derived, nElems, elemPropertyBits, prpBit, comm, nParts)

#### Arguments

Type IntentOptional AttributesName
type(tem_sparta_type), intent(in) :: origin
type(tem_sparta_type), intent(inout) :: derived
integer, intent(in) :: nElems
integer(kind=long_k), intent(in) :: elemPropertyBits(nElems)
integer, intent(in) :: prpBit
integer, intent(in) :: comm
integer, intent(in) :: nParts

### private subroutine tem_exchange_long(me, val, nComponents, comm)

#### Arguments

Type IntentOptional AttributesName
type(tem_sparta_type), intent(in) :: me
integer(kind=long_k), intent(inout), allocatable:: val(:)
integer, intent(in) :: nComponents
integer, intent(in) :: comm

### private subroutine tem_exchange_double(me, val, nComponents, comm)

#### Arguments

Type IntentOptional AttributesName
type(tem_sparta_type), intent(in) :: me
real(kind=double_k), intent(inout), allocatable:: val(:)
integer, intent(in) :: nComponents
integer, intent(in) :: comm

### private subroutine tem_exchange_long2(me, val, nComponents, comm)

#### Arguments

Type IntentOptional AttributesName
type(tem_sparta_type), intent(in) :: me
integer(kind=long_k), intent(inout), allocatable:: val(:,:)
integer, intent(in) :: nComponents
integer, intent(in) :: comm

### private subroutine tem_exchange_double2(me, val, nComponents, comm)

#### Arguments

Type IntentOptional AttributesName
type(tem_sparta_type), intent(in) :: me
real(kind=double_k), intent(inout), allocatable:: val(:,:)
integer, intent(in) :: nComponents
integer, intent(in) :: comm

### private subroutine tem_set_sparta(me, comm, nParts, send_count)

#### Arguments

Type IntentOptional AttributesName
type(tem_sparta_type), intent(inout) :: me
integer, intent(in) :: comm
integer, intent(in) :: nParts
integer, intent(in) :: send_count(0:nParts-1)