def set_boundary_conditions_access(g_a):
    # this will reset the outer (ghost) elements back to the boundary cond.
    if rlo == 0 or clo == 0 or chi == dim:
        a = ga.access_ghosts(g_a)
        if rlo == 0:
            a[0,:] = 100 # I own a top row
        if clo == 0:
            a[:,0] = 75 # I own a left column
        if chi == dim:
            a[:,-1] = 50 # I own a right column
        ga.release_update_ghosts(g_a)
    ga.sync()
        ga.release_update_ghosts(g_a)
    ga.sync()

set_boundary_conditions_access(g_a)
iteration = 0
start = ga.wtime()
while True:
    ga.sync()
    iteration += 1
    if iteration % HOW_MANY_STEPS_BEFORE_CONVERGENCE_TEST == 0:
        # check for convergence will occur, so make a copy of the GA
        ga.copy(g_a, g_b)
    # the iteration
    ga.update_ghosts(g_a)
    set_boundary_conditions_access(g_a)
    my_array = ga.access_ghosts(g_a)
    my_array[1:-1,1:-1] = (
            my_array[0:-2, 1:-1] +
            my_array[2:, 1:-1] +
            my_array[1:-1,0:-2] +
            my_array[1:-1, 2:]) / 4
    ga.release_ghosts(g_a)
    if iteration % HOW_MANY_STEPS_BEFORE_CONVERGENCE_TEST == 0:
        if convergence_test_L2(g_a, g_b):
            break

if DEBUG or True and rank == 0:
    print ga.get(g_a)

if rank == 0:
    print iteration