A thin rectangular plate under a uniaxial tension has a uniform stress distribution. Introducing a circular hole in the plate disturbs the uniform stress distribution near the hole, resulting in a significantly higher than average stress. Such a thin plate, subject to in-plane loading, can be analyzed as a 2-D plane-stress elasticity problem. In theory, if the plate is infinite, then the stress near the hole is three times higher than the average stress. For a rectangular plate of finite width, the stress concentration factor is a function of the ratio of hole diameter to the plate width. This example approximates the stress concentration factor using a plate of a finite width.
R=solve(model);maxUxPDE=max(R.Displacement.ux);maxVonMisesStressPDE=max(R.VonMisesStress);maxSxxPDE=max(R.Stress.sxx);figurepdeplot(R.Mesh,XYData=R.Displacement.ux,...ColorMap="jet")axisequaltitle("Displacement Along x-Direction")
12345
figurepdeplot(R.Mesh,XYData=R.Stress.sxx,...ColorMap="jet")axisequaltitle("Normal Stress Along x-Direction")
mesh=model.Mesh;% PDE mesh% Nodes : 2 x nNode% Elements : 3 x nElemnodes=mesh.Nodes.';% nNode x 2elems=mesh.Elements.';% nElem x 3nNode=size(nodes,1);nElem=size(elems,1);ifsize(elems,2)~=3error('This conversion script expects a linear triangular mesh.');end%% ------------------------------------------------------------------------% 3) Identify boundary entities from PDE labels%% ------------------------------------------------------------------------loadEdgeID=2;fixEdgeID=4;fixVertexID=1;loadNodeIDs=unique(findNodes(mesh,"region","Edge",loadEdgeID));fixEdgeNodes=unique(findNodes(mesh,"region","Edge",fixEdgeID));fixVertNodes=unique(findNodes(mesh,"region","Vertex",fixVertexID));loadNodeIDs=loadNodeIDs(:);fixEdgeNodes=fixEdgeNodes(:);fixVertNodes=fixVertNodes(:);%% ------------------------------------------------------------------------% 4) Build boundary segments on the loaded edge%% ------------------------------------------------------------------------TR=triangulation(elems,nodes);bedges=freeBoundary(TR);% nb x 2 boundary node pairsisLoadSeg=all(ismember(bedges,loadNodeIDs.'),2);loadSegs=bedges(isLoadSeg,:);ifisempty(loadSegs)warning('No boundary segments found on PDE edge %d.',loadEdgeID);end%% ------------------------------------------------------------------------% 5) Convert edge traction to equivalent nodal loads%% For a 2-node linear boundary segment:% f_e = \int N^T t * thk ds% For constant traction:% f_e = (L*thk/2) * [tx; ty; tx; ty]%% ------------------------------------------------------------------------thickness=1;% choose consistent thickness for Tri31traction=[100;0];% same as PDE edge loadnodalLoads=zeros(nNode,2);fori=1:size(loadSegs,1)s=loadSegs(i,:);x1=nodes(s(1),:);x2=nodes(s(2),:);L=norm(x2-x1);fe=(L*thickness/2)*[traction(:);traction(:)];% 4x1nodalLoads(s(1),:)=nodalLoads(s(1),:)+fe(1:2).';nodalLoads(s(2),:)=nodalLoads(s(2),:)+fe(3:4).';end
opsMAT=OpenSeesMatlab();ops=opsMAT.opensees;ops.wipe();ops.model('basic','-ndm',2,'-ndf',2);% Nodesfori=1:nNodeops.node(i,nodes(i,1),nodes(i,2));end% Material + elementsmatTag=1;type2D='PlaneStress';ops.nDMaterial('ElasticIsotropic',matTag,E,nu);fore=1:nElemn=elems(e,:);ops.element('Tri31',e,n(1),n(2),n(3),thickness,type2D,matTag);end
Output
[OpenSees] Tri31 - Written by Roozbeh G. Mikola and N.Sitar, UC Berkeley
%% ------------------------------------------------------------------------% 7) Boundary conditions%% EdgeBC(4): XDisplacement = 0 -> fix ux on all nodes of edge 4% VertexBC(1): YDisplacement = 0 -> fix uy on node(s) of vertex 1%% ------------------------------------------------------------------------fixX=false(nNode,1);fixY=false(nNode,1);fixX(fixEdgeNodes)=true;fixY(fixVertNodes)=true;fori=1:nNodeiffixX(i)||fixY(i)ops.fix(i,double(fixX(i)),double(fixY(i)));endend%% ------------------------------------------------------------------------% 8) Loads%% ------------------------------------------------------------------------ops.timeSeries('Linear',1);ops.pattern('Plain',1,1);tol=0;fori=1:nNodefx=nodalLoads(i,1);fy=nodalLoads(i,2);ifabs(fx)>tol||abs(fy)>tolops.load(i,fx,fy);endend
1 2 3 4 5 6 7 8 9101112131415
%% ------------------------------------------------------------------------% 9) Static analysis%% ------------------------------------------------------------------------ops.constraints('Plain');ops.numberer('RCM');ops.system('BandGeneral');ops.test('NormDispIncr',1e-8,50);ops.algorithm('Newton');ops.integrator('LoadControl',1/2);ops.analysis('Static');ODB=opsMAT.post.createODB("myODB");% create ODBok=ops.analyze(2);% Auto record results to ODBODB.close();% close when you want to stop recorder
[OpenSeesMatlab] Model summary
Nodes: 4072
Plane elements: 7808
1234567
nodeResp=opsMAT.post.getNodalResponse("myODB");ux=nodeResp.disp.ux;maxUx=max(ux(:));fprintf("Maximal deflection in the x-direction:\n"+..." OpenSeesMatlab: %g meters\n"+..." MATLAB PDE : %g meters\n",...maxUx,maxUxPDE);
Output
Maximal deflection in the x-direction:
OpenSeesMatlab: 0.222333 meters
MATLAB PDE : 0.222333 meters
1 2 3 4 5 6 7 8 910
opts=opsMAT.vis.defaultPlotNodalResponseOptions;opts.fixed.show=false;opts.surf.showEdges=false;opts.deform.show=false;opsMAT.vis.plotNodalResponse(nodeResp,respType="disp",stepIdx="absMax",respComponent="UX",opts=opts);colormap("jet")axisofftitle("Displacement Along x-Direction")
Maximal Von Mises stress:
OpenSeesMatlab: 317.613 Pa
MATLAB PDE : 317.613 Pa
1 2 3 4 5 6 7 8 91011
opts=opsMAT.vis.defaultPlotContinuumResponseOptions;opts.fixed.show=false;opts.surf.showEdges=false;opts.deform.show=false;opsMAT.vis.plotContinuumResponse(planeResp,...respType="StressMeasureAtNode",respComponent="sxx",opts=opts);axisequalcolormap("jet")title("Normal Stress Along x-Direction")