if ( liveUpdate | savePlot ):
    pyplot.ion()
    fig, ax = pyplot.subplots(1)


###### Main time loop ##########################################################
for time in range(maxIterations):
    # bounce back distributions at walls
    for i in range(q):
        fin[i, noSlipBoundary] = fin[noslip[i], noSlipBoundary]

    # Calculate macroscopic density and velocity
    (rho, u) = getMacroValues(fin)

    #right wall: pressure equal to one
    fin[:,nxl,:] = cumulantBoundary(1 - pressureDrop, u[:,nxl,:])

    #left wall:
    fin[:,0,:] = cumulantBoundary(1 + pressureDrop, u[:,0,:])

    # Collision step.
    fpost = collisionFunction(fin, rho, u, omega )

    # Streaming step
    fin = stream(fpost)

    # Visualization
    if ( (time % plotEveryN == 0) & (liveUpdate  | savePlot) & (time > skipFirstN) ):

        if ( liveUpdate | savePlot ):
            ax.clear()

###### Main time loop ##########################################################
for time in range(maxIterations):
    # bounce back distributions at obstacle
    for i in range(q):
        fin[i, obstacle] = fin[noslip[i], obstacle]
    # and walls
    for i in range(q):
        fin[i, noSlipBoundary] = fin[noslip[i], noSlipBoundary]

    # Calculate macroscopic density and velocity
    (rho, u) = getMacroValues(fin)

    #right wall: pressure equal to one
    fin[:,nxl,:] = cumulantBoundary(1, u[:,nxl-1,:])

    #left wall:
    fin[:,0,:] = cumulantBoundary(rho[0,:], vel[:,0,:])

    # Collision step.
    fpost[:,1:nx-1,1:ny-1] = collisionFunction(fin[:,1:nx-1,1:ny-1], rho[1:nx-1,1:ny-1], u[:,1:nx-1,1:ny-1], omega )

    # Streaming step
    fin = stream(fpost)

    # Visualization
    if ( (time % plotEveryN == 0) & (analysis | liveUpdate  | savePlot) & (time > skipFirstN) ):
        # Here, distributions are streamed into the obstacle -> compute drag and lift
        scaling = preComputeFactorForScaling/sumPopulations(fin[:,completeBoundStencil])
        scaledFin = fin.copy()