Skip to content

Commit 550b46a

Browse files
authored
Merge pull request #8 from jessdtate/master
Adding matlab inverse examples
2 parents 1060c0e + e32e2d5 commit 550b46a

File tree

99 files changed

+17362
-1767
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+17362
-1767
lines changed
242 KB
Binary file not shown.
969 KB
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

MatlabLibrary/README.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
README
2+
======
3+
4+
This directory contains a library of Matlab functions developed
5+
at the SCI institute and the CIBC, which are provided to extend the basic Matlab
6+
functions with code which helps in Biological Simulation Applications
7+
and with the integration into SCIRun.
8+
9+
The functions in this library are organized in directories which correspond
10+
to different projects being pursued at the SCI institute and the CIBC.
11+
12+
Add this directory and all the subdirectories to your matlab path to use these
13+
functions in SCIRun and the Fwd/Inv Toolkit.
14+
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
function [ LocMassMat, jcbInt ] = BuildLocMassMat_LinearTet( rhsType,vertX, vertY, vertZ, ws, phi )
2+
% This function build the local mass matrix system. Only works for linear tet element.
3+
% It hard codes the calculation of derivatives, quadratures are used only for integration
4+
%Copyright: Dafang Wang, SCI Institute, 2008-01-30
5+
6+
% rhsType: rright hand side type, 0 for laplace
7+
% elmtOrder the order of the base test polynomials,1 for linear, 2 for quadratic
8+
% vertX: x-coordinates for 4 vertices of the tet
9+
% vertY, vertZ: same as vertX
10+
% zp, ws, the quadrature points and weights in x,y,z dimensions respectively.
11+
%
12+
% IMPORTANT:
13+
% Basis func phi are values defined over quaduatures. It doesn't matter whether '-1to1' or '0to1' space.
14+
% The integration is done based on the '-1to1' tet. The weights have been set in that way.
15+
%
16+
%Output:
17+
18+
w_x = ws(:,1);
19+
w_y = ws(:,2);
20+
w_z = ws(:,3);
21+
localMatDim = 4;
22+
23+
%calculate the jacobi from [-1,1] std tet to physical tet elements
24+
[ jcbInt, jcbmatInt ] = JcbStdTet2GeneralTet( vertX, vertY, vertZ, '-1to1' );
25+
26+
LocMassMat = zeros( localMatDim, localMatDim);
27+
28+
for p = 1:localMatDim
29+
for q = p:localMatDim
30+
integrand = phi(:,:,:,p) .* phi(:,:,:,q);
31+
LocMassMat(p,q) = IntegrationInTet(integrand, w_x, w_y, w_z, jcbInt );
32+
LocMassMat(q,p) = LocMassMat(p,q);
33+
end
34+
end
35+
return;
36+
37+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38+
% calculate the integration in the tet, follow the section 4.1.1.2 in spencer's book
39+
% jcb, the jacobian from [-1,1] tet to physical tet, wx,wy,wz are weights
40+
% derived from [-1,1] and have been adapted for tet integration
41+
function r = IntegrationInTet(f, wx, wy, wz, jcb )
42+
nx = length(wx); ny = length(wy); nz = length(wz);
43+
for i = 1:nz
44+
f(:,:, i ) = f(:,:,i) * wz(i);
45+
end
46+
for i = 1:ny
47+
f(:,i,:) = f(:,i,:) * wy(i);
48+
end
49+
for i = 1:1:nx
50+
f(i,:,:) = f(i,:,:) * wx( i );
51+
end
52+
r = sum(sum(sum(f ) ) ) * abs(jcb );
53+
return;
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
function [ LocStMat, LocDerivMat, vol, jcbInt, localRHS ] = BuildLocStiffMat_LinearTet( rhsFlag, ...
2+
conduct, vertX, vertY, vertZ, varargin)
3+
% This function build the local stiffness matrix system
4+
% 1. It hard codes the calculation of derivatives
5+
% 2. The integration in the stiffness matrix is hard coded, as the derivatives are all zero.
6+
% 3. If right-hand size source is needed, quadratures are used for its integration.
7+
% 4. It differs from BuildLocStMatTet() in that it doesn't use quadrature for integration
8+
%Copyright: Dafang Wang, SCI Institute, 2011-10-30
9+
10+
% rhsType: right hand side type, 0 for laplace
11+
% rhsFlag: 1 if compute rhs
12+
% conduct: the conductivity within this element
13+
% vertX: x-coordinates for 4 vertices of the tet
14+
% vertY, vertZ: same as vertX
15+
% coefmatBase: each column is the coefficient of the basis in [0,1] canonical basis
16+
% zp, ws, the quadrature points and weights in x,y,z dimensions respectively.
17+
% Note that quadratures points are defined within a [-1,1] cube, but the
18+
% weights have been adapted for integration in tetrahedra
19+
20+
% Output:
21+
% - vol: element volume
22+
23+
localMatDim = 4;
24+
LocStMat = zeros(4,4); LocDerivMat = zeros(3,4);
25+
26+
%Calculate the coefficients of basis functions in the current tet, in physical space
27+
coefmatBase = CalPhyBasisTet( 1, [vertX, vertY, vertZ] );
28+
for i = 1:4
29+
LocDerivMat(:, i ) = coefmatBase( 2:4, i ); %each column contains the dx, dy, dz for one basis func
30+
end
31+
%grad(u) = localDerivMat * [u1;u2;u3; u4]; the field value at 4 vertices
32+
33+
%calculate the jacobi from [-1,1] std tet to physical tet elements
34+
[ jcbInt, jcbmatInt ] = JcbStdTet2GeneralTet( vertX, vertY, vertZ, '-1to1' );
35+
vol = ComputeTetVolume( [vertX, vertY, vertZ] );
36+
37+
LocStMat = zeros( localMatDim, localMatDim);
38+
for i =1:4
39+
for j = 1: i
40+
k = (conduct * LocDerivMat(:, j) )' * LocDerivMat(:, i) * vol;
41+
LocStMat( i, j ) = k;
42+
LocStMat( j, i ) = k;
43+
end
44+
end
45+
46+
if rhsFlag == 1 %need to compute rhs
47+
if ~exist('varargin') disp('BuildLocStiffMat_LinearTet.m: error \n'); return; end
48+
rhsType = varargin{1};
49+
if rhsType == 0
50+
localRHS = zeros( localMatDim, 1);
51+
else %use quadratuves
52+
zp = varargin{2}; ws = varargin{3};
53+
z_x = zp(:,1); w_x = ws(:,1);
54+
z_y = zp(:,2); w_y = ws(:,2);
55+
z_z = zp(:,3); w_z = ws(:,3);
56+
qdrNumX = length(z_x); qdrNumY = length(z_y); qdrNumZ = length(z_z);
57+
elmtX = zeros(qdrNumX, qdrNumY, qdrNumZ);
58+
[elmtX, elmtY, elmtZ] = TransformStdQdr2PhySpace(z_x, z_y, z_z, vertX, vertY, vertZ, 'Tet');
59+
vecXYZ = cat(4, elmtX, elmtY, elmtZ); %the last dimension is the xyz value
60+
61+
[phi, phidX, phidY, phidZ] = EvalBasisTet(elmtOrder, coefmatBase, vecXYZ );
62+
63+
%calculate the rhs source term
64+
eF = Test_Right_Side_Function( 3, rhsType, conduct, elmtX, elmtY, elmtZ );
65+
for p = 1:localMatDim
66+
rhsTerm = phi(:,:,:,p).* eF;
67+
localRHS( p,1 ) = IntegrationInTet(rhsTerm, w_x, w_y, w_z, jcbInt );
68+
end
69+
end
70+
end
71+
72+
73+
return;
74+
end
75+
76+
function [vol] = ComputeTetVolume( vertices )
77+
78+
vol = elemVolumeCalculation([1 2 3 4], vertices);
79+
80+
end
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
%Build FE-based matrices to be used for total variation
2+
clear;
3+
filename = '../ts_ht1_mesh1_Tr1.mat';
4+
FileOut = 'tvFE_mesh1_Tr1.mat';
5+
load(filename);
6+
7+
feDerivMat = zeros( eleNumH, 3, 4); % partial deriv in each element
8+
feStiffMat = zeros( eleNumH, 4, 4); %stiffness matrix in each cell
9+
10+
% stH = sparse( ndNumH, ndNumH);
11+
conduct = eye(3,3);
12+
eleVol_H = zeros( eleNumH,1);
13+
14+
%%%%%%%%%%%%% feDerivMat and feStiffMat
15+
16+
%-----------------Build the stiffness matrix. -----------------
17+
for i = 1:eleNumH
18+
ch = elmtH( i, 1:4);
19+
vx = ndMatH( ch, 1); vy = ndMatH(ch, 2); vz = ndMatH(ch, 3);
20+
21+
[ LocStMat, LocDerivMat, vol ] = BuildLocStiffMat_LinearTet( 0, conduct, vx, vy, vz);
22+
eleVol_H( i ) = vol;
23+
feDerivMat( i, :, :) = LocDerivMat;
24+
feStiffMat( i, :, :) = LocStMat;
25+
% stH( ch, ch) = stH(ch, ch) + LocStMat;
26+
end
27+
% full( MatrixDiff( stH, stMatH_std)) %validation
28+
29+
%-----------------Build the mass matrix. -----------------
30+
[z_x, w_x] = JacobiGLZW( 4, 0, 0);
31+
[z_y, w_y] = JacobiGRZW( 4, 1, 0 ); w_y = w_y / 2;
32+
[z_z, w_z] = JacobiGRZW( 4, 2, 0 ); w_z = w_z / 4;
33+
zpTet = [ z_x, z_y, z_z]; wsTet = [w_x, w_y, w_z];
34+
qdTet = Transform2StdTetSpace( z_x, z_y, z_z, '0to1');
35+
coefmatBaseTet = LocalCanonicalTetBasis('Base', 1);
36+
phiTet = EvalBasisTet(1, coefmatBaseTet, qdTet);
37+
38+
gMassMat = sparse( ndNum, ndNum);
39+
for i = 1:eleNum
40+
cn = Elmt( i, :);
41+
vx = NdMat(cn, 1); vy = NdMat(cn,2); vz = NdMat(cn, 3);
42+
[ locMassMat, jcbInt ] = BuildLocMassMat_LinearTet( 0,vx, vy, vz, wsTet, phiTet );
43+
gMassMat( cn, cn) = gMassMat(cn, cn) + locMassMat;
44+
end
45+
46+
%-----------------Build the FE matrix for dual -----------------
47+
[z_x, w_x] = JacobiGLZW( 4, 0, 0);
48+
[z_y, w_y] = JacobiGRZW( 4, 1, 0 ); w_y = w_y / 2;
49+
[z_z, w_z] = JacobiGRZW( 4, 2, 0 ); w_z = w_z / 4;
50+
zpTet = [ z_x, z_y, z_z]; wsTet = [w_x, w_y, w_z];
51+
qdTet = Transform2StdTetSpace( z_x, z_y, z_z, '0to1');
52+
coefmatBaseTet = LocalCanonicalTetBasis('Base', 1);
53+
phiTet = EvalBasisTet(1, coefmatBaseTet, qdTet);
54+
55+
Ax = sparse( ndNumH, ndNumH); Ay = Ax; Az = Ax;
56+
for i = 1:eleNumH
57+
ch = elmtH( i, 1:4);
58+
vx = ndMatH( ch, 1); vy = ndMatH(ch, 2); vz = ndMatH(ch, 3);
59+
locDerivMat = squeeze(feDerivMat( i, :, :));
60+
[ locAx, locAy, locAz ] = BuildLocCrossDerivMat_LinearTet( vx, vy, vz, wsTet, phiTet, locDerivMat );
61+
62+
Ax( ch, ch) = Ax( ch, ch) + locAx;
63+
Ay( ch, ch) = Ay( ch, ch) + locAy;
64+
Az( ch, ch) = Az( ch, ch) + locAz;
65+
end
66+
67+
massMatT = full(gMassMat( ndv_TsSurf, ndv_TsSurf));
68+
M1 = mR' * (gStMat \ mQ'); %M1 is full matrix
69+
M1A = M1 \ [ Ax, Ay, Az];
70+
71+
%----------------------- End -------------------------------------------------
72+
clear i z_* w_* cn ch Loc*Mat loc*Mat vx vy vz opt jcb* locA* vol
73+
save( FileOut );
74+
75+
% %Compute true TV value
76+
% feGradMag = zeros( eleNumH, 1); %gradient magnitude
77+
% feGradMag0 = ComputeGradMagPerTet( elmtH, feDerivMat, vTMP0); %true grad mag
78+
% feTV0 = dot( eleVol_H, feGradMag0);
79+
80+
81+
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
function coefmat = CalPhyBasisTet( order, vts )
2+
% Each column of coefmat is the coefficients of the basis function defined
3+
% in a prism in physical domain. The vertices of the prism is given by vts
4+
5+
% Input: each row of vts gives the x/y/z coordinates of a vertice, the
6+
% ordering of vertices must follow the right-hand rule:
7+
% cross((v2-v1),(v3-v1)) = v4-v1
8+
9+
switch order
10+
case 1
11+
sz = 4;
12+
Lb = zeros(sz, sz);
13+
for i =1:sz
14+
x = vts(i,1);
15+
y = vts(i,2);
16+
z = vts(i,3);
17+
evec = [1, x, y, z];
18+
Lb( i, :) = evec;
19+
end
20+
rhs = eye(sz);
21+
coefmat = Lb \ rhs;
22+
23+
case 2
24+
sz = 10;
25+
Lb = zeros(sz, sz);
26+
Onode = zeros( sz, 3); %all vertices
27+
Onode(1:4,:) = vts;
28+
Onode( 5, :) = mean( vts([1,2], :) );
29+
Onode( 6, :) = mean( vts([1,3], :) );
30+
Onode( 7, :) = mean( vts([1,4], :) );
31+
Onode( 8, :) = mean( vts([2,3], :) );
32+
Onode( 9, :) = mean( vts([2,4], :) );
33+
Onode( 10, :) = mean( vts([3,4], :) );
34+
for s = 1:sz
35+
x = Onode(s,1);
36+
y = Onode(s,2);
37+
z = Onode(s,3);
38+
evec = [ 1, x, y, z, x*x, y*y, z*z, x*y, x*z, y*z];
39+
Lb( s, :) = evec;
40+
end
41+
rhs = eye(sz);
42+
coefmat = Lb \ rhs;
43+
44+
case 3
45+
% disp('CalPhyBasisTet(): cubic case needed to be completed');
46+
sz = 20;
47+
Lb = zeros(sz, sz);
48+
Onode = zeros( sz, 3); %all vertices
49+
%node:
50+
Onode(1:4,:) = vts;
51+
%edge:
52+
Onode( 5, :) = (2*vts(1,:) + vts(2,:) ) / 3; %x^2
53+
Onode( 6, :) = (vts(1,:) + 2*vts(2,:) ) / 3; %x^3
54+
Onode( 7, :) = (2*vts(1,:) + vts(3,:) ) / 3; %y^2
55+
Onode( 8, :) = (vts(1,:) + 2*vts(3,:) ) / 3; %y^3
56+
Onode( 9, :) = (2*vts(1,:) + vts(4,:) ) / 3; %z^2
57+
Onode( 10, :) = (vts(1,:) + 2*vts(4,:) ) / 3; %z^3;
58+
59+
Onode( 11, :) = (2*vts(2,:) + vts(3,:) ) / 3; %x^2 * y
60+
Onode( 12, :) = (vts(2,:) + 2*vts(3,:) ) /3; %x * y^2
61+
Onode( 13, :) = (2*vts(2,:) + vts(4,:) )/3; %x^2 * z
62+
Onode( 14, :) = (vts(2,:) + 2*vts(4,:) )/3; %x* z^2
63+
Onode( 15, :) = (2*vts(3,:) + vts(4,:) ) /3; %y^2 * z
64+
Onode( 16, :) = (vts(3,:) + 2*vts(4,:) ) /3; %y* z^2;
65+
66+
%face:
67+
Onode(17, :) = mean( [Onode(1,:); Onode(2,:); Onode(3,:)] ); %xy
68+
Onode(18, :) = mean( [Onode(1,:); Onode(2,:); Onode(4,:)] ); %xz
69+
Onode(19, :) = mean( [Onode(1,:); Onode(3,:); Onode(4,:)] ); %yz
70+
Onode(20, :) = mean( [Onode(2,:); Onode(3,:); Onode(4,:)] ); %xYz
71+
72+
for s = 1:sz
73+
x = Onode(s,1);
74+
y = Onode(s,2);
75+
z = Onode(s,3);
76+
xx = x*x; yy = y*y; zz = z*z;
77+
xy = x*y; yz=y*z; xz = x*z;
78+
ev = [ 1, x, y, z, xx, xx*x, yy, yy*y,zz, zz*z, xx*y, x*yy, xx*z, x*zz, yy*z, y*zz, xy, xz, yz, x*y*z ];
79+
Lb( s, :) = ev;
80+
end
81+
rhs = eye(sz);
82+
coefmat = Lb \ rhs;
83+
end
84+
return
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
function feGradMag = ComputeGradMagPerTet( elmtH, feDerivMat, v)
2+
%compute gradient magnitude for each linear tetrahedral element
3+
% Input:
4+
% - v: the field data located at nodes
5+
% - feDerivMat: a Nele*3*4 matrix, each 3*4 matric is the partial deriv for the 4 local basis functions in each ele
6+
% in 2D triangles, each tri has an 2*3 matrix for the partial deriv
7+
eleNumH = size( elmtH, 1);
8+
feGradMag = zeros( eleNumH, 1);
9+
for i = 1:eleNumH
10+
cv = v( elmtH(i,:) );
11+
feGradMag( i ) = norm( squeeze( feDerivMat(i,:,:) ) * cv, 2);
12+
end
13+
14+
end

0 commit comments

Comments
 (0)