Расчет плоских ферм и арок. Расчетная схема фермы с принятой нумерацией узлов и стержней, страница 6

  for( i = 0; i<2*numNodes; i++ )

     MatrixA[i] = new double[2*numNodes];

// Результат выполнения трех строк пункта 13 - динамически создана матрица

// матрицы жесткости фермы

// Обнуление элементов двумерного массива MatrixA

  for( i = 0; i<2*numNodes; i++ )

     for( j = 0; j<2*numNodes; j++ )

       MatrixA[i][j] = 0;

// Пункт 13

// Функция FillGlobalMatrix каждого стержня заполняет матрицу MatrixA фермы

// (см. листинг файла Rod.cpp)

  for( i = 0; i<numRods; i++ )

     rod[i].FillGlobalMatrix(MatrixA);

// Пункт 14

// Создание массива матрицы-столбца внешних сил

  MatrixB = new double[2*numNodes];

// Обнуление элементов одномерного массива MatrixB

  for( i = 0; i<2*numNodes; i++ )

     MatrixB[i] = 0;

// Пункт 15

// Функция FillForceMatrix каждого стержня заполняет матрицу MatrixB

// внешних сил (см. листинг файла Force.cpp)

  for( i = 0; i<numNodes; i++ )

     force[i].FillForceMatrix(MatrixB, i);

// Пункт 16

// Учет вшених связей состоит в том, что из матриц MatrixA и MatrixB

// мы вычеркиваем строки и столбцы, соответствующие уравнениям относительно // перемещений, которые вследствие наложенных внешних связей заведомо равны // нулю

// Индексы пропуска строк и столбцов

  long skipRows=0, skipColumns=0;

// Проходим по каждому уравнению (по каждой строке) для каждого перемещения // узла

  for( i = 0; i<2*numNodes; i++ )

  {

     // Учет связей в глобальной матрице (в строках)

// Если опоры в узле int(i/2) по направлению i%2 (0 - вдоль 0Х, 1 - вдоль // 0Y) нет, то в "упакованную" (в вычеркнутыми строками) матрицу MatrixA

// можно записать значение из старой матрицы MatrixA.

     if( ! node[ int(i/2) ].ThereIsConnection(i) )

     {

       skipColumns=0;

// Проходим по каждому коэффициенту в i-ой строке (по каждому столбцу в

// i-ой строке) для каждого перемещения узла

       for( j = 0; j<2*numNodes; j++ )

       {

          // Учет связей в глобальной матрице (в столбцах)

// Если опоры в узле int(j/2) по направлению j%2 (0 - вдоль 0Х, 1 -

// вдоль 0Y) нет, то в "упакованную" (в вычеркнутыми столбцами)

// матрицу MatrixA можно записать значение из старой матрицы MatrixA.

          if( ! node[ int(j/2) ].ThereIsConnection(j) )

            MatrixA[i-skipRows][j-skipColumns] = MatrixA[i][j];

// Иначе, если есть опора, то запомнить, что в этой i-ой строке был

// пропущен столбец ...

          else

            skipColumns++;

// ... и всего таких пропущенных столбцов теперь skipColumns

       }

       // Учет связей в матрице-столбце сил

       MatrixB[i-skipRows] = MatrixB[i];

     }

// Иначе, если есть опора, то запомнить, что в матрице была пропущена

// строка ...

     else

       skipRows++;

// ... и всего таких пропущенных строк теперь skipRows

  }

// Вычислить количество уравнений без перемещений, соответствующих опорам

  equations = 2*numNodes - skipRows;

// Пункт 17

// Создание массива матрицы-столбца перемещений узлов по незакрепленным

// направлениям

  MatrixX = new double[2*numNodes];

// Обнуление элементов одномерного массива MatrixX

  for( i = 0; i<2*numNodes; i++ )

     MatrixX[i] = 0;

// Пункт 18

// Решение системы уравнений вида A*x=b методом LU-разложения (см. листинг

// файла Solving.cpp)

  LUDecomposition(equations, MatrixA, MatrixB, MatrixX);

// Пункт 19

// Создание массива матрицы-столбца перемещений

  Displace = new double[2*numNodes];

// Пункт 20

// Заполнение массива матрицы-столбца перемещений с учетом, что матрица

// MatrixX заполнена только перемещениями узлов по незакрепленным внешними

// связями направлениям. Используется та же идея, что и в пункте 17

  skipRows=0;

  for( i = 0; i<2*numNodes; i++ )

  {

     if( !node[ int(i/2) ].ThereIsConnection(i) )

       Displace[i] = MatrixX[i-skipRows];

     else

     {

       Displace[i] = 0;

       skipRows++;

     }

  }

// Пункт 21

// Функция CalcForce каждого стержня по перемещениям двух узлов этого стержня

// вычисляет продольное усилие (см. листинг файла Rod.cpp)

  for( i = 0; i<numRods; i++ )

  {

     long place1 = 2*rod[i].node1, place2 = 2*rod[i].node2;

     rod[i].CalcForce(Displace[ place1 ], Displace[ place1+1 ],

       Displace[ place2 ], Displace[ place2+1 ]);