📄 center_crack.m
字号:
% *************************************************************************
% TWO DIMENSIONAL ELEMENT FREE GALERKIN CODE
% Nguyen Vinh Phu
% LTDS, ENISE, Juillet 2006
% *************************************************************************
% Description:
% This is a simple Matlab code of the EFG method which is the most familiar
% meshless methods using MLS approximation and Galerkin procedure to derive
% the discrete equations.
% Domain of influence can be : (1) circle and (2) rectangle
% Weight function : cubic or quartic spline function
% Nodes can be uniformly distributed nodes or randomly distributed
% (in the latter case, this is read from a finite element mesh file)
% Numerical integration is done with background mesh
% Essential boundary condition is imposed using Lagrange multipliers or
% penalty method.
% In case of Lagrange multipliers, but use the Dirac delta function to
% approximate lamda, we obtain the boundary point collocation method
% For fracture mechanics, the enriched EFG is used. This is a local PUM
% enrichment scheme which has the form:
%
% u = N_i * u_i + N_j * H(x) * a_j + N_k * (B_i * b_ik)
% with H(x) / Heaviside function and B_i(x) the branch functions
% u_i, a_j and B_ik are nodal parameters.
% External utilities: the mesh, post processing is done with the Matlab
% code of Northwestern university, Illinois, USA
% *************************************************************************
% Problem: the infinite plate with centered crack under tension
% +++++++++++++++++++++++++++++++++++++
% PROBLEM INPUT DATA
% +++++++++++++++++++++++++++++++++++++
clear all
clc
state = 0;
tic; % help us to see the time required for each step
% Dimension of the domain (it is simply a rectangular region L x W)
D = 10 ;
L = 10 ;
% Material properties
E = 1e7 ;
nu = 0.3 ;
stressState='PLANE_STRAIN';
% Loading
sigmato = 1e4 ;
% Crack data
a = 5 ; % modeled crack length
cracklength=100; % real crack length
xCr = [0 D/2; a D/2];
xTip = [a D/2];
seg = xCr(2,:) - xCr(1,:); % tip segment
alpha = atan2(seg(2),seg(1)); % inclination angle
QT=[cos(alpha) sin(alpha); -sin(alpha) cos(alpha)];
% Inputs special to meshless methods, domain of influence
shape = 'circle' ; % shape of domain of influence
dmax = 1.7 ; % radius = dmax * nodal spacing
form = 'cubic_spline' ; % using cubic spline weight function
% Choose method to impose essential boundary condition
% disp_bc_method = 1 : Lagrange multiplier method
% disp_bc_method = 2 : Penalty method
disp_bc_method = 1 ;
% If Lagrange multiplier is used, choose approximation to be used for lamda
% la_approx = 100 ; % using finite element approximation
% la_approx = 200 ; % using point collocation method
if disp_bc_method == 1
la_approx = 200 ;
end
% If penalty function is used, then choose "smart" penalty number :-)
if disp_bc_method == 2
alpha = 1e7 ; % penalty number
end
% +++++++++++++++++++++++++++++++++++++
% NODE GENERATION
% +++++++++++++++++++++++++++++++++++++
% Steps:
% 1. Node coordinates
% 2. Nodes' weight function including : shape (circle or rectangle), size
% and form (quartic spline or the other)
disp([num2str(toc),' NODE GENERATION'])
% Node density defined by number of nodes along two directions
nnx = 20 ;
nny = 20 ;
% node generation, node is of size (nnode x 2)
% Corner points of the rectangle domain
pt1 = [0 0];
pt2 = [D 0];
pt3 = [D L];
pt4 = [0 L];
node = square_node_array(pt1,pt2,pt3,pt4,nnx,nny);
numnode = size(node,1);
% Define boundaries
% Bottom, right and top edges are imposed by exact displacement
uln=nnx*(nny-1)+1; % upper left node number
urn=nnx*nny; % upper right node number
lrn=nnx; % lower right node number
lln=1; % lower left node number
cln=nnx*(nny-1)/2+1; % node number at (0,0)
rightEdge= [ lrn:nnx:(uln-1); (lrn+nnx):nnx:urn ]';
leftEdge = [ uln:-nnx:(lrn+1); (uln-nnx):-nnx:1 ]';
topEdge = [ uln:1:(urn-1); (uln+1):1:urn ]';
botEdge = [ lln:1:(lrn-1); (lln+1):1:lrn ]';
% get nodes on essential boundaries
botNodes = unique(botEdge);
rightNodes = unique(rightEdge);
topNodes = unique(topEdge);
leftNodes = unique(leftEdge);
disp_nodes = [botNodes ; rightNodes; topNodes];
disp_nodes = unique(disp_nodes);
num_disp_nodes = length(disp_nodes);
% Domain of influence for every nodes
% Uniformly distributed nodes
% Definition : rad = dmax*max(deltaX,deltaY)
% deltaX,deltaY are nodal spacing along x,y directions
deltaX = L/(nnx-1);
deltaY = D/(nny-1);
delta = max(deltaX,deltaY);
di = ones(1,numnode)*dmax*delta ;
% +++++++++++++++++++++++++++++++++++++
% GAUSS POINTS
% +++++++++++++++++++++++++++++++++++++
% Steps:
% 1. Mesh generation using available meshing algorithm of FEM
% 2. Using isoparametric mapping to transform Gauss points defined in each
% element (background element) to global coordinates
disp([num2str(toc),' BUILD GAUSS POINT FOR DOMAIN '])
% Meshing, Q4 elements
inc_u = 1;
inc_v = nnx;
node_pattern = [ 1 2 nnx+2 nnx+1 ];
element = make_elem(node_pattern,nnx-1,nny-1,inc_u,inc_v);
% Building Gauss points
[w,q]=quadrature(6, 'GAUSS', 2 ); % 4x4 Gaussian quadrature for each cell
W = [];
Q = [];
J = [];
for e = 1 : size(element,1) % element loop
sctr=element(e,:); % element scatter vector
for i = 1:size(w,1) % quadrature loop
pt=q(i,:); % quadrature point
wt=w(i); % quadrature weight
[N,dNdxi]=lagrange_basis('Q4',pt); % Q4 shape functions
J0=node(sctr,:)'*dNdxi; % element Jacobian matrix
Q = [Q; N' * node(sctr,:)]; % global Gauss point
W = [W; wt]; % global Gauss point
J = [J; det(J0)];
end
end
clear w,q ;
% +++++++++++++++++++++++++++++++++++++
% LEVEL SET INITIALIZATION
% SELECTION OF ENRICHED NODES
% +++++++++++++++++++++++++++++++++++++
% Only normal level sets are computed and stored in nodes
x0 = xCr(1,1); y0 = xCr(1,2);
x1 = xCr(2,1); y1 = xCr(2,2);
t = 1/norm(seg)*seg;
for i = 1 : numnode
x = node(i,1);
y = node(i,2);
l = sqrt((x1-x0)*(x1-x0)+(y1-y0)*(y1-y0)) ;
phi = (y0-y1)*x + (x1-x0)*y + (x0*y1-x1*y0);
ls(i,1) = phi/l; % normal LS
ls(i,2) = ([x y]-xTip)*t'; % tangent LS
dt(i) = norm([x y]-xTip); % distances from node I to tip
end
set1 = find(abs(ls(:,1)) - di' < 0);
set2 = find(ls(:,2) < 0);
set3 = find(dt - di < 0); % tip nodes
set4 = intersect(set1,set2); % split nodes
% some nodes belong to both sets, remove tip
split_nodes = setdiff(set4,set3);
tip_nodes = set3;
% +++++++++++++++++++++++++++++++++++++
% PLOT NODES,BACKGROUND MESH, GPOINTS
% +++++++++++++++++++++++++++++++++++++
disp([num2str(toc),' PLOT NODES AND GAUSS POINTS'])
figure
hold on
cntr = plot([0,L,L,0,0],[0,0,D,D,0]);
set(cntr,'LineWidth',3)
h = plot(node(:,1),node(:,2),'bo');
set(h,'MarkerSize',8.5);
cr = plot(xCr(:,1),xCr(:,2),'r-');
set(cr,'LineWidth',3)
n1 = plot(node(split_nodes,1),node(split_nodes,2),'r*');
n2 = plot(node(tip_nodes,1),node(tip_nodes,2),'rh');
set(n1,'MarkerSize',15);
set(n2,'MarkerSize',15);
plot(node(disp_nodes,1),node(disp_nodes,2),'ks');
axis equal
axis off
theta = -pi:0.1:pi;
for i = 1 : size(split_nodes',1)
a = di(i); % radius of support
x = node(split_nodes(i),1) + a*cos(theta);
y = node(split_nodes(i),2) + a*sin(theta);
cir = plot(x,y,'k-');
end
for i = 1 : size(set3',1)
a = di(i); % radius of support
x = node(set3(i),1) + a*cos(theta);
y = node(set3(i),2) + a*sin(theta);
cir = plot(x,y,'r.-');
end
figure
hold on
cntr = plot([0,L,L,0,0],[0,0,D,D,0]);
set(cntr,'LineWidth',3)
plot_mesh(node,element,'Q4','--');
plot(Q(:,1),Q(:,2),'r*');
cr = plot(xCr(:,1),xCr(:,2),'r-');
set(cr,'LineWidth',3)
axis off
% +++++++++++++++++++++++++++++++++++++
% DOMAIN ASSEMBLY
% +++++++++++++++++++++++++++++++++++++
disp([num2str(toc),' DOMAIN ASSEMBLY'])
% Initialisation
total_num_node = numnode + size(split_nodes,2)*1 + size(tip_nodes,2)*4 ;
K = sparse(2*total_num_node,2*total_num_node);
f = zeros(2*total_num_node,1);
if ( strcmp(stressState,'PLANE_STRESS') )
C=E/(1-nu^2)*[ 1 nu 0;
nu 1 0 ;
0 0 0.5*(1-nu) ];
else
C=E/(1+nu)/(1-2*nu)*[ 1-nu nu 0;
nu 1-nu 0;
0 0 0.5-nu ];
end
% Due to the presence of additional dofs, the assembly is a little
% bit difficult than in FEM. We use fictitious nodes to handle these
% additional dofs. At a H(x) enriched node, we add one fantom node and
% at tip enriched node, four fantom nodes are added. These fictitious nodes
% are numbered from the total number of true nodes, ie, from numnode+1 ...
pos = zeros(numnode,1);
nsnode = 0 ;
ntnode = 0 ;
for i = 1 : numnode
[snode] = ismember(i,split_nodes);
[tnode] = ismember(i,tip_nodes);
if (snode ~= 0)
pos(i) = (numnode + nsnode*1 + ntnode*4) + 1 ;
nsnode = nsnode + 1 ;
elseif (tnode ~= 0)
pos(i) = (numnode + nsnode*1 + ntnode*4) + 1 ;
ntnode = ntnode + 1 ;
end
end
% --------------------------
% Loop on Gauss points
% --------------------------
for igp = 1 : size(W,1)
pt = Q(igp,:); % quadrature point
% ----------------------------------------------
% find nodes in neighbouring of Gauss point pt
% ----------------------------------------------
[index] = define_support(node,pt,di);
% For enriched EFG, here is the most important part
% Nodes within neighbouring of GPs include normal nodes, H enriched
% nodes and tip enriched nodes
% ISMEMBER(A,S) for the array A returns an array of the same size as A
% containing 1 where the elements of A are in the set S and 0 otherwise.
[sctrB,snode,tnode] = assembly(index,split_nodes,tip_nodes,...
pos);
% compute B matrix
B = Bmatrix(pt,index,node,di,form,...
snode,tnode,xCr,xTip,alpha);
% Then K matrix
K(sctrB,sctrB) = K(sctrB,sctrB) + B'*C*B * W(igp)*J(igp) ;
end % end of loop on Gauss Points
% +++++++++++++++++++++++++++++++++++++
% INTEGRATE ON TRACTION BOUNDARY
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -