Skip to content

Commit

Permalink
Final commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
larsgeb committed Apr 1, 2018
1 parent 0061340 commit d7557ea
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 38 deletions.
74 changes: 42 additions & 32 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
import time

# --- Setup; using the config as a 'global variable module' --- #
config.dt = 0.01
config.nt = 3000
config.ny = 20
config.nx = 40
config.dy = 1 / (config.ny - 1)
config.dx = 2 / (config.ny - 1)
config.ny = 40
config.nx = 80
config.dy = 1.0 / (config.ny)
config.dx = 2.0 / (config.nx)
config.dt = 0.001
config.nt = int(0.5 / config.dt)
dt = config.dt
nt = config.nt
ny = config.ny
Expand All @@ -29,29 +29,38 @@
useSuperLUFactorizationEq2 = True # Speeds up, quite a bit!

# Physical parameters (stream potential is 0 on all boundaries, hardcoded).
sqrtRa = 7
sqrtRa = 14
Tbottom = 1
Ttop = 0
tempDirichlet = [Tbottom, Ttop]
tempDirichlet = np.array([np.ones((nx,)) * Tbottom, np.ones((nx,)) * Ttop])
tempNeumann = [0, 0]

# Use initial instability (also changes nt to 3000)
instability = True

# Plotting settings
generateAnimation = True
generateEvery = 10
generateFinal = False
qInt = 1 # What's the quiver vector interval? Want to plot every vector?
qScale = 20 # Scale the vectors?
qInt = 4 # What's the quiver vector interval? Want to plot every vector?
qScale = 40 # Scale the vectors?

# --- No modifications below this point! --- #

print("Buoyancy driven flow:\nRayleigh number: %.2f\ndt: %.2f\nnt: %.2f\ndx/dy: %.2f" % (sqrtRa * sqrtRa, dt, nt, dx))
assert (dx == dy)

# Initial conditions
startT = np.expand_dims(np.linspace(Tbottom, Ttop, ny), 1).repeat(nx, axis=1)
startT[2:3, int(nx / 2 - 1):int(nx / 2 + 1)] = 0.5
if instability:
startT[int(ny / 2 - 3):int(ny / 2 + 3), int(nx / 2 - 3):int(nx / 2 + 3)] = 1.0
startT = grid.fieldToVec(startT)
startPsi = np.expand_dims(np.zeros(ny), 1).repeat(nx, axis=1) # start with zeros for streamfunctions
startPsi = grid.fieldToVec(startPsi)

print("Buoyancy driven flow:\nRayleigh number: %.2f\ndt: %.2e\nnt: %i\ndx: %.2e\ndy: %.2e" % (
sqrtRa * sqrtRa, dt, nt, dx, dy))
print("Critical CFL velocity: %.2e" % (dx / dt))

# Generate operators for differentials
dyOpPsi = op.dyOp()
dxOpPsi = op.dxOpStream()
Expand Down Expand Up @@ -120,8 +129,8 @@
maxSpeedArr.append(maxSpeed)

# calculate heat fluxes
heatFluxConduction = np.sum(- grid.vecToField(dyOpTemp @ Tnplus1 - rhsDyOpTemp)[-10, :])
heatFluxAdvection = sqrtRa * uy[-10, :] @ grid.vecToField(Tnplus1)[-10, :]
heatFluxConduction = np.sum(- grid.vecToField(dyOpTemp @ Tnplus1 - rhsDyOpTemp)[int(ny / 2), :])
heatFluxAdvection = sqrtRa * uy[int(ny / 2), :] @ grid.vecToField(Tnplus1)[int(ny / 2), :]
totalHeatFlux = heatFluxAdvection + heatFluxConduction

# accumulate values
Expand All @@ -141,7 +150,8 @@

# plot maximum fluid velocity
ymax = 10
ax2.set_ylim([1e-5, ymax if maxSpeed < ymax else maxSpeed]) # ternary statement, cool stuff
ax2.set_ylim([1e-5, ymax if np.max(maxSpeedArr) * (10 ** 0.1) < ymax else np.max(maxSpeedArr) * (
10 ** 0.1)]) # ternary statement, cool stuff
ax2.semilogy(t[::generateEvery], maxSpeedArr)
cflV = dx / dt
ax2.semilogy([0, nt * dt], [cflV, cflV], linestyle=":")
Expand All @@ -160,21 +170,21 @@
ax3.set_ylabel("q [heat flux]")
ax3.set_xlim([0, nt * dt])
ymax = totalHeatFluxArr[0] * 1.3
ax3.set_ylim([0, ymax if totalHeatFlux < ymax else totalHeatFlux * 1.1])
ax3.set_ylim([0, ymax if np.max(totalHeatFluxArr) * 1.1 < ymax else np.max(totalHeatFluxArr) * 1.1])

