Matlab

Spreadsheet Link (for Microsoft Excel)[^1]

1. 用MATLAB绘制出长方体的代码

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
%% 根据三维空间中起点坐标和终点坐标绘制长方体
%输入start_point: 起点坐标,如[1,1,1];
%输入final_point: 终点坐标,如[5,6,7];
%输出: 长方体
function plot_cuboid(start_point,final_point)
%% 根据起点和终点,计算长方体的8个的顶点
vertexIndex=[0 0 0;0 0 1;0 1 0;0 1 1;1 0 0;1 0 1;1 1 0;1 1 1];
cuboidSize=final_point-start_point; %方向向量
vertex=repmat(start_point,8,1)+vertexIndex.*repmat(cuboidSize,8,1);
%% 定义6个平面分别对应的顶点
facet=[1 2 4 3;1 2 6 5;1 3 7 5;2 4 8 6;3 4 8 7;5 6 8 7];
%% 定义8个顶点的颜色,绘制的平面颜色根据顶点的颜色进行插补
color=[0;0;0;0;1;1;1;1];
%% 绘制并展示图像
patch('Vertices',vertex,'Faces',facet,'FaceVertexCData',color,'FaceColor','interp','FaceAlpha',0.5);
view([1,1,1]);
xlabel('X');
ylabel('Y');
zlabel('Z');
grid on
%% 设置xyz显示范围
xmin=min(vertex(:,1))-1;
xmax=max(vertex(:,1))+1;
ymin=min(vertex(:,2))-1;
ymax=max(vertex(:,2))+1;
zmin=min(vertex(:,3))-1;
zmax=max(vertex(:,3))+1;
axis([xmin xmax ymin ymax zmin zmax])
end

使用方式

只需要在脚本函数中输入长方体的两个顶点坐标,即可绘制长方体,实例如下:

1
2
3
clear
clc
plot_cuboid([1,1,1],[5,6,7]);

2. 用MATLAB读取fluent case和data数据

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
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% MATLAB读取Ansys fluent 16.0 六面体网格的cas和dat文件
%
% 作者:陈曦 E-mail: chenxiseu@seu.edu.cn
%
% V2在V1版本的基础上增加读入dat文件的功能
% V4_1在V4上升级,简化非结构网格接触面部分的处理,加入了FaceBCTypeList
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%文件输出开关
%如果要输出NeighbourCellList和CellListInFace,请将下面OutputSwitch变量置为1,如果不输出将下面OutputSwitch变量置为0!!!!!
OutputSwitch = 1;
%是否读取data文件
ReadDatFileSwitch = 1;

%检测数据体头部的正则表达式
CommentExp = '(?:[\s]*)(?:\(0[\s]+")([^\\)]*)(?:[\s]*"\)+)';%注释头
DimensionExp = '(?:[\s]*)(?:\(2[\s]+)([23])(?:[\s]*\))';%三维or二维头
NodeExp = '(?:[\s]*)(?:\((?:30)?10[\s]+\()([0-9a-fA-F]+[\s]+)([0-9a-fA-F]+[\s]+)([0-9a-fA-F]+[\s]+)([012][\s]+)([23])(?:[\s]*\))+';%结点头
FaceExp = '(?:[\s]*)(?:\((?:30)?13[\s]+\()([0-9a-fA-F]+[\s]+)([0-9a-fA-F]+[\s]+)([0-9a-fA-F]+[\s]+)([0-9a-fA-F]+[\s]*)([0-9a-fA-F]*)(?:[\s]*\))+';%面头
CellExp = '(?:[\s]*)(?:\((?:30)?12[\s]+\()([0-9a-fA-F]+[\s]+)([0-9a-fA-F]+[\s]+)([0-9a-fA-F]+[\s]+)(\d+[\s]?)([0-7]?)(?:[\s]*\))+';%网格单元头
ZoneExp = '(?:[\s]*)(?:\(39[\s]+\()([0-9]+[\s]+)([a-z\-]+[\s]+)([a-z\_0-9\!\$\%\&\*\/\:\<\=\>\?\~\^\.\+\-]+[\s]+)([0-9]+[\s]*)(?:\))+';%区域头

%类型定义
CellElementType = [3,3;4,4;4,4;8,6;5,5;6,5];%网格单元类型
%FaceType = [0,2,3,4];%面类型,未使用

%关键数据
TotalNumOfNode = 0;%总节点数
TotalNumOfFace = 0;%总面数
TotalNumOfCell = 0;%总单元数
NodeZoneInfo = [0 0 0 0 0];%节点区域信息
FaceZoneInfo = [0 0 0 0 0];%面区域信息
CellZoneInfo = [0 0 0 0 0];%单元区域信息
NodeList = zeros(3,1);%节点list,按顺序存节点,1-3行分别为x,y和z坐标
FaceListInNode = zeros(4,1);%面list,按顺序存面。因为目前只能处理六面体网格,因此用4个节点定义一个面
FaceTypeList = zeros(1,1);%面类型list,按顺序存facetype
FaceBCTypeList = zeros(1,1);%面边界类型list,按顺序canfacebctype
NeighbourCellList = zeros(2,1);%面两边网格单元list,第1和第2行按face的顺序记录face两边的网格单元编号,如果是边界面,则有一个是网格单元编号是0
CellListInFace = zeros(6,1);%网格单元面list,按网格顺序存所有网格的面。因为目前只能处理六面体,所以6个面定义一个网格
CellListInNode = zeros(8,1);%网格单元节点list,按网格顺序存所有网格的节点。因为目前只能处理六面体,所以8个节点定义一个网格
CellListInCell = zeros(6,1);%网格单元的相邻网格list,按网格顺序存所有网格的编号。因为目前只能处理六面体,所以一个网格有6个公用面相邻网格
CellTypeList = zeros(1,1);%网格类型list
CellElementTypeList = zeros(1,1);%网格形状类型list
ZoneInfoList = {0, '', '', 0};%区域信息list
Is3D = 0;%维度类型flag
NodeZoneInfoFlag = 0;%节点区域信息flag
FaceZoneInfoFlag = 0;%面区域信息flag
CellZoneInfoFlag = 0;%网格单元信息flag
ZoneInfoListFlag = 0;%区域信息list的flag

%打开cas文件
[FileName, PathName] = uigetfile('*.cas', 'Select a fluent case file');
if isequal(FileName,0)
disp('User selected Cancel')
else
CasFileId = fopen(fullfile(PathName, FileName));

