首页/文章/ 详情

SimPC博士:几何非线性有限元基本原理及matlab编程(下)

1年前浏览2124


导读:大家好,我是仿真秀专栏作者SimPC,近日笔者荣获了“仿真秀2022年度优秀讲师”荣誉称号,在此也感谢广大用户对我的仿真秀专栏内容认可。在未来的每一天,我还将继续在仿真秀官网分享自己的原创视频课程、文章、参与用户问答,为用户提供答疑、个性化培训和技术咨询服务等。
SimPC博士
全文目录
  • Part1 ·更新拉格朗日法(UL) ·共旋法(CR) ·切线刚度矩阵 

  • Part2 ·非线性系统求解算法 

  • Part3 ·几何非线性代码实现 
本文接《几何非线性有限元基本原理及matlab编程(上)》、SimPC博士:几何非线性有限元基本原理及matlab编程(中)继续分享。
4、几何非线性matlab代码实现
(1)非线性求解算法流程总结
在前面的部分中,描述了通过增量迭代数值方法求解线性化平衡方程组的过程。通用求解算法的流程图如图19所示。
图19
(2)matlab代码实现
① 切线刚度矩阵的matlab代码
根据公式(24),切线刚度矩阵中的弹性刚度矩阵实现代码如下:
根据公式(25),切线刚度矩阵中的几何刚度矩阵实现代码如下,注释掉的部分为应变张量的高阶项,可根据需要决定计算与否:
在上述弹性刚度矩阵和几何刚度矩阵得到后,单元的切线刚度矩阵实现代码为:
② 非线性系统求解的matlab代码
主函数首先初始化节点位移向量 U、载荷比值 lr。然后,增量迭代过程以一个while循环开始,该循环一直运行直到达到最大步数。增量步数计数器在增量循环开始时立即递增。预测阶段从更新UL公式的参考构型开始。在当前的平衡构型下,即在上一步结束时获得的单元内力和节点位移基础上,计算预测阶段的切线刚度矩阵 Kt。因此,tangStiffMtxUL()函数接收单元结构体数据的向量和节点位移的向量,两者都使用上一步的结果进行了更新。然后,切线刚度矩阵用于计算位移的切线增量d_Ut,通过使用参考载荷矢量求解线性系统,求解线性系统函数solveLinearSystem()。
下一步是计算预测阶段荷载比增量。当增量步是第一步时,预测增量的初始符号s设置为正数,且负载率增量 d_lr认为指定,另外存储第一步中位移切线增量d_Ut的范数的平方值,n2。该值用来在后续步骤中计算GSP。对于剩余的增量步(增量步>1),GSP根据公式(41)计算,增量符号在根据公式(42)进行调整,即每次 GSP 值为负时必须反转预测阶段荷载比增量的符号。之后,根据式(40)获得增量大小的调整因子J。需要指出表达式中的变量 iter存储上一步执行的迭代次数,必须将其增加1以避免被零除,因为预测的解对应于零次迭代。如果用户选择以恒定增量执行分析,则调整因子J的值设置为一。最后,根据公式(38)计算预测的荷载比增量。得到荷载率预测增量后,根据式(36)计算位移预测增量d_U(仅使用位移的切线增量),并对当前增量步的载荷比和位移增量(D_lr 和 D_U)进行更新。
迭代校正阶段,首先迭代次数的计数器iter被初始化为零,因为假设第一次校正迭代仅在预测阶段的收敛之后才开始。然后迭代循环开始于一个while循环中,该循环运行直到达到最大迭代次数或者不收敛时停止。
在迭代循环开始时,载荷比和节点位移的总值用上次迭代获得的修正增量更新,或者如果刚进入循环则用预测阶段的增量更新。外部节点力矢量 P 很容易从总载荷比lr中获得,而内部节点力矢量 F 需要在通过intForcesUL()函数针对当前节点位移进行计算。然后通过外力和内力矢量之间的差获得残余力矢量 R。
基于残余力范数的标准检查当前迭代的收敛性,如公式(43) 所示。如果与参考荷载向量的比足够小,则迭代收敛,算法退出循环进入下一个增量步。否则,算法继续进行下一次迭代校正并立即递增迭代次数inter。
荷载和位移增量校正迭代前先要选择迭代方案。如果选择标准的 Newton-Raphson 迭代,将使用更新后的构型来计算新的切线刚度矩阵,即使用在上一次迭代结束时获得的单元内力和节点位移。否则,如果选择修正Newton-Raphson 迭代法,则继续使用在预测阶段的得到的切线刚度矩阵。
位移校正的切线增量d_Ut和残余增量d_Ur分别使用参考载荷Pref和残余力R用线性系统计算。荷载比比的迭代校正选用恒定圆柱弧长法的表达式,由方程式(45)给出。最终根据方程(36)得到节点位移的迭代修正。一旦获得载荷和位移的修正值,运用其增量值来更新前增量步。最后,更新总的位移和荷载。
对于给定的位移计算内力基于UL公式通过函数intForcesUL()实现,首先初始化内力的全局向量,然后,对所有单元执行循环,计算局部坐标系下每个单元的内力矢量,将其转换为全局坐标系下的内力矢量,并将其组装至全局矢量中。在循环开始时,计算单元伸长率D_L,是通过当前单元长度 L_c 与参考配置(每个增量步开始时)的长度 L_1 之间的差值获得的。之后,计算单元刚体旋转角度(单元与全局坐标系X轴的角度),即每个增量步开始时的角度angle_1+刚体旋转增量 rbr。当前角度在单元结构体中更新。
内力增量矢量 D_f1弹性刚度矩阵与相对位移矢量(变形矢量)的乘积计算得出的。此增量添加到总内力矢量,获得局部坐标系中当前构型下的总内力fl存储在单元数据结构中,用于计算切线刚度矩阵(几何刚度矩阵)。通过将局部坐标系中的内力矢量乘以旋转矩阵,获得全局坐标系下的内力矢量。最后,使用单元索引矢量将单元内力插入到全局矢量中。




























































  
(预测阶段代码)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会在求解内力的函数中用到intForcesULfor i = 1:Model.nelElem(i).L_1     = elemLength(Elem(i),U); %L_1  Length from beggining of stepElem(i).angle_1 = Elem(i).angle; %angle_1 Angle with horizontal axis from beggining of stepElem(i).fi_1    = Elem(i).fi; %fi_1 Vector of internal forces in local system from beggining of stepend% 切线刚度矩阵(根据Ui-1更新Ki0)[Kt,Elem] = tangStiffMtxUL(Model,Anl,Elem,U) ;  %%根据i-1增量步的位结束移向量更新节点位置后得到的单元刚度矩阵(单元长度,单元角度),但返回的Elem只更新了Ke用来接下来计算内力% 预测解位移的切线增量delta_Ui1d_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;%第一增量步中位移切线增量的范数的平方值,会在后续分析步计算GSPelse 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 componentsD_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 signd_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 resultsd_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 processiter = 0;conv = 0;while (conv == 0 && iter < Anl.max_iter)% External and internal forcesP = lr * Pref;[F,Elem] = intForcesUL(Model,Elem,U,D_U,1);%采用上一次迭代计算得到的Ke,并根据D_U对Ele.angle和Ele.fi进行更新R = P - F;    %残余力矢量   % Store iteration resultsResult.U_iter(:,size(Result.U_iter,2)+1) = U;Result.lr_iter(size(Result.lr_iter,2)+1) = lr;% Check for  convergenceconv = (norm(R(1:Model.neqf))/norm(Pref(1:Model.neqf)) < Anl.tol);if (conv == 1)break;end% Start/keep corrective cycle of iterationsiter = iter + 1;[Kt,Elem] = tangStiffMtxUL(Model,Anl,Elem,U);   %每次迭代更新,标准牛顿拉普森方法,Elem.ke更新
% Tangent and residual increments of displacementsd_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 stepD_lr = D_lr + d_lr;D_U  = D_U  + d_U;
% Total values of load ratio and displacementslr = lr + d_lr;U  = U  + d_U; end%----------------------------------------------------------------------------------  
















































  
(内力计算)function [F,Elem] = intForcesUL(Model,Elem,U,D_U,update_angle)% Initialize global vector of internal forcesF = zeros(Model.neq,1);for i = 1:Model.nel% Lengths: Beginning of step, current, and step incrementL_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 anglerbr   = elemAngleIncr(Elem(i),U,D_U);%rbr带有符号,增加正值,减少负值angle = Elem(i).angle_1 + rbr;
% Update element angleif (update_angle)Elem(i).angle = angle;end
% Rotation matrix from local to global coordinate systemc = 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 displacementsdl = [0; 0 ; r1; D_L; 0; r2];%没有y向变形,只有轴向和转动变形???% Increment of internal forces in local systemD_fl = Elem(i).ke * dl;
% Total internal forces in local systemfl = Elem(i).fi_1 + D_fl;
% Store total internal forces in local systemElem(i).fi = fl;% Transform internal forces from local system to global systemfg = rot * fl;% Assemble element internal forces to global vectorgle    = Elem(i).gle;F(gle) = F(gle) + fg;endend  
希望大家关注笔者仿真秀专栏,大家学习Matlab编程过程中,有任何疑问都可以扫码进入仿真秀Matlab有限元编程用户交流群,群里还会分发更多Matlab编程学习资料。



