0% found this document useful (0 votes)
12 views

Code Word

Uploaded by

kiet.phamk20bk
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views

Code Word

Uploaded by

kiet.phamk20bk
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 4

function domain = xfem_explicit(varargin)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%
% 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.

%----- Integrator Options.


dt = 0.005; % Delta time per step.
ngp = 2; % Number of gauss points per dimension.
tint_type = 0; % Type of time integrator. 0 = velocity verlet, 1 = newmark-beta.
subint_tri = true; % Whether or not to subintegrate using triangles.
tri_ngp = 4; % Number of gauss points (total) for triangles.

%----- Abaqus mesh file.


mesh.scale = 1.0e0; % Scale the mesh for size-effect studies.
mesh.file = './meshes/xfem_simple.inp'; % Simple xfem test, 16 element square.

%----- Crack endpoints.


% crack = []; % No crack.
crack = [-2.0, 0.0; 2.0, 0.0]; % Crack xfem_simple.inp down the middle.

%----- Boundary Conditions, one per row.


% Use -inf or inf to indicate min or max coordinate of a dimension.
%-- X-velocities and Y-velocities, [x coord, velocity] or [y coord, velocity].
% bc.vx = [-inf, 0.0];
% bc.vy = [inf, 0.5; % Pull top and bottom.
% -inf, -0.5];
bc.vy = [-inf, -0.5]; % Pull down on bottom edge.

%----- Mass Matrix Options.


mass_type = 0; % 0 = row-summed. 1 = consistent. 2 = diagonalized.
lump_non_xfem = 1; % if(consistent) Lump the standand DOFs.
lump_xfem = 0; % if(consistent) Lump standard part of XFEM DOFs.
ignore_muq = 1; % if(row-summed) Ignore the MUQ terms.
%--- Recommended: comment/uncomment lines below to set multiple mass options at once.
% mass_type=1; lump_non_xfem=0; lump_xfem=0; %---> Exact solution.
% mass_type=1; lump_non_xfem=1; lump_xfem=0; %---> Exact XFEM solution, common FEM lumping.
mass_type=0; ignore_muq=1; %---> Next best. Some forces across crack.
% mass_type=2; %---> Poor in general.

% 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

domain.sdf = LS.sdf(crack,domain); % Calculate the sdf at every node.


domain = SINT.quadpoints(domain); % Calculate the new quadpoints.
calculate_mass_matrix(); % Calculate the mass matrix.

% Create the output figure.


figure(); title(fig.title); fig.axis = gca; fig.handle = gcf;

%----------------------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

% Calculate the mass matrix.


function calculate_mass_matrix()
if(mass_type==1) % Consistent.
domain.inv_mass = consistent_mass_matrix(lump_non_xfem, lump_xfem);
elseif(mass_type==2) % Diagonalized.
invM = diagonal_mass_matrix();
domain.inv_mass = invM(1:size(invM,1)/2,:);
domain.xfem.inv_mass = invM(size(invM,1)/2+1:end,:);
elseif(mass_type==0) % Row-Summed.
invM = row_sum_mass_matrix(ignore_muq);
domain.inv_mass = invM(1:size(invM,1)/2,:);
domain.xfem.inv_mass = invM(size(invM,1)/2+1:end,:);
else
disp('Invalid type choice for mass matrix.');
end
disp('Done calculating mass matrix.');
end

% Calculate the consistent mass matrix. Optionally lump


% the non-xfem degrees of freedom using row-sum. Optionally
% lump MUU on the xfem DOFs using row-sum.
function [invM] = consistent_mass_matrix(lump_non_xfem, lump_xfem)
name = 'Consistent mass matrix';
if(lump_non_xfem) name = strcat(name,', with FEM lumping'); end
if(lump_xfem) name = strcat(name,', with partial XFEM lumping'); end
disp(strcat(name,'...'));
fig.title = {fig.title; name};

[MUU,MUQ,MQQ] = FEM.mass_matrices(domain, lump_non_xfem, lump_xfem);


M = [MUU, MUQ; MUQ', MQQ];
figure(); spy(M);
invM = inv(M);
end

% Calculate the diagonalized mass matrix.


function [invM] = diagonal_mass_matrix()
name = 'Diagonalized mass matrix';
disp(strcat(name,'...'));
fig.title = {fig.title; name};

% Calculate the mass matrices, but we only need MUU.


[MUU,MUQ,MQQ] = FEM.mass_matrices(domain,true,true);
MQ = sparse(domain.nn,1);
% Calculate the XFEM mass matrix.
for(e=1:domain.ne)
element = domain.element(e);
X = domain.gather(domain.X,e);
conn = domain.conn(e,:);
for(q=1:length(element.gp))
if(element.xfem)
detJ = det(FEM.J(element,X,element.gp(q,:)));
w = element.gw(q) * detJ;
N = element.N(element.gp(q,:),false);
P = element.N(element.gp(q,:),true);
% Element mass matrices.
ml = w * rho / element.nne;
% Scatter.
for(i=1:element.nne)
MQ(conn(i)) = MQ(conn(i)) + ml;
end
end
end
end
M = [sum(MUU,2); MQ];
invM = 1.0./M;
end

% Calculate the row-summed mass matrix.


function [invM] = row_sum_mass_matrix(ignore_muq)
name = 'Row-summed mass matrix';
if(ignore_muq) name = strcat(name,', ignoring MUQ terms'); end
disp(strcat(name,'...'));
fig.title = {fig.title; name};

[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

You might also like