# Swapping arrays during time-stepping

**URL:** <https://fortran-lang.discourse.group/t/swapping-arrays-during-time-stepping/7354>\
**Category:** Poll\
**Created:** [February 6, 2024, 10:29pm UTC](https://fortran-lang.discourse.group/t/swapping-arrays-during-time-stepping/7354 "2024-02-06T22:29:36Z")\
**Posts on this page:** 1\
**Showing post:** 1

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [February 6, 2024, 10:29pm UTC](https://fortran-lang.discourse.group/t/swapping-arrays-during-time-stepping/7354/1 "2024-02-06T22:29:36Z")

</div>

For time-stepping large PDE problems, it’s common to read from one array (the previous time step), and write to a second array (the result at the new time step). Afterward the arrays are swapped. This is also known as the “flip-flop” approach, or ping-ponging. The separate arrays also make the update step easier to parallelise (no race conditions).

What is your favourite implementation approach? (Scroll down for examples)

_Poll ([view on site](https://fortran-lang.discourse.group/t/swapping-arrays-during-time-stepping/7354/1))_

### Separate arrays with parity flag

```fortran
real, allocatable :: f1(:), f2(:)
integer :: flipflop

! ... initialize f

flipflop = 1

do step = 1, nsteps

    select case(flipflop)
    case(1)
        call sweep(fin=f1,fout=f2)
    case(2)
        call sweep(fin=f2,fout=f1)
    end select
    flipflop = 3 - flipflop

end do

```

If zero-based indexing is used, the parity flag can be inverted using

```fortran
! 0-based indexing
flipflop = 1 - flipflop

```

### Array with extra dimension

This one relies on array slicing or dummy argument association. Integer flags are used to denote the old and new arrays.

```auto
real, allocatable :: f(:,:)
integer :: tmp, old, new

allocate(f(n,2))

! ... initialize f
old = 1
new = 2

do step = 1, nsteps

    call sweep(fin=f(:,kold),fout=f(:,knew))

    tmp = old
    old = new
    new = tmp

end do

```

Alternatively, the integer flags can be calculated before the update like this:

```fortran
    old = mod(step+1,2) + 1
    new = mod(step+2,2) + 1

```

or after the update, like this:

```fortran
    old = 3 - old
    new = 3 - new

```

### Pointer swap

```auto
real, allocatable, target :: f1(:), f2(:)
real, pointer :: fold(:), fnew(:), ftmp(:)

fold => f1
fnew => f2

do step = 1, nsteps

    call sweep(fin=fold,fout=fnew)

    ftmp => fold
    fold => fnew
    fnew => ftmp

end do

```

### Overwrite old array

```fortran
real, allocatable :: fold(:), fnew(:)

do step = 1, nsteps
    call sweep(fin=fold,fout=fnew)
    fold = fnew
end do

```

---

_[View the full topic](https://fortran-lang.discourse.group/t/swapping-arrays-during-time-stepping/7354)._
