1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143 | %% --- Materials ---
ops.wipe();
ops.model('basic', '-ndm', 3, '-ndf', 6);
ops.uniaxialMaterial('Concrete02', 2, -35, -0.005, -8.75, 0.02, 0.1, 2.0, 2000);
ops.uniaxialMaterial('Concrete02', 3, -30, -0.003, -6.0, 0.01, 0.1, 2.0, 2000);
ops.uniaxialMaterial('Steel02', 4, 400, 2.0e5, 0.01, 18, 0.925, 0.15);
%% --- Geometry: rectangular double-cell hollow box ---
% This example creates a double-cell hollow box section using MATLAB
% built-in polyshape operations. The section is divided into:
% 1) confined core concrete,
% 2) unconfined cover concrete,
% 3) longitudinal rebars placed along offset boundary paths.
% Overall section dimensions.
B = 2400; % Total section width in the y-direction
H = 1600; % Total section height in the z-direction
% Void dimensions and locations.
voidB = 800; % Width of each rectangular void
voidH = 1100; % Height of each rectangular void
voidCy = 600; % Distance from section center to each void center
% Rebar layout parameters.
barGap = 180; % Target spacing of rebars along each boundary path
rebarR = 12.5; % Rebar radius, e.g., D25 bar
% Cover and mesh parameters.
coverThick = 40; % Clear concrete cover thickness
barCover = coverThick + rebarR; % Distance from concrete face to rebar center
meshSize = 80; % Target mesh size for triangular meshing
% Create the outer rectangular boundary.
outerPoly = polyshape( ...
[-B/2, B/2, B/2, -B/2], ...
[-H/2, -H/2, H/2, H/2]);
% Create the left rectangular void.
void1 = polyshape( ...
[-voidCy-voidB/2, -voidCy+voidB/2, -voidCy+voidB/2, -voidCy-voidB/2], ...
[-voidH/2, -voidH/2, voidH/2, voidH/2]);
% Create the right rectangular void.
void2 = polyshape( ...
[ voidCy-voidB/2, voidCy+voidB/2, voidCy+voidB/2, voidCy-voidB/2], ...
[-voidH/2, -voidH/2, voidH/2, voidH/2]);
% Combine the two voids into one polyshape object.
voids = union([void1; void2]);
% Concrete wall region = outer box minus the two voids.
wallRegion = subtract(outerPoly, voids);
% Offset the outer boundary inward by coverThick.
% This defines the inner limit of the outer cover layer.
outerCoreLimit = polybuffer(outerPoly, -coverThick, 'JointType', 'miter');
% Offset each void boundary outward by coverThick.
% These regions represent the cover concrete around the inner void faces.
voidCover1 = polybuffer(void1, coverThick, 'JointType', 'miter');
voidCover2 = polybuffer(void2, coverThick, 'JointType', 'miter');
voidCovers = union([voidCover1; voidCover2]);
% Confined core = wall concrete inside the outer core limit,
% excluding the cover zones around the void boundaries.
coreRegion = intersect(wallRegion, outerCoreLimit);
coreRegion = subtract(coreRegion, voidCovers);
% Unconfined cover = remaining concrete outside the confined core.
coverRegion = subtract(wallRegion, coreRegion);
%% --- Parts ---
% Each part is assigned an OpenSees material tag and an independent mesh size.
clear parts
parts(1).name = 'Confined core';
parts(1).matTag = 2;
parts(1).geometry = coreRegion;
parts(1).meshSize = meshSize+10; % slightly coarser mesh for core concrete
parts(2).name = 'Unconfined cover';
parts(2).matTag = 3;
parts(2).geometry = coverRegion;
parts(2).meshSize = meshSize; % finer mesh for cover regions
%% --- Rebars using offset boundary + lineRebars ---
% Rebar centerlines are generated by offsetting concrete boundaries.
% The offset distance is coverThick + rebar radius, so that the clear cover
% from concrete face to rebar surface is approximately coverThick.
% Outer rebar path: offset the outer boundary inward.
outerBarPath = polybuffer(outerPoly, -barCover, 'JointType', 'miter');
% Inner rebar paths: offset void boundaries outward into the concrete walls.
innerBarPath1 = polybuffer(void1, barCover, 'JointType', 'miter');
innerBarPath2 = polybuffer(void2, barCover, 'JointType', 'miter');
% Extract boundary vertices from the offset paths.
[yOuter, zOuter] = boundary(outerBarPath);
[yIn1, zIn1] = boundary(innerBarPath1);
[yIn2, zIn2] = boundary(innerBarPath2);
% Generate rebar coordinates along each closed path.
% lineRebars guarantees that all path vertices are occupied by rebars and
% inserts additional bars along each segment according to the target gap.
outerBars = fs.lineRebars(yOuter, zOuter, gap=barGap, closed=true);
innerBars1 = fs.lineRebars(yIn1, zIn1, gap=barGap, closed=true);
innerBars2 = fs.lineRebars(yIn2, zIn2, gap=barGap, closed=true);
% Merge all bar coordinates and remove duplicates at overlapping vertices.
allBarCoords = unique([outerBars; innerBars1; innerBars2], 'rows');
clear rebars
rebars(1).name = 'HRB400 D25';
rebars(1).matTag = 4;
rebars(1).coords = allBarCoords;
rebars(1).area = pi * rebarR^2;
|