CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Wiki > PFV 3D diffusion matrix

PFV 3D diffusion matrix

From CFD-Wiki

(Difference between revisions)
Jump to: navigation, search
(Created page with "Function '''DMat3D8W.m''' for pressure-free velocity diffusion matrix <pre> </pre>")
 
Line 2: Line 2:
<pre>
<pre>
 +
function [Dm,RowNdx,ColNdx]=DMat3D8W(Xe, Elcon, nn2nft)
 +
% DMAT3D8W - Affine hexahedron (linear 3D Hermite) element diffusion matrix.
 +
%
 +
% 3D linear-complete, normal-conforming, divergence-free, Hermite basis
 +
%  functions on 8-node rectangular hexahedral elements with 6 DOF per node
 +
%  using Gauss quadrature on the 2x2x2 reference cube.
 +
% The assumed nodal numbering starts with 1 at the lower left corner (-1,-1,-1)
 +
%  of the element .
 +
%
 +
% Usage:
 +
%  [Dm,Rndx,Cndx] = DMat3D8W(Xe,Elcon,nn2nft)
 +
%  Xe(1,:) -  x-coordinates of 8 corner nodes of element. 
 +
%  Xe(2,:) -  y-coordinates of 8 corner nodes of element. 
 +
%  Xe(3,:) -  z-coordinates of 8 corner nodes of element. 
 +
%  Elcon(8) - connectivity matrix for this element, list of nodes.
 +
%  nn2nft(1,n) - global freedom number for node n.
 +
%  nn2nft(2,n) - global freedom type for node n.
 +
%
 +
% Calls:
 +
%  V8xyzcW(n,x,y,z).
 +
%
 +
% Jonas Holdeman, July 2011
 +
 +
% Constants and fixed data
 +
nc=[-1,-1,-1; 1,-1,-1; -1,1,-1; 1,1,-1; -1,-1,1; 1,-1,1; -1,1,1; 1,1,1]; % defines corner nodal order
 +
ndfn=6;        % number of degrees of freedom per node.
 +
nne=8;        % number of nodes per element
 +
ndfe=ndfn*nne;  % number of degrees of freedom per element (48)
 +
 +
% Define 3-point quadrature data once, on first call.
 +
% Gaussian weights and absissas to integrate 5th degree polynomials exactly on cube.
 +
global GQC3;
 +
if (isempty(GQC3))      % Define 3-point quadrature data once, on first call.
 +
  Aq=[-.774596669241483, .000000000000000,.774596669241483]; %Abs
 +
  Hq=[ .555555555555556, .888888888888889,.555555555555556]; %Wts
 +
  GQC3.xa=zeros(27,1); GQC3.ya=zeros(27,1); GQC3.za=zeros(27,1); GQC3.wt=zeros(27,1);
 +
  nr=0;
 +
  for nz=1:3; for ny=1:3; for nx=1:3
 +
      nr=nr+1; GQC3.xa(nr)=Aq(nx); GQC3.ya(nr)=Aq(ny); GQC3.za(nr)=Aq(nz);
 +
      GQC3.wt(nr)=Hq(nx)*Hq(ny)*Hq(nz);
 +
  end; end; end
 +
  GQC3.size=nr;
 +
end
 +
% Define 4-point quadrature data once, on first call.
 +
% Gaussian weights and absissas to integrate 7th degree polynomials exactly on cube.
 +
global GQC4;
 +
if (isempty(GQC4))      % Define 4-point quadrature data once, on first call.
 +
  Aq=[-.861136311594053,-.339981043584856,.339981043584856, .861136311594053]; %Abs
 +
  Hq=[ .347854845137454, .652145154862546,.652145154862546, .347854845137454]; %Wts
 +
  GQC4.xa=zeros(64,1); GQC4.ya=zeros(64,1); GQC4.za=zeros(64,1); GQC4.wt=zeros(64,1);
 +
  nr=0;
 +
  for nz=1:4; for ny=1:4; for nx=1:4
 +
      nr=nr+1; GQC4.xa(nr)=Aq(nx); GQC4.ya(nr)=Aq(ny); GQC4.za(nr)=Aq(nz);
 +
      GQC4.wt(nr)=Hq(nx)*Hq(ny)*Hq(nz);
 +
  end; end; end
 +
  GQC4.size=nr;
 +
end
 +
%--------------------------------------------------------------------
 +
%xa=GQC3.xa; ya=GQC3.ya; za=GQC3.za; W=GQC3.wt; Nq=GQC3.size;
 +
