📄 alg125.m
字号:
% Finite Element Algorithm 12.5
%
% To approximate the solution to an elliptic partial-differential
% equation subject to Dirichlet, mixed, or Neumann boundary
% conditions:
%
% Input: see STEP 0
%
% Output: description of triangles, nodes, line integrals, basis
% functions, linear system to be solved, and the
% coefficients of the basis functions
%
%
% Step 0
% General outline
%
% 1. Triangles numbered: 1 to K for triangles with no edges on
% Script-S-1 or Script-S-2, K+1 to N for triangles with
% edges on script-S-2, N+1 to M for remaining triangles.
% Note: K=0 implies that no triangle is interior to D.
% Note: M=N implies that all triangles have edges on
% script-S-2.
%
% 2. Nodes numbered: 1 to LN for interior nodes and nodes on
% script-S-2, LN+1 to LM for nodes on script-S-1.
% Note: LM and LN represent lower case m and n resp.
% Note: LN=LM implies that script-S-1 contains no nodes.
% Note: If a node is on both script-S-1 and script-S-2, then
% it should be treated as if it were only on script-S-1.
%
% 3. NL=number of line segments on script-S-2
% line(I,J) is an NL by 2 array where
% line(I,1)= first node on line I and
% line(I,2)= second node on line I taken
% in positive direction along line I
%
% 4. For the node labelled KK,KK=1,...,LM we have:
% A) coordinates XX(KK),YY(KK)
% B) number of triangles in which KK is a vertex= LL(KK)
% C) II(KK,J) labels the triangles KK is in and
% NV(KK,J) labels which vertex node KK is for
% each J=1,...,LL(KK)
%
% 5. NTR is an M by 3 array where
% NTR(I,1)=node number of vertex 1 in triangle I
% NTR(I,2)=node number of vertex 2 in triangle I
% NTR(I,3)=node number of vertex 3 in triangle I
%
% 6. Function subprograms:
% A) P,Q,R,F,G,G1,G2 are the functions specified by
% the particular differential equation
% B) RR is the integrand
% R*N(J)*N(K) on triangle I in step 4
% C) FFF is the integrand F*N(J) on triangle I in step 4
% D) GG1=G1*N(J)*N(K)
% GG2=G2*N(J)
% GG3=G2*N(K)
% GG4=G1*N(J)*N(J)
% GG5=G1*N(K)*N(K)
% integrands in step 5
% E) QQ(FF) computes the double integral of any
% integrand FF over a triangle with vertices given by
% nodes J1,J2,J3 - the method is an O(H**2) approximation
% for triangles
% F) SQ(PP) computes the line integral of any integrand PP
% along the line from (XX(J1),YY(J1)) to (XX(J2),YY(J2))
% by using a parameterization given by:
% X=XX(J1)+(XX(J2)-XX(J1))*T
% Y=YY(J1)+(YY(J2)-YY(J1))*T
% for 0 <= t <= 1
% and applying Simpson's composite method with H=.01
%
% 7. Arrays:
% A) A,B,C are M by 3 arrays where the basis function N
% for the Ith triangle, Jth vertex is
% N(X,Y)=A(I,J)+B(I,J)*X+C(I,J)*Y
% for J=1,2,3 and I=1,2,...,M
% B) XX,YY are LM by 1 arrays to hold coordinates of nodes
% C) line,LL,II,NV,NTR have been explained above
% D) Gamma and Alpha are clear
%
% 8. Note that A,B,C,XX,YY,I,I1,I2,J1,J2,J3,Delta are reserved
% storage so that in any subprogram we know that
% triangle I has vertices (XX(J1),YY(J1)),(XX(J2),YY(J2)),
% (XX(J3),YY(J3)). That is, vertex 1 is node J1, vertex 2 is
% node J2, vertex 3 is node J3 unless a line integral is
% involved in which case the line integral goes from node J1
% to node J2 in triangle I or unless vertex I1 is node J1
% and vertex I2 is node J2 - the basis functions involve
% A(I,I1)+B(I,I1)*X+C(I,I1)*Y for vertex I1 in triangle I
% and A(I,I2)+B(I,I2)*X+C(I,I2)*Y for vertex I2 in triangle I
% delta is 1/2 the area of triangle I
%
% To change problems:
% 1) change functions P,Q,R,F,G,G1,G2
% 2) change data input for K,N,M,LN,LM,NL.
% 3) change data input for XX,YY,LLL,II,NV.
% 4) change data input for line.
syms('OK', 'AA', 'NAME', 'INP', 'K', 'N', 'M', 'LN1', 'LM', 'NL');
syms('KK', 'XX', 'YY', 'LLL', 'J', 'II', 'NV', 'LL', 'N1', 'N2');
syms('NTR', 'I', 'LINE', 'FLAG', 'OUP', 'K1', 'L', 'GAMMA');
syms('ALPHA', 'J1', 'J2', 'J3', 'DELTA', 'A', 'B', 'C', 'I1');
syms('JJ1', 'I2', 'JJ2', 'ZZ', 'HH', 'JI', 'XJ', 'XJ1', 'XJ2');
syms('XI1', 'XI2', 'INN', 'CCC', 'x', 's', 'y');
TRUE = 1;
FALSE = 0;
fprintf(1,'This is the Finite Element Method.\n');
OK = FALSE;
fprintf(1,'The input will be from a text file in the following form:\n');
fprintf(1,'K N M n m nl\n\n');
fprintf(1,'Each of the above is an integer -');
fprintf(1,'separate with at least one blank.\n\n');
fprintf(1,'Follow with the input for each node in the form:\n');
fprintf(1,'x-coord., y-coord., number of triangles in which the');
fprintf(1,' node is a vertex.\n\n');
fprintf(1,'Continue with the triangle number and vertex number for\n');
fprintf(1,'each triangle in which the node is a vertex.\n');
fprintf(1,'Separate each entry with at least one blank.\n\n');
fprintf(1,'After all nodes have been entered follow with information\n');
fprintf(1,'on the lines over which line integrals must be computed.\n');
fprintf(1,'The format of this data will be the node number of the\n');
fprintf(1,'starting node, followed by the node number of the ending\n');
fprintf(1,'node for each line, taken in the positive direction.\n');
fprintf(1,'There should be 2 * nl such entries, each an integer\n');
fprintf(1,'separated by a blank.\n\n');
fprintf(1,'Functions can be input or coded as procedures.\n');
fprintf(1,'The example has all functions as procedures.\n');
fprintf(1,'However, the functions could be input by uncommenting\n');
fprintf(1,'the code as indicated.\n');
fprintf(1,'Have the functions P,Q,R,F,G,G1,G2 been created and\n');
fprintf(1,'has the input file been created? Answer Y or N.\n');
AA = input(' ','s');
if AA == 'Y' | AA == 'y'
% Remove "%" from the following statements if functions are to be input.
% fprintf(1,'Input function P(X,Y) in terms of x and y\n');
% s = input(' ','s');
% P = inline(s,'x','y');
% fprintf(1,'Input function Q(X,Y) in terms of x and y\n');
% s = input(' ','s');
% Q = inline(s,'x','y');
% fprintf(1,'Input function R(X,Y) in terms of x and y\n');
% s = input(' ','s');
% R = inline(s,'x','y');
% fprintf(1,'Input function F(X,Y) in terms of x and y\n');
% s = input(' ','s');
% F = inline(s,'x','y');
% fprintf(1,'Input function G(X,Y) in terms of x and y\n');
% s = input(' ','s');
% G = inline(s,'x','y');
% fprintf(1,'Input function G1(X,Y) in terms of x and y\n');
% s = input(' ','s');
% G1 = inline(s,'x','y');
% fprintf(1,'Input function G2(X,Y) in terms of x and y\n');
% s = input(' ','s');
% G2 = inline(s,'x','y');
fprintf(1,'Input the file name in the form - drive:\\name.ext\n');
fprintf(1,'for example: A:\\DATA.DTA\n');
NAME = input(' ','s');
INP = fopen(NAME,'rt');
OK = TRUE;
K = fscanf(INP, '%d',1);
N = fscanf(INP, '%d',1);
M = fscanf(INP, '%d',1);
LN1 = fscanf(INP, '%d',1);
LM = fscanf(INP, '%d',1);
NL = fscanf(INP, '%d',1);
XX = zeros(1,LM);
YY = zeros(1,LM);
LL = zeros(1,LM);
II = zeros(LM,M);
NV = zeros(LM,M);
LINE = zeros(NL,2);
NTR = zeros(M,3);
A = zeros(M,3);
B = zeros(M,3);
C = zeros(M,3);
GAMMA = zeros(1,LM);
ALPHA = zeros(LN1,LN1+1);
for KK = 1 : LM
XX(KK) = fscanf(INP, '%f',1);
YY(KK) = fscanf(INP, '%f',1);
LLL = fscanf(INP, '%d',1);
for J = 1 : LLL
II(KK,J) = fscanf(INP, '%d',1);
NV(KK,J) = fscanf(INP, '%d',1);
end;
LL(KK) = LLL;
for J = 1 : LLL
N1 = II(KK,J);
N2 = NV(KK,J);
NTR(N1,N2) = KK;
end;
end;
if NL > 0
for I = 1 : NL
for J = 1 : 2
LINE(I,J) = fscanf(INP, '%d',1);
end;
end;
end;
fclose(INP);
else
fprintf(1,'The program will end so that the preparations\n');
fprintf(1,'can be completed.\n');
end;
if OK == TRUE
fprintf(1,'Choice of output method:\n');
fprintf(1,'1. Output to screen\n');
fprintf(1,'2. Output to text file\n');
fprintf(1,'Please enter 1 or 2.\n');
FLAG = input(' ');
if FLAG == 2
fprintf(1,'Input the file name in the form - drive:\\name.ext\n');
fprintf(1,'for example: A:\\OUTPUT.DTA\n');
NAME = input(' ','s');
OUP = fopen(NAME,'wt');
else
OUP = 1;
end;
fprintf(OUP, 'FINITE ELEMENT METHOD\n\n\n');
K1 = K+1;
N1 = LN1+1;
fprintf(OUP, 'Vertices and Nodes of Triangles\n');
fprintf(OUP, 'Triangle-node number for vertex 1 to 3\n');
for I = 1 : M
fprintf(OUP, '%5d', I);
for J = 1 : 3
fprintf(OUP, '%4d', NTR(I,J));
end;
fprintf(OUP, '\n');
end;
fprintf(OUP, 'x and y coordinates of nodes\n');
for KK = 1 : LM
fprintf(OUP, '%5d%11.8f%11.8f\n', KK, XX(KK), YY(KK));
end;
fprintf(OUP, 'Lines of the Domain\n');
for KK = 1 : NL
fprintf(OUP, '%5d%4d%4d\n', KK, LINE(KK,1), LINE(KK,2));
end;
% STEP 1
if LM ~= LN1
for L = N1 : LM
GAMMA(L) = G(XX(L),YY(L));
end;
end;
% STEP 2 - initialization of ALPHA - note that ALPHA(I,LN1+1) = BETA(I)
for I = 1 : LN1
for J = 1 : N1
ALPHA(I,J) = 0;
end;
end;
% STEPS 3, 4, and 6-12 are within the next loop
% for each triangle I let node J1 be vertex 1, node J2 be vertex 2
% and node J3 be vertex 3
% STEP 3
for I = 1 : M
J1 = NTR(I,1);
J2 = NTR(I,2);
J3 = NTR(I,3);
DELTA = XX(J2)*YY(J3)-XX(J3)*YY(J2)-XX(J1)*(YY(J3)-YY(J2));
DELTA = DELTA + YY(J1)*(XX(J3)-XX(J2));
A(I,1) = (XX(J2)*YY(J3)-YY(J2)*XX(J3))/DELTA;
B(I,1) = (YY(J2)-YY(J3))/DELTA;
C(I,1) = (XX(J3)-XX(J2))/DELTA;
A(I,2) = (XX(J3)*YY(J1)-YY(J3)*XX(J1))/DELTA;
B(I,2) = (YY(J3)-YY(J1))/DELTA;
C(I,2) = (XX(J1)-XX(J3))/DELTA;
A(I,3) = (XX(J1)*YY(J2)-YY(J1)*XX(J2))/DELTA;
B(I,3) = (YY(J1)-YY(J2))/DELTA;
C(I,3) = (XX(J2)-XX(J1))/DELTA;
% STEP 4
% I1 = J for STEP 4 and I1 = K for STEP 7
for I1 = 1 : 3
% STEP 8
JJ1 = NTR(I,I1);
% I2 = K for STEP 4 and I2 = J for STEP 9
for I2 = 1 : I1
% STEP 4 and STEP 10
JJ2 = NTR(I,I2);
ZZ = B(I,I1)*B(I,I2)*QQ(1,XX,YY,DELTA,J1,J2,J3,I1,I2,A,B,C);
ZZ = ZZ + C(I,I1)*C(I,I2)*QQ(2,XX,YY,DELTA,J1,J2,J3,I1,I2,A,B,C);
ZZ = ZZ - QQ(3,XX,YY,DELTA,J1,J2,J3,I1,I2,A,B,C);
% STEPS 11 and 12
if JJ1 <= LN1
if JJ2 <= LN1
ALPHA(JJ1,JJ2) = ALPHA(JJ1,JJ2)+ZZ;
if JJ1 ~= JJ2
ALPHA(JJ2,JJ1) = ALPHA(JJ2,JJ1)+ZZ;
end;
else
ALPHA(JJ1,N1) = ALPHA(JJ1,N1)-ZZ*GAMMA(JJ2);
end;
else
if JJ2 <= LN1
ALPHA(JJ2,N1) = ALPHA(JJ2,N1)-ZZ*GAMMA(JJ1);
end;
end;
end;
HH = -QQ(4,XX,YY,DELTA,J1,J2,J3,I1,I2,A,B,C);
if JJ1 <= LN1
ALPHA(JJ1,N1) = ALPHA(JJ1,N1)+HH;
end;
end;
end;
% output the basis functions
fprintf(OUP, 'Basis Functions\n');
fprintf(OUP, 'Triangle - Vertex - Node - Function\n');
for I = 1 : M
for J = 1 : 3
fprintf(OUP,'%4d%3d%3d%13.8f%13.8f',I,J,NTR(I,J),A(I,J),B(I,J));
fprintf(OUP,'%13.8f\n',C(I,J));
end;
end;
% STEP 5
% for each line segment JI = 1 ,..., NL and for each triangle
% I, I = K1 ,..., N which may contain line JI, search all 3 vertices
% for possible correspondences.
% STEP 5 and STEPS 13-19
if NL ~= 0 & N ~= K
for JI = 1 : NL
for I = K1 : N
for I1 = 1 : 3
% I1 = J in STEP 5 and I1 = K in STEP 14
% STEP 15
J1 = NTR(I,I1);
if LINE(JI,1) == J1
for I2 = 1 : 3
% I2 = K in STEP 5 and I2 = J in STEP 16
% STEP 17
J2 = NTR(I,I2);
if LINE(JI,2) == J2
% There is a correspondence of vertex I1 in triangle I with
% node J1 as the start of line JI and vertex I2 with
% node J2 as the end of line JI
% STEP 5
XJ = SQ(1,XX,YY,J1,J2,I,I1,I2,A,B,C);
XJ1 = SQ(4,XX,YY,J1,J2,I,I1,I2,A,B,C);
XJ2 = SQ(5,XX,YY,J1,J2,I,I1,I2,A,B,C);
XI1 = SQ(2,XX,YY,J1,J2,I,I1,I2,A,B,C);
XI2 = SQ(3,XX,YY,J1,J2,I,I1,I2,A,B,C);
% STEPS 8 and 19
if J1 <= LN1
if J2 <= LN1
ALPHA(J1,J1) = ALPHA(J1,J1)+XJ1;
ALPHA(J1,J2) = ALPHA(J1,J2)+XJ;
ALPHA(J2,J2) = ALPHA(J2,J2)+XJ2;
ALPHA(J2,J1) = ALPHA(J2,J1)+XJ;
ALPHA(J1,N1) = ALPHA(J1,N1)+XI1;
ALPHA(J2,N1) = ALPHA(J2,N1)+XI2;
else
ALPHA(J1,N1) = ALPHA(J1,N1)-XJ*GAMMA(J2)+XI1;
ALPHA(J1,J1) = ALPHA(J1,J1)+XJ1;
end;
else
if J2 <= LN1
ALPHA(J2,N1) = ALPHA(J2,N1)-XJ*GAMMA(J1)+XI2;
ALPHA(J2,J2) = ALPHA(J2,J2)+XJ2;
end;
end;
end;
end;
end;
end;
end;
end;
end;
% output ALPHA
fprintf(OUP, 'Matrix ALPHA follows:\n');
for I = 1 : LN1
fprintf(OUP, 'Row%4d\n', I);
for J = 1 : N1
fprintf(OUP, '%13.10e\n ', ALPHA(I,J));
end;
end;
fprintf(OUP, '\n');
% STEP 20
if LN1 > 1
INN = LN1-1;
for I = 1 : INN
I1 = I+1;
for J = I1 : LN1
CCC = ALPHA(J,I)/ALPHA(I,I);
for J1 = I1 : N1
ALPHA(J,J1) = ALPHA(J,J1)-CCC*ALPHA(I,J1);
end;
ALPHA(J,I) = 0;
end;
end;
end;
GAMMA(LN1) = ALPHA(LN1,N1)/ALPHA(LN1,LN1);
if LN1 > 1
for I = 1 : INN
J = LN1-I;
CCC = ALPHA(J,N1);
J1 = J+1;
for KK = J1 : LN1
CCC = CCC-ALPHA(J,KK)*GAMMA(KK);
end;
GAMMA(J) = CCC/ALPHA(J,J);
end;
end;
% STEP 21
% output gamma
fprintf(OUP, 'Coefficients of Basis Functions:\n');
for I = 1 : LM
LLL = LL(I);
fprintf(OUP, '%3d %14.8f %d', I, GAMMA(I), I);
for J = 1 : LLL
fprintf(OUP, '%4d', II(I,J));
end;
fprintf(OUP, '\n');
end;
if OUP ~= 1
fclose(OUP);
fprintf(1,'Output file %s created successfully \n',NAME);
end;
% STEP 23
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -