<filename>Post-Processor.py
import numpy as np
import matplotlib.pyplot as plt
from os import listdir
import matplotlib.animation as anim

#%%

# Data paths (delete as appropriate)
# MVSC (Windows users):
path = './x64/Release/'
# Linux/iOS users:
#path = './Life/'

#%%

# Initialise the number of processors to occupy domain in each direction
n_proc_rows = 0
n_proc_cols = 0
# Extract macro-info using file titles
for file in listdir(path + 'meta/'):
    i = int(file.split('_')[0])
    j = int(file.split('_')[1])
    if (i > n_proc_rows):
        n_proc_rows = i;
    if (j > n_proc_cols):
        n_proc_cols = j;
# Make number inclusive        
n_proc_rows += 1;
n_proc_cols += 1;
n_procs = n_proc_rows*n_proc_cols
# Infer number of iterations from metadata
iter = int(listdir(path + 'meta/')[0].split('_')[2])
# Initialise arrays to signify what processor sits where in the domain
i_array = np.zeros((n_proc_rows * n_proc_cols), dtype=int)
j_array = np.zeros((n_proc_rows * n_proc_cols), dtype=int)
# Initialise arrays to signify 
imax_local_array = np.zeros((n_proc_rows * n_proc_cols), dtype=int)
jmax_local_array = np.zeros((n_proc_rows * n_proc_cols), dtype=int)
time_array = np.zeros((n_proc_rows * n_proc_cols))

for r in range(n_proc_rows):
    for c in range(n_proc_cols):
        string = np.genfromtxt(path + 'meta/%i_%i_%i_%i_info.txt' % (r,c,iter, n_procs))
        i_array[r * n_proc_cols + c] = r
        j_array[r * n_proc_cols + c] = c
        imax_local_array[r * n_proc_cols + c] = int(string[0])
        jmax_local_array[r * n_proc_cols + c] = int(string[1])
        time_array[r * n_proc_cols + c] = float(string[2])

row_cumsum = np.cumsum(imax_local_array[::n_proc_cols])
col_cumsum = np.cumsum(jmax_local_array[0:n_proc_cols])

imax_global = int(row_cumsum[-1])
jmax_global = int(col_cumsum[-1])
matrix = np.zeros((imax_global , jmax_global))
matrix_store = np.zeros((iter, imax_global, jmax_global))

for it in range(iter):
    row_start = 0
    line_artist = []
    for r in range(n_proc_rows):
        row_end = row_cumsum[r]
        col_start = 0
        for c in range(n_proc_cols):
            A = np.genfromtxt(path + 'data/%i_%i_%i.txt' % (r,c,it))
            index = r * n_proc_cols + c

            col_end = col_cumsum[c]
            matrix[row_start : row_end , col_start : col_end] = A.reshape((imax_local_array[index], jmax_local_array[index]))
            
            plt.plot([col_start, col_end], [row_end, row_end], 'b-', linewidth = 1)
            plt.plot([col_end, col_end], [row_start, row_end], 'b-', linewidth = 1)
            
            col_start = col_end
        row_start = row_end   

    matrix_store[it, :, :] = matrix

plt.title("Domain Decomposition for %i x %i environment" % (imax_global, jmax_global))
plt.show()

def create_animation():
    fig = plt.figure()
    plt.title('Game of Life')
    plt.xlabel('i')
    plt.ylabel('j')
    imgs = []
    
    for it in range(iter):
        img = plt.imshow(matrix_store[it], 'binary', animated=True)
        title = plt.title("%i generations" % it, animated=True)
        imgs.append([img, title])    
    ani = anim.ArtistAnimation(fig, imgs, interval=50, blit=True)
    ani.save('game.mp4')
    plt.close(fig)  # prevent final frame plot from showing up inline below

    return ani

print("Computational time for Game of Life = %f" % np.mean(time_array))
ani = create_animation()
print('Preparing mp4 gif (please wait a moment.)')
ani.save('game.mp4')