|
FEATool Multiphysics
v1.18.1
Finite Element Analysis Toolbox
|
EX_HEATTRANSFER11 Design optimization for cooling with target temperature.
[ FEA, OUT ] = EX_HEATTRANSFER11( VARARGIN ) Heat transfer example for cooling of a heated block using cooling pipes. An optimization problem is defined and set up to reach (but not exceed) a target temperature, Tstar, with n=1-9 number of cooling pipes with variable diameter, D = 5-18 mm.
+--------------------------------+ | Heated Top Block | +--------------------------------+ T(x,n,D) <= Tstar | Cooling Plate with n x Pipes | | (D) ( ) ( ) ( ) ( ) | +--------------------------------+
Accepts the following property/value pairs.
Input Value/{Default} Description
-----------------------------------------------------------------------------------
npipes array {[1, 9]} Minimum and maximum number of pipes
diam array {[0.005, 0.018]} Minimum and maximum pipe diameter
Tstar scalar {358.15} Target temperature [K]
iplot scalar 0/{1} Plot solution and error (=1)
.
Output Value/(Size) Description
-----------------------------------------------------------------------------------
fea struct Problem definition struct
out struct Output struct
cOptDef = { 'npipes', [1, 9];
'diam', [0.005, 0.019];
'Tstar', 358.15;
'iplot', 1;
'tol', 0.1;
'fid', 1 };
[got,opt] = parseopt( cOptDef, varargin{:} );
feaCache = containers.Map( 'KeyType', 'char', 'ValueType', 'any' ); % Handle (in-place) cache.
% Outer loop: evaluate all integer n (starting D from previous result).
if( ~isempty(opt.fid) )
fprintf(opt.fid, '%-4s %-10s %-12s %-12s %-10s\n', 'n', 'D (m)', 'Tmax (K)', 'Cost', 'FEA calls');
fprintf(opt.fid, '%s\n', repmat('-', 1, 51));
end
penaltyWeight = 1e4;
D0 = (opt.diam(1) + opt.diam(2)) / 2;
nValues = opt.npipes(1):opt.npipes(2);
res = struct('n', {}, 'D', {}, 'cost', {}, 'ff', {});
for it = 1:length(nValues)
n = nValues(it);
[Dopt, cost, ff] = innerOpt(n, opt.Tstar, opt.diam(1), opt.diam(2), penaltyWeight, D0, feaCache);
res(it) = struct('n', n, 'D', Dopt, 'cost', cost, 'ff', ff);
D0 = Dopt; % Warm start next n.
if( ~isempty(opt.fid) )
fprintf(opt.fid, '%-4d %-10.4f %-12.2f %-12.4f %-10d\n', ...
n, Dopt, opt.Tstar+ff.Ineq, cost, feaCache.Count);
end
end
% Select best feasible result.
costs = [res.cost];
[~, idx] = min(costs);
best = res(idx);
Tmax = opt.Tstar + best.ff.Ineq;
if( ~isempty(opt.fid) )
fprintf(opt.fid, '\n--- Optimal solution ---\n');
fprintf(opt.fid, 'Number of pipes : %d\n', best.n);
fprintf(opt.fid, 'Pipe diameter : %.4f m\n', best.D);
fprintf(opt.fid, 'Max temperature : %.2f K (%.2f C)\n', Tmax, Tmax - 273.15);
fprintf(opt.fid, 'Objective value : %.4f K\n', best.ff.Fval);
yn = 'No'; if( ff.Ineq <= 0 ), yn = 'Yes'; end
fprintf(opt.fid, 'Feasible : %s\n', yn);
fprintf(opt.fid, 'Total FEA calls : %d\n', feaCache.Count);
end
[~,fea] = l_run_fea_optimization_problem([best.n; best.D], opt.Tstar);
% Error checking.
out.err = abs(opt.Tstar - Tmax);
out.pass = out.err < opt.tol;
% Postprocessing.
if( opt.iplot )
postplot( fea, 'surfexpr', 'T' )
% Mirror solution.
fea_mirror = fea;
fea_mirror.geom = l_block_cooling_geometry( best.n, best.D, 3 ); % 3D geometry for plotting.
fea_mirror.grid.p(1,:) = 0.2 - fea_mirror.grid.p(1,:); % Offset and mirror grid points.
postplot( fea_mirror, 'surfexpr', 'T' )
title(sprintf('Optimal solution: n=%d pipes, D=%.4f m | T_{max}=%.2f K', ...
best.n, best.D, Tmax));
end
if( ~nargout )
clear fea out
end
%