Part1 ·更新拉格朗日法(UL) ·共旋法(CR) ·切线刚度矩阵
Part2 ·非线性系统求解算法
(预测阶段代码)
function Result = solve(Model,Anl,Elem,Pref)
% 初始化节点位移和荷载比
U = zeros(Model.neq,1);
lr = 0;
% 初始化result结构体,并插入初始平衡点
Result = struct('U_step',[],'U_iter',[],'lr_step',[],'lr_iter',[]);
Result.U_step(:,1) = U;
Result.U_iter(:,1) = U;
Result.lr_step(1) = lr;
Result.lr_iter(1) = lr;
%===========开始增量步求解过程====================================
step = 0;
while (step < Anl.max_steps)
step = step + 1;
% 更新参考构型下的UL方程(L_1根据上一增量步结束时的位移U进行更新;angle_1随着迭代步更新并将上一增量步结束的angle作为该步angle_1;内力fi_1同angle)
% 此处更新的L_1,angle_1和phi_1会在求解内力的函数中用到intForcesUL
for i = 1:Model.nel
Elem(i).L_1 = elemLength(Elem(i),U); %L_1 Length from beggining of step
Elem(i).angle_1 = Elem(i).angle; %angle_1 Angle with horizontal axis from beggining of step
Elem(i).fi_1 = Elem(i).fi; %fi_1 Vector of internal forces in local system from beggining of step
end
% 切线刚度矩阵(根据Ui-1更新Ki0)
[Kt,Elem] = tangStiffMtxUL(Model,Anl,Elem,U) ; %%根据i-1增量步的位结束移向量更新节点位置后得到的单元刚度矩阵(单元长度,单元角度),但返回的Elem只更新了Ke用来接下来计算内力
% 预测解位移的切线增量delta_Ui1
d_Ut = solveLinearSystem(Model,Kt,Pref);%delta_Ui1预测阶段的位移的切线增量,接下来是计算预测阶段的荷载比增量(增量步是否为第一增量步对应的荷载比增量公式不同)
if (step == 1)
s = 1; %第一增量步的预测阶段的增量的符号默认为正
d_lr = Anl.init_incr; %delta_lamda_11 人为规定预测阶段d_lr
n2 = d_Ut'*d_Ut;%第一增量步中位移切线增量的范数的平方值,会在后续分析步计算GSP
else
GSP = n2 / (d_Ut'*d_Ut_1);%公式(41) % Generalized Stiffness Parameter
if (GSP < 0)
s = -s; %公式(42) 增量步符号
end
% 增量步调整系数J
% J = sqrt((Anl.trg_iter + 1) / (iter + 1));%目标迭代次数/上一增量步步的迭代次数(公式(40))必须将其增加 1 以避免被零除,因为预测的解对应于零次迭代
J = 1;
%% 预测阶段荷载比增量 采用圆柱弧长法
% Extract free DOF components
D_U_temp = D_U(1:Model.neqf);
d_Ut_temp = d_Ut(1:Model.neqf);
d_lr = J * sqrt((D_U_temp'*D_U_temp) /(d_Ut_temp'*d_Ut_temp));%公式38:圆柱弧长法
% Apply correct sign
d_lr = s * d_lr;
end
% 荷载比要小于规定值(==1)
if ((Anl.max_ratio > 0.0 && lr + d_lr > Anl.max_ratio) ||...
(Anl.max_ratio < 0.0 && lr + d_lr < Anl.max_ratio))
d_lr = Anl.max_ratio - lr;%保证恰好达到最终的荷载比增量1实现荷载的全部施加
end
d_U = d_lr * d_Ut;%根据公式(36)预测阶段假定残差为零因此,只有前一项切线增量
% Store predicted results
d_lr_1 = d_lr; d_Ut_1 = d_Ut; d_U_1 = d_U;
% 前步的载荷比和位移增量(后续会随着迭代不断更新叠加)
D_lr = d_lr; D_U = d_U;
% 总荷载比和位移
lr = lr + d_lr;
U = U + d_U;
%
(校正迭代阶段代码)
% Start iterative process
iter = 0;
conv = 0;
while (conv == 0 && iter < Anl.max_iter)
% External and internal forces
P = lr * Pref;
[F,Elem] = intForcesUL(Model,Elem,U,D_U,1);%采用上一次迭代计算得到的Ke,并根据D_U对Ele.angle和Ele.fi进行更新
R = P - F; %残余力矢量
% Store iteration results
Result.U_iter(:,size(Result.U_iter,2)+1) = U;
Result.lr_iter(size(Result.lr_iter,2)+1) = lr;
% Check for convergence
conv = (norm(R(1:Model.neqf))/norm(Pref(1:Model.neqf)) < Anl.tol);
if (conv == 1)
break;
end
% Start/keep corrective cycle of iterations
iter = iter + 1;
[Kt,Elem] = tangStiffMtxUL(Model,Anl,Elem,U); %每次迭代更新,标准牛顿拉普森方法,Elem.ke更新
% Tangent and residual increments of displacements
d_Ut = solveLinearSystem(Model,Kt,Pref);
d_Ur = solveLinearSystem(Model,Kt,R);
% 荷载比修正(公式(45))恒定弧长法-圆柱法
a = d_Ut'*d_Ut;
b = d_Ut'*(d_Ur + D_U);
c = d_Ur'*(d_Ur + 2*D_U);%D_U为上一迭代步的值,d_Ur为本步更新后的值
s_iter = sign(D_U'*d_Ut);
d_lr = -b/a + s_iter*sqrt((b/a)^2 - c/a);
%如果增量步过大可能会出现复数
if (~isreal(d_lr))
conv = -1;
break;
end
% 公式(36)
d_U = d_lr * d_Ut + d_Ur;
% Increments of load ratio and displacements for current step
D_lr = D_lr + d_lr;
D_U = D_U + d_U;
% Total values of load ratio and displacements
lr = lr + d_lr;
U = U + d_U;
end
%----------------------------------------------------------------------------------
(内力计算)
function [F,Elem] = intForcesUL(Model,Elem,U,D_U,update_angle)
% Initialize global vector of internal forces
F = zeros(Model.neq,1);
for i = 1:Model.nel
% Lengths: Beginning of step, current, and step increment
L_1 = Elem(i).L_1;%每个增量步开始时进行更新
L_c = elemLength(Elem(i),U);
D_L = L_c - L_1;
% Rigid body rotation from step beginning and current angle
rbr = elemAngleIncr(Elem(i),U,D_U);%rbr带有符号,增加正值,减少负值
angle = Elem(i).angle_1 + rbr;
% Update element angle
if (update_angle)
Elem(i).angle = angle;
end
% Rotation matrix from local to global coordinate system
c = cos(angle);
s = sin(angle);
rot = [ c -s 0 0 0 0;
s c 0 0 0 0;
0 0 1 0 0 0;
0 0 0 c -s 0;
0 0 0 s c 0;
0 0 0 0 0 1 ];
% Relative rotations(变形转角)
r1 = D_U(Elem(i).n1.dof(3)) - rbr;
r2 = D_U(Elem(i).n2.dof(3)) - rbr;
% Vector of local displacements
dl = [0; 0 ; r1; D_L; 0; r2];%没有y向变形,只有轴向和转动变形???
% Increment of internal forces in local system
D_fl = Elem(i).ke * dl;
% Total internal forces in local system
fl = Elem(i).fi_1 + D_fl;
% Store total internal forces in local system
Elem(i).fi = fl;
% Transform internal forces from local system to global system
fg = rot * fl;
% Assemble element internal forces to global vector
gle = Elem(i).gle;
F(gle) = F(gle) + fg;
end
end
【编者按】