Code Word
Code Word
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%
% Author: Philip Moseley
% [email protected]
%
% Usage: Calculates the dynamic FE response to a 2d system under load.
% Assumes plane strain, and uses XFEM to model discontinuities
% in the system without remeshing.
%
% License: Academic Free License v3.0. You may modify and distribute
% the code as you please, as long as you maintain the
% attribution notices.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%
old_path = path; addpath(genpath('.'));
%------------------------Input--------------------------
%----- General Options.
E = 144; % Elastic modulus.
nu = 0.18; % Poisson's ratio.
rho = 11.3751; % Density.
steps = 500; % Number of simulation steps.
os = 5; % Output steps (how often to plot).
fig.scale = 1.0e0; % Factor to visibly scale the displaced mesh.
fig.xfem = false; % Plot the XFEM surfaces.
fig.ref = true; % Plot reference mesh underneath displaced mesh.
% Load optional user input file. Should be a struct with fields for changed inputs, i.e.,
% ui.dt = 0.001; xfem_explicit(ui);
if(size(varargin,2)==1)
names = fieldnames(varargin{1});
for i = 1:length(names)
eval([names{i}, ' = varargin{1}.(names{i});']);
end
end
%-----------------------Prepare-------------------------
domain = create_domain(mesh,false,false,false);
FEM = engine_fem(E,nu,rho);
LS = engine_ls();
% Space integrator.
SINT = engine_quadrature(FEM,ngp,subint_tri,tri_ngp,1);
% Time integrator.
if(tint_type==0)
TINT = engine_velocity_verlet();
fig.title = 'Velocity Verlet';
else
TINT = engine_newmark_beta();
fig.title = 'Newmark-Beta';
end
%----------------------Calculate------------------------
for(s=1:steps)
% Update positions.
domain = TINT.pre(domain,dt);
domain.xfem = TINT.pre(domain.xfem,dt); %TINT và pre trong file engine_newmark_beta và
engine_velocity_verlet vì tint_type = 0 nên chọn TINT = engine_velocity_verlet();
% Integrate the forces over each element.
for(e=1:domain.ne)
element = domain.element(e);
X = domain.gather(domain.X,e);
f = 0.0; Q = 0.0;
for(q=1:length(element.gp))
x = element.gp(q,:);
[F,dNdX,dPdX] = FEM.deformation_gradient(domain,e,x); % trong engine_fem
S = element.gw(q) * det(FEM.J(element,X,x)) * FEM.PK2(F);
f = f-reshape_voigt(S * FEM.B0(element,F,dNdX));
if(element.xfem)
Q = Q-reshape_voigt(S * FEM.B0(element,F,dPdX));
end
end
% Scatter into the full matrices.
domain.a1 = domain.scatter(domain.a1,f,e);
if(element.xfem)
domain.xfem.a1 = domain.scatter(domain.xfem.a1,Q,e);
end
end
% Calculate the accelerations from forces.
forces_to_accels();
% Update velocities.
domain = TINT.post(domain,dt);
domain.xfem = TINT.post(domain.xfem,dt);
% Apply the boundary conditions.
domain = apply_bcs(domain,bc,fig,false,0.0);
% Plot the results live.
if(mod(s,os)==0)
plot_disp_mesh(domain,bc,crack,fig);
end
end
path(old_path);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
% Helper Functions.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
% Convert forces to accelerations.
function forces_to_accels()
if(mass_type==1)
% Consistent mass matrix.
accels = domain.inv_mass * [domain.a1; domain.xfem.a1];
domain.a1 = accels(1:size(accels,1)/2,:);
domain.xfem.a1 = accels(size(accels,1)/2+1:end,:);
elseif(mass_type==0 || mass_type==2)
% Diagonalized mass matrices.
for(i=1:size(domain.a1,1))
for(j=1:size(domain.a1,2))
domain.a1(i,j) = domain.a1(i,j)*domain.inv_mass(i);
domain.xfem.a1(i,j) = domain.xfem.a1(i,j)*domain.xfem.inv_mass(i);
end;end;end;end
[MUU,MUQ,MQQ] = FEM.mass_matrices(domain,true,true);
if(ignore_muq)
M = [sum(MUU,2); sum(MQQ,2)];
else
M = [sum(MUU,2)+sum(MUQ,2); sum(MQQ,2)+sum(MUQ',2)];
end
invM = 1.0./M;
end
end