【编者按】

本文作者从以一维梁单元组成的结构为对象来阐述几何非线性有限元算法逻辑及其Matlab实现。看似简单的问题剖析,但揭示了非线性求解器的开发原理,打通有限元理论与编程实践之间的屏障。虽然网络上存在着较多有限元教学课程,大多偏理论,距离有限元软件的开发还存在一定距离,已有的有限元编程教程缺乏系统性。在美国制裁之手伸向工业软件的大背景下,本系列课程致力于帮助那些有志于从事有限元软件开发的同学快速掌握基本有限元算法原理及编程实现。即使你不做开发,但从事工程仿真模拟工作,了解软件背后的算法逻辑也有助于定义仿真参数时做到有理有据。
如果对相关内容感兴趣,可关注本文作者在仿真秀平台发布的《Matlab有限元编程从入门到精通》系列讲座课程,利用Matlab实现有限元数值求解算法,从而求解各类物理场问题,课程主要以案例的形式进行讲解,即使有限元理论欠缺的同学也不必担心,中间会穿插案例中所涉及到的有限元基本理论,案例不局限于力学问题的有限元求解,还会涉及传热学等问题的有限元求解。所涉及的单元有杆单元,梁单元,平面三角形单元,四边形单元,板壳单元,四面体/六面体实体单元等等,力学问题有静力学问题,也有动力学问题,后期还会涉及材料非线性、几何非线性、接触非线性等非线性问题,内容丰富,后期会不断更新完善,预计至少有30节课程,每节课都是一个小时左右,干货满满,欢迎学习!
(完)
参考文献
Rafael Lopez Rangel.Educational Tool for Structural Analysis of Plane Frame Models with Geometric Nonlinearity[D].PUC.2019
作者:SimPC博士   仿真秀专栏作者
声明:本文首发仿真秀App,部分图片和内容转自网如有不当请联系我们,欢迎分享,禁止私自转载,转载请联系我们。

来源:仿真秀App
System静力学非线性通用理论材料
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2023-02-17
最近编辑:1年前
仿真圈
技术圈粉 知识付费 学习强国
获赞 9823粉丝 21210文章 3432课程 216
点赞
收藏
未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习 福利任务 兑换礼品
下载APP
联系我们
帮助与反馈