xa=GQC4.xa; ya=GQC4.ya; za=GQC4.za; W=GQC4.wt; Nq=GQC4.size;
 +
 +
% ---------------------------------------------------
 +
global Z3_V8xd; global Z3_V8yd; global Z3_V8zd;
 +
if (isempty(Z3_V8xd) | size(Z3_V8xd,2)~=Nq)
 +
  Z3_V8xd=cell(nne,Nq); Z3_V8yd=cell(nne,Nq); Z3_V8zd=cell(nne,Nq);
 +
  for k=1:Nq
 +
    for m=1:nne
 +
      ncm=nc(m,:);
 +
      [Z3_V8xd{m,k},Z3_V8yd{m,k},Z3_V8zd{m,k}]=V8xyzcW(ncm,xa(k),ya(k),za(k));
 +
    end
 +
  end
 +
end  % if (isempty(*))
 +
% ----------------- End fixed data ------------------
 +
%
 +
Ti=cell(nne);
 +
for m=1:nne
 +
  Jt=Xe*GTL(nc(:,:),nc(m,1),nc(m,2),nc(m,3));
 +
  Det=det(Jt);
 +
  JtiD=inv(Jt)*Det;
 +
  J=Jt';
 +
  Ti{m}=blkdiag(J,JtiD);
 +
end  % loop m
 +
 +
%Det=Jt(1,1)*Jt(2,2)*Jt(3,3)-Jt(1,1)*Jt(2,3)*Jt(3,2)-Jt(2,2)*Jt(1,3)*Jt(3,1)...
 +
%  -Jt(3,3)*Jt(1,2)*Jt(2,1)+Jt(1,2)*Jt(2,3)*Jt(3,1)+Jt(2,1)*Jt(1,3)*Jt(3,2);
 +
 +
Dm=zeros(ndfe,ndfe);        % Preallocate arrays
 +
dF1=zeros(3,ndfe); dF2=zeros(3,ndfe); dF3=zeros(3,ndfe);  % derivatives of shape functions
 +
 +
for k=1:Nq 
 +
  Jt=Xe*GTL(nc(:,:),xa(k),ya(k),za(k));    % transpose of Jacobian at (xa,ya,za)
 +
  Det=det(Jt);
 +
%  Det=Jt(1,1)*Jt(2,2)*Jt(3,3)-Jt(1,1)*Jt(2,3)*Jt(3,2)-Jt(2,2)*Jt(1,3)*Jt(3,1)...
 +
