This live script is written as a guided walkthrough for a verification benchmark. It compares a known structural response with the result produced by the OpenSeesMatlab workflow. Read the text cells first, then run each code cell in order so that the variables, model state, and recorded results are available for the later sections.
This example shows how to analyze a 3-D mechanical part under an applied load using the finite element analysis model and determine the maximal deflection.
The following commands carry out this step of the workflow. Run this cell after the previous sections so the required variables and model state already exist.
1
clc;clear;
Output
[OpenSeesMatlab] [EXCEPTION] Polyscope has not been initialized
1 2 3 4 5 6 7 8 9101112131415161718
E=200e9;nu=0.3;rho=0.0;model=femodel(AnalysisType="structuralStatic",...Geometry="BracketWithHole.stl");model.MaterialProperties=materialProperties(...YoungsModulus=E,...PoissonsRatio=nu);model.FaceBC(4)=faceBC(Constraint="fixed");model.FaceLoad(8)=faceLoad(SurfaceTraction=[0;0;-1e4]);figurepdegplot(model,FaceLabels="on");view(30,30);title("Bracket with Face Labels")
12345
pdeModel=generateMesh(model,GeometricOrder="linear");figurepdemesh(pdeModel);title("Mesh with Linear Tetrahedral Elements")
123
result=solve(pdeModel);minUzPDE=min(result.Displacement.uz);fprintf("Maximal deflection in the z-direction is %g meters.",minUzPDE)
Output
Maximal deflection in the z-direction is -1.44604e-05 meters.
mesh=pdeModel.Mesh;% PDE toolbox:% mesh.Nodes : 3 x nNode% mesh.Elements : nNodePerElem x nElemnodes=mesh.Nodes.';% nNode x 3elems=mesh.Elements.';% nElem x nennNode=size(nodes,1);nElem=size(elems,1);nen=size(elems,2);ifnen~=4error(['This script currently expects linear 4-node tetrahedra. ',...'Please use generateMesh(..., GeometricOrder="linear").']);end%% ------------------------------------------------------------------------% Find face nodes for fixed boundary and loaded boundary%% ------------------------------------------------------------------------fixedFaceID=4;loadedFaceID=8;traction=[0;0;-1e4];% N/m^2fixedNodeIDs=findNodes(mesh,"region","Face",fixedFaceID);loadNodeIDs=findNodes(mesh,"region","Face",loadedFaceID);fixedNodeIDs=unique(fixedNodeIDs(:));loadNodeIDs=unique(loadNodeIDs(:));%% ------------------------------------------------------------------------% Build boundary triangles on the loaded face and convert traction% to equivalent nodal loads%% ------------------------------------------------------------------------% For a tetra mesh, each tetra has 4 triangular faces.% Boundary faces are those triangle faces that appear only once.allBoundaryTris=getBoundaryTrianglesFromTets(elems);% Keep only boundary triangles whose 3 nodes are all on Face 8isOnLoadFace=all(ismember(allBoundaryTris,loadNodeIDs.'),2);loadFaceTris=allBoundaryTris(isOnLoadFace,:);ifisempty(loadFaceTris)warning('No boundary triangles were found on loaded Face %d.',loadedFaceID);end% Assemble nodal force vector from surface tractionnodalLoads=zeros(nNode,3);fori=1:size(loadFaceTris,1)tri=loadFaceTris(i,:);xyz=nodes(tri,:);% 3 x 3A=triangleArea3D(xyz);% Constant traction on linear triangle:% equivalent nodal load = traction * A / 3 for each of 3 nodesfe=(A/3)*traction(:);% 3 x 1 for one nodenodalLoads(tri,:)=nodalLoads(tri,:)+repmat(fe.',3,1);end
The following commands carry out this step of the workflow. Run this cell after the previous sections so the required variables and model state already exist.
123
%% ------------------------------------------------------------------------% Local functions%% ------------------------------------------------------------------------
functionbtris=getBoundaryTrianglesFromTets(tets)%GETBOUNDARYTRIANGLESFROMTETS Return unique boundary triangle faces% tets: nElem x 4f1=tets(:,[123]);f2=tets(:,[124]);f3=tets(:,[134]);f4=tets(:,[234]);allFaces=[f1;f2;f3;f4];allFacesSorted=sort(allFaces,2);[uFaces,~,ic]=unique(allFacesSorted,'rows');counts=accumarray(ic,1);isBoundary=counts(ic)==1;boundaryFacesSorted=allFacesSorted(isBoundary,:);% Keep orientation-free representationbtris=boundaryFacesSorted;endfunctionA=triangleArea3D(xyz)%TRIANGLEAREA3D Area of a 3D triangle% xyz: 3 x 3, each row is one node coordinatev1=xyz(2,:)-xyz(1,:);v2=xyz(3,:)-xyz(1,:);A=0.5*norm(cross(v1,v2));end