# Plot titles
ax1.set_title("Temperature and velocity field\nstep = %i, dt = %.2f, t = %.2f" % (it, dt, t[-1] - dt),
ax1.set_title("Temperature and velocity field\nstep = %i, dt = %.2e, t = %.2f" % (it, dt, t[-1] - dt),
FontSize=7)
ax2.set_title("Maximum fluid velocity over time", FontSize=7)
ax3.set_title("Heat fluxes over time", FontSize=7)

# Plot and redo!
plt.savefig("fields/field%i.png" % (it / generateEvery))
plt.savefig("simulations/field%i.png" % (it / generateEvery))
clrbr.remove()
ax1.clear()
ax2.clear()
ax3.clear()
print("plotted time step:", it, end='\r')
print("plotted time step:", it, end='\r')

# reset time level for fields
Tn = Tnplus1
Expand All @@ -196,8 +206,8 @@
# Enforcing column vector
Tnplus1.shape = (nx * ny, 1)
# Enforcing Dirichlet
Tnplus1[0::ny] = Tbottom
Tnplus1[ny - 1::ny] = Ttop
Tnplus1[0::ny] = np.expand_dims(tempDirichlet[0], 1)
Tnplus1[ny - 1::ny] = np.expand_dims(tempDirichlet[1], 1)

# Solve for Psi n+1
if (useSuperLUFactorizationEq1):
Expand All @@ -214,16 +224,16 @@
Psinplus1[-ny:] = 0

end = time.time()
print("\nRuntime of time-marching: ", end - start, "seconds")
print("\nRuntime of time-marching: %.2e seconds" % (end - start))

# And output figure(s)
if (generateFinal):
ux = grid.vecToField(dyOpPsi @ Psinplus1)
uy = grid.vecToField(dxOpPsi @ Psinplus1)
maxSpeed = np.max(np.square(ux) + np.square(uy))
plt.quiver(np.flipud(ux), -np.flipud(uy))
plt.imshow(np.flipud(grid.vecToField(Tnplus1)), cmap=plt.get_cmap('magma'))
plt.colorbar()
plt.tight_layout()
plt.title("Maximum speed: %.2f" % maxSpeed)
plt.savefig("Convection-field.png")
# if (generateFinal):
# ux = grid.vecToField(dyOpPsi @ Psinplus1)
# uy = grid.vecToField(dxOpPsi @ Psinplus1)
# maxSpeed = np.max(np.square(ux) + np.square(uy))
# plt.quiver(np.flipud(ux), -np.flipud(uy))
# plt.imshow(np.flipud(grid.vecToField(Tnplus1)), cmap=plt.get_cmap('magma'))
# plt.colorbar()
# plt.tight_layout()
# plt.title("Maximum speed: %.2f" % maxSpeed)
# plt.savefig("Convection-field.png")
12 changes: 6 additions & 6 deletions operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ def dyOpTemp(bcDirArray):

# First construct the right hand side from one-sided difference formulas for y = 0 & y = ymax and the Dirichlet BC.
rhs = np.zeros((nx * ny,))
for i in range(nx):
rhs[0 + ny * i] = bcDirArray[0] / dy # y = 0
rhs[ny * (i + 1) - 1] = - bcDirArray[1] / dy # y = ymax
for ix in range(nx):
rhs[0 + ny * ix] = bcDirArray[0][ix] / dy # y = 0
rhs[ny * (ix + 1) - 1] = - bcDirArray[1][ix] / dy # y = ymax
rhs = np.expand_dims(rhs, 1) # Make it an explicit column vector

# We use the central difference formula for all the inner derivatives ...
Expand Down Expand Up @@ -186,11 +186,11 @@ def dlOpTemp(bcDirArray, bcNeuArray):

# Now we need to construct the RHS for the Dirichlet points
for ix in range(nx):
rhsPart = (A[:, ix * ny] * bcDirArray[0]).todense().A
rhsPart = (A[:, ix * ny] * bcDirArray[0][ix]).todense().A
rhsPart.shape = (nx * ny, 1)
rhs = rhs - np.copy(rhsPart)
toKeep[ix * ny] = 0
rhsPart = (A[:, (ix + 1) * ny - 1] * bcDirArray[1]).todense().A
rhsPart = (A[:, (ix + 1) * ny - 1] * bcDirArray[1][ix]).todense().A
rhsPart.shape = (nx * ny, 1)
rhs = rhs - np.copy(rhsPart)
toKeep[(ix + 1) * ny - 1] = 0
Expand Down Expand Up @@ -269,7 +269,7 @@ def dyOpStream():

def dlOpStreamMod():
"""Create discrete operator on 2d grid for d²Psi / dy² using central and Dirichlet boundary conditions. It is not
the traditional operator, as some entries are modified to simplify the solving of equation 1 from the project.
the traditional operator, as some entri=es are modified to simplify the solving of equation 1 from the project.
Status: finished on 21 March.
Expand Down

0 comments on commit d7557ea

Please sign in to comment.