Where \(\left \vert D\right \vert \) is the determinant of \(\begin {pmatrix} 1 & x_{1} & y_{1}\\ 1 & x_{2} & y_{2}\\ 1 & x_{3} & y_{3}\end {pmatrix} \) which is \(\left \vert D\right \vert =-y_{1}x_{2}+x_{3}y_{1}+x_{1}y_{2}-x_{3}y_{2}-x_{1}y_{3}+x_{2}y_{3}\).
This quantity is twice the area of the triangle \(A=\frac {1}{2}\left ( x_{1}\left ( y_{2}-y_{3}\right ) +x_{2}\left ( y_{3}-y_{1}\right ) +x_{3}\left ( y_{1}-y_{2}\right ) \right ) \).
Substituting (2) into (1) in order to find the shape functions gives
Now that the shape functions are found, the test or weight function \(w\left ( x,y\right ) \) can be found. Since \(w_{i}\left ( x,y\right ) =\frac {\partial \tilde {u}}{\partial \tilde {u}_{i}}\) for \(i=1,2,3\), therefore this results in
And similarly for other \(f\left ( x,y\right ) \). These were all integrated off-line and the resulting expression evaluated during the run of the program. These expression are all functions of the node coordinates \(\left ( x_{1},y_{1},x_{2},y_{2},x_{3},y_{3}\right ) \). No actual integration is done in the code, but only evaluation of the integration result obtained. The integration was done using Mathematica. These are the results for the three functions of interest. The integration was done on two
triangles. The odd numbered ones and the even numbered ones due to the node numbering difference. For odd numbered triangles, the integration limits are \(\int \limits _{x_1}^{x_2}\int \limits _{y_1}^{y_{3}-x}dydx\) while on the even numbered elements the limits are \(\int \limits _{x_{2}}^{x_{1}}\int \limits _{y_1}^{y_{2}-x}dydx\) as shown in this diagram
Note that this is not how integration is normally done in actual finite element methods. Using Gaussian quadrature method is the recommended way. This method was done here for learning and to compare.
4.16.1 case 1
Case \(f\left ( x,y\right )=1\). For odd numbered elements
This is an implementation of the above for \(f(x,y)=1\). The coordinates mapping was first carried out in order to map each elements local node numbers to the global node numbering so we know where to add each element stiffness matrix to the global stiffness matrix. Also we need to build the mapping of each element to the physical coordinates of its local node number 1 to use for calculating the force vector since that depends
on physical location of each element.
The mapping of physical coordinate location relative to the global frame of reference is shown below
functionmatlab_98()closeall;clearall;number_of_elements=[16*264*2 256*2 625*2];function_string={'1'};%function_handles={@f_1,@f_xy,@f_2};%somethingwrong with the other%cases,need to work more on it.function_handles={@f_1};figure_image_file={'matlab_e98_1'};fori=1:length(function_handles)forj=1:length(number_of_elements)plot_file=sprintf('%s_%d',figure_image_file{i},...number_of_elements(j));closeall;solve_poisson_2D_square(function_handles{i},...function_string{i},number_of_elements(j),plot_file);endendend%----------------------------------functionk_local=getk(area,x1,y1,x2,y2,x3,y3)k11=(y2-y3)^2+(x3-x2)^2;k12=(y2-y3)*(y3-y1)+(x3-x2)*(x1-x3);k13=(y2-y3)*(y1-y2)+(x3-x2)*(x2-x1);k22=(y3-y1)^2+(x1-x3)^2;k23=(y3-y1)*(y1-y2)+(x1-x3)*(x2-x1);k33=(y1-y2)^2+(x2-x1)^2;k_local= [k11 k12 k13;k12 k22 k23;k13 k23 k33];k_local= k_local/(4*area);end%----------------------------------------------------%usethis for f(x,y)=1functionf_local=f_1(area,x1,y1,x2,y2,x3,y3,ele)ifmod(ele,2)f_local=[(1/(12*area))*((x1 - x2)*(x2^3 + x1^2*...(x2 - x3 + 2*y2 - 2*y3) +...3*x3*(y1 - y3)*(y1 - 2*y2 + y3) - x2^2*(x3 - 2*y2 + 2*y3) -...3*x2*(y1^2 + x3*y2 - x3*y3 + y2*y3 - y1*(y2 + y3)) + x1*(x2^2 -...3*(y2 - y3)*(x3 - y1 + y3) - x2*(x3 - 2*y2 + 2*y3))));-((1/(12*area))*((x1 - x2)*(x1^3 + x1^2*(x2 - x3 + 2*y1 - 2*y3) -...3*x3*(y1 - y3)^2 - 3*x2*(y1 - y3)*(x3 - y1 + y3) -...x2^2*(x3 - 2*y1 + 2*y3) + x1*(x2^2 + 3*x3*(-y1 + y3) -...x2*(x3 - 2*y1 + 2*y3)))));((x1 - x2)^2*(x1^2 + x2^2 + x1*(x2 + 2*y1 + y2 - 3*y3) +...x2*(y1 + 2*y2 - 3*y3) + 3*(y1 - y3)*(y2 - y3)))/(12*area)];elsef_local=[((x1 - x2)*(x2^3 + 3*x3*(y1 - y2)^2 + x1*(x2^2 +...3*(y1 - y2)*(y2 - y3) - x2*(x3 + y2 - y3)) + x1^2*...(x2 - x3 + 2*y2 - 2*y3) -...3*x2*(y1 - y2)*(y1 - y3) - x2^2*(x3 + y2 - y3)))/(12*area);-((1/(12*area))*((x1 - x2)*(x1^3 - 3*x3*(y1 - y2)^2 -...3*x2*(y1 - y2)*(x3 - y1 + y3) + x1^2*...(x2 - x3 + 2*y1 - 3*y2 + y3) -...x2^2*(x3 - 2*y1 + 2*y3) + x1*(x2^2 - 3*(y1 - y2)*(x3 + y2 - y3)...+ x2*(-x3 + 2*y1 - 3*y2 + y3)))));((x1 - x2)^2*(x1^2 + x1*(x2 + 2*y1 - 2*y2) + ...x2*(x2 + y1 - y2)))/(12*area)];endend%----------------------------------------------------functionsolve_poisson_2D_square(fh,rhs,M,plot_file)%fhis function which evaluate the force vector%rhsis string which is the f(x,y), for plotting only%M=totalnumber of elementsL= 1;%lengthof gridN= 3;%numberof nodes per elementh=(L/sqrt(M/2));%areais same for each element, otherwise use%area= 0.5*(x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2));area=(1/2)*h^2;N1=sqrt(M/2)+1;%numberof nodes per edgedof=3;nodes= N1^2;%totalnumber of nodeskk=zeros(nodes);%globalstiffness vectorf=zeros(nodes,1);%globalforce vectormtb= generate_coordinates_table(M);fmtb= generate_physical_coordinates_table(M,h);fori = 1:Mx1 = fmtb(i,1); y1 = fmtb(i,2);x2 = fmtb(i,3); y2 = fmtb(i,4);x3 = fmtb(i,5); y3 = fmtb(i,6);k_local=getk(area,x1,y1,x2,y2,x3,y3);%callto load different force vector, pre-computed offlinef_local=fh(area,x1,y1,x2,y2,x3,y3,i);forii = 1:N%assembleforce vector and global stiffness matrixf(mtb(i,ii)) = f(mtb(i,ii)) + f_local(ii);forjj = 1:Nkk(mtb(i,ii),mtb(i,jj)) = kk(mtb(i,ii),mtb(i,jj))+...k_local(ii,jj);endendend%fixthe global stiffness matrix and force vector for B.C.edge_nodes=[1:N1(N1+1):N1:nodes-N1+1 ...(2*N1):N1:nodes nodes-N1+2:nodes-1];fori=1:length(edge_nodes)z=edge_nodes(i);kk(z,:)=0;f(z)=0;endfori=1:length(edge_nodes)z=edge_nodes(i);kk(z,z)=1;endy=kk\f;%solveZ=reshape(y,N1,N1);[X,Y]=meshgrid(0:h:1,0:h:1);h=surf(X,Y,Z);shadinginterpset(h','edgecolor','k');set(gcf,'defaulttextinterpreter','latex');plot_title=sprintf('$\\nabla^2u=%s$, number of elements $%d$',rhs,M);title(plot_title,'fontweight','bold','fontsize',14);print(gcf,'-dpdf','-r600',['images/',plot_file]);print(gcf,'-dpng','-r300',['images/',plot_file]);figure;[C,h]= contourf(X,Y,Z);clabel(C,h)set(gcf,'defaulttextinterpreter','latex');title(plot_title,'fontweight','bold','fontsize',14);colormapcoolprint(gcf,'-dpdf','-r300',['images/',plot_file,'_c']);print(gcf,'-dpng','-r300',['images/',plot_file,'_c']);end%----------------------------------------------------functionA=generate_coordinates_table(M)%M=number_of_elementsA=zeros(M,3);n=2*sqrt(M/2);%numberof elements per rowfori=1:n/2forj=1:nele=j+n*(i-1);ifj==1A(ele,:)=[(n/2+1)*(i-1)+1 (n/2+1)*(i-1)+2 (n/2+1)*i+1];elseifmod(j,2)A(ele,:) =[A(ele-1,3) A(ele-1,3)+1 A(ele-1,1)];elseA(ele,:) =[A(ele-1,3)+1 A(ele-1,3) A(ele-1,2)];endendendendend%----------------------------------------------------functionA=generate_physical_coordinates_table(M,h)%M=number_of_elementsA=zeros(M,6);n=2*sqrt(M/2);%numberof elements per rowfori=1:n/2forj=1:nele=j+n*(i-1);ifj==1A(ele,:)=[0 (i-1)*h h (i-1)*h 0 i*h];elseifmod(j,2)A(ele,:) =[A(ele-1,5) A(ele-1,6) ...A(ele-1,5)+h A(ele-1,6) A(ele-1,1) A(ele-1,2)];elseA(ele,:) =[A(ele-1,5)+h A(ele-1,6) ...A(ele-1,5) A(ele-1,6) A(ele-1,3) A(ele-1,4)];endendendendend
Here is the output for the three force functions, for different number of elements.