⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 alg125.m

📁 Numerical Anaysis 8th Edition by Burden and Faires
💻 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 + -