Существует множество способов создания блочных матриц в Фортране, ответы, уже отмеченные @francescalus, показывают пару, и у меня наверняка есть некоторые в моем наборе инструментов. Вот другой подход, возможно, более простой, но удовлетворительный для непосредственных требований OP.
Сначала объявите переменную для блоков, в следующем она называется blk
, и она объявлена как m*m
. Тогда это так же просто, как ...
ke = 0.0 ! All elements will be 0.0 unless otherwise assigned
! Define the block on the diagonal, and assign it
blk = RESHAPE([-4.0, 1.0, 0.0, 1.0, -4.0, 1.0, 0.0, 1.0, -4.0], [m,m])
DO i = 1, n, m
ke(i:i+m-1,i:i+m-1) = blk
END DO
! Now the off-diagonal blocks
blk = RESHAPE([1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0], [m,m])
DO i = 4, n, m
ke(i:i+m-1,i-m:i-1) = blk
ke(i-m:i-1,i:i+m-1) = blk
END DO
Если бы я собирался использовать это в рабочем коде, то я бы обернул его в рутину и уделил больше внимания таким вопросам, как использование выделяемых массивов, передача предполагаемой массивы, такие хорошие вещи.
Другие полезные инструменты в арсенале программистов на Фортране: chsift
и eoshift
. Я мог бы использовать последний следующим образом. Во-первых, давайте иметь массив элементов типа 1011 * с двойными числами, называемый line
, затем
ke = 0.0
line = [0.0, 1.0, 0.0, 1.0, -4.0, 1.0, 0.0, 1.0, 0.0]
ke((n/2)+1,:) = line
DO i = 1, 4
ke(i,:) = EOSHIFT(line,m+2-i)
ke(n-i+1,:) = EOSHIFT(line,-(m+2-i))
END DO
Что касается эффективности, я сомневаюсь, что между любыми подходами здесь есть много, или в аналогичных подходах. Я полагаю, что минимизация количества сканирований по массивам была бы хорошей идеей, и посещение элементов в удобном для памяти порядке также было бы полезно. Но все они должны посетить каждый элемент хотя бы один раз. Я бы go за самый простой подход, то есть тот, который I нашел самым простым для рассматриваемой проблемы; Ваш выбор для вашей проблемы может быть другим. Заботьтесь об эффективности, только если профилирование показывает, что есть проблема.