首页/文章/ 详情

开源:三维弹塑性有限元分析程序

1年前浏览1453

代码说明

  三维弹塑性有限元分析程序。采用C3D8单元,Von Mises屈服准则,关联流动法则,各向同性运动硬化法则,位移加载模式,映射返回算法,牛顿迭代。
  代码可以自动给长方体划分六面体网格,用户可以自定义长方体的三个尺寸,以及三个方向的单元尺寸,代码会自动生成节点编号和节点坐标信息。
  代码可以计算C3D8单元,如形函数、应变-位移矩阵、刚度矩阵等等。采用高斯积分方法计算刚度矩阵。
  弹塑性部分,采用Von Mises屈服准则,关联流动法则,各向同性运动硬化法则,应力试探和矫正采用映射返回算法。
  代码最后将计算的结果输出为Paraview可读取的Vtk文件,用于后续的可视化处理。

全部程序

% 三维弹塑性有限元分析程序 (立方体模型)
clear; clc; close all;  % 清除工作区、命令窗口和图形窗口
CoreNum=16; % 设置并行计算使用的CPU核心数(利用多核加速计算)
if isempty(gcp('nocreate')) % 检查并行计算池是否存在,不存在则创建
    parpool('local',CoreNum); % 创建包含16个工作线程的本地并行计算池
end
% ========================== 前处理 ==========================
% 材料参数 (基于J2塑性理论)
E = 200e3;         % 弹性模量 (MPa) - 胡克定律基础参数,公式:σ = Eε
nu = 0.3;          % 泊松比 - 横向应变与纵向应变比值,公式:ν = -ε横向/ε纵向
sigma_y0 = 200;    % 初始屈服应力 (MPa) - von Mises屈服准则临界值,σ_eq ≥ σ_y0时进入塑性
H = 0.1 * E;       % 硬化模量 (MPa) - 线性硬化模型参数,公式:σ_y = σ_y0 + Hε_p^eq

% 几何参数 (定义10×10×10 mm立方体模型)
Lx = 1; Ly = 1; Lz = 1;  % 模型尺寸 (mm)
nx = 10; ny = 10; nz = 10;  % 各方向单元数量,总单元数=10×10×10=1000

% 加载参数 (准静态位移控制加载)
total_disp = 1;   % 总位移量 (mm) - 模型右端沿X方向的总位移
n_steps = 10;       % 加载步数 - 控制位移增量为total_disp/n_steps

% 高斯积分设置 (2×2×2积分点,用于数值积分)
gauss_points = [-1/sqrt(3), 1/sqrt(3)];  % 一维高斯点坐标(对应ξ, η, ζ方向)
gauss_weights = [1, 1];                  % 高斯积分权重,用于加权求积

% 生成结构化六面体网格
[nodes, elements] = generate_mesh(Lx, Ly, Lz, nx, ny, nz);
n_nodes = size(nodes, 1);      % 节点总数:(nx+1)(ny+1)(nz+1)=11×11×11=1331
n_elements = size(elements, 1); % 单元总数:nx×ny×nz=1000

% 有限元求解变量初始化
dof_per_node = 3;              % 每个节点3个平动自由度(X, Y, Z方向)
total_dof = n_nodes * dof_per_node;  % 系统总自由度:1331×3=3993
U = zeros(total_dof, 1);       % 全局位移向量(待求解未知量)
F_ext = zeros(total_dof, 1);   % 外力向量(本例无体力,仅位移加载)

% 积分点历史变量(记录塑性状态)
n_gauss = 8;  % 每个单元8个高斯积分点(2×2×2布局)
plastic_strain = zeros(6, n_gauss, n_elements); % 塑性应变张量(Voigt六分量:[ε_xx, ε_yy, ε_zz, γ_xy, γ_yz, γ_zx])
eq_plastic_strain = zeros(n_gauss, n_elements); % 等效塑性应变(硬化参数,ε_p^eq)

% ======================== 边界条件 ========================
% 固定X=0的面(全自由度固定)- Dirichlet边界条件
fixed_nodes = find(nodes(:,1) == 0);  % 查找X坐标为0的所有节点
% 将节点编号转换为自由度编号(每个节点3个自由度:X(3i-2), Y(3i-1), Z(3i))
fixed_dof = sort([3*fixed_nodes-2; 3*fixed_nodes-1; 3*fixed_nodes]);