while ~feof(CasFileId)
Line = fgetl(CasFileId);
if length(Line) < 65536 %一个行长度判断,用来加快处理速度
if ~isempty(regexp(Line, CommentExp, 'match'))
TokenStr = regexp(Line, CommentExp, 'tokens');
CommentStr = cell2mat(TokenStr{1});
disp(CommentStr);%如果匹配了注释,就直接输出
elseif ~isempty(regexp(Line, DimensionExp, 'match'))
TokenStr = regexp(Line, DimensionExp, 'tokens');
DimensionNum = str2num(cell2mat(TokenStr{1}));%如果匹配了维度信息,就输出网格是三维还是二维
if DimensionNum == 3
Is3D = 1;
disp('The grid is 3D.')
else
Is3D = 0;
disp('The grid is not 3D.')
end
elseif ~isempty(regexp(Line, NodeExp, 'match'))%如果匹配了节点信息
TokenStr = regexp(Line, NodeExp, 'tokens');
ZoneID = hex2dec(TokenStr{1}{1});
if(ZoneID == 0)
TotalNumOfNode = hex2dec(TokenStr{1}{3});
fprintf("Total number of nodes is: %d\n", TotalNumOfNode);
NodeList = zeros(3,TotalNumOfNode);
else
CurrentInfo = 1;
if NodeZoneInfoFlag == 0
NodeZoneInfoFlag = 1;
else
NodeZoneInfo = [NodeZoneInfo;[0 0 0 0 0]];
CurrentInfo = size(NodeZoneInfo,1);
end
NodeZoneInfo(CurrentInfo,1) = ZoneID;
NodeZoneInfo(CurrentInfo,2) = hex2dec(TokenStr{1}{2});
NodeZoneInfo(CurrentInfo,3) = hex2dec(TokenStr{1}{3});
NodeZoneInfo(CurrentInfo,4) = hex2dec(TokenStr{1}{4});
NodeZoneInfo(CurrentInfo,5) = hex2dec(TokenStr{1}{5});
fprintf("Start to read node information in section %d from %d to %d...\n", NodeZoneInfo(CurrentInfo,1), NodeZoneInfo(CurrentInfo,2), NodeZoneInfo(CurrentInfo,3));
fseek(CasFileId, 1, 'cof');
NodeList(:, NodeZoneInfo(CurrentInfo,2): NodeZoneInfo(CurrentInfo,3)) = fread(CasFileId, [3 NodeZoneInfo(CurrentInfo,3)-NodeZoneInfo(CurrentInfo,2)+1], 'double');
disp("Read node information done.");
end
elseif ~isempty(regexp(Line, FaceExp, 'match'))%如果匹配了面信息
TokenStr = regexp(Line, FaceExp, 'tokens');
ZoneID = hex2dec(TokenStr{1}{1});
if(ZoneID == 0)
TotalNumOfFace = hex2dec(TokenStr{1}{3});
fprintf("Total number of faces is: %d\n", TotalNumOfFace);
FaceListInNode = zeros(4,TotalNumOfFace);
NeighbourCellList = zeros(2,TotalNumOfFace);
FaceTypeList = zeros(1,TotalNumOfFace);
FaceBCTypeList = zeros(1,TotalNumOfFace);
else
CurrentInfo = 1;
if FaceZoneInfoFlag == 0
FaceZoneInfoFlag = 1;
else
FaceZoneInfo = [FaceZoneInfo;[0 0 0 0 0]];
CurrentInfo = size(FaceZoneInfo,1);
end
FaceZoneInfo(CurrentInfo,1) = ZoneID;% Zone ID
FaceZoneInfo(CurrentInfo,2) = hex2dec(TokenStr{1}{2});% First
FaceZoneInfo(CurrentInfo,3) = hex2dec(TokenStr{1}{3});% Last
FaceZoneInfo(CurrentInfo,4) = hex2dec(TokenStr{1}{4});% BC type
FaceZoneInfo(CurrentInfo,5) = hex2dec(TokenStr{1}{5});% Face type
FaceBCTypeList(FaceZoneInfo(CurrentInfo,2):FaceZoneInfo(CurrentInfo,3)) = FaceZoneInfo(CurrentInfo,4);
fprintf("Start to read face information in section %d from %d to %d...\n", FaceZoneInfo(CurrentInfo,1), FaceZoneInfo(CurrentInfo,2), FaceZoneInfo(CurrentInfo,3));
%计算二进制数据体的字节长度,这是因为数据体用的变长(ushort和ulong)的数据类型存储信息,以压缩数据,所以要判断一下。
fseek(CasFileId, 1, 'cof');
Offset1 = ftell(CasFileId);
tmpLine = fgetl(CasFileId);
while ~strcmp(tmpLine, 'End of Binary Section 3013)')
tmpLine = fgetl(CasFileId);
end
Offset = ftell(CasFileId) - Offset1 - size(tmpLine,2)-3;
fseek(CasFileId, Offset1, 'bof');
%如果不是非结构网格间接触面,正常处理
if FaceZoneInfo(CurrentInfo,4) < 1000
if FaceZoneInfo(CurrentInfo,5) == 0%混合区域
NumBytes = Offset/(FaceZoneInfo(CurrentInfo,3)-FaceZoneInfo(CurrentInfo,2)+1)/2;
ReadValueType = '';
if NumBytes > 4 && NumBytes < 7
ReadValueType = 'ushort';
elseif NumBytes > 8 && NumBytes < 14
ReadValueType = 'ulong';
else
msgbox("Not ushort or ulong? Binary data read error!");
exit;
end
for j=FaceZoneInfo(CurrentInfo,2):1:FaceZoneInfo(CurrentInfo,3)
FaceTypeList(j) = fread(CasFileId, [1 1], ReadValueType);
if FaceTypeList(j) >= 2 && FaceTypeList(j) <= 4
FaceListInNode(1:FaceTypeList(j),j) = fread(CasFileId, [FaceTypeList(j) 1], ReadValueType);
NeighbourCellList(:,j) = fread(CasFileId, [2 1], ReadValueType);
elseif FaceTypeList(j) == 5
msgbox("Polygonal in mixed face zone not coded yet.");
exit;
else
msgbox("Face type not 0, 2, 3, 4, or 5? Binary data read error!");
exit;
end
end
disp("Read face information done.");
elseif FaceZoneInfo(CurrentInfo,5) == 5%非规则多边形区域
msgbox("Polygonal in mixed face zone not coded yet.");
exit;
else
CurFaceType = FaceZoneInfo(CurrentInfo,5);
NumBytes = round(Offset/(FaceZoneInfo(CurrentInfo,3)-FaceZoneInfo(CurrentInfo,2)+1)/(CurFaceType+2));
FaceData = 0;
if NumBytes == 2
FaceData = fread(CasFileId, [CurFaceType+2 FaceZoneInfo(CurrentInfo,3)-FaceZoneInfo(CurrentInfo,2)+1], 'ushort');
elseif NumBytes == 4
FaceData = fread(CasFileId, [CurFaceType+2 FaceZoneInfo(CurrentInfo,3)-FaceZoneInfo(CurrentInfo,2)+1], 'ulong');
else
msgbox("Binary data read error!");
exit;
end
FaceTypeList(FaceZoneInfo(CurrentInfo,2):FaceZoneInfo(CurrentInfo,3)) = CurFaceType;
FaceListInNode(1:CurFaceType,FaceZoneInfo(CurrentInfo,2):FaceZoneInfo(CurrentInfo,3)) = FaceData(1:CurFaceType, :);
NeighbourCellList(:,FaceZoneInfo(CurrentInfo,2):FaceZoneInfo(CurrentInfo,3)) = FaceData(CurFaceType+1:CurFaceType+2, :);
disp("Read face information done.");
end
else %如果是非结构网格相接触面,则只有c0和c1的信息
if FaceZoneInfo(CurrentInfo,5) == 0%混合区域
NumBytes = Offset/(FaceZoneInfo(CurrentInfo,3)-FaceZoneInfo(CurrentInfo,2)+1)/3;%此时只有一个表示没有节点的0,还有c0和c1
FaceData = 0;
if NumBytes == 2
FaceData = fread(CasFileId, [3 FaceZoneInfo(CurrentInfo,3)-FaceZoneInfo(CurrentInfo,2)+1], 'ushort');
elseif NumBytes == 4
FaceData = fread(CasFileId, [3 FaceZoneInfo(CurrentInfo,3)-FaceZoneInfo(CurrentInfo,2)+1], 'ulong');
else
msgbox("Intersection of non-conformal grid read not ushort or ulong? Binary data read error!");
exit;
end
FaceTypeList(FaceZoneInfo(CurrentInfo,2):FaceZoneInfo(CurrentInfo,3)) = 0;
FaceListInNode(:,FaceZoneInfo(CurrentInfo,2):FaceZoneInfo(CurrentInfo,3)) = 0;
NeighbourCellList(:,FaceZoneInfo(CurrentInfo,2):FaceZoneInfo(CurrentInfo,3)) = FaceData(2:3,:);
disp("Read face information done.");
elseif FaceZoneInfo(CurrentInfo,5) == 5%非规则多边形区域
msgbox("Polygonal in Intersection of non-conformal grids? should never be here!");
exit;
else
msgbox("Intersection of non-conformal grids? should never be here!");
exit;
end
end
end
elseif ~isempty(regexp(Line, CellExp, 'match'))%如果匹配了网格单元信息
TokenStr = regexp(Line, CellExp, 'tokens');
ZoneID = hex2dec(TokenStr{1}{1});
if(ZoneID == 0)
TotalNumOfCell = hex2dec(TokenStr{1}{3});
fprintf("Total number of cells is: %d\n", TotalNumOfCell);
CellListInFace = zeros(6,TotalNumOfCell);
CellListInNode = zeros(8,TotalNumOfCell);
CellTypeList = zeros(1,TotalNumOfCell);
CellElementTypeList = zeros(1,TotalNumOfCell);
else
CurrentInfo = 1;
if CellZoneInfoFlag == 0
CellZoneInfoFlag = 1;
else
CellZoneInfo = [CellZoneInfo;[0 0 0 0 0]];
CurrentInfo = size(CellZoneInfo,1);
end
CellZoneInfo(CurrentInfo,1) = ZoneID;% Zone ID
CellZoneInfo(CurrentInfo,2) = hex2dec(TokenStr{1}{2});% First cell
CellZoneInfo(CurrentInfo,3) = hex2dec(TokenStr{1}{3});% Last cell
CellZoneInfo(CurrentInfo,4) = hex2dec(TokenStr{1}{4});% Cell type
CellZoneInfo(CurrentInfo,5) = hex2dec(TokenStr{1}{5});% Element type
fprintf("Start to read cell information in section %d from %d to %d...\n", CellZoneInfo(CurrentInfo,1), CellZoneInfo(CurrentInfo,2), CellZoneInfo(CurrentInfo,3));

