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

Code Word

Uploaded by

kiet.phamk20bk
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views

Code Word

Uploaded by

kiet.phamk20bk
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
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