% 在X=Lx的面施加X方向位移- 位移控制边界条件
loaded_nodes = find(nodes(:,1) == Lx);  % 查找X坐标为Lx的所有节点
loaded_dof = 3*loaded_nodes - 2;        % X方向自由度编号(每个节点的第1个自由度)

% ====================== 主分析循环(增量加载) ======================
for step = 1:n_steps
    fprintf('加载步 %d/%d\n', step, n_steps);
    
    % 施加位移增量(控制加载速率)
    disp_inc = total_disp / n_steps;  % 每步位移增量
    U(loaded_dof) = U(loaded_dof) + disp_inc;  % 更新加载端X方向位移
    
    % 牛顿-拉夫逊迭代(求解非线性平衡方程 F_int(U) = F_ext)
    tol = 1e-6;       % 收敛容差:残余力范数小于1e-6 MPa
    max_iter = 20;    % 最大迭代次数,防止不收敛
    residual_norm = 1; % 初始残余力范数(用于循环条件)
    iter = 0;         % 迭代计数
    
    while residual_norm > tol && iter < max_iter
        iter = iter + 1;
        
        % 初始化全局刚度矩阵(稀疏存储)和内力向量
        K_global = sparse(total_dof, total_dof);  % 切线刚度矩阵(稀疏矩阵节省内存)
        F_int = zeros(total_dof, 1);              % 内力向量(初始为零)
        
        % 遍历所有单元,组装系统矩阵
        for el = 1:n_elements
            el_nodes = elements(el, :);  % 获取当前单元8个节点编号
            
            % 映射单元节点到自由度(每个节点3个自由度,共24个自由度/单元)
            el_dof = zeros(1, 24);
            for i = 1:8
                el_dof(3*i-2:3*i) = [3*el_nodes(i)-2, 3*el_nodes(i)-1, 3*el_nodes(i)];
            end
            
            % 提取单元位移向量(24×1)
            U_el = U(el_dof);
            
            % 初始化单元刚度矩阵和内力向量
            K_el = zeros(24, 24);  % 单元切线刚度矩阵
            F_el = zeros(24, 1);   % 单元内力向量
            
            % 高斯积分循环(2×2×2积分点)
            for ix = 1:2
                xi = gauss_points(ix);  % 自然坐标ξ
                for iy = 1:2
                    eta = gauss_points(iy);  % 自然坐标η
                    for iz = 1:2
                        zeta = gauss_points(iz);  % 自然坐标ζ
                        gpt = (ix-1)*4 + (iy-1)*2 + iz;  % 积分点索引(1-8)
                        
                        % 获取形函数及其对自然坐标的导数(八节点六面体等参单元)
                        [N, dN_dxi, dN_deta, dN_dzeta] = hex8_shape(xi, eta, zeta);
                        
                        % 计算雅可比矩阵(自然坐标→物理坐标的映射)
                        J = zeros(3,3);
                        for i = 1:8
                            x = nodes(el_nodes(i), 1); % 节点X坐标
                            y = nodes(el_nodes(i), 2); % 节点Y坐标
                            z = nodes(el_nodes(i), 3); % 节点Z坐标
                            % 雅可比矩阵元素:J = ∂(x,y,z)/∂(ξ,η,ζ)
                            J(1,1) = J(1,1) + dN_dxi(i)*x;
                            J(1,2) = J(1,2) + dN_dxi(i)*y;
                            J(1,3) = J(1,3) + dN_dxi(i)*z;
                            J(2,1) = J(2,1) + dN_deta(i)*x;
                            J(2,2) = J(2,2) + dN_deta(i)*y;
                            J(2,3) = J(2,3) + dN_deta(i)*z;
                            J(3,1) = J(3,1) + dN_dzeta(i)*x;
                            J(3,2) = J(3,2) + dN_dzeta(i)*y;
                            J(3,3) = J(3,3) + dN_dzeta(i)*z;
                        end
                        detJ = det(J);  % 雅可比行列式(体积缩放因子,detJ>0保证映射有效性)
                        invJ = inv(J);  % 雅可比逆矩阵(用于导数转换)
                        
                        % 构造应变-位移矩阵B(6×24,Voigt记号)
                        B = zeros(6, 24);
                        for i = 1:8
                            % 形函数对物理坐标的导数:∇N = J⁻¹·∂N/∂(ξ,η,ζ)
                            dN_dx = invJ * [dN_dxi(i); dN_deta(i); dN_dzeta(i)]; %#ok<MINV>
                            idx = 3*i-2;  % 节点自由度起始索引(如节点1对应自由度1,2,3)
                            % 填充B矩阵(对应Voigt应变分量)
                            B(1, idx) = dN_dx(1);   % ε_xx = ∂u/∂x
                            B(2, idx+1) = dN_dx(2); % ε_yy = ∂v/∂y
                            B(3, idx+2) = dN_dx(3); % ε_zz = ∂w/∂z
                            B(4, idx) = dN_dx(2);    % γ_xy = ∂v/∂x + ∂u/∂y(Voigt记号中γ_xy=2ε_xy)
                            B(4, idx+1) = dN_dx(1);
                            B(5, idx+1) = dN_dx(3);  % γ_yz = ∂w/∂y + ∂v/∂z
                            B(5, idx+2) = dN_dx(2);
                            B(6, idx) = dN_dx(3);    % γ_zx = ∂u/∂z + ∂w/∂x
                            B(6, idx+2) = dN_dx(1);
                        end
                        
                        % 计算应变增量:Δε = B·ΔU(当前迭代的位移增量)
                        delta_epsilon = B * U_el;
                        
                        % 提取上一增量步的历史变量
                        alpha_prev = eq_plastic_strain(gpt, el);  % 等效塑性应变ε_p^eq(旧值)
                        ep_prev = plastic_strain(:, gpt, el);     % 塑性应变张量ε_p(旧值)
                        
                        % 本构积分:隐式径向返回算法(求解塑性应力状态)
                        [stress, D, alpha_new, ep_new] = ...
                            radial_return(E, nu, sigma_y0, H, delta_epsilon, alpha_prev, ep_prev);
                        
                        % 更新历史变量(用于下次迭代或增量步)
                        plastic_strain(:, gpt, el) = ep_new;  % 存储新的塑性应变张量
                        eq_plastic_strain(gpt, el) = alpha_new;  % 存储新的等效塑性应变
                        
                        % 计算积分点贡献(高斯积分权重×体积元)
                        weight = gauss_weights(ix)*gauss_weights(iy)*gauss_weights(iz)*detJ;
                        % 单元刚度矩阵积分:K_e = ∫B^T·D·B dV(通过高斯积分近似)
                        K_el = K_el + (B' * D * B) * weight;
                        % 单元内力积分:F_int_e = ∫B^T·σ dV
                        F_el = F_el + (B'
 * stress) * weight;
                    end
                end
            end
            
            % 组装到全局系统(有限元核心步骤:单元矩阵→全局矩阵)
            K_global(el_dof, el_dof) = K_global(el_dof, el_dof) + K_el; %#ok<*SPRIX>
            F_int(el_dof) = F_int(el_dof) + F_el;
        end
        
        % 计算残余力:R = F_ext - F_int(外力-内力,非线性方程残差)
        residual = F_ext - F_int;
        
        % 应用边界条件:固定自由度置零,保留自由自由度
        free_dof = setdiff(1:total_dof, fixed_dof);  % 未约束的自由度索引
        K_red = K_global(free_dof, free_dof);         % 缩减的刚度矩阵(仅自由自由度)
        residual_red = residual(free_dof);             % 缩减的残余力向量
        
        % 检查收敛性(残余力范数是否小于容差)
        residual_norm = norm(residual_red);
        fprintf('  迭代 %d: 残差 = %.4e\n', iter, residual_norm);
        
        % 求解位移增量:ΔU = K_red⁻¹·R_red(线性方程组求解,稀疏矩阵法)
        delta_U = zeros(total_dof, 1);
        delta_U(free_dof) = K_red \ residual_red;  % 使用反斜杠运算符求解线性系统
        
        % 更新位移向量(牛顿-拉夫逊迭代核心:U_{k+1} = U_k + ΔU)
        U = U + delta_U;
    end
end

% ======================== 后处理 ========================
% 绘制变形图(放大10倍便于观察小变形)
figure;
plot_deformed(nodes, elements, U);
title('变形图');
xlabel('X'); ylabel('Y'); zlabel('Z');

% 绘制等效应力云图(基于节点平均应力)
figure;
node_stress=plot_stress(nodes, elements, U, plastic_strain);
title('等效应力云图');
xlabel('X'); ylabel('Y'); zlabel('Z');

output_vtk('result.vtk', nodes, elements, U, node_stress);

fprintf('分析完成!\n');


% 生成结构化六面体网格
function [nodes, elements] = generate_mesh(Lx, Ly, Lz, nx, ny, nz)
    dx = Lx/nx; dy = Ly/ny; dz = Lz/nz;  % 单元尺寸(物理坐标间隔)
    n_nodes = (nx+1)*(ny+1)*(nz+1);      % 节点总数(每个方向节点数=单元数+1)
    nodes = zeros(n_nodes, 3);            % 节点坐标矩阵(X,Y,Z)
    elements = zeros(nx*ny*nz, 8);        % 单元拓扑矩阵(每个单元8个节点)
    
    % 生成节点坐标(规则网格,按Z-Y-X顺序排列)
    node_id = 1;
    for k = 0:nz  % Z方向循环
        for j = 0:ny  % Y方向循环
            for i = 0:nx  % X方向循环
                nodes(node_id, :) = [i*dx, j*dy, k*dz];  % 节点坐标=单元尺寸×索引
                node_id = node_id + 1;
            end
        end
    end
    
    % 生成单元连接(八节点六面体,右手法则排序)
    el_id = 1;
    for k = 1:nz  % Z方向单元循环
        for j = 1:ny  % Y方向单元循环
            for i = 1:nx  % X方向单元循环
                % 计算底层4节点和顶层4节点的全局编号
                n1 = (k-1)*(nx+1)*(ny+1) + (j-1)*(nx+1) + i;       % 底层前左
                n2 = n1 + 1;                                        % 底层前右
                n4 = (k-1)*(nx+1)*(ny+1) + j*(nx+1) + i;           % 底层后左
                n3 = n4 + 1;                                        % 底层后右
                n5 = n1 + (nx+1)*(ny+1);                           % 顶层前左
                n6 = n2 + (nx+1)*(ny+1);                           % 顶层前右
                n7 = n3 + (nx+1)*(ny+1);                           % 顶层后右
                n8 = n4 + (nx+1)*(ny+1);                           % 顶层后左
                % 存储单元节点(右手法则:底层逆时针→顶层逆时针,保证法向量一致性)
                elements(el_id, :) = [n1, n2, n3, n4, n5, n6, n7, n8];
                el_id = el_id + 1;
            end
        end
    end
end

% 八节点六面体单元的三线性形函数及其导数
function [N, dN_dxi, dN_deta, dN_dzeta] = hex8_shape(xi, eta, zeta)
    N = zeros(8,1);          % 形函数值(N1到N8)
    dN_dxi = zeros(8,1);     % 形函数对ξ的导数
    dN_deta = zeros(8,1);    % 形函数对η的导数
    dN_dzeta = zeros(8,1);   % 形函数对ζ的导数
    
    % 参考坐标系中节点坐标(标准立方体顶点,ξ,η,ζ∈{-1,1})
    xi_vec = [-1, 1, 1, -1, -1, 1, 1, -1];  % 节点1-8的ξ坐标
    eta_vec = [-1, -1, 1, 1, -1, -1, 1, 1];  % 节点η坐标
    zeta_vec = [-1, -1, -1, -1, 1, 1, 1, 1];  % 节点ζ坐标
    
    % 计算三线性形函数及其导数(N_i = (1+ξξ_i)(1+ηη_i)(1+ζζ_i)/8)
    for i = 1:8
        N(i) = (1/8)*(1+xi*xi_vec(i))*(1+eta*eta_vec(i))*(1+zeta*zeta_vec(i));
        dN_dxi(i) = (1/8)*xi_vec(i)*(1+eta*eta_vec(i))*(1+zeta*zeta_vec(i));  % ∂N_i/∂ξ
        dN_deta(i) = (1/8)*(1+xi*xi_vec(i))*eta_vec(i)*(1+zeta*zeta_vec(i));  % ∂N_i/∂η
        dN_dzeta(i) = (1/8)*(1+xi*xi_vec(i))*(1+eta*eta_vec(i))*zeta_vec(i);  % ∂N_i/∂ζ
    end
end

% J2塑性理论隐式本构积分(径向返回算法)
function [stress, D, alpha_new, ep_new] = radial_return(E, nu, sigma_y0, H, delta_epsilon, alpha_prev, ep_prev)
    % 计算弹性常数
    mu = E/(2*(1+nu));       % 剪切模量,公式:μ = E/(2(1+ν))
    lambda = E*nu/((1+nu)*(1-2*nu));  % Lamé常数,公式:λ = Eν/[(1+ν)(1-2ν)]
    
    % 弹性刚度矩阵(Voigt表示,三维弹性本构:σ = D_el·ε)
    D_el = [lambda+2*mu, lambda, lambda, 0, 0, 0;
            lambda, lambda+2*mu, lambda, 0, 0, 0;
            lambda, lambda, lambda+2*mu, 0, 0, 0;
            0,0,0,mu,0,0;
            0,0,0,0,mu,0;
            0,0,0,0,0,mu];
    
    % 弹性预测步:计算试探应力(假设当前增量步为弹性)
    stress_tr = D_el * delta_epsilon;  % 试探应力,σ_tr = D_el·Δε
    s_tr = deviatoric(stress_tr);      % 试探偏应力,s_tr = σ_tr - (trσ_tr/3)I
    sigma_tr_eq = sqrt(3/2 * (s_tr'*s_tr));  % von Mises等效应力,σ_eq = sqrt(3/2 s_tr:s_tr)
    
    % 当前屈服应力(考虑线性硬化)
    sigma_y = sigma_y0 + H*alpha_prev;  % σ_y = σ_y0 + Hε_p^eq(α_prev=ε_p^eq旧值)
    
    if sigma_tr_eq <= sigma_y  % 未屈服,弹性状态
        stress = stress_tr;          % 应力不变
        D = D_el;                   % 切线刚度为弹性刚度
        alpha_new = alpha_prev;      % 等效塑性应变不变
        ep_new = ep_prev;            % 塑性应变不变
    else  % 屈服,塑性状态
        n_tr = s_tr / sigma_tr_eq;  % 流动方向单位向量,n = s_tr/σ_tr_eq
        delta_gamma = (sigma_tr_eq - sigma_y) / (3*mu + H);  % 塑性乘子增量,Δγ = (σ_tr_eq - σ_y)/(3μ + H)
        
        % 应力修正:径向返回至屈服面,σ = σ_tr - 2μΔγ n
        stress = stress_tr - 2*mu*delta_gamma*n_tr;
        
        % 塑性应变更新,Δε_p = sqrt(3/2)Δγ n
        delta_ep = delta_gamma * sqrt(3/2) * n_tr;
        ep_new = ep_prev + delta_ep;  % 累积塑性应变
        alpha_new = alpha_prev + delta_gamma;  % 累积等效塑性应变
        
        % 计算一致切线模量(保证牛顿法二次收敛)
        theta = 1 - 3*mu*delta_gamma/sigma_tr_eq;  % 修正参数
        theta_bar = 1 / (1 + H/(3*mu)) - (1 - theta);  % 偏量部分修正参数
        I_dev = diag([1,1,1,0.5,0.5,0.5]) - [1;1;1;0;0;0]*[1,1,1,0,0,0]/3;  % 偏量投影算子,I_dev = I - (1/3)1⊗1
        
        % 切线刚度矩阵,D = D_el - 2μ[θ_bar(n⊗n) + θ(I_dev - n⊗n)]
        D = D_el - 2*mu*theta_bar*(n_tr*n_tr'
) - 2*mu*theta*(I_dev - n_tr*n_tr');
    end
end

% 计算应力张量的偏应力部分
function s = deviatoric(sigma)
    p = (sigma(1) + sigma(2) + sigma(3)) / 3;  % 静水压力,公式:p = (σ_xx + σ_yy + σ_zz)/3
    s = sigma;  % 复 制应力张量
    s(1:3) = s(1:3) - p;  % 正应力分量减去静水压力,得到偏应力分量
    % 剪应力分量不变(剪应力天然属于偏量部分)
end

% 绘制变形后的三维模型
function plot_deformed(nodes, elements, U)
    scale = 10;  % 变形放大系数,便于观察小变形(实际位移×scale)
    
    % 提取各方向位移分量(按自由度顺序)
    Ux = U(1:3:end);  % X方向位移
    Uy = U(2:3:end);  % Y方向位移
    Uz = U(3:3:end);  % Z方向位移
    
    % 计算变形后节点坐标:原始坐标 + 放大后位移
    deformed_nodes = nodes + scale * [Ux, Uy, Uz];
    
    % 绘制六面体单元(每个单元6个面)
    for el = 1:size(elements,1)
        el_nodes = elements(el,:);  % 单元节点编号
        X = deformed_nodes(el_nodes,1);  % 变形后X坐标
        Y = deformed_nodes(el_nodes,2);  % 变形后Y坐标
        Z = deformed_nodes(el_nodes,3);  % 变形后Z坐标
        
        % 六面体的6个面(右手法则定义顶点顺序,保证法向量一致性)
        faces = [1,2,3,4; 5,6,7,8; 1,2,6,5; 2,3,7,6; 3,4,8,7; 4,1,5,8];
        for f = 1:6
            % 绘制半透明面片(FaceAlpha=0.1)
            patch(X(faces(f,:)), Y(faces(f,:)), Z(faces(f,:)), '
b', 'FaceAlpha', 0.1);
        end
    end
    
    axis equal;  % 等比例显示坐标轴,避免图形变形
    grid on;     % 显示网格线辅助观察
    view(3);     % 切换至三维视角
end

% 绘制节点平均等效应力云图,并返回节点等效应力
function node_stress = plot_stress(nodes, elements, U, plastic_strain)
    n_nodes = size(nodes, 1);  % 节点总数
    node_stress = zeros(n_nodes, 1);  % 节点等效应力(初始为零)
    node_count = zeros(n_nodes, 1);   % 每个节点的积分点贡献计数

    % 遍历所有单元和积分点,插值应力到节点(单元平均法)
    for el = 1:size(elements,1)
        for gpt = 1:8
            % 取该积分点的塑性应变张量
            ep = plastic_strain(:,gpt,el);
            % 计算von Mises等效应力
            seq = sqrt( (ep(1)-ep(2))^2 + (ep(2)-ep(3))^2 + (ep(3)-ep(1))^2 ...
                + 6*(ep(4)^2 + ep(5)^2 + ep(6)^2) ) / sqrt(2);
            % 将积分点应力累加到所属节点(8个节点/单元)
            for i = 1:8
                n = elements(el,i);  % 节点编号
                node_stress(n) = node_stress(n) + seq;
                node_count(n) = node_count(n) + 1;
            end
        end
    end

    % 计算节点平均应力(总应力/贡献积分点数)
    node_stress = node_stress ./ max(node_count,1);

    % 计算变形后坐标(放大显示位移场)
    Ux = U(1:3:end);
    Uy = U(2:3:end);
    Uz = U(3:3:end);
    deformed_nodes = nodes + 10 * [Ux, Uy, Uz];

    % 绘制应力云图(散点图,颜色映射应力大小,点大小50)
    scatter3(deformed_nodes(:,1), deformed_nodes(:,2), deformed_nodes(:,3), ...
        50, node_stress, '
filled');
    colorbar;  % 显示颜色标尺
    title('
等效应力分布');
    axis equal;  % 等比例坐标轴
    grid on;     % 显示网格
    view(3);     % 三维视角
end


% VTK导出函数(支持八节点六面体单元和节点标量)
function output_vtk(filename, nodes, elements, U, node_stress)
    % 变形后节点坐标(放大10倍)
    scale = 10;
    Ux = U(1:3:end);
    Uy = U(2:3:end);
    Uz = U(3:3:end);
    deformed_nodes = nodes + scale * [Ux, Uy, Uz];

    n_nodes = size(nodes,1);
    n_elements = size(elements,1);

    fid = fopen(filename, '
w');
    fprintf(fid, '
# vtk DataFile Version 3.0\n');
    fprintf(fid, 'ElasPlastic result\n');
    fprintf(fid, 'ASCII\n');
    fprintf(fid, 'DATASET UNSTRUCTURED_GRID\n');
    % 节点坐标
    fprintf(fid, 'POINTS %d float\n', n_nodes);
    for i = 1:n_nodes
        fprintf(fid, '%f %f %f\n', deformed_nodes(i,1), deformed_nodes(i,2), deformed_nodes(i,3));
    end
    % 单元连接
    fprintf(fid, 'CELLS %d %d\n', n_elements, n_elements*9);
    for i = 1:n_elements
        % VTK八节点六面体单元类型,节点编号从0开始
        fprintf(fid, '8 %d %d %d %d %d %d %d %d\n', elements(i,:)-1);
    end
    % 单元类型
    fprintf(fid, 'CELL_TYPES %d\n', n_elements);
    for i = 1:n_elements
        fprintf(fid, '%d\n', 12); % 12=VTK_HEXAHEDRON
    end
    % 节点标量(等效应力)
    fprintf(fid, 'POINT_DATA %d\n', n_nodes);
    fprintf(fid, 'SCALARS von_mises float 1\n');
    fprintf(fid, 'LOOKUP_TABLE default\n');
    for i = 1:n_nodes
        fprintf(fid, '%f\n', node_stress(i));
    end
    fclose(fid);
    fprintf('VTK文件已导出: %s\n', filename);
end



来源:有限元先生
DeformSTEPS非线性UM理论材料控制ParaView
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2025-06-27
最近编辑:1年前
外太空土豆儿
博士 我们穷极一生,究竟在追寻什么?
获赞 46粉丝 48文章 123课程 0
点赞
收藏
作者推荐

由四节点单元构造八节点单元形函数

概述  本次帖子在前面帖子的基础上构造高阶的四边形单元,首先四边形每条边的中间布置一个节点,并确定该节点的形函数,然后再根据形函数的性质对四边形四个角点的形函数进行修正。帖子采用图示的方式对构造形函数的每一步进行详解,有限元书里面省略的内容我都会一一呈现。线性四边形单元形函数回顾  前文已经通过拉格朗日插值法构造了线性四边形单元的形函数,下面是四边形单元的图示  上面每个节点对应的形函数为   注意,右上角的星号是为了将线性四节点单元的形函数和二阶四边形单元的形函数进行区别,这一篇帖子重点讲解二阶四边形单元形函数的构造,所以将二阶单元的形函数用 来表示。构造二阶四边形单元  有限元中的单元形式多种多样,从节点数量和布置的角度看,有的但与那只是在角点处布置了节点,这种单元形式一般为线性单元,但是线性单元无法近似曲边或者曲面,因此有的单元边的中间位置也布置了若干个节点,但并不是所有的单元边中间位置都布置了节点,有的只有一部分边布置了节点。  这里效仿之前的帖子,还是先把二阶四边形单元的形状给出来  上图中,四个角点的编号与线性单元相同,二阶单元又在每个边的中间位置设置了一个点,即图中红色点。四个角点和四个边中点分别按照逆时针排列。  下面开始从边中点开始构造二阶四边形单元。  这里以5号节点为例,首先构造5号节点的形函数。我们知道形函数需要满足在当前节点数值为1,其余节点数值为0的条件。因此,考虑到5号内节点的位置和g方向上面的二次关系,可以将5号节点的形函数设置为   5号节点的坐标为 ,上述形函数满足在5号节点数值为0的条件。  但是,节点1和2的形函数在节点5的数值就不是0了,因此需要对节点1和2位置的形函数进行修正。首先修正1号节点的形函数,假如不修正的话,1号节点在节点5处的取值示意图为  上图说明,如果不修正,1号节点形函数在5号节点的数值为 ,不满足其余节点数值为0的条件,因此必须修正,1号节点在5号的取值要减掉 即   修正之后,将节点5的坐标 代入到节点1的形函数 中为   因为边152为二次,修正后的示意图为  修正后节点1的形函数在节点   同样的道理,共用节点1的边除了边152,还有184,这时我们将节点8的坐标 代入到修正后的节点1的形函数为   我们发现修正后,节点1的形函数在8处仍然不等于0,这说明还需要继续修正,我们可以仿照将节点5的形函数 引入到节点1形函数的方式,将节点8的形函数 引入到节点1的形函数。  首先需要写出节点8的形函数,对比节点5的形函数,不难写出节点8的形函数为   如果没有将节点8的形函数引入到节点1形函数,那么节点1的形函数在节点8的取值示意图为  下面将这个 给减掉,即   下面进行验证,将节点8的坐标代入到经过本次修正后的节点1的形函数   说明这次修正之后,节点1满足了在其余节点数值为0的条件,经过本次修正后,节点1形函数在节点8和5的取值示意图为  经过两次修正以后,发现边152和边184均保证了形函数的二次性质,同样的道理可以写出所有的形函数为 总结  帖子在线性四节点单元的基础上,依据形函数的性质构造了二阶四边形单元,即八节点四边形单元的形函数。对其中的计算过程进行了详细的解释,书里面省略的基础性的推导本体帖子均给出详细过程。来源:有限元先生

未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习计划 福利任务
下载APP
联系我们
帮助与反馈