if CellZoneInfo(CurrentInfo,5) == 0
%计算二进制数据体的字节长度
fseek(CasFileId, 1, 'cof');
Offset1 = ftell(CasFileId);
tmpLine = fgetl(CasFileId);
while ~strcmp(tmpLine, 'End of Binary Section 3012)')
tmpLine = fgetl(CasFileId);
end
Offset = ftell(CasFileId) - Offset1 - size(tmpLine,2)-3;
fseek(CasFileId, Offset1, 'bof');
NumBytes = Offset/(CellZoneInfo(CurrentInfo,3)-CellZoneInfo(CurrentInfo,2)+1);
if NumBytes == 2
CellElementTypeList(CellZoneInfo(CurrentInfo,2):CellZoneInfo(CurrentInfo,3)) = fread(CasFileId, [1 CellZoneInfo(CurrentInfo,3)-CellZoneInfo(CurrentInfo,2)+1], 'ushort');
elseif NumBytes == 4
CellElementTypeList(CellZoneInfo(CurrentInfo,2):CellZoneInfo(CurrentInfo,3)) = fread(CasFileId, [1 CellZoneInfo(CurrentInfo,3)-CellZoneInfo(CurrentInfo,2)+1], 'ulong');
else
msgbox("Intersection of non-conformal grid read not ushort or ulong? Binary data read error!");
exit;
end
else
CellElementTypeList(CellZoneInfo(CurrentInfo,2):CellZoneInfo(CurrentInfo,3)) = CellZoneInfo(CurrentInfo,5);
end
CellTypeList(CellZoneInfo(CurrentInfo,2):CellZoneInfo(CurrentInfo,3)) = CellZoneInfo(CurrentInfo,4);
end
elseif ~isempty(regexp(Line, ZoneExp, 'match'))%如果匹配了区域信息,就输出出来
TokenStr = regexp(Line, ZoneExp, 'tokens');
CurrentInfo = 1;
if ZoneInfoListFlag == 0
ZoneInfoListFlag = 1;
else
ZoneInfoList = [ZoneInfoList;{0,'','',0}];
CurrentInfo = size(ZoneInfoList,1);
end
ZoneInfoList{CurrentInfo,1} = str2num(TokenStr{1}{1});
ZoneInfoList{CurrentInfo,2} = TokenStr{1}{2};
ZoneInfoList{CurrentInfo,3} = TokenStr{1}{3};
ZoneInfoList{CurrentInfo,4} = str2num(TokenStr{1}{4});
fprintf("Zone information obtained: Zone ID=%d, Zone Type=%s, Zone Name=%s, Domain ID=%d.\n", ZoneInfoList{CurrentInfo,1}, ZoneInfoList{CurrentInfo,2}, ZoneInfoList{CurrentInfo,3}, ZoneInfoList{CurrentInfo,4});
end
end
end
fclose(CasFileId);

%初始化cells与faces信息
fprintf("Start to initialize cell geometrical information...\n");
fprintf("Step 1: Initialize cell surrounding faces...\n");
CellSurroundFaceCount = zeros(1,TotalNumOfCell);

%初始化CellListInFace
for i=1:1:TotalNumOfFace
if FaceListInNode(1,i) ~= 0 && FaceListInNode(2,i) ~= 0 && FaceListInNode(3,i) ~= 0 && FaceListInNode(4,i) ~= 0 %跳过不正常的面
if NeighbourCellList(1,i) > 0 && NeighbourCellList(1,i) <= TotalNumOfCell
CellSurroundFaceCount(1,NeighbourCellList(1,i)) = CellSurroundFaceCount(1,NeighbourCellList(1,i)) + 1;
CellListInFace(CellSurroundFaceCount(1,NeighbourCellList(1,i)), NeighbourCellList(1,i)) = i;
end
if NeighbourCellList(2,i) > 0 && NeighbourCellList(2,i) <= TotalNumOfCell
CellSurroundFaceCount(1,NeighbourCellList(2,i)) = CellSurroundFaceCount(1,NeighbourCellList(2,i)) + 1;
CellListInFace(CellSurroundFaceCount(1,NeighbourCellList(2,i)), NeighbourCellList(2,i)) = i;
end
end
end
fprintf("Cell surrounding faces initialization done.\n");

%初始化CellListInNode
fprintf("Step 2: Initialize cell vertex...\n");
for i=1:1:TotalNumOfCell
VertexMat = [FaceListInNode(:,CellListInFace(1,i)), FaceListInNode(:,CellListInFace(2,i)), FaceListInNode(:,CellListInFace(3,i)), FaceListInNode(:,CellListInFace(4,i)), FaceListInNode(:,CellListInFace(5,i)), FaceListInNode(:,CellListInFace(6,i))];
VertexMat = reshape(VertexMat, [1 24]);
VertexMat = sort(VertexMat);
VertexMat = reshape(VertexMat, [3 8]);
CellListInNode(:,i) = VertexMat(1,:)';
end
fprintf("Cell vertex initialization done.\n");

%初始化CellListInCell
fprintf("Step 3: Initialize cell surrounding cells......\n");
CellListInCell = zeros(6,TotalNumOfCell);
for i=1:1:TotalNumOfCell
for j=1:1:6
if NeighbourCellList(1,CellListInFace(j,i)) == 0 || NeighbourCellList(2,CellListInFace(j,i)) == 0
CellListInCell(j,i) = 0;
else
if NeighbourCellList(1,CellListInFace(j,i)) == i
CellListInCell(j,i) = NeighbourCellList(2,CellListInFace(j,i));
else
CellListInCell(j,i) = NeighbourCellList(1,CellListInFace(j,i));
end
end
end
end
fprintf("Cell surrounding cells initialization done.\n");
fprintf("Cell geometrical information initialization done.\n");

