Содержание ↓
Глава 12

Запуск решателя непосредственно в Octave

Этот режим продолжает исходный способ работы МКЭ-Ф: студент открывает проект в установленном GNU Octave, читает входной файл и вызывает численное ядро напрямую. Docker и браузерный GUI не требуются. Теми же точками входа выполняется большая часть автоматических проверок решателя.

1. Что необходимо

  • GNU Octave 8.4 или новее; проект локально проверяется на Octave 11.3.0;
  • полная копия каталога МКЭ-Ф с файлами setup.m, src, scripts, examples и tests;
  • право чтения исходных файлов и право записи только в выбранный студентом каталог результатов.

GNU Octave является единственной поддерживаемой средой выполнения. Совместимость с MATLAB не тестируется и не гарантируется.

Дополнительные пакеты Octave, Python, npm и сетевое подключение для вычислений не нужны. Можно использовать графическое окно Octave только как терминал либо полностью безоконный octave-cli.

Рабочий каталог

Все команды ниже начинают из корня репозитория — каталога, в котором лежит setup.m. Если Octave открыт в другом месте, сначала выполните cd с собственным абсолютным путём к МКЭ-Ф.

2. Подключение ядра к пути Octave

В окне команд GNU Octave:

cd('C:/путь/к/MKE-F');
addpath(pwd);
setup;

На Linux и macOS путь может выглядеть как /home/student/MKE-F. Функция setup добавляет только каталоги модели, общих операций, трёх решателей, результатов и скриптов. Она не запускает расчёт и не изменяет входные данные.

Проверить подключение можно без вычислений:

which StructFEProblem
which solveStatic
which solveModal
which solveTransient

Каждая команда должна показать файл внутри текущего проекта, а не другую копию МКЭ-Ф.

3. Первый расчёт через RunSelected

Файлы CasePreprocessorStatic.txt, CasePreprocessorModal.txt и CasePreprocessorTransient.txt уже содержат секцию analysis. Поэтому один и тот же вызов выбирает нужный решатель из входного файла:

addpath(pwd);
setup;

casePath = fullfile('examples', 'cases', ...
    'CasePreprocessorStatic.txt');
options = struct('verbose', true, 'plotting', false);
problem = StructFEProblem(casePath, options);
result = problem.RunSelected();

result.analysisType
result.displacements
result.reactions

StructFEProblem читает TXT, строит сетку, нумерует степени свободы, создаёт элементы и собирает разреженные матрицы K и M. RunSelected() читает только конфигурацию analysis и вызывает RunStatic, RunModal или RunTransient.

Попробуйте три готовых файла

Заменяйте имя на CasePreprocessorModal.txt или CasePreprocessorTransient.txt. Для модального ответа смотрите result.frequenciesHz и result.modeShapes; для переходного — result.time, result.displacements, result.velocities и result.accelerations.

4. Старые файлы и явные методы

Файлы, созданные до появления секции analysis, остаются допустимыми. Для них вид расчёта задаётся методом, как в историческом интерфейсе программы:

staticProblem = StructFEProblem(fullfile( ...
    'examples', 'cases', 'Case1ElementBeam.txt'));
staticResult = staticProblem.RunStatic();

modalProblem = StructFEProblem(fullfile( ...
    'examples', 'cases', 'CaseBeam.txt'));
modalResult = modalProblem.RunModal();

transientProblem = StructFEProblem(fullfile( ...
    'examples', 'cases', 'CaseBeamDyn.txt'));
transientResult = transientProblem.RunTransient( ...
    1e-4, 1e-2, 3, 2);

Аргументы переходного метода — шаг времени, длительность, номер контрольного узла и локальная степень свободы. Последние два значения проверяются даже при plotting=false, хотя в безоконном режиме график не строится.

5. Чистые функции численного ядра

Для изучения алгоритма полезно отделить чтение и сборку от решения. GetAnalysisModel() создаёт обычную структуру значений, которую решатели не изменяют:

addpath(pwd);
setup;

problem = StructFEProblem(fullfile( ...
    'examples', 'cases', 'Case1ElementBeam.txt'));
model = problem.GetAnalysisModel();
staticResult = solveStatic(model);

modalProblem = StructFEProblem(fullfile( ...
    'examples', 'cases', 'CaseBeam.txt'));
modalModel = modalProblem.GetAnalysisModel();
modalResult = solveModal(modalModel);

transientProblem = StructFEProblem(fullfile( ...
    'examples', 'cases', 'CaseBeamDyn.txt'));
transientModel = transientProblem.GetAnalysisModel();
transientOptions = struct('timeStep', 1e-4, ...
    'duration', 1e-2);
transientResult = solveTransient( ...
    transientModel, transientOptions);

