Поскольку моделирование ребра, выступающего в качестве поверхности с результирующим стержнем значительно сложнее, чем обычное создание стержня типа ребро, была для преобразования ребra в модель поверхности с результирующим стержнем создана в EXCEL-VBA следующая программа.
Чтобы преобразовать ребро в поверхностную модель, необходимо выполнить следующие шаги:
- Считывание параметров ребра (сечение, ориентация и т.д.)
- Создание поверхности ребра
- создать результирующую балку
- Удаление ребра в виде стержня
Далее мы покажем в качестве примера фрагменты всего исходного кода. Полный код программы можно скачать в конце данной статьи.
Считывание параметров ребра
Пользователь имеет возможность выбрать в интерфейсе программы ребро, которое нужно трансформировать. Для этого необходима работа с функцией EnableSelections. Пока EnableSelections активирована с настройкой true, из RFEM считываются только выбранные элементы. Считывание выбранного стержня выглядит следующим образом.
' get interface of active model
Set iMod = iApp.GetActiveModel
' get interface of (structural) model data
Dim iModData As RFEM5.IModelData2
Set iModData = iMod.GetModelData
' get selected member
iModData.EnableSelections True
Dim mems() As RFEM5.Member
Dim selMem As RFEM5.Member
mems = iModData.GetMembers
selMem = mems(0)
iModData.EnableSelections False
Для моделирования ребра требуются следующие параметры:
- Сечение ребра, номера поверхностей и полезная ширина
- Ориентация ребра
- Материал ребра
В программе RFEM ребро является типом стержня. В случае программирования через интерфейс COM это означает, что данные ребра необходимо получить через два различных интерфейса. Во-первых это интерфейс для стержня, а во-вторых - интерфейс для ребра. Интерфейс ребра можно получить через IModelData.GetRib. GetRib ожидает номер ребра, содержащийся в стержне посредством Member.RibNo.
' get parameters of rib
' #####################
Dim iRb As RFEM5.IRib
Set iRb = iModData.GetRib(selMem.RibNo, AtNo)
Dim selRb As RFEM5.Rib
selRb = iRb.GetData
Dim rbCrsc As RFEM5.RibCrossSection
rbCrsc = iRb.GetRibCrossSection
Интерфейс ребра затем предложит два различных элемента: общие данные ребра через структуру Rib и данные сечения ребра через RibCrossSection. Rib содержит номера поверхностей, расположение ребра и полезные ширины. RibCrossSection содержит описание и размеры внутреннего сечения ребра, которое также используется в RF-CONCRETE Members (ITCU).
Кроме того, требуется ориентация, которая определяется местной системой координат стержня. Доступ к системе координат осуществляется через интерфейс стержня. Функция IMemer.GetLocalCoordinateSystem возвращает структуру CoordinateSystem.
Dim cosy As RFEM5.CoordinateSystem
cosy = iModData.GetMember(selMem.no, AtNo).GetLocalCoordinateSystem(0#).GetData
GetLocalCoordinateSystem все еще ожидает ввода x-расположения на стержне, которое было задано на 0,0 или его начало. В дополнение к упомянутым параметрам также требуется материал стержня, который можно получить из поперечного сечения стержня.
Dim selCrsc As RFEM5.CrossSection
selCrsc = iModData.GetCrossSection(selMem.StartCrossSectionNo, AtNo).GetData
Создание поверхности ребра
Вначале программа предназначена только для прямых ребер на положительной стороне z. Поскольку ребро также может быть расположено в наклонной плоскости, необходимо создать поверхность с помощью ориентации стержня. Переменная cosy местной системы координат стержня включает в себя направляющий вектор для местной оси z - cosy.AxisZ, с соответствующими тремя значениями x, y и z. Этот вектор нормализирован таким образом, что при его умножении на высоту ребра показывает расстояние и направление нижней кромки ребра. Для граничных линий поверхности ребра данный вектор умножается на высоту ребра и прибавляется к начальному и конечному узлу. Таким образом мы получим два конечных узла нижней кромки поверхности ребра. Обратите внимание на то, что высота ребра также включает половину толщины поверхности полезной ширины. Для упрощения используется только толщина поверхности на первой стороне (-y в местной системе координат) из сечения ребра (UpperLeftFlangeThickness). После того, как будут получены узлы, можно создать граничные линии и поверхность ребра.
- code.vb#
' create/calculate nodes
' ######################
Dim nodes() As RFEM5.Node
nodes = selNodes
nodes(0).no = index_n + 1
nodes(1).no = index_n + 2
Dim h_rib As Double
h_rib = (rbCrsc.Depth - rbCrsc.UpperLeftFlangeThickness / 2)
nodes(0).X = nodes(0).X + h_rib * cosy.AxisZ.X
nodes(0).Y = nodes(0).Y + h_rib * cosy.AxisZ.Y
nodes(0).Z = nodes(0).Z + h_rib * cosy.AxisZ.Z
nodes(1).X = nodes(1).X + h_rib * cosy.AxisZ.X
nodes(1).Y = nodes(1).Y + h_rib * cosy.AxisZ.Y
nodes (1).Z = nodes (1).Z + h_rib * cozy.AxisZ.Z
' create lines
' ############
Dim lines(0 To 2) As RFEM5.RfLine
lines(0).no = index_l + 1
lines(1).no = index_l + 2
lines(2).no = index_l + 3
lines(0).NodeList = str(selNodes(0).no) + "," + str(nodes(0).no)
lines(1).NodeList = str(selNodes(1).no) + "," + str(nodes(1).no)
lines(2).NodeList = str(nodes(0).no) + "," + str(nodes(1).no)
' create surface
' ##############
Dim surf As RFEM5.Surface
surf.BoundaryLineCount = 4
surf.BoundaryLineList = str(selLine.no) + "," + str(lines(0).no) + "," + str(lines(2).no) + "," + str(lines(1).no)
surf.Comment = "rib"
surf.GeometryType = PlaneSurfaceType
surf.MaterialNo = selCrsc.MaterialNo
surf.Thickness.Type = ConstantThicknessType
surf.Thickness.Constant = rbCrsc.WebThickness
surf.StiffnessType = StandardStiffnessType
surf.no = index_s + 1
- /код#
Каждая из переменных index_n, index_l, index_s содержит последний индекс соответствующего элемента из RFEM. Для установления данных индексов обратитесь к исходному коду, который можно скачать в конце нашей статьи.
создать результирующую балку
Результирующий стержень, как и ребро, состоит из двух элементов: стандартной структуры Member и дополнительных данных ResultBeam. Дополнительные данные можно редактировать только через интерфейс для стержня, поэтому сначала необходимо создать стержень, а затем можно передавать данные через интерфейс IMember. Поскольку стержень обычно должен быть расположен внецентренно, то начальный и конечный узлы создаются прямо в центре сдвига без эксцентриситета стержня. Эксцентриситет сохраняется в RibCrossSection. Таким образом можно скопировать начальный и конечный узлы исходного ребра и использовать в качестве основы. С помощью направляющих векторов y и z из местной системы координат стержня мы можем передвинуть скопированные узлы на правильное место. Для последующего расчета результирующий стержень должен иметь сечение, которое вначале копируется с исходного ребра. Затем обозначение сечения импортируется из RibCrossSection, а содержание CrossSection.TextID удаляется, поскольку в противном случае оно будет применено для создания сечения, вместо символьной строки из CrossSection.Description.
- code.vb#
' create nodes for result member and calculate eccentricity
Dim resNodes() As RFEM5.Node
resNodes = selNodes
resNodes (0).no = index_n + 3
resNodes (1).no = index_n + 4
resNodes(0).X = selNodes(0).X + rbCrsc.Eccentricity.Z * cosy.AxisZ.X + rbCrsc.Eccentricity.Y * cosy.AxisY.X
resNodes(0).Y = selNodes(0).Y + rbCrsc.Eccentricity.Z * cosy.AxisZ.Y + rbCrsc.Eccentricity.Y * cosy.AxisY.Y
resNodes(0).Z = selNodes(0).Z + rbCrsc.Eccentricity.Z * cosy.AxisZ.Z + rbCrsc.Eccentricity.Y * cosy.AxisY.Z
resNodes(1).X = selNodes(1).X + rbCrsc.Eccentricity.Z * cosy.AxisZ.X + rbCrsc.Eccentricity.Y * cosy.AxisY.X
resNodes(1).Y = selNodes(1).Y + rbCrsc.Eccentricity.Z * cosy.AxisZ.Y + rbCrsc.Eccentricity.Y * cosy.AxisY.Y
resNodes(1).Z = selNodes(1).Z + rbCrsc.Eccentricity.Z * cosy.AxisZ.Z + rbCrsc.Eccentricity.Y * cosy.AxisY.Z
' create line
Dim resLine As RFEM5.RfLine
resLine.no = index_l + 4
resLine.NodeCount = 2
resLine.Type = PolylineType
resLine.NodeList = str(resNodes(0).no) & "," & str(resNodes(1).no)
' create cross section
Dim resCrsc As RFEM5.CrossSection
resCrsc = selCrsc
resCrsc.description = rbCrsc.description
resCrsc.no = index_c + 1
resCrsc.TextID = ""
' create member
Dim resMem As RFEM5.Member
resMem.LineNo = resLine.no
resMem.no = index_m + 1
resMem.Type = ResultBeamType
resMem.StartCrossSectionNo = resCrsc.no
resMem.Rotation = selMem.Rotation
' send data to RFEM
' ####################
iModData.PrepareModification
- Узлы iModData.SetNodes
- Линии iModData.SetLines
- iModData.SetSurface
- iModData.SetNodes resNodes
- iModData.SetLine resLine
- iModData.SetCrossSection resCrsc
- iModData.SetMember resMem
iModData.FinishModification
- /код#
После создания стержня (а также узлов, линий, сечения и поверхности) необходимо установить и передать параметры результирующего стержня. Результирующий стержень интегрирует внутренние силы других элементов (стержней, поверхностей, тел) и преобразовывает их в внутренние силы стержня в соответствии с их расположением. Для вовлечения правильных элементов у результирующего стержня есть два основных варианта. Можно задать интегрируемые элементы и дополнительно ограничить область интегрирования с помощью тела (цилиндра или куба). В данном случае будет применен номер новой поверхности ребра и номера поверхностей полезных ширин, если таковые имеются. В качестве области интегрирования выберем прямоугольный параллелепипед, который (местно) можно задать в направлении +/- y и +/- z. Данные из RibCrossSection снова будут применены в качестве значений. Необходимо обратить внимание на то, что даже в случае отсутствия полезной ширины, необходимо применить ширину интегрирования для правильного интегрирования плиты над ребром. Дополнительная ширина должна составлять половину толщины поверхности.
- code.vb#
' set result beam parameters
' ##########################
Dim resBeam As RFEM5.ResultBeam
Dim iResBeam As RFEM5.IResultBeam
Set iResBeam = iModData.GetMember(resMem.no, AtNo).GetExtraData
resBeam = iResBeam.GetData
' set integrated elements
If selRb.SurfaceNoSide1 Then
- resBeam. включитьSurfaces = str(selRb.SurfaceNoSide1) & ,
End If
If selRb.SurfaceNoSide2 Then
- resBeam. включитьSurfaces = resBeam. AnnexSurfaces & str(selRb.SurfaceNoSide2) &,
End If
resBeam.IncludeSurfaces = resBeam.IncludeSurfaces & str(surf.no)
' set integration area
resBeam.Integrate = WithinCuboidGeneral
Dim resBeamParam(0 To 3) As Double
' +y, -y, +z, -z
If selRb.WidthSide2 Then
- resBeamParam (0) = selRb.WidthSide2 - rbCrsc.Eccentricity.Y
Else
- resBeamParam (0) = 0,5 * rbCrsc.WebThickness - rbCrsc.Eccentricity.Y
End If
If selRb.WidthSide1 Then
- resBeamParam (1) = selRb.WidthSide1 + rbCrsc.Eccentricity.Y
Else
- resBeamParam (1) = 0,5 * rbCrsc.WebThickness + rbCrsc.Eccentricity.Y
End If
resBeamParam (2) = rbCrsc.Depth
resBeamParam (3) = rbCrsc.Depth
resBeam.Parameters = resBeamParam
' send new result beam parameters to RFEM
iModData.PrepareModification
iResBeam.SetData resBeam
iModData.FinishModification
- /код#
Удаление ребра в виде стержня
Поскольку из поверхностей было создано новое ребро, теперь мы можем удалить стержень, старое ребро. Любой элемент можно удалить с помощью функции DeleteObjects интерфейса IModelData. Так как элементы редактируются, то необходимо снова применить блок Prepare/Finish modification.
- code.vb#
' Remove Rib
'##########
iModData.PrepareModification
iModData.DeleteObjects MemberObject, str(selMem.no)
iModData.FinishModification
- /код#
Заключение
Из-за простоты применения, ребра в виде стержней не всегда могут соответствовать всем аспектам более сложной модели. Создать ребро в виде стержня просто, а потому представленная здесь программа сочетает в себе простое создание ребра как стержня с более детальным моделированием и созданием ребра из поверхностей. В дополнение к уже известным элементам, таким как интерфейсы стержня (IMember), мы представили интерфейс IRib, который, помимо прочего, обеспечивает доступ к сечению ребра. Кроме того, была считана местная система координат стержня и создана поверхность ребра с помощью векторного расчета.
Взгляд в будущее
В программе существуют возможность более подробных настроек. Например, можно было учесть положение ребра (вверху, внизу, в середине). Другим вариантом могло быть расширение на ребра с вутом или даже ребра на изогнутых линиях.