%计算网格单元中心坐标
fprintf("Start to calculate cell center...\n");
CellCenter = zeros(3,TotalNumOfCell);
for i=1:1:TotalNumOfCell
CellCenter(:,i) = 0.125*(NodeList(:,CellListInNode(1,i)) + NodeList(:,CellListInNode(2,i)) + NodeList(:,CellListInNode(3,i)) + NodeList(:,CellListInNode(4,i)) + NodeList(:,CellListInNode(5,i)) + NodeList(:,CellListInNode(6,i)) + NodeList(:,CellListInNode(7,i)) + NodeList(:,CellListInNode(8,i)));
end
fprintf("Cell center calculation done.\n");

%输出变量
if OutputSwitch==1
fprintf("Start to output NeighbourCellList and CellListInFace.\n");
save([PathName,'\\NeighbourCellList.mat'],'NeighbourCellList');
save([PathName,'\\CellListInFace.mat'],'CellListInFace');
save([PathName,'\\CellListInCell.mat'],'CellListInCell');
end
end

%开始读取dat文件,默认和cas文件在同一个路径下
if ReadDatFileSwitch == 1
%初始化存储速度和温度信息的变量,根据需求修改
VelocityInCell = zeros(TotalNumOfCell,3);
TemperatureInCell = zeros(TotalNumOfCell,1);

%数据头
DataExp = '(?:[\s]*)(?:\(3300[\s]+\()([0-9]+[\s]+)([0-9]+[\s]+)([0-9]+[\s]+)([0-9]+[\s]+)([0-9]+[\s]+)([0-9]+[\s]+)([0-9]+)(?:[\s]*\))+';
%要读取的数据类型,参见xfile.h
SV_UFlag = 111;
SV_VFlag = 112;
SV_WFlag = 113;
SV_TFlag = 3;
%终止区域编号,用来控制读取哪些zone,取cell,face和node zone编号里的最大值
MaxZoneNum = 23;
%读取控制flag,设置为1表示读取数据,如果输出cell的值,就把需要的cell
%zone对应的flag设置为1,例如这里我要输出zone编号为16的cell
%zone信息,我就把TargetZoneFlag(16)设置为1
TargetZoneFlag = zeros(MaxZoneNum,1);
TargetZoneFlag(16) = 1;

%开始读取
fprintf("Start to read data file...\n");
DatFileName = [FileName(1:length(FileName)-3),'dat'];
if exist(fullfile(PathName, DatFileName),'file')
DatFileId = fopen(fullfile(PathName, DatFileName));
while ~feof(DatFileId)
Line = fgetl(DatFileId);
if length(Line) < 65536
if ~isempty(regexp(Line, DataExp, 'match'))
TokenStr = regexp(Line, DataExp, 'tokens');
SubSectionId = str2num(TokenStr{1}{1});
TargetZoneId = str2num(TokenStr{1}{2});
if SubSectionId == SV_UFlag && TargetZoneFlag(TargetZoneId)
StartCell = str2num(TokenStr{1}{6});
EndCell = str2num(TokenStr{1}{7});
fprintf("Start to read x velocity information in cell zone %d from %d to %d...\n", TargetZoneId, StartCell, EndCell);
fseek(DatFileId, 1, 'cof');
VelocityInCell(StartCell:EndCell,1) = fread(DatFileId, [1 EndCell-StartCell+1], 'double');
fprintf("Reading x velocity information in cell zone %d done\n", TargetZoneId);
elseif SubSectionId == SV_VFlag && TargetZoneFlag(TargetZoneId)
StartCell = str2num(TokenStr{1}{6});
EndCell = str2num(TokenStr{1}{7});
fprintf("Start to read y velocity information in cell zone %d from %d to %d...\n", TargetZoneId, StartCell, EndCell);
fseek(DatFileId, 1, 'cof');
VelocityInCell(StartCell:EndCell,2) = fread(DatFileId, [1 EndCell-StartCell+1], 'double');
fprintf("Reading y velocity information in cell zone %d done\n", TargetZoneId);
elseif SubSectionId == SV_WFlag && TargetZoneFlag(TargetZoneId)
StartCell = str2num(TokenStr{1}{6});
EndCell = str2num(TokenStr{1}{7});
fprintf("Start to read z velocity information in cell zone %d from %d to %d...\n", TargetZoneId, StartCell, EndCell);
fseek(DatFileId, 1, 'cof');
VelocityInCell(StartCell:EndCell,3) = fread(DatFileId, [1 EndCell-StartCell+1], 'double');
fprintf("Reading z velocity information in cell zone %d done\n", TargetZoneId);
elseif SubSectionId == SV_TFlag && TargetZoneFlag(TargetZoneId)
StartCell = str2num(TokenStr{1}{6});
EndCell = str2num(TokenStr{1}{7});
fprintf("Start to read temperature information in cell zone %d from %d to %d...\n", TargetZoneId, StartCell, EndCell);
fseek(DatFileId, 1, 'cof');
TemperatureInCell(StartCell:EndCell,1) = fread(DatFileId, [1 EndCell-StartCell+1], 'double');
fprintf("Reading temperature information in cell zone %d done\n", TargetZoneId);
end
end
end
end
fclose(DatFileId);
else
fprintf("Fail to read data, dat file does not exist.\n");
end
%输出
DataInCell = [VelocityInCell,TemperatureInCell];
save([PathName,'\\DataInCell.mat'],'DataInCell');
end

MatlabReadFluentFile.7z

3. 用MATLAB将数据写入fluent case

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
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% MATLAB写入Ansys fluent 16.0 六面体网格的dat文件
%
% 作者:陈曦 E-mail: chenxiseu@seu.edu.cn
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%加载要写入的数据,测试用的ModifiedDataInCell.mat中前3列是速度场数据(1-3列分别是x,y,z三个速度分量),第4列是温度场数据
LoadData = load('ModifiedDataInCell.mat');%把里面的文本换成回写数据的mat文件名!!!!!!!
%网格单元(cell)总数
TotalNumOfCell = 202657;%运行FluentDataProcessV4_1.m后可以获得
%回写开关标志位
WriteVelocityFlag = 1;%如果等于1,回写速度场
WriteTemperatureFlag = 1;%如果等于1,回写温度场
%加载回写数据

WriteBackData = LoadData.DataInCell;
WriteBackVelocityInCell = WriteBackData(:,1:3);
WriteBackTemperatureInCell = WriteBackData(:,4);
SV_UFlag = 111;
SV_VFlag = 112;
SV_WFlag = 113;
SV_TFlag = 3;

