I'm having trouble understanding why this for loop is not working. Full code is also below.
I want to calculate the temperature at future time points (j+1) based on the temperatures at the previous time point (j) using the finite volume method. I have setup functions to calculate the conduction in, out, and the internal generation within a node. I have another function which sums these together and determines the resultant temperature based on an energy balance equation. My issue though is specifically with the loop below:
for j in range(1, n): # time
for e in range(1, i-1): # position
T[e,j] = Tn_plus_1( T[e, j-1] , timestep,rho[e], cp[e], re_nodes[e] , rw_nodes[e],
conduction_in(k[e-1], rw_nodes[e],T[e, j-1], T[e-1, j-1], r_nodes[e], r_nodes[e-1]),
conduction_out(k[e], re_nodes[e], T[e+1, j-1], T[e, j-1], r_nodes[e+1], r_nodes[e] ),
fraction[j]*internal_gen(q_dens[e], timestep, rho[e], cp[e]) )
Tn_plus_1 is a function to calculate the temperature of a node at the next timestep based on an energy balance and finite volume method. Conduction in, out, and internal generation are functions to calculate the heat transfer due to each mechanism into or out of a particular node. I set up for loops to iterate over time and position to determine the temperature evolution in each node for the duration of the analysis.
The issue is that the conduction out term does not apply correctly to node 7. I suspect the same issue is occurring with the conduction in term at the second node. The thought process behind the loop is that I want to calculate the temperatures of the internal nodes, and maintain the boundary condition on the two external nodes. Hence, I set the loop between 1 and i-1 (with 0 and i being the boundaries).
There are 9 position nodes in total (r, re, and rw each have 9 values). There are also 9 values for the material properties (rho, cp, k).
I'm new to Python and suspect the issue is to do me getting muddled up with Python indexing, but I don’t understand where exactly the loop is going wrong for the two nodes next to each boundary. Thanks in advance.
import numpy as np
import matplotlib.pylab as plt
empty = np.zeros(9) # empty array to fill with required properties
#material properties (will vary with position at a later stage)
k = empty + 23
rho = empty + 1600
cp = empty + 1700
#node spacing
dr_internal = 0.15
dr_external = 0.14
r_nodes = np.linspace(0, 1.2, 9) # nodes, m
r_nodes2 = np.insert(r_nodes,9 , r_nodes[-1]+dr_external) #inserting additional point to determine
east boundary on last node
re_nodes = (r_nodes2[1:] + r_nodes2[:-1]) / 2 #east locations
rw_nodes = np.insert(re_nodes, 0, 0)[:-1] #west locations
#q density for the internal generation term
q_dens = empty + 4400000
q_dens[0] = 0
q_dens[1] = q_dens[1]*0.625
q_dens[-1] = q_dens[-1]*0.5
#setting up time increments for the analysis
timestep = 15
steps = 100
total_time = timestep * steps
time = np.arange(0, steps*timestep, timestep)
#defining the number of time points and spacial nodes
i = len(r_nodes)
n = len(time)
T = np.zeros((i,n))
#initialising temperatures based on the boundary condition and initial condition
IC = 873
BC = [873, 873]
T[0,:] = BC[0]
T[-1,:] = BC[1]
T[:,0] = IC
#energy generation is time dependent, so creating a fraction to multiply internal generation term by
fraction=np.zeros(steps)
for j in range(1, steps):
time2 = j*timestep
fraction[j] = 0.06*time2**(-0.2)
fraction[0] = 0.06
def conduction_in( kw, rw, Ti, Ti_minus_1, ri, ri_minus_1):
return (-kw*rw*((Ti-Ti_minus_1)/(ri-ri_minus_1)))
def conduction_out(k, re, Ti_plus_1, Ti, ri_plus_1, ri):
return (k*re*((Ti_plus_1-Ti)/(ri_plus_1-ri)))
def internal_gen(q_dens, dt, rho, cp):
return q_dens*dt/(rho*cp)
def Tn_plus_1(Ti, dt, rho, cp, re, rw, conduction_in, conduction_out, internal_gen):
return Ti + ((2*dt/(rho*cp*(re**2-rw**2)))*(conduction_in - conduction_out ))+ internal_gen
for j in range(1, n): # time
for e in range(1, i-1): # position
T[e,j] = Tn_plus_1( T[e, j-1] , timestep,rho[e], cp[e], re_nodes[e] , rw_nodes[e],
conduction_in(k[e-1], rw_nodes[e],T[e, j-1], T[e-1, j-1], r_nodes[e], r_nodes[e-1]),
conduction_out(k[e], re_nodes[e], T[e+1, j-1], T[e, j-1], r_nodes[e+1], r_nodes[e] ),
fraction[j]*internal_gen(q_dens[e], timestep, rho[e], cp[e]) )
plt.plot(T[:,99])
What I get:

What I expect:

range(n)instead ofrange(1,m)) and re-review your code.