问题
我正在运行一个Matlab脚本,该脚本创建一个存储在'.m'文件中的网格几何体;所有这些都是为了使用有限元求解器运行。我给它提供了许多元素,它创建了一个适合边界的四边形网格;几何的两个例子如图1和图2所示。当我仅将它用于单个数量的元素时,它的效果很好。另一方面,当我尝试在循环中使用网格生成脚本,改变所需元素的数量(n = 1,2,4,... 32,64)时,文件读取就像我刚刚运行它在n = 1时就像'.m'文件没有被重写一样。
图1.具有10个四边形元素的网格。
图2.具有40个四边形元素的网格。
当前方法
for i = 1:4
n = 2^i % n stores the desired number of elements (2^i is only an example)
% Check if '.m' file exists in current directory
allFiles = dir(currentFolder)
allNames = {allFiles.name}
check = ismember('p4.m',allNames);
% If so, delete the file
if check
delete 'p4.m'
end
% Create the 'p4.m' file
p4Mesh(n)
end
p4Mesh功能摘要:
function p4Mesh
close all;
inputfile = 'p4.m';
% open file
fid = fopen(inputfile,'w');
fprintf(fid,'MESH CODE HERE')
% Close file
[st] = fclose('all');
end
答案 0 :(得分:2)
p4
函数定义可能正在缓存,因此您不会在后续调用p4()
时获取写入磁盘的新版本。使用clear p4
删除缓存的定义,并在每次更新时强制重新读取p4.m
。
您可能遇到了Matlab函数定义缓存的问题。当您第一次调用函数或类时,Matlab从磁盘上的.m
文件中读取定义,编译并运行它,然后保持该编译定义的缓存。文件写入不太可能落后于Matlab循环,因为fopen / fprintf / fclose是同步的,而Matlab是单线程的。但是Matlab的功能加载机制可能没有像你需要的那样快速地注意到磁盘上的变化。
Matlab将重新读取函数定义,如果它注意到磁盘上的定义已更改。如果您从Matlab编辑器中保存一个函数文件,它会立即注意到更改,因为它通过Matlab进行。但是如果你从代码中编写文件的内容,它看起来就像一个外部的变化。 Matlab以与系统相关的方式获取有关这些更改的更新,例如从操作系统获取文件更改通知事件,或定期轮询文件系统以检查文件时间戳。有关详细信息,请参阅doc changeNotification
和doc changeNotificationAdvanced
。
由于您在紧密循环中重新编写文件,因此更新可能发生得太快,无法通知Matlab的更改通知。事实上,Matlab可能会延迟文件更新检查,直到它完成运行用户功能(出于性能和一致性的原因),因此可能根本不会执行更新检查,直到完成循环并从该脚本返回到命令行。在这种情况下,如果您在循环内多次调用p4()
,它将在每次第一次传递时使用缓存函数定义,并且您将看到该函数的相同输出。这听起来就像你在描述的那样。
要查看这是否是实际发生的情况,请在将其作为Matlab函数调用的机制之外检查磁盘上p4.m
文件的内容。您可以使用许多系统上可用的md5sum
程序输出它的一行校验和。或者你可以调用cat
或者只是使用fopen / fread / fclose重新读取它,然后从Matlab中将它或md5校验和打印到控制台。如果每个传递文件在磁盘上看起来不同,但是你从调用p4()
得到相同的输出,它可能是函数缓存。
您可以强制Matlab从磁盘上的当前.m
文件重新读取函数,方法是使用clear
命令从内存中删除其缓存的编译定义。在这种情况下,在您调用clear p4;
以写出p4mesh
文件之后,再次调用p4.m
之前,请在循环的每个过程中执行p4
。
在循环中执行pause
或drawnow
也可以让Matlab的函数缓存机制有机会注意磁盘上更新的.m
文件。但是clear p4
应该更加可靠和确定,因为它每次都会强制重新阅读。
从长远来看,如果你能让你的教授给你一个p4mesh
生成.mat
数据文件而不是.m
函数定义文件,可能会更好,比如评论者建议。 .mat
数据文件更适合快速更改定义,并且没有此缓存问题。