Эффективность класса MATLAB

Я стараюсь сделать это коротко. У меня возникла задача численного моделирования потока в газовой трубе. Я моделирую, используя разные модели для воздушного потока (уравнения переноса), движущегося от одной границы к другой (т.е. справа налево). Вопрос в том, что, поскольку я использую разные модели для представления указанного потока газа и граничных условий, у меня есть много таких функций, как:

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 и численном моделировании (студент), и я также спрашиваю, как обычно решаются такие проблемы. Заранее спасибо! Также в качестве бонуса: если кто-то увлекается практическим моделированием систем PDE с помощью Matlab - у меня возникли вопросы типа «Как выбрать числовую схему - какие критерии следует учитывать?»

Еще раз спасибо, желаю всем приятного дня!


person William D.    schedule 28.09.2018    source источник
comment
Все ли функции для модели 1 связаны? Или вы запускаете симуляции, где используете, например, разные модели на разных границах?   -  person Cris Luengo    schedule 28.09.2018
comment
Приносим извинения за то, что не заявили об этом четко. Не все функции относятся к первой модели. Я получаю разные наборы потоков, источников и границ для каждой модели. Чтобы уточнить это: Например, я мог бы запустить моделирование с потоком и источниками для модели 1, тогда я также должен был использовать соответствующие граничные условия для модели 1. У меня сейчас есть четыре разные модели (в конце может быть больше, чем )   -  person William D.    schedule 28.09.2018
comment
Хорошо, поэтому вы запускаете симуляцию для модели 1 или для модели 2, но никогда не используете, например, поток модели 1 с источником модели 2. Это позволяет легко изолировать код для каждой модели в ее собственном исходном файле.   -  person Cris Luengo    schedule 28.09.2018
comment
точно. проблема здесь (и я не упомянул об этом), что у меня есть какое-то дерево решений: сначала я выбираю модель (и соответствующий поток, источник и границы), а затем мне также нужно определиться с числовой схемой (как они используются). Моя текущая работа состоит в сравнении различных числовых схем на разных моделях (разная степень упрощения).   -  person William D.    schedule 28.09.2018


Ответы (1)


Предполагая, что методы, связанные с моделью 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, но несколько проще. Я не думаю, что будет большая разница в производительности, но единственный способ узнать наверняка - это реализовать и рассчитать различные варианты. Что наиболее эффективно меняется с течением времени по мере улучшения JIT MATLAB.

Обратите внимание, что предложенная здесь схема также позволяет включать данные (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. См. соответствующую документацию.


Если вы также управляете кодом функций числовой схемы, которые принимают эти дескрипторы функций, вы можете написать method1 et al. чтобы вместо этого вернуть массив ячеек с дескрипторами, а numerical_scheme_1 et al. функции для получения массива ячеек дескрипторов. Тогда вы можете просто сделать:

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

[Отказ от ответственности: этот код не тестировался, но я не понимаю, почему он не работает ...]

person Cris Luengo    schedule 28.09.2018
comment
работает как шарм и дает мне больше возможностей, чем раньше. Благодарность! - person William D.; 04.10.2018