Thermal fin

1. Problem statement

We consider the problem of designing a thermal fin to effectively remove heat from a surface. The two-dimensional fin, shown in Figure below, consists of a vertical central post and four horizontal subfins; the fin conducts heat from a prescribed uniform flux source at the root, Γroot Γroot , through the large-surface-area subfins to surrounding flowing air. The fin is characterized by a five-component parameter vector, or input, μ=(μ1,μ2,,μ5), where μi=ki,i=1,,4, and μ5=Bi;μ may take on any value in a specified design set DR5.

fin2d 4 mesh
Figure 1. Geometry of 2D thermal fin

Here ki is the thermal conductivity of the ith subfin (normalized relative to the post conductivity k01 ); and Bi is the Biot number, a nondimensional heat transfer coefficient reflecting convective transport to the air at the fin surfaces (larger Bi means better heat transfer). For example, suppose we choose a thermal fin with k1=0.4,k2=0.6,k3=0.8,k4=1.2, and Bi=0.1; for this particular configuration μ={0.4,0.6,0.8,1.2,0.1}, which corresponds to a single point in the set of all possible configurations D (the parameter or design set). The post is of width unity and height four; the subfins are of fixed thickness t=0.25 and length L=2.5.

We are interested in the design of this thermal fin, and we thus need to look at certain outputs or cost-functionals of the temperature as a function of μ. We choose for our output Troot , the average steady-state temperature of the fin root normalized by the prescribed heat flux into the fin root. The particular output chosen relates directly to the cooling efficiency of the fin lower values of Troot  imply better thermal performance. The steadystate temperature distribution within the fin, u(μ), is governed by the elliptic partial differential equation

ρiCiuitkiΔui=0 in Ωi,i=0,,4,

where Δ is the Laplacian operator, and ui refers to the restriction of u to Ωi. Here Ωi is the region of the fin with conductivity ki,i=0,,4 and volumetric heat capacity (ρC)i,i=0,,4: Ω0 is thus the central post, and Ωi,i=1,,4, corresponds to the four subfins.

The entire fin domain is denoted Ω(ˉΩ=4i=0ˉΩi); the boundary Ω is denoted Γ. We must also ensure continuity of temperature and heat flux at the conductivity discontinuity interfaces Γiint Ω0Ωi,i=1,,4, where Ωi denotes the boundary of Ωi, we have on Γiint i=1,,4 :

u0=ui(u0ni)=ki(uini)

here ni is the outward normal on Ωi. Finally, we introduce a Neumann flux boundary condition on the fin root

(u0n0)=1 on Γroot ,

which models the heat source; and a Robin boundary condition

ki(uini)=Biui on Γiext,i=0,,4,

which models the convective heat losses. Here Γiext  is that part of the boundary of Ωi exposed to the flowing fluid; note that 4i=0Γiext=ΓΓroot . The average temperature at the root, Troot (μ), can then be expressed as O(u(μ)), where

O(v)=Γroot v

2. Implementation

First, we initialize the Feel++ environment and set the working directory.

import feelpp
from feelpp_project import laplacian
import json
import os

d = os.getcwd()
print(f"directory={d}")
e = feelpp.Environment(['fin'], config=feelpp.localRepository("."))
python
Results
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
File :1
----> 1 import feelpp
      2 from feelpp_project import laplacian
      3 import json

ModuleNotFoundError: No module named 'feelpp'

Next, we set the configuration file for the simulation and load the specifications from a JSON file.

feelpp.Environment.setConfigFile(f"{d}/src/cases/laplacian/fin/fin1/fin2d.cfg")
# Reading the JSON file
data = laplacian.loadSpecs(f"{d}/src/cases/laplacian/fin/fin2d.json")
print(data)
python
Results
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
File :1
----> 1 feelpp.Environment.setConfigFile(f"{d}/src/cases/laplacian/fin/fin1/fin2d.cfg")
      2 # Reading the JSON file
      3 data = laplacian.loadSpecs(f"{d}/src/cases/laplacian/fin/fin2d.json")

NameError: name 'feelpp' is not defined

Now, we create a Laplacian object, set the specifications, and run the simulation.

lap = laplacian.get(dim=2, order=1)
lap.setSpecs(data)
lap.run()
meas=lap.measures()
python
Results
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
File :1
----> 1 lap = laplacian.get(dim=2, order=1)
      2 lap.setSpecs(data)
      3 lap.run()

NameError: name 'laplacian' is not defined

After running the simulation, we convert the results to a Pandas DataFrame and set the 'time' column as the index for easy data manipulation.

import pandas as pd
df = pd.DataFrame(meas)
df.set_index('time', inplace=True)
print(df.to_markdown())
python
Results
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
File :2
      1 import pandas as pd
----> 2 df = pd.DataFrame(meas)
      3 df.set_index('time', inplace=True)
      4 print(df.to_markdown())

NameError: name 'meas' is not defined

In the next block, we plot the mean temperature values at the fin root and the exterior using Plotly.

Temperatures
import plotly.graph_objects as go
import numpy as np

fig = go.Figure()
fig.add_trace(go.Scatter(x=df.index, y=df["mean_Gamma_root"], mode='lines', name='T_{Gamma Root}'))
fig.add_trace(go.Scatter(x=df.index, y=df["mean_Gamma_ext"], mode='markers', name='T_{Gamma Ext}'))
fig.add_trace(go.Scatter(x=df.index, y=df["min"], mode='markers', name='min T'))
fig.add_trace(go.Scatter(x=df.index, y=df["max"], mode='markers', name='max T'))
fig.update_layout(title='Temperature', xaxis_title='time', yaxis_title='T')
fig.show()
python
Results

Lastly, we plot the heat flux values at the fin root and the exterior.

Fluxes
fig = go.Figure()
fig.add_trace(go.Scatter(
    x=df.index, y=df["flux_Gamma_root"], mode='lines', name='Flux_{Gamma Root}'))
fig.add_trace(go.Scatter(
    x=df.index, y=df["flux_Gamma_ext"], mode='markers', name='Flux_{Gamma Ext}'))
fig.update_layout(title='Heat Flux', xaxis_title='time', yaxis_title='Flux')
fig.show()
python
Results