%  -Jt(3,3)*Jt(1,2)*Jt(2,1)+Jt(1,2)*Jt(2,3)*Jt(3,1)+Jt(2,1)*Jt(1,3)*Jt(3,2);
 +
  JtbD=Jt/Det;
 +
  Jti=inv(Jt);
 +
  JtiD=Jti*Det;
 +
  Ji=Jti';
 +
  for m=1:nne
 +
    mm=6*(m-1);  mm3=mm+1:mm+6;  ncm=nc(m,:);
 +
    dF1(:,mm3)=JtbD*(Ji(1,1)*Z3_V8xd{m,k}+Ji(1,2)*Z3_V8yd{m,k}+Ji(1,3)*Z3_V8zd{m,k})*Ti{m};
 +
    dF2(:,mm3)=JtbD*(Ji(2,1)*Z3_V8xd{m,k}+Ji(2,2)*Z3_V8yd{m,k}+Ji(2,3)*Z3_V8zd{m,k})*Ti{m};
 +
    dF3(:,mm3)=JtbD*(Ji(3,1)*Z3_V8xd{m,k}+Ji(3,2)*Z3_V8yd{m,k}+Ji(3,3)*Z3_V8zd{m,k})*Ti{m};
 +
  end  % loop m 
 +
 
 +
  Dm = Dm + (dF1'*dF1 + dF2'*dF2 + dF3'*dF3)*W(k)*Det;
 +
end  % loop k
 +
 +
gf=zeros(ndfe,1);
 +
m=0;
 +
for k=1:8
 +
  m=m+1; gf(m)=nn2nft(1,Elcon(k));  % get global freedom number
 +
  for k1=2:6
 +
    m=m+1; gf(m)=gf(m-1)+1;  % next
 +
  end  % if
 +
end %  loop on k
 +
RowNdx=repmat(gf,1,ndfe);
 +
ColNdx=RowNdx';
 +
RowNdx=reshape(RowNdx,ndfe*ndfe,1);
 +
ColNdx=reshape(ColNdx,ndfe*ndfe,1);
 +
Dm=reshape(Dm,ndfe*ndfe,1);
 +
return;
 +
 +
% ---------------------------------------------------------
 +
 +
function G=GTL(ni,q,r,s)
 +
% Transposed gradient (derivatives) of scalar trilinear mapping function.
 +
% The parameter ni can be a vector of coordinate pairs.
 +
G=[.125*ni(:,1).*(1+ni(:,2).*r).*(1+ni(:,3).*s), .125*ni(:,2).*(1+ni(:,1).*q).*(1+ni(:,3).*s), ...
 +
    .125*ni(:,3).*(1+ni(:,1).*q).*(1+ni(:,2).*r)];
 +
return;
</pre>
</pre>

Latest revision as of 12:17, 20 July 2011

Function DMat3D8W.m for pressure-free velocity diffusion matrix

function [Dm,RowNdx,ColNdx]=DMat3D8W(Xe, Elcon, nn2nft)
% DMAT3D8W - Affine hexahedron (linear 3D Hermite) element diffusion matrix.
%
% 3D linear-complete, normal-conforming, divergence-free, Hermite basis 
%   functions on 8-node rectangular hexahedral elements with 6 DOF per node 
%   using Gauss quadrature on the 2x2x2 reference cube. 
% The assumed nodal numbering starts with 1 at the lower left corner (-1,-1,-1) 
%   of the element . 
%
% Usage:
%   [Dm,Rndx,Cndx] = DMat3D8W(Xe,Elcon,nn2nft)
%   Xe(1,:) -  x-coordinates of 8 corner nodes of element.  
%   Xe(2,:) -  y-coordinates of 8 corner nodes of element.  
%   Xe(3,:) -  z-coordinates of 8 corner nodes of element.  
%   Elcon(8) - connectivity matrix for this element, list of nodes. 
%   nn2nft(1,n) - global freedom number for node n.
%   nn2nft(2,n) - global freedom type for node n.
%
% Calls:
%   V8xyzcW(n,x,y,z).
%
% Jonas Holdeman, July 2011


% Constants and fixed data
nc=[-1,-1,-1; 1,-1,-1; -1,1,-1; 1,1,-1; -1,-1,1; 1,-1,1; -1,1,1; 1,1,1]; % defines corner nodal order
ndfn=6;        % number of degrees of freedom per node. 
nne=8;         % number of nodes per element
ndfe=ndfn*nne;  % number of degrees of freedom per element (48)

% Define 3-point quadrature data once, on first call. 
% Gaussian weights and absissas to integrate 5th degree polynomials exactly on cube. 
global GQC3;
if (isempty(GQC3))       % Define 3-point quadrature data once, on first call. 
   Aq=[-.774596669241483, .000000000000000,.774596669241483]; %Abs
   Hq=[ .555555555555556, .888888888888889,.555555555555556]; %Wts
   GQC3.xa=zeros(27,1); GQC3.ya=zeros(27,1); GQC3.za=zeros(27,1); GQC3.wt=zeros(27,1); 
   nr=0; 
   for nz=1:3; for ny=1:3; for nx=1:3
       nr=nr+1; GQC3.xa(nr)=Aq(nx); GQC3.ya(nr)=Aq(ny); GQC3.za(nr)=Aq(nz); 
       GQC3.wt(nr)=Hq(nx)*Hq(ny)*Hq(nz);
   end; end; end
  GQC3.size=nr; 
end
% Define 4-point quadrature data once, on first call. 
% Gaussian weights and absissas to integrate 7th degree polynomials exactly on cube. 
global GQC4;
if (isempty(GQC4))       % Define 4-point quadrature data once, on first call. 
   Aq=[-.861136311594053,-.339981043584856,.339981043584856, .861136311594053]; %Abs
   Hq=[ .347854845137454, .652145154862546,.652145154862546, .347854845137454]; %Wts
   GQC4.xa=zeros(64,1); GQC4.ya=zeros(64,1); GQC4.za=zeros(64,1); GQC4.wt=zeros(64,1); 
   nr=0; 
   for nz=1:4; for ny=1:4; for nx=1:4
       nr=nr+1; GQC4.xa(nr)=Aq(nx); GQC4.ya(nr)=Aq(ny); GQC4.za(nr)=Aq(nz); 
       GQC4.wt(nr)=Hq(nx)*Hq(ny)*Hq(nz);
   end; end; end
  GQC4.size=nr; 
end
%--------------------------------------------------------------------
%xa=GQC3.xa; ya=GQC3.ya; za=GQC3.za; W=GQC3.wt; Nq=GQC3.size;
xa=GQC4.xa; ya=GQC4.ya; za=GQC4.za; W=GQC4.wt; Nq=GQC4.size;

% ---------------------------------------------------
global Z3_V8xd; global Z3_V8yd; global Z3_V8zd;
if (isempty(Z3_V8xd) | size(Z3_V8xd,2)~=Nq)
  Z3_V8xd=cell(nne,Nq); Z3_V8yd=cell(nne,Nq); Z3_V8zd=cell(nne,Nq);
  for k=1:Nq
    for m=1:nne
      ncm=nc(m,:);
      [Z3_V8xd{m,k},Z3_V8yd{m,k},Z3_V8zd{m,k}]=V8xyzcW(ncm,xa(k),ya(k),za(k));
    end
  end
end   % if (isempty(*))
% ----------------- End fixed data ------------------
%
Ti=cell(nne);
for m=1:nne
  Jt=Xe*GTL(nc(:,:),nc(m,1),nc(m,2),nc(m,3));
  Det=det(Jt);
  JtiD=inv(Jt)*Det;
  J=Jt';
  Ti{m}=blkdiag(J,JtiD);
end  % loop m

%Det=Jt(1,1)*Jt(2,2)*Jt(3,3)-Jt(1,1)*Jt(2,3)*Jt(3,2)-Jt(2,2)*Jt(1,3)*Jt(3,1)...
%   -Jt(3,3)*Jt(1,2)*Jt(2,1)+Jt(1,2)*Jt(2,3)*Jt(3,1)+Jt(2,1)*Jt(1,3)*Jt(3,2);

Dm=zeros(ndfe,ndfe);        % Preallocate arrays
dF1=zeros(3,ndfe); dF2=zeros(3,ndfe); dF3=zeros(3,ndfe);  % derivatives of shape functions

for k=1:Nq  
  Jt=Xe*GTL(nc(:,:),xa(k),ya(k),za(k));    % transpose of Jacobian at (xa,ya,za)
  Det=det(Jt);
%  Det=Jt(1,1)*Jt(2,2)*Jt(3,3)-Jt(1,1)*Jt(2,3)*Jt(3,2)-Jt(2,2)*Jt(1,3)*Jt(3,1)...
%   -Jt(3,3)*Jt(1,2)*Jt(2,1)+Jt(1,2)*Jt(2,3)*Jt(3,1)+Jt(2,1)*Jt(1,3)*Jt(3,2);
  JtbD=Jt/Det;
  Jti=inv(Jt); 
  JtiD=Jti*Det; 
  Ji=Jti';
  for m=1:nne
    mm=6*(m-1);  mm3=mm+1:mm+6;  ncm=nc(m,:);
    dF1(:,mm3)=JtbD*(Ji(1,1)*Z3_V8xd{m,k}+Ji(1,2)*Z3_V8yd{m,k}+Ji(1,3)*Z3_V8zd{m,k})*Ti{m};
    dF2(:,mm3)=JtbD*(Ji(2,1)*Z3_V8xd{m,k}+Ji(2,2)*Z3_V8yd{m,k}+Ji(2,3)*Z3_V8zd{m,k})*Ti{m};
    dF3(:,mm3)=JtbD*(Ji(3,1)*Z3_V8xd{m,k}+Ji(3,2)*Z3_V8yd{m,k}+Ji(3,3)*Z3_V8zd{m,k})*Ti{m};
  end   % loop m  
  
  Dm = Dm + (dF1'*dF1 + dF2'*dF2 + dF3'*dF3)*W(k)*Det;
end  % loop k 

gf=zeros(ndfe,1);
m=0;
for k=1:8
  m=m+1; gf(m)=nn2nft(1,Elcon(k));  % get global freedom number 
  for k1=2:6
    m=m+1; gf(m)=gf(m-1)+1;  % next 
  end  % if
end %  loop on k
RowNdx=repmat(gf,1,ndfe);
ColNdx=RowNdx';
RowNdx=reshape(RowNdx,ndfe*ndfe,1);
ColNdx=reshape(ColNdx,ndfe*ndfe,1); 
Dm=reshape(Dm,ndfe*ndfe,1);
return;

% ---------------------------------------------------------

function G=GTL(ni,q,r,s)
% Transposed gradient (derivatives) of scalar trilinear mapping function. 
% The parameter ni can be a vector of coordinate pairs. 
G=[.125*ni(:,1).*(1+ni(:,2).*r).*(1+ni(:,3).*s), .125*ni(:,2).*(1+ni(:,1).*q).*(1+ni(:,3).*s), ... 
    .125*ni(:,3).*(1+ni(:,1).*q).*(1+ni(:,2).*r)];
return;
My wiki