MaxZoneNum = 23;
%写入区域控制flag,设置为1表示写入该区域数据。如果需要向特定的zone写入cell值,就把需要的cell
%zone对应的flag设置为1,例如这里我要向zone编号为16的区域写入新的cell值,
%因此把TargetZoneFlag(16)设置为1
TargetZoneFlag = zeros(MaxZoneNum,1);
TargetZoneFlag(16) = 1;
%写入数据头,参见fluent帮助
DataExp = '(?:[\s]*)(?:\(3300[\s]+\()([0-9]+[\s]+)([0-9]+[\s]+)([0-9]+[\s]+)([0-9]+[\s]+)([0-9]+[\s]+)([0-9]+[\s]+)([0-9]+)(?:[\s]*\))+';
OtherExp1 = '(?:[\s]*)(?:\(3302[\s]+\()([0-9]+[\s]+)([0-9]+[\s]+)([0-9]+[\s]+)([0-9]+)(?:[\s]*\))+';
OtherExp2 = '(?:[\s]*)(?:\(3314[\s]+\()([0-9]+[\s]+)([0-9]+[\s]+)([0-9]+[\s]+)([0-9]+[\s]+)([0-9]+[\s]+)([0-9]+[\s]+)([0-9]+)(?:[\s]*\))+';
%选择输出文件,注意该文件不会被覆盖,而是工作路径下会出现一个WriteBack***.dat的文件,这个文件才是含有被写入数据的文件。
%测试可以选fluent-mesh2.dat
[DatFileName, PathName] = uigetfile('*.dat', 'Select a fluent dat file');
if isequal(DatFileName,0)
disp('User selected Cancel')
else
DatFileId = fopen(fullfile(PathName, DatFileName), 'rb');
WriteBackDatFileId = fopen(fullfile(PathName, ['WriteBack',DatFileName]), 'wb');
while ~feof(DatFileId)
Line = fgets(DatFileId);
fwrite(WriteBackDatFileId,Line,'char');
if length(Line) < 65536 && ~isempty(regexp(Line, DataExp, 'match'))
TokenStr = regexp(Line, DataExp, 'tokens');
SubSectionId = str2num(TokenStr{1}{1});
TargetZoneId = str2num(TokenStr{1}{2});
if SubSectionId == SV_UFlag && TargetZoneFlag(TargetZoneId)
StartCell = str2num(TokenStr{1}{6});
EndCell = str2num(TokenStr{1}{7});
Factor = str2num(TokenStr{1}{3});
fseek(DatFileId, 1, 'cof');
VelocityInCell(StartCell:EndCell,1) = fread(DatFileId, [1 (EndCell-StartCell+1)*Factor], 'double');
if WriteVelocityFlag == 1
fprintf("Start to write new x velocity information in cell zone %d from %d to %d...\n", TargetZoneId, StartCell, EndCell);
fwrite(WriteBackDatFileId,'(');
fwrite(WriteBackDatFileId,WriteBackVelocityInCell(StartCell:EndCell,1),'double');
fprintf("Writing new x velocity information in cell zone %d done\n", TargetZoneId);
else
fprintf("Start to write x velocity information in cell zone %d from %d to %d...\n", TargetZoneId, StartCell, EndCell);
fwrite(WriteBackDatFileId,'(');
fwrite(WriteBackDatFileId,VelocityInCell(StartCell:EndCell,1),'double');
fprintf("Writing x velocity information in cell zone %d done\n", TargetZoneId);
end
elseif SubSectionId == SV_VFlag && TargetZoneFlag(TargetZoneId)
StartCell = str2num(TokenStr{1}{6});
EndCell = str2num(TokenStr{1}{7});
Factor = str2num(TokenStr{1}{3});
fseek(DatFileId, 1, 'cof');
VelocityInCell(StartCell:EndCell,2) = fread(DatFileId, [1 (EndCell-StartCell+1)*Factor], 'double');
if WriteVelocityFlag == 1
fprintf("Start to write new y velocity information in cell zone %d from %d to %d...\n", TargetZoneId, StartCell, EndCell);
fwrite(WriteBackDatFileId,'(');
fwrite(WriteBackDatFileId,WriteBackVelocityInCell(StartCell:EndCell,2),'double');
fprintf("Writing new y velocity information in cell zone %d done\n", TargetZoneId);
else
fprintf("Start to write y velocity information in cell zone %d from %d to %d...\n", TargetZoneId, StartCell, EndCell);
fwrite(WriteBackDatFileId,'(');
fwrite(WriteBackDatFileId,VelocityInCell(StartCell:EndCell,2),'double');
fprintf("Writing y velocity information in cell zone %d done\n", TargetZoneId);
end
elseif SubSectionId == SV_WFlag && TargetZoneFlag(TargetZoneId)
StartCell = str2num(TokenStr{1}{6});
EndCell = str2num(TokenStr{1}{7});
Factor = str2num(TokenStr{1}{3});
fseek(DatFileId, 1, 'cof');
VelocityInCell(StartCell:EndCell,3) = fread(DatFileId, [1 (EndCell-StartCell+1)*Factor], 'double');
if WriteVelocityFlag == 1
fprintf("Start to write new z velocity information in cell zone %d from %d to %d...\n", TargetZoneId, StartCell, EndCell);
fwrite(WriteBackDatFileId,'(');
fwrite(WriteBackDatFileId,WriteBackVelocityInCell(StartCell:EndCell,3),'double');
fprintf("Writing new z velocity information in cell zone %d done\n", TargetZoneId);
else
fprintf("Start to write z velocity information in cell zone %d from %d to %d...\n", TargetZoneId, StartCell, EndCell);
fwrite(WriteBackDatFileId,'(');
fwrite(WriteBackDatFileId,VelocityInCell(StartCell:EndCell,3),'double');
fprintf("Writing z velocity information in cell zone %d done\n", TargetZoneId);
end
elseif SubSectionId == SV_TFlag && TargetZoneFlag(TargetZoneId)
StartCell = str2num(TokenStr{1}{6});
EndCell = str2num(TokenStr{1}{7});
Factor = str2num(TokenStr{1}{3});
fseek(DatFileId, 1, 'cof');
TemperatureInCell(StartCell:EndCell,1) = fread(DatFileId, [1 (EndCell-StartCell+1)*Factor], 'double');
if WriteTemperatureFlag == 1
fprintf("Start to write new temperature information in cell zone %d from %d to %d...\n", TargetZoneId, StartCell, EndCell);
fwrite(WriteBackDatFileId,'(');
fwrite(WriteBackDatFileId,WriteBackTemperatureInCell(StartCell:EndCell,1),'double');
fprintf("Writing new temperature information in cell zone %d done\n", TargetZoneId);
else
fprintf("Start to write temperature information in cell zone %d from %d to %d...\n", TargetZoneId, StartCell, EndCell);
fwrite(WriteBackDatFileId,'(');
fwrite(WriteBackDatFileId,TemperatureInCell(StartCell:EndCell,1),'double');
fprintf("Writing temperature information in cell zone %d done\n", TargetZoneId);
end
else
StartCell = str2num(TokenStr{1}{6});
EndCell = str2num(TokenStr{1}{7});
Factor = str2num(TokenStr{1}{3});
fprintf("Start to write other information in zone %d from %d to %d...\n", TargetZoneId, StartCell, EndCell);
fseek(DatFileId, 1, 'cof');
TempData = fread(DatFileId, [1 (EndCell-StartCell+1)*Factor], 'double');
fwrite(WriteBackDatFileId,'(');
fwrite(WriteBackDatFileId,TempData,'double');
fprintf("Writing other information in zone %d done\n", TargetZoneId);
end
elseif length(Line) < 65536 && ~isempty(regexp(Line, OtherExp1, 'match'))
TokenStr = regexp(Line, OtherExp1, 'tokens');
DataCount = str2num(TokenStr{1}{1});
Factor = str2num(TokenStr{1}{3});
TargetZoneId = str2num(TokenStr{1}{4});
fprintf("Start to write residual information.\n");
fseek(DatFileId, 1, 'cof');
TempData = fread(DatFileId, [1 DataCount*3*Factor], 'double');
fwrite(WriteBackDatFileId,'(');
fwrite(WriteBackDatFileId,TempData,'double');
fprintf("Writing residual in domain %d done\n", TargetZoneId);
elseif length(Line) < 65536 && ~isempty(regexp(Line, OtherExp2, 'match'))
TokenStr = regexp(Line, OtherExp2, 'tokens');
StartCell = str2num(TokenStr{1}{6});
EndCell = str2num(TokenStr{1}{7});
Factor = str2num(TokenStr{1}{3});
TargetZoneId = str2num(TokenStr{1}{2});
fprintf("Start to write other information in zone %d from %d to %d...\n", TargetZoneId, StartCell, EndCell);
fseek(DatFileId, 1, 'cof');
TempData = fread(DatFileId, [1 (EndCell-StartCell+1)*Factor], 'double');
fwrite(WriteBackDatFileId,'(');
fwrite(WriteBackDatFileId,TempData,'double');
fprintf("Writing other information in zone %d done\n", TargetZoneId);
end
end
fclose(DatFileId);
fclose(WriteBackDatFileId);
end