Это точные функции ядра, на которые ссылаются главы о расчётах:

  • solveStatic.m — редукция, решение, реакции, равновесие и результаты элементов;
  • solveModal.m — обобщённая собственная задача и полные формы;
  • solveTransient.m — метод средних ускорений Ньюмарка и полные истории;
  • createAnalysisModel.m — контракт неизменяемой структуры модели.

Повторный вызов с той же структурой должен дать тот же ответ: решатели не сохраняют состояние между запусками.

6. Доступ к матрицам и промежуточным данным

Матрицы хранятся разреженно. Для лабораторной сначала смотрите размер, число ненулевых коэффициентов и симметрию; превращайте в полную матрицу только небольшие примеры:

size(problem.K)
nnz(problem.K)
norm(problem.K - problem.K.', inf)

K = full(problem.K);       % только для небольшой модели
M = full(problem.M);
dofMap = problem.mesh.iMnod

У чистой модели те же данные называются model.stiffness, model.mass, model.dofMap и model.nodeCoordinates. Так можно сопоставлять каждую строку формулы с исполняемым массивом.

7. Полностью безоконный запуск

Тот же код можно выполнить из системного терминала. На Windows официальный дистрибутив обычно предоставляет octave-cli; на Linux часто доступна команда octave:

octave-cli --no-gui --quiet --no-history --eval "addpath(pwd); setup; problem = StructFEProblem(fullfile('examples','cases','CasePreprocessorStatic.txt')); result = problem.RunSelected(); disp(result.displacements);"

Эквивалентная команда с исполняемым файлом octave:

octave --no-gui --quiet --no-history --eval "addpath(pwd); setup; run_octave_smoke_tests;"

Ключ --no-gui отключает окно Octave, --quiet убирает стартовый баннер, --no-history не записывает историю команд. Параметр модели plotting=false предотвращает создание графических окон самим проектом.

8. Те же проверки, которыми сопровождается решатель

Быстрая интеграционная проверка читает десять входных файлов, проверяет разреженную сборку и запускает статику, моды, импульсные и гармонические переходные задачи:

addpath(pwd);
setup;
run_octave_smoke_tests;

Полная локальная проверка затем добавляет независимые численные инварианты, восстановление результатов, экспорт и целостность автономных HTML-страниц:

addpath(pwd);
setup;
run_octave_tests;
Что означает успешный тест

Smoke-набор отвечает на вопрос «все поставляемые задачи собираются и выполняются?». Verification-набор отдельно проверяет формулы, размерности, симметрию, равновесие, модальный эталон Mario Paz, схему Ньюмарка и восстановление усилий. Для изменения ядра нужны оба уровня.

9. Сохранение и последующий анализ

Структуры Octave можно сохранить для продолжения лабораторной:

save('-mat7-binary', fullfile('output', ...
    'local-static.mat'), 'model', 'staticResult');

Если нужен автономный браузерный просмотр только результата, Docker всё равно не требуется:

exportPostprocessorData(model, staticResult, ...
    fullfile('output', 'local-static.json'), ...
    struct('title', 'Локальный статический расчёт', ...
           'prettyPrint', true));

После этого откройте postprocessor/index.html прямо с диска и выберите JSON. Это не запускает код Octave из браузера: вычисление уже завершено локально, а HTML только проверяет и визуализирует данные.

10. Типичные затруднения

Сообщение или симптомЧто проверить
StructFEProblem undefinedOctave открыт не в корне проекта либо не выполнены addpath(pwd); setup;.
MKEF:MissingAnalysisConfigurationСтарый файл не содержит analysis. Используйте явный RunStatic, RunModal или RunTransient.
Файл не найденПроверьте pwd и собирайте путь через fullfile, не полагаясь на разделитель конкретной ОС.
Механизм или вырожденная системаПроверьте закрепления, нулевые длины, свойства элементов и наличие массы на свободных СС.
Появляется окно графикаСоздавайте задачу с struct('verbose', false, 'plotting', false) и запускайте Octave с --no-gui.

Маршрут чтения исходного кода

  1. StructFEProblem.m — совместимый фасад чтения, сборки и запуска;
  2. FEMesh.m — разбор TXT и проверка входа;
  3. createStructuralElement.m — элементные матрицы;
  4. assembleGlobalMatrices.m — глобальная разреженная сборка;
  5. partitionDOFs.m — свободные и закреплённые СС;
  6. один из трёх solve*.m, перечисленных выше;
  7. recoverElementResults.m — локальные перемещения и усилия.

Контейнерный backend и браузерный GUI являются оболочкой вокруг этой последовательности. Локальный запуск обращается к тем же файлам ядра напрямую.