-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathmain_thermalConductionBenchmarks.m
More file actions
195 lines (161 loc) · 7.38 KB
/
Copy pathmain_thermalConductionBenchmarks.m
File metadata and controls
195 lines (161 loc) · 7.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
%% Licensing
%
% License: BSD License
% cane Multiphysics default license: cane/license.txt
%
% Main authors: Andreas Apostolatos
% Marko Leskovar
%
%% Script documentation
%
% Task : Transient heat transfer analysis for two benchmark cases
%
% Date : 21.04.2020
%
%% Preamble
clear;
clc;
close all;
%% Includes
% Add general math functions
addpath('../../generalMath/');
% Add all functions related to parsing
addpath('../../parsers/');
% Add all functions related to the low order basis functions
addpath('../../basisFunctions/');
% Add the equation system solvers
addpath('../../equationSystemSolvers/');
% Add all the efficient computation functions
addpath('../../efficientComputation/');
% Include functions related to transient analysis
addpath('../../transientAnalysis/');
% Add all functions related to body forces
addpath('../../FEMPlateInMembraneActionAnalysis/loads/');
% Add all functions related to heat transfer analysis
addpath('../../FEMThermalConductionAnalysis/solvers/',...
'../../FEMThermalConductionAnalysis/solutionMatricesAndVectors/',...
'../../FEMThermalConductionAnalysis/loads/',...
'../../FEMThermalConductionAnalysis/graphics/',...
'../../FEMThermalConductionAnalysis/output/',...
'../../FEMThermalConductionAnalysis/initialConditions/',...
'../../FEMThermalConductionAnalysis/postprocessing/', ...
'../../FEMThermalConductionAnalysis/transientAnalysis/');
%% Parse data from GiD input file
% Define the path to the case
pathToCase = '../../inputGiD/FEMThermalConductionAnalysis/';
% caseName = 'transientSquareCavity';
caseName = 'transientWallHeating';
% Parse the data from the GiD input file
[thermalMsh, homDOFs, inhomDOFs, valuesInhomDOFs, propNBC, propAnalysis, ...
propParameters, propNLinearAnalysis, propThermalDynamics, propGaussInt] = ...
parse_ThermalModelFromGid(pathToCase, caseName, 'outputEnabled');
%% UI
% On the computation of the body forces
computeBodyForces = 'undefined';
% Equation system solver
solve_LinearSystem = @solve_LinearSystemMatlabBackslashSolver;
% solve_LinearSystem = @solve_LinearSystemGMResWithIncompleteLUPreconditioning;
% On the writing the output function
propVTK.isOutput = false;
propVTK.writeOutputToFile = @writeOutputFEMThermalConductionAnalysisToVTK;
propVTK.VTKResultFile = 'undefined';
% Initialize graphics index
propGraph.index = 1;
% On transient inhomogeneous Dirichlet boundary conditions
updateInhomDOFs = 'undefined';
propIDBC = [];
% Choose the appropriate matrix update computation corresponding to the
% chosen time integration scheme
if strcmp(propThermalDynamics.method,'IMPLICIT_EULER')
propThermalDynamics.computeProblemMtrcsTransient = ...
@computeProblemMtrcsImplicitEulerThermalConduction;
propThermalDynamics.computeUpdatedVct = ...
@computeBETITransientUpdatedVctAccelerationField;
elseif strcmp(propThermalDynamics.method,'GALERKIN')
propThermalDynamics.computeProblemMtrcsTransient = ...
@computeProblemMtrcsGalerkinThermalConduction;
propThermalDynamics.computeUpdatedVct = ...
@computeBETITransientUpdatedVctAccelerationField;
elseif strcmp(propThermalDynamics.method,'CRANK_NICOLSON')
propThermalDynamics.computeProblemMtrcsTransient = ...
@computeProblemMtrcsCrankNicolsonThermalConduction;
propThermalDynamics.computeUpdatedVct = ...
@computeBETITransientUpdatedVctAccelerationField;
else
error('Invalid time integration method selected in propStrDynamics.method as %s',propThermalDynamics.method);
end
% Define the initial condition function
computeInitialConditions = @computeInitCndsFEMThermalConductionAnalysis;
%% Define intial temperature and/or applied heat flux
if strcmp(caseName, 'transientSquareCavity')
propThermalDynamics.temperatureInit = 300;
propNBC.flux = 0;
elseif strcmp(caseName, 'transientWallHeating')
propThermalDynamics.temperatureInit = 200;
propNBC.flux = 0;
end
%% Solve the transient heat transfer problem
[THistory, WComplete, minElSize] = solve_FEMThermalConductionTransient ...
(thermalMsh, homDOFs, inhomDOFs, valuesInhomDOFs, ...
updateInhomDOFs, propNBC, @computeLoadVctFEMThermalConductionAnalysis, ...
propParameters, computeBodyForces, propAnalysis, computeInitialConditions, ...
@computeStiffMtxAndLoadVctFEMThermalConductionAnalysisCST, ...
propNLinearAnalysis, propIDBC, propThermalDynamics, solve_LinearSystem, ...
@solve_FEMLinearSystem, propGaussInt, propVTK, caseName,'outputEnabled');
%% Define properties related to the computation of the analytical solution
% Define the number of infinite series sum for the analytical solution
propPostproc.k = 200;
% Compute the height and the width of the computational domain
propPostproc.height = abs(max(thermalMsh.nodes(:, 3)) - min(thermalMsh.nodes(:, 3)));
propPostproc.width = abs(max(thermalMsh.nodes(:, 2)) - min(thermalMsh.nodes(:, 2)));
%% Define a function to compute analytical results
if strcmp(caseName, 'transientSquareCavity')
propPostproc.computeAnalytical = @(x, y, t, propPostproc) ...
propPostproc.T1 + (propPostproc.T2 - propPostproc.T1) * (2/pi) * ...
sum(((((-1).^((1:propPostproc.k) + 1)) + 1)./(1:propPostproc.k)) .* ...
sin(((1:propPostproc.k)*pi*x)/propPostproc.width).* ...
(sinh(((1:propPostproc.k)*pi*y)/propPostproc.width)./ ...
sinh(((1:propPostproc.k)*pi*propPostproc.height)/propPostproc.width)));
% Assign temperatures
propPostproc.T1 = min(valuesInhomDOFs);
propPostproc.T2 = max(valuesInhomDOFs);
elseif strcmp(caseName, 'transientWallHeating')
propPostproc.computeAnalytical = @(x,y,t,propPostproc) ...
propPostproc.T2 + (propPostproc.T1 - propPostproc.T2)*(4/pi)* ...
sum((1./(2*(1:propPostproc.k) - 1)).* ...
exp(-(((2*(1:propPostproc.k) - 1)*pi)/propPostproc.width)*propPostproc.alpha*t).* ...
sin(((2*(1:propPostproc.k) - 1)*pi*x)/propPostproc.width));
% Assign temperatures and alpha
propPostproc.T1 = propThermalDynamics.temperatureInit;
propPostproc.T2 = max(valuesInhomDOFs);
% Compute thermal diffusivity
propPostproc.alpha = propParameters.alpha;
end
%% Visualize analytical solution at one time instance
if strcmp(caseName, 'transientSquareCavity') || strcmp(caseName, 'transientWallHeating')
t = propThermalDynamics.TEnd;
propGraph.index = plot_analyticalSolutionAtTimeInstance ...
(thermalMsh, t, propPostproc, propGraph, 'outputEnabled');
end
%% Compute the selected resultant at the chosen Cartesian location over time
x = 0.6;
y = 0.6;
[timeSpaceDiscrete, resultantNumerical, resultantAnalytical] = ...
computeTemperatureAtPointOverTime...
(x, y, thermalMsh, THistory, ...
propThermalDynamics, propPostproc, 'outputEnabled');
%% Plot the selected resultant at the chosen Cartesian location over time
figure(propGraph.index)
if ~ischar(resultantAnalytical)
plot(timeSpaceDiscrete, resultantAnalytical, 'black',...
timeSpaceDiscrete, resultantNumerical, 'blue', 'LineWidth', 2);
legend('Analytical', 'FEM', 'Orientation', 'horizontal', 'Location', 'southoutside');
else
plot(timeSpaceDiscrete, resultantNumerical, 'blue', 'LineWidth', 2);
end
grid on;
xlabel('Time [seconds]');
ylabel('Temperature');
title(sprintf('Evolution of Temperature at point X = (%d, %d)', x, y));
propGraph.index = propGraph.index + 1;
%% END OF THE SCRIPT