WriteBack.7z

[^1]: # Spreadsheet Link (for Microsoft Excel)

## 1. ​[`matlabinit`](https://www.mathworks.com/help/releases/R2023a/exlink/matlabinit.html)

> ​`matlabinit` 初始化 Spreadsheet Link™ 软件并启动 MATLAB。如果电子表格链接软件已初始化并且 MATLAB 正在运行,则后续调用不会执行任何操作。用于在将首选项设置为 时手动启动电子表格链接和 MATLAB 会话
>

**从 Excel 工具栏初始化电子表格链接和 MATLAB Microsoft**

当您使用Microsoft Excel,初始化电子表格链接,并随时使用 Excel 工具栏手动启动 MATLAB。

在​ **“开发工具**​”选项卡上的“​**代码**​”组中,单击“​**宏**”。

在“​**宏名称**​”框中,输入并单击“​**运行**​”。`matlabinit`

电子表格链接初始化,MATLAB 启动。您现在可以使用电子表格链接从 MATLAB 导入数据,或将工作表中的现有数据导出到 MATLAB 中,并在 Excel 中运行 MATLAB 函数。

### 1.1 **技巧**

- 您可以将函数包含在宏中 子程序。`matlabinit`
- 不能将函数作为工作表运行 单元格公式或宏函数。 是一个宏 子程序。子例程不能作为工作表单元格中的函数运行。只 Excel 函数可以在工作表单元格中运行。`matlabinitmatlabinit`

### 1.2 **替代功能**

您可以执行 [`MLOpen`](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlopen.html) 来启动 MATLAB。

​[`MLOpen`](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlopen.html)

1
2
3
= MLOpen()%启动 MATLAB 进程。用于在给定的 MATLAB 会话中停止后重新启动该会话
MLOpen %启动 MATLAB 进程。用于在给定Microsoft中停止 MATLAB 会话后重新启动该会话 Excel会话。在 VBA 宏中使用此语法。
out = MLOpen() %允许您在以下情况下捕获错误 在 VBA 宏中执行。如果失败,则是一个包含错误代码的字符串。否则,
**启动 MATLAB 会话** 从工作表启动 MATLAB 会话: ​`MLOpen()` ## 2. **输出参数** 全部折叠 ​`out`​ **— 成功指示器**​`0` **| 字符串标量** ​`0`如果命令成功。否则,包含错误的字符串 法典。 ## 3. ​[`MLPutMatrix`](https://www.mathworks.com/help/releases/R2023a/exlink/mlputmatrix.html)
1
2
3
= MLPutMatrix(var_name, mdat) %使用 中指定的数据创建或覆盖 MATLAB 工作区中的矩阵。函数创建,如果它不 存在。直接在工作表中工作时使用此语法
MLPutMatrix var_name, mdat % 使用 中指定的数据创建或覆盖 MATLAB 工作区中的矩阵。用 VBA 宏中的此语法
out = MLPutMatrix(var_name,mdat) %允许您在 VBA 宏中执行时查找错误。如果失败,则是一个包含 错误代码。
> ​`= MLPutMatrix(`​[`var\_name`](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlputmatrix.html#mw_8532ace8-708c-4fa3-b1df-25e57cda4f9f)​`, `​[`mdat`](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlputmatrix.html#mw_65e3beb5-2797-45f1-adb7-e9a8b3137118)​`)`​ 使用 中指定的数据创建或覆盖 MATLAB 工作区中的矩阵。函数创建,如果它不 存在。*直接在工作表中工作时使用此语法。*​`var_name`​®`mdatMLPutMatrixvar_name` > **创建 MATLAB 矩阵** 在 MATLAB 工作区中创建一个矩阵,使用 Excel工作表。`MLPutMatrix`® 在单元格中输入值 1 到 5。`A1E1` 通过 定义单元格区域的名称。有关定义的说明 名称,请参阅 Excel 帮助。`testDataA1E1` 范围名称显示在​ **“名称”中 框**​,以选择范围。`testData` ![](https://ww2.mathworks.cn/help/releases/R2023a/exlink/excel_named_range.png)[https://ww2.mathworks.cn/help/releases/R2023a/exlink/excel_named_range.png](https://ww2.mathworks.cn/help/releases/R2023a/exlink/excel_named_range.png) 在单元格中执行函数。 用作要创建的矩阵的名称。将区域名称指定为要包含在矩阵中的数据。
1
= MLPutMatrix("A", testData)
按 **Enter** 后,Excel 会在 MATLAB 工作区中创建矩阵。矩阵包含单元格区域中包含的数据。`testData` **使用 VBA 宏创建 MATLAB 矩阵** 使用 VBA 中的函数在 MATLAB 工作区中创建矩阵 宏观。`MLPutMatrix` 在单元格中输入值 1 到 5。`A1E1` 通过 定义单元格区域的名称。有关定义的说明 名称,请参阅 Excel 帮助。`testDataA1E1` 范围名称显示在​ **“名称”中 框**​,以选择范围。`testData` ![](https://ww2.mathworks.cn/help/releases/R2023a/exlink/excel_named_range.png)[https://ww2.mathworks.cn/help/releases/R2023a/exlink/excel_named_range.png](https://ww2.mathworks.cn/help/releases/R2023a/exlink/excel_named_range.png) 在 Excel 中的“**开发工具”** 选项卡上,单击“​**代码**​”组中的“​**Visual Basic**”。将打开“Visual Basic 编辑器”窗口。 选择​ **“插入&gt;模块**”以插入新模块。在模块1窗口中,输入此VBA代码 包含名为 的宏。
1
2
3
Sub PutMatrix()
MLPutMatrix "A", testData
End Sub
宏使用该函数使用单元格区域中的数据在 MATLAB 工作区中创建矩阵。`PutMatrixMLPutMatrixAtestData` 有关使用模块的详细信息,请参阅 Excel 帮助。 选择任何工作表单元格。通过单击“运行”**运行宏 子/用户窗体** VBA 工具栏上的按钮。有关运行宏的详细信息, 请参阅 Excel 帮助。 该函数在 MATLAB 工作区中创建矩阵。`MLPutMatrix` ## 4. **输入参数** ​`var_name`​ **— MATLAB 矩阵字符串的名称** 要创建或覆盖的 MATLAB 矩阵的名称,指定为字符串。 ​`var_name`​在引号中直接指定矩阵名称。 不带引号指定工作表单元格地址(或 范围名称),其中包含矩阵名称。`var_name` ​**例:** ​`"A"` ​`mdat`​ **— 数据字符串的位置** 要复制到[`var\_name`](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlputmatrix.html#mw_8532ace8-708c-4fa3-b1df-25e57cda4f9f)中的数据的位置,指定为 字符串。 ​`mdat`必须是工作表单元格地址或区域名称。不要 将位置括在引号中。 **例:**​`testData` **例:**​`A1` ## 5. **技巧** - 如果[`var\_name`](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlputmatrix.html#mw_8532ace8-708c-4fa3-b1df-25e57cda4f9f)​存在,则函数 将其内容替换为 [`MDAT`](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlputmatrix.html#mw_65e3beb5-2797-45f1-adb7-e9a8b3137118)​ 的内容。`MLPutMatrix` - 中的空数字数据单元格在 由 标识的 MATLAB 矩阵。`mdatvar_name` - 如果 的任何元素包含字符串数据,则成为 MATLAB 单元数组。中的空字符串元素在 MATLAB 单元数组中变为 s。`mdatmdatmdatNaN` - 在子例程中使用时,请指出 工作表数据使用`MLPutMatrix`​Microsoft Excel®宏观。例如:`Range`
1
2
3
Sub test()
MLPutMatrix "a", Range("A1:A3")
End Sub
如果工作表中有命名区域,则可以指定名称而不是 范围。例如:
1
2
3
Sub test() 
MLPutMatrix "a", Range("temp")
End Sub
### 5.1 excel中**创建 MATLAB 矩阵**
1
= MLPutMatrix("A", testData)
按 **Enter** 后,Excel 会在 MATLAB 工作区中创建矩阵。矩阵包含单元格区域中包含的数据。`testData` ### 5.2 **使用 VBA 宏创建 MATLAB 矩阵**
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

%在 MATLAB 工作区中创建一个矩阵,使用 Excel工作表。在单元格中输入值 1 到 5。
通过 定义单元格区域的名称。在单元格中执行函数。 用作要创建的矩阵的名称。将区域名称指定为要包含在矩阵中的数据。按 Enter 后,Excel 会在 MATLAB 工作区中创建矩阵。矩阵包含单元格区域中包含的数据。范围名称显示在“名称”中 框,以选择范围。testData
Sub PutMatrix()
MLPutMatrix "A", testData
End Sub

Sub test()
MLPutMatrix "a", Range("A1:A3")
End Sub

%如果工作表中有命名区域,则可以指定名称而不是 范围
Sub test()
MLPutMatrix "a", Range("temp")
End Sub
## 6. ​[`MLPutRanges`](https://www.mathworks.com/help/releases/R2023a/exlink/mlputranges.html)
1
2
3
4

= MLPutRanges()
MLPutRanges
out = MLPutRanges()
**Microsoft Visual Basic 宏中将 Excel 命名范围导出到 MATLAB Microsoft 无输出** 调用函数以发送命名范围中的数据 当前工作表到 MATLAB。 ​`MLPutRanges` **Microsoft Visual Basic 宏中将 Excel 命名范围导出到 MATLAB Microsoft 带输出** 调用函数以发送命名范围中的数据 当前工作表到 MATLAB。 ​`out = MLPutRanges()` ​`out`如果函数成功,则返回 0 或带有相应错误代码的字符串(如果函数失败) ## 7. ​[`MLGetMatrix`](https://www.mathworks.com/help/releases/R2023a/exlink/mlgetmatrix.html)
1
2
3
= MLGetMatrix(var_name,edat)  %将 MATLAB 矩阵的内容写入 Excel 工作表中,从左上角由 指定的单元格开始
MLGetMatrix var_name, edat %将 MATLAB 矩阵的内容写入 Excel 工作表中,从左上角由 指定的单元格开始
out = MLGetMatrix(var_name,edat) %允许您在 VBA 宏中执行函数时查找错误。如果函数失败, 然后是一个包含错误代码的字符串。否则,为
### 7.1 **直接使用位置将矩阵内容写入工作表** 在 MATLAB 中访问矩阵的内容并将内容写入工作表。指定名称 矩阵和目标单元格显式。 在 MATLAB 中定义一个 4×3 矩阵。
1
A = [1,2,3;4,5,6;7,8,9;10,11,12]
1
2
3
4
5
6
A =

1 2 3
4 5 6
7 8 9
10 11 12
打开 Excel 并确保在 工作表。要从工作表的单元格开始编写 MATLAB 矩阵的内容,请输入此 单元格中的文本,然后按 **Enter** 键:
1
= MLGetMatrix("A","Sheet1!A3")
**使用位置间接将矩阵内容写入工作表** 在 MATLAB 中访问矩阵的内容并将内容写入工作表。指定目标 使用单元格引用的矩阵内容。 在 MATLAB 中定义一个 4×3 矩阵。`A`
1
A = [1,2,3;4,5,6;7,8,9;10,11,12]
1
2
3
4
5
6
A =

1 2 3
4 5 6
7 8 9
10 11 12
打开 Excel 并在单元格中输入矩阵的名称。 ![](https://ww2.mathworks.cn/help/releases/R2023a/exlink/excel-ml-get-matrix-indirect-output-a.png)[https://ww2.mathworks.cn/help/releases/R2023a/exlink/excel-ml-get-matrix-indirect-output-a.png](https://ww2.mathworks.cn/help/releases/R2023a/exlink/excel-ml-get-matrix-indirect-output-a.png) 在单元格 中输入目标单元格的引用。 ![](https://ww2.mathworks.cn/help/releases/R2023a/exlink/excel-ml-get-matrix-indirect-output-a6.png)[https://ww2.mathworks.cn/help/releases/R2023a/exlink/excel-ml-get-matrix-indirect-output-a6.png](https://ww2.mathworks.cn/help/releases/R2023a/exlink/excel-ml-get-matrix-indirect-output-a6.png) 确保已选择单元格。访问由单元格中的字符串命名的 MATLAB 矩阵,然后 通过使用 中的引用将矩阵的内容写入工作表 细胞。在单元格中输入此文本,然后按 **Enter** 键:
1
= MLGetMatrix(A1,A2)
**使用VBA宏将矩阵内容写入工作表** 在 MATLAB 中访问矩阵的内容,并使用 VBA 宏将内容写入工作表。 在 MATLAB 中定义一个 4×3 矩阵。
1
A = [1,2,3;4,5,6;7,8,9;10,11,12]
1
2
3
4
5
6
A =

1 2 3
4 5 6
7 8 9
10 11 12
在 Excel 中的“**开发工具”** 选项卡上,单击“​**代码**​”组中的“​**Visual Basic**”。将打开“Visual Basic 编辑器”窗口。 从“插入”菜单中,选择 **“** 模块”以**插入**新模块。在模块1中 窗口中,输入此VBA代码,其中包含一个名为.
1
2
3
4
Sub GetMatrix()
MLGetMatrix "A","B2"
MatlabRequest
End Sub
​`MatlabRequest`初始化内部电子表格链接™变量并使其正常工作 在子例程中 - ​[`MLEvalString`](https://www.mathworks.com/help/releases/R2023a/exlink/mlevalstring.html)
1
2
3
= MLEvalString(command) %指定 用于在 MATLAB 工作区中求值的 MATLAB 命令。 在工作表单元格中工作时使用此语法
MLEvalString command
err = MLEvalString(command) %返回 执行时的执行状态 一个 VBA 宏
**在工作表单元格中创建对角矩阵** 在单元格中输入变量。 在从 到 的单元格范围内输入数字 1 到 5。 使用 将单元格区域分配给 MATLAB 中的变量。 在单元格中输入此文本。
1
=MLPutMatrix(A1,B1:F1)
![](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlevalstring_example_setup.png)[https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlevalstring_example_setup.png](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlevalstring_example_setup.png) 用于创建矩阵 , 包含使用变量中的五个数字的对角线。 在单元格中输入此文本。
1
=MLEvalString("b = diag(a);")
![](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlevalstring_example.png)[https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlevalstring_example.png](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlevalstring_example.png) 将矩阵从 MATLAB 检索到 Excel 单元格中。在单元格中输入此文本。 ​`=MLGetMatrix("b","A9")` 具有对角线的矩阵通过 出现在单元格中。 ![](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlevalstring_example_result.png)[https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlevalstring_example_result.png](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlevalstring_example_result.png) **在VBA宏中创建对角矩阵** 在单元格中输入变量。 在从 到 的单元格范围内输入数字 1 到 5。 单击​ **“开发人员**​”选项卡Microsoft Excel®, ,然后单击“​**Visual Basic**”。 插入一个新模块并将此VBA代码输入到代码中 部分。此示例代码假定名为 的宏。 有关使用模块的详细信息,请参阅 Excel 帮助。`Diagonal`
1
2
3
4
5
6
7
8
Sub Diagonal()

MLPutMatrix "a", Range("B1:F1")
MLEvalString "b = diag(a);"
MLGetMatrix "b", "A3"
MatlabRequest

End Sub
通过单击 **“运行子/用户窗体”来运行宏 (F5)。** 对角矩阵通过出现在单元格中。 ![](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlevalstring_example_vba.png)[https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlevalstring_example_vba.png](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlevalstring_example_vba.png) **无效命令的返回错误** 在单元格中输入变量。 在从 到 的单元格范围内输入数字 1 到 5。`aA1B1F1` 单击Microsoft中的​ **“开发工具**​”选项卡 卓越, ,然后单击“​**Visual Basic**”。The Visual Basic Editor 窗口打开。 插入一个新模块并将此无效的VBA代码输入到 窗口的“代码”部分。此示例代码假定名为 的宏。 有关使用模块的详细信息,请参阅 Excel 帮助。`Diagonal`
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Sub Diagonal()

Dim err As Variant

MLPutMatrix "a", Range("B1:F1")
err = MLEvalString("b = diag(2a);") 'Invalid code

If err <> 0 Then
MsgBox err
End If

MLGetMatrix "b", "A3"
MatlabRequest

End Sub
通过单击“运行​**子/用户窗体**”来运行宏 VBA 工具栏。有关运行宏的详细信息,请参阅 Excel 帮助。 此电子表格链接™错误显示:。要显示 MATLAB 错误,请参阅 [`MLShowMatlabErrors`](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlshowmatlaberrors.html)​。`\#COMMAND!` ## 8. ​[`MLGetFigure`](https://www.mathworks.com/help/releases/R2023a/exlink/mlgetfigure.html)
1
2
3
= MLGetFigure(width, height) %将当前 MATLAB 图形导入到 Excel 工作表中,将图形的左上角放在当前 工作表单元格。在 Excel 中指定图形的规范化宽度和高度
MLGetFigure width, height %将当前 MATLAB 图形导入 Excel 工作表,将图形的左上角放在当前 工作表单元格。在 VBA 宏中使用此语法
out = MLGetFigure(width,height) %允许您在 VBA 宏中执行时查找错误。 如果失败,则为字符串 包含错误代码。否则,为
**将当前 MATLAB 图形导入 Excel 中** 在 MATLAB 中创建图形后,将该图形导入到 Excel 工作表中。 **注意** 如果使用 Excel 2007 或 2010,则导入图的宽度和高度 将是原始图形大小的四分之一。 在 MATLAB 中使用[`峰值`](https://ww2.mathworks.cn/help/releases/R2023a/matlab/ref/peaks.html)​和[`冲浪`](https://ww2.mathworks.cn/help/releases/R2023a/matlab/ref/surf.html)函数创建线框网格。图的 窗口显示线框网格。 ​`z = peaks(25);surf(z)` ![](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlgetfigure_surf.png)[https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlgetfigure_surf.png](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlgetfigure_surf.png) 打开 Excel 并确保在 工作表。使用该函数将当前图形导入工作表。在单元格中输入此文本 ,然后按​**回车键**​。`A1MLGetFigure` ​`= MLGetFigure(.8, .8)` 该函数导入当前图形 到工作表中,将图形的左上角放在 选定的单元格。`MLGetFigure` ![](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlgetfigure_imported.png)[https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlgetfigure_imported.png](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlgetfigure_imported.png) **使用VBA宏导入当前图形** 在 MATLAB 中创建图形后,使用 VBA 宏将该图形导入到 Excel 工作表中。 在 MATLAB 中使用[`峰值`](https://ww2.mathworks.cn/help/releases/R2023a/matlab/ref/peaks.html)​和[`冲浪`](https://ww2.mathworks.cn/help/releases/R2023a/matlab/ref/surf.html)函数创建线框网格。图的 窗口显示线框网格。
1
2
z = peaks(25);
surf(z)
![](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlgetfigure_surf.png)[https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlgetfigure_surf.png](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlgetfigure_surf.png) 在 Excel 中的“**开发工具”** 选项卡上,单击“​**代码**​”组中的“​**Visual Basic**”。将打开“Visual Basic 编辑器”窗口。 选择​ **“插入&gt;模块**​”以插入新模块。在“模块1”窗口中,输入此VBA 包含名为 的宏的代码。`MyFigure`
1
2
3
4
Sub MyFigure()
MLGetFigure 0.8, 0.8
MatlabRequest
End Sub
宏使用该函数导入当前图形 到工作表中。 初始化内部 电子表格链接™变量并启用到 子例程中的函数。 选择图形位置的单元格。运行 通过单击宏 运行**子/用户窗体** VBA上的按钮 工具栏。 该函数导入当前图形 到工作表中,将图形的左上角放在 选定的单元格。`MLGetFigure` ![](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlgetfigure_vba_imported.png)[https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlgetfigure_vba_imported.png](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlgetfigure_vba_imported.png) ## 9. **输入参数** 全部折叠 ​`width`​ **—宽度实数** 导入 Excel 工作表时 MATLAB 图形的宽度(以标准化单位表示),指定为实数。 **例:**​`0.5` ​`height`​ **—高度实数** 导入 Excel 工作表时 MATLAB 图形的高度(以标准化单位表示),指定为实数。 **例:**​`0.5` ​[`MLAutoStart`](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlautostart.html)​ | [`MLOpen`](https://ww2.mathworks.cn/help/releases/R2023a/exlink/mlopen.html)
1
2
3
4
= MLAutoStart(flag) %自动设置 启动电子表格链接™和 MATLAB 软件。状态更改将在下次启动 Excel 会话时生效。直接在 工作表
MLAutoStart flag %设置自动启动 电子表格链接和 MATLAB 软件。状态更改将在下次启动 Excel 会话时生效
out = MLAutoStart(flag)
%允许您在 VBA 宏中执行时捕获错误。 如果失败,则为字符串 包含错误代码
**取消电子表格链接和 MATLAB 的自动启动** 在工作表中输入以下命令: ​`MLAutoStart("no")` 电子表格链接和 MATLAB 不会在后续的 Excel 会话中启动 调用。 ## 10. **输入参数** ​`flag`​ **— 自动启动指定**​`“是”`​ **(默认) |** ​`“不”` 要么 .`"yes""no"` 指定每次自动启动电子表格链接和 MATLAB 软件`"yes"`​Microsoft Excel®会话开始。指定取消 电子表格链接和 MATLAB 软件的自动启动。`"no"` ## 11. **输出参数** ​`out`​ **— 成功指示器**​`0` **| 字符串标量** ​`0`如果命令成功。否则,字符串 包含错误代码。