我尽量简短。我遇到一个问题,涉及到带有燃气管道的流动的数值模拟。我使用不同的模型来模拟从一个边界到另一边界(即从右到左)传播的气流(传输方程)。 问题是,由于我使用不同的模型来表示所述气流和边界条件,因此我得到了很多功能,例如:
boundary_left_model_1
boundary_right_model_1
boundary_left_model_2
boundary_right_model_2
boundary_left_model_2b
boundary_right_model_2b
....
flux_model_1
flux_model_2
....
source_model_1
source_model_2
.....
我通过(例如)在数值方案之前分配了所需的函数:
boundary_left = @[needed function];
boundary_right=@ [needed function];
flux = @[needed function];
source=@ [needed function];
接下来是这样的:
Solution = numerical_scheme_#1(boundary_left,boundary_right,flux,source,parameters);
您明白了。
现在,构建程序最有效的方法是什么(在结构化的同时)?据我所知,我有三个选择:
1)我在matlab函数文件中定义了每个函数(将会产生很多文件)
2)我为数字方案定义了脚本中的每个函数(这将导致文件较长,因此难以调整/读取)
3)我用包含所有模型的方法为边界条件创建了一个类,通量和包含相应函数的源的类为一个边界条件。在为数字方案分配函数时,我将调用所需的方法。 (似乎复杂且效率低下,不确定在matlab中调用方法所需的时间,但对我来说是最结构化的方式)
我可能应该注意,我对Matlab和数值模拟(学生)还是比较陌生,同时我也在询问一般如何解决此类问题。提前致谢! 另外还有一个好处:如果有人喜欢使用Matlab进行PDE系统的实际仿真-我会收到诸如“如何确定数值方案-应该考虑哪个标准”之类的问题。
再次感谢,祝大家度过愉快的一天!
答案 0 :(得分:0)
假设与模型1相关的方法始终一起使用,而不与模型2或3的方法混合使用,那么您可以在一个文件中为一个模型设置具有所有功能的代码:
% MODEL1 Methods that implement model 1
function [boundary_left,boundary_right,flux,source] = model1
boundary_left = @boundary_left_method;
boundary_right = @boundary_right_method;
flux = @flux_method;
source = @source_method;
function [out, args] = boundary_left_method(input, args)
% [implementation]
end
function [out, args] = boundary_right_method(input, args)
% [implementation]
end
function [out, args] = flux_method(input, args)
% [implementation]
end
function [out, args] = source_method(input, args)
% [implementation]
end
end
基本上,这里有一个函数可将句柄返回实现一组方法的一组函数。 boundary_left_method
是私有函数,因此不能直接访问,但是model1
可以将这些函数的句柄返回,从而使它们可以访问。
您现在可以这样做:
[boundary_left,boundary_right,flux,source] = model1;
Solution = numerical_scheme_1(boundary_left,boundary_right,flux,source,parameters);
此解决方案与OP建议的自定义类解决方案非常相似,但更为简单。我认为在性能上不会有很大的不同,但是要确定的唯一方法就是实施和确定各种选择的时间。随着MATLAB的JIT的提高,最有效的变化是随着时间的推移。
请注意,此处提出的方案还允许将数据(parameters
)包含在以下功能中:
% MODEL1 Methods that implement model 1
function [boundary_left,boundary_right,flux,source] = model1(parameters)
boundary_left = @boundary_left_method;
boundary_right = @boundary_right_method;
flux = @flux_method;
source = @source_method;
function [out, args] = boundary_left_method(input, args)
out = input * parameters; % You can use PARAMETERS here, note that it is not
% an input argument to this nested function, it is
% found in the parent scope.
end
% ...
end % This end here is important now, this way `boundary_left_method` is an
% nested function, not simply a separate function within the same file.
现在返回的函数句柄boundary_left
中嵌入了parameters
的数据。参见the relevant documentation。
如果您还控制采用这些函数句柄的数字方案函数的代码,则可以编写method1
等。返回句柄的单元格数组,而numerical_scheme_1
等。函数获取句柄的单元格数组。然后,您可以简单地执行以下操作:
numerical_scheme_1(method1,parameters);
numerical_scheme_1(method2,parameters);
numerical_scheme_1(method3,parameters);
numerical_scheme_2(method1,parameters);
numerical_scheme_2(method2,parameters);
numerical_scheme_2(method3,parameters);
% etc.
然后可以使用循环遍历所有组合:
schemes = {@numerical_scheme_1, @numerical_scheme_2, ... };
methods = {method1, method2, method3, ... };
for ii=1:numel(schemes)
for jj=1:numel(methods)
schemes{ii}(methods{jj},parameters);
end
end
[免责声明:此代码未经测试,但我不明白为什么它不起作用...]