| > |
restart:
interface(showassumed = 0):
with(plots):
#####################################################################
# EDUCATIONAL MAPLE WORKSHEET
# TRANSIENT AXISYMMETRIC HEAT CONDUCTION IN A FINITE CYLINDRICAL ROD
#
# Purpose
# -------
# This worksheet explains, derives, evaluates, and checks a double-series
# solution for a finite cylindrical rod subject to a radially varying,
# time-dependent heat flux q(r,t) at z = 0.
#
# The solution is axisymmetric:
#
# T = T(r,z,t)
#
# There is no dependence on the angular coordinate theta.
#
# IMPORTANT MAPLE NOTE
# --------------------
# The name gamma is protected in Maple. Therefore this worksheet uses
# the name axialWaveNumber instead of gamma.
#
# Also note:
# local declarations are used only inside proc ... end proc.
# All definitions outside procedures are global worksheet assignments.
#####################################################################
#####################################################################
# 0. PHYSICAL MODEL AND DOMAIN
#
# Domain:
#
# 0 <= r <= a
# 0 <= z <= L
# t >= 0
#
# Variables:
#
# r : radial coordinate
# z : axial coordinate
# t : time
#
# Material constants:
#
# K : thermal conductivity
# rho : density
# cp : specific heat capacity
# alpha : thermal diffusivity
#
# Relation:
#
# alpha = K/(rho*cp)
#
# Governing equation:
#
# rho*cp*T_t = K*(T_rr + (1/r)*T_r + T_zz)
#
# or equivalently:
#
# T_t = alpha*(T_rr + (1/r)*T_r + T_zz)
#
# Boundary conditions:
#
# BC1 -K*T_z(r,0,t) = q(r,t) applied heat flux
# BC2 T_z(r,L,t) = 0 insulated end
# BC3 T(a,z,t) = 0 prescribed wall temperature
# BC4 T_r(0,z,t) = 0 axisymmetry
#
# Initial condition:
#
# IC T(r,z,0) = 0
#
# CORNER COMPATIBILITY
# --------------------
# BC1 and BC3 meet at (r,z)=(a,0).
#
# Because BC3 gives T(a,z,t)=0 for every z, its axial derivative at the
# corner is also zero:
#
# T_z(a,0,t)=0.
#
# Then BC1 requires:
#
# q(a,t)=0.
#
# Hence q(a,t)=0 is necessary for classical compatibility.
#####################################################################
#####################################################################
# 1. SYMBOLIC PARAMETERS
#####################################################################
assume(K > 0):
assume(rho > 0):
assume(cp > 0):
assume(alpha > 0):
assume(a > 0):
assume(L > 0):
alpha_relation := alpha = K/(rho*cp):
#####################################################################
# 2. PDE, BOUNDARY CONDITIONS, AND INITIAL CONDITION
#####################################################################
PDE_cylinder :=
diff(T(r,z,t),t)
=
alpha*(
diff(T(r,z,t),r$2)
+
diff(T(r,z,t),r)/r
+
diff(T(r,z,t),z$2)
):
BC1_flux :=
-K*D[2](T)(r,0,t)
=
q(r,t):
BC2_top :=
D[2](T)(r,L,t)
=
0:
BC3_wall :=
T(a,z,t)
=
0:
BC4_axis :=
D[1](T)(0,z,t)
=
0:
IC :=
T(r,z,0)
=
0:
corner_compatibility :=
q(a,t)
=
0:
#####################################################################
# 3. RADIAL STURM-LIOUVILLE SYSTEM
#
# WHY BESSEL FUNCTIONS APPEAR
# ----------------------------
# Separation of variables in cylindrical coordinates produces
#
# R'' + (1/r)R' + beta^2 R = 0.
#
# The solution regular at r=0 is J_0(beta*r). The wall condition
# R(a)=0 selects discrete values beta_m=mu_m/a, where mu_m is the
# m-th positive zero of J_0.
#
# The radial eigenproblem is
#
# R'' + (1/r)R' + beta^2 R = 0,
# R'(0) = 0,
# R(a) = 0.
#
# Hence:
#
# R_m(r) = J_0(mu_m*r/a),
#
# where mu_m is the m-th positive zero of J_0.
#
# beta_m = mu_m/a.
#
# Orthogonality:
#
# int(r*R_m(r)*R_j(r),r=0..a) = 0, m<>j,
#
# and
#
# int(r*R_m(r)^2,r=0..a)
# = a^2*J_1(mu_m)^2/2.
#####################################################################
mu :=
m ->
BesselJZeros(0,m):
beta :=
m ->
mu(m)/a:
Rmode :=
(m,rvalue) ->
BesselJ(0,mu(m)*rvalue/a):
Rnorm :=
m ->
a^2*BesselJ(1,mu(m))^2/2:
#####################################################################
# 4. RADIAL EXPANSION OF THE APPLIED HEAT FLUX
#
# The flux profile must be expanded in the same radial eigenfunctions.
# The weight r in the integral is essential: it comes from the
# cylindrical area element and the Sturm-Liouville inner product.
#
# q(r,t) = Sum(q_m(t)*R_m(r),m=1..infinity),
#
# with
#
# q_m(t) =
# 2/(a^2*J_1(mu_m)^2)
# * int(r*q(r,t)*J_0(mu_m*r/a),r=0..a).
#####################################################################
qmode :=
(m,tvalue) ->
2
/
(
a^2*BesselJ(1,mu(m))^2
)
*
Int(
r*q(r,tvalue)*BesselJ(0,mu(m)*r/a),
r=0..a
):
#####################################################################
# 5. AXIAL EIGENFUNCTIONS
#
# The axial eigenfunctions are cosines because the homogenized axial
# problem has Neumann conditions at z=0 and z=L. The n=0 mode is the
# constant axial mode and must be retained.
#
# The homogeneous axial conditions are Neumann conditions:
#
# Z_n'(0)=0, Z_n'(L)=0.
#
# Thus:
#
# Z_0(z)=1,
# Z_n(z)=cos(n*Pi*z/L), n>=1.
#####################################################################
Zmode :=
(n,zvalue) ->
piecewise(
n=0,
1,
cos(n*Pi*zvalue/L)
):
axialWaveNumber :=
n ->
n*Pi/L:
axial_factor :=
n ->
piecewise(
n=0,
1,
2
):
#####################################################################
# 6. MODAL EQUATIONS
#
# Projection converts the PDE into independent first-order ODEs for
# the modal amplitudes A[m,n](t). Each mode decays at a rate determined
# by radial diffusion plus axial diffusion.
#
# Write
#
# T(r,z,t)
# =
# Sum(
# Sum(A[m,n](t)*R_m(r)*Z_n(z),n=0..infinity),
# m=1..infinity
# ).
#
# Projection gives
#
# A[m,n]'(t)
# + alpha*(beta_m^2 + gamma_n^2)*A[m,n](t)
#
# =
# axial_factor(n)*alpha*q_m(t)/(K*L),
#
# with A[m,n](0)=0.
#
# Therefore:
#
# A[m,n](t)
# =
# axial_factor(n)*alpha/(K*L)
# *
# int(
# exp(-alpha*(beta_m^2+gamma_n^2)*(t-s))*q_m(s),
# s=0..t
# ).
#####################################################################
decay :=
(m,n) ->
alpha*(
beta(m)^2
+
axialWaveNumber(n)^2
):
Amn :=
(m,n,tvalue) ->
axial_factor(n)*alpha/(K*L)
*
Int(
exp(
-decay(m,n)*(tvalue-s)
)
*
qmode(m,s),
s=0..tvalue
):
#####################################################################
# 7. FORMAL DOUBLE-SERIES SOLUTION
#
# This is a formal symbolic representation. Maple may display inert
# Int and Sum objects. Numerical work below uses finite sums and
# evaluates the radial projections numerically.
#####################################################################
T_exact :=
Sum(
Sum(
Amn(m,n,t)
*
Rmode(m,r)
*
Zmode(n,z),
n=0..infinity
),
m=1..infinity
):
printf("\nFormal double-series solution:\n"):
T(r,z,t) = T_exact;
#####################################################################
# 8. A COMPATIBLE EXAMPLE FLUX
#
# The factor 1-(r/a)^2 forces q(a,t)=0. The factor sin(omega*t)
# forces q(r,0)=0, making the flux compatible with the zero initial
# temperature at t=0.
#
# Choose
#
# q(r,t) = q0*(1-(r/a)^2)*sin(omega*t).
#
# This satisfies:
#
# q(a,t)=0 for every t,
#
# and also q(r,0)=0, so the flux is compatible with the zero initial
# temperature at t=0.
#####################################################################
assume(q0 > 0):
assume(omega > 0):
q_example :=
(rvalue,tvalue) ->
q0*(
1-(rvalue/a)^2
)
*
sin(omega*tvalue):
corner_check :=
simplify(
q_example(a,t)
):
printf(
"\nCorner compatibility check q(a,t): %a\n",
corner_check
):
initial_flux_check :=
simplify(
q_example(r,0)
):
printf(
"Initial flux compatibility check q(r,0): %a\n",
initial_flux_check
):
#####################################################################
# 9. RADIAL COEFFICIENTS FOR THE EXAMPLE FLUX
#
# Since q(r,t)=f(r)*sin(omega*t), write
#
# q_m(t)=Q_m*sin(omega*t).
#####################################################################
Qm :=
m ->
simplify(
2*q0
/
(
a^2*BesselJ(1,mu(m))^2
)
*
Int(
r
*
(
1-(r/a)^2
)
*
BesselJ(0,mu(m)*r/a),
r=0..a
)
):
qmode_example :=
(m,tvalue) ->
Qm(m)*sin(omega*tvalue):
#####################################################################
# 10. CLOSED TIME CONVOLUTION FOR SINUSOIDAL HEATING
#
# For lambda_mn = alpha*(beta_m^2+gamma_n^2),
#
# int(
# exp(-lambda_mn*(t-s))*sin(omega*s),
# s=0..t
# )
#
# =
# (
# lambda_mn*sin(omega*t)
# -omega*cos(omega*t)
# +omega*exp(-lambda_mn*t)
# )
# /
# (
# lambda_mn^2+omega^2
# ).
#####################################################################
TimeConvolution :=
(m,n,tvalue) ->
(
decay(m,n)*sin(omega*tvalue)
-
omega*cos(omega*tvalue)
+
omega*exp(-decay(m,n)*tvalue)
)
/
(
decay(m,n)^2
+
omega^2
):
Amn_example :=
(m,n,tvalue) ->
axial_factor(n)*alpha/(K*L)
*
Qm(m)
*
TimeConvolution(m,n,tvalue):
T_example_exact :=
Sum(
Sum(
Amn_example(m,n,t)
*
Rmode(m,r)
*
Zmode(n,z),
n=0..infinity
),
m=1..infinity
):
printf(
"\nSeries solution for q(r,t)=q0*(1-(r/a)^2)*sin(omega*t):\n"
):
T(r,z,t) = T_example_exact;
#####################################################################
# 11. NUMERICAL PARAMETER VALUES
#
# Replace these demonstration values by the physical values of the rod.
# Units must be consistent. In SI units:
# K [W/(m K)], rho [kg/m^3], cp [J/(kg K)], a,L [m], q0 [W/m^2].
#
# K : thermal conductivity
# rho : density
# cp : specific heat
# alpha : thermal diffusivity K/(rho*cp)
#####################################################################
Kval :=
10.0:
rhoval :=
7800.0:
cpval :=
500.0:
alphaval :=
Kval/(rhoval*cpval):
aval :=
0.5:
Lval :=
2.0:
q0val :=
1000.0:
omegaval :=
1.0:
Mterms :=
15:
Nterms :=
25:
#####################################################################
# 12. NUMERICAL RADIAL EIGENVALUES AND EIGENFUNCTIONS
#
# Bessel zeros are cached implicitly by Maple when repeatedly evaluated.
# The radial eigenfunctions automatically satisfy T(a,z,t)=0.
#####################################################################
mu_num :=
m ->
evalf(
BesselJZeros(0,m)
):
beta_num :=
m ->
mu_num(m)/aval:
Rmode_num :=
(m,rvalue) ->
BesselJ(
0,
mu_num(m)*rvalue/aval
):
gamma_num :=
n ->
n*Pi/Lval:
axial_factor_num :=
n ->
piecewise(
n=0,
1.0,
2.0
):
decay_num :=
(m,n) ->
alphaval*(
beta_num(m)^2
+
gamma_num(n)^2
):
#####################################################################
# 13. NUMERICAL RADIAL FLUX COEFFICIENTS
#
# Qm_num is a Maple procedure because it needs a local variable and
# option remember. This avoids recalculating the same quadrature for
# every plot point.
#
# Hardware quadrature is used once for each radial mode.
#####################################################################
Qm_num :=
proc(m)
option remember;
local mum;
mum :=
mu_num(m);
return evalf(
2*q0val
/
(
aval^2*BesselJ(1,mum)^2
)
*
evalf(
Int(
x
*
(
1-(x/aval)^2
)
*
BesselJ(
0,
mum*x/aval
),
x=0..aval,
method=_Gquad
)
)
);
end proc:
#####################################################################
# 14. NUMERICAL MODAL AMPLITUDES
#####################################################################
TimeConvolution_num :=
(m,n,tvalue) ->
(
decay_num(m,n)*sin(omegaval*tvalue)
-
omegaval*cos(omegaval*tvalue)
+
omegaval*exp(-decay_num(m,n)*tvalue)
)
/
(
decay_num(m,n)^2
+
omegaval^2
):
Amn_num :=
(m,n,tvalue) ->
axial_factor_num(n)
*
alphaval
/
(
Kval*Lval
)
*
Qm_num(m)
*
TimeConvolution_num(m,n,tvalue):
#####################################################################
# 15. TRUNCATED DOUBLE SERIES
#
# The exact solution uses infinitely many radial and axial modes.
# Numerically, we truncate at m=1..M and n=0..N.
# Increase M and N until the result changes negligibly.
#####################################################################
Tnum :=
proc(rvalue,zvalue,tvalue,M,N)
local m;
local n;
local total;
if not type(rvalue,numeric) then
return 'procname'(rvalue,zvalue,tvalue,M,N);
end if;
if not type(zvalue,numeric) then
return 'procname'(rvalue,zvalue,tvalue,M,N);
end if;
if not type(tvalue,numeric) then
return 'procname'(rvalue,zvalue,tvalue,M,N);
end if;
total :=
add(
add(
Amn_num(m,n,tvalue)
*
Rmode_num(m,rvalue)
*
piecewise(
n=0,
1.0,
cos(n*Pi*zvalue/Lval)
),
n=0..N
),
m=1..M
);
return evalf(total);
end proc:
#####################################################################
# 16. NUMERICAL CHECKS
#
# A small nonzero wall value, for example 1e-14, is numerical roundoff
# and should be interpreted as zero.
#####################################################################
printf(
"\nNumerical q(a,t) check at t=1: %g\n",
q0val*(1-(aval/aval)^2)*sin(omegaval)
):
printf(
"Initial temperature check T(r,z,0): %g\n",
Tnum(0.2,0.7,0.0,Mterms,Nterms)
):
printf(
"Outer-wall check T(a,z,t): %g\n",
Tnum(aval,0.7,1.0,Mterms,Nterms)
):
printf(
"Sample temperature T(0.2,0.7,1): %g\n",
Tnum(0.2,0.7,1.0,Mterms,Nterms)
):
#####################################################################
# 17. TEMPERATURE ON THE r-z CROSS-SECTION AT A FIXED TIME
#####################################################################
tplot :=
2.0:
CrossSectionTemperature :=
plot3d(
(rvalue,zvalue) ->
Tnum(
rvalue,
zvalue,
tplot,
Mterms,
Nterms
),
0..aval,
0..Lval,
labels =
[
"radius r",
"axial coordinate z",
"temperature T(r,z,t)"
],
title =
cat(
"Axisymmetric temperature field at t = ",
tplot
),
axes =
boxed,
grid =
[35,45],
orientation =
[55,65]
):
CrossSectionTemperature;
#####################################################################
# 18. RADIAL TEMPERATURE PROFILES AT z=0
#####################################################################
RadialProfiles :=
plot(
[
rvalue ->
Tnum(
rvalue,
0.0,
0.5,
Mterms,
Nterms
),
rvalue ->
Tnum(
rvalue,
0.0,
1.0,
Mterms,
Nterms
),
rvalue ->
Tnum(
rvalue,
0.0,
2.0,
Mterms,
Nterms
)
],
0..aval,
labels =
[
"radius r",
"temperature T(r,0,t)"
],
legend =
[
"t = 0.5",
"t = 1.0",
"t = 2.0"
],
title =
"Radial temperature profiles on the heated end",
thickness =
2,
adaptive =
false,
numpoints =
180
):
RadialProfiles;
#####################################################################
# 19. EDUCATIONAL CONVERGENCE STUDY
#
# A truncated series should be checked by increasing M and N.
# The following procedure compares several truncation levels at one
# selected point (rtest,ztest,ttest).
#####################################################################
ConvergenceStudy :=
proc(rtest,ztest,ttest)
local truncations;
local j;
local Mj;
local Nj;
local valuej;
truncations :=
[
[5,8],
[8,12],
[12,18],
[15,25],
[20,35]
];
printf(
"\nConvergence study at r=%g, z=%g, t=%g\n",
rtest,
ztest,
ttest
);
printf(
" M N T_MN\n"
);
for j from 1 to nops(truncations) do
Mj := truncations[j][1];
Nj := truncations[j][2];
valuej :=
Tnum(
rtest,
ztest,
ttest,
Mj,
Nj
);
printf(
"%7d %7d %20.12g\n",
Mj,
Nj,
valuej
);
end do;
return NULL;
end proc:
ConvergenceStudy(
0.2,
0.7,
1.0
):
#####################################################################
# 20. EDUCATIONAL SUMMARY
#
# 1. Because q=q(r,t), radial dependence cannot be discarded.
#
# 2. The wall condition T(a,z,t)=0 gives Bessel J_0 radial modes.
#
# 3. The insulated axial end and homogenized lower-end condition give
# cosine modes in z.
#
# 4. The compatibility condition q(a,t)=0 is required at the corner
# where BC1 and BC3 meet.
#
# 5. The exact solution is a double infinite series.
#
# 6. Tnum evaluates a truncated version of that series.
#
# 7. Mterms and Nterms should be selected through a convergence study.
#####################################################################
printf(
"\nWorksheet completed successfully.\n"
):
#####################################################################
# END OF THE EDUCATIONAL MAPLE WORKSHEET